import sys import shutil import argparse import logging import configparser from time import time from datetime import timedelta from pathlib import Path from .grafana import Silencer from .stl import copy_stl from .run import run _t0 = time() parser = argparse.ArgumentParser( prog='run', description='Run the OpenFoam simulation', ) parser.add_argument('-c', '--config', default='config.ini', type=Path, help='Configuration file') parser.add_argument('-l', '--log-level', default='INFO', type=str, help='Log level') args = parser.parse_args() config = configparser.ConfigParser() config.read(args.config) logging.basicConfig( filename=config.get('main', 'log_file', fallback=None), level=args.log_level ) log = logging.getLogger('openfoam') log.info('Starting program') if config.getboolean('grafana', 'pause', fallback=False): log.info('Silencing Grafana alert') grafana = Silencer( url=config.get('grafana', 'url'), apikey=config.get('grafana', 'apikey'), ) grafana.silence_alert() input_dir = Path(config.get('main', 'input_dir'), config.get('main', 'case'))\ .expanduser() work_dir = Path(config.get('main', 'work_dir')).expanduser() if not work_dir.exists(): log.error(f'Work directory ({work_dir}) not found') sys.exit(1) case_dir = work_dir.joinpath(config.get('main', 'case')) if case_dir.exists(): log.info(f'Deleting case ({case_dir})') shutil.rmtree(case_dir) log.info(f'Copying case ({input_dir} -> {case_dir})') shutil.copytree(input_dir, case_dir) def step(command, alias=None): if alias == None: alias = command log.info(f'Running {alias}') code = run(command, case_dir, alias) if code != 0: log.error(f'{alias} failed') sys.exit(code) log.info(f'{alias} finished successfully') if config.getboolean('stl', 'copy', fallback=False): stl_in = Path(config.get('stl', 'from')).expanduser() if not stl_in.exists(): log.error(f'STL from directory does not exist ({stl_in})') sys.exit(1) log.info(f'Copying stl directory ({stl_in})') copy_stl(stl_in, case_dir) if config.getboolean('blockMesh', 'enable', fallback=False): step(('blockMesh')) if config.getboolean('snappyHexMesh', 'enable', fallback=False): step(('snappyHexMesh', '-overwrite'), 'snappyHexMesh') log.info('Copying 0.org -> 0') shutil.copytree( case_dir.joinpath('0.org'), case_dir.joinpath('0'), ) if config.getboolean('setFields', 'enable', fallback=False): step(('setFields')) if config.getboolean('olaFlow', 'enable', fallback=False): cmd = ('olaFlow') if config.getboolean('parallel', 'enable', fallback=False): cmd = ( 'mpirun', '-np', config.get('parallel', 'threads'), 'olaFlow', '-parallel' ) step(('decomposePar')) step(cmd, 'olaFlow') if config.getboolean('parallel', 'enable', fallback=False) \ and config.getboolean('reconstructPar', 'enable', fallback=False): step(('reconstructPar')) log.info(f'Deleting processor directories') for proc_dir in case_dir.glob(r'processor*'): log.info(f'Deleting {proc_dir}') shutil.rmtree(proc_dir) if config.getboolean('grafana', 'pause', fallback=False): log.info('Unsilencing Grafana alert') grafana.unsilence_alert() _t1 = time() log.info(f'Program ended successfully after {timedelta(seconds=_t1-_t0)}')