import sys import argparse import logging import configparser from pprint import pp from time import time from datetime import timedelta from pathlib import Path from distutils import dir_util import subprocess as sp _t0 = time() parser = argparse.ArgumentParser( description='Run the OpenFoam simulation' ) parser.add_argument('-c', '--config', default='config.ini', type=Path, help='Configuration file (default config.ini)') 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['main'].get('log_file', None), level=args.log_level ) log = logging.getLogger('openfoam') log.info('Starting program') input_dir = Path(config['main']['input_dir'], config['main']['case']) work_dir = Path(config['main']['work_dir']) if not work_dir.exists(): log.error(f'Work directory ({work_dir}) not found') sys.exit(1) case_dir = work_dir.joinpath(config['main']['case']) if case_dir.exists(): log.info(f'Deleting case ({case_dir})') dir_util.remove_tree(str(case_dir)) log.info(f'Copying case ({input_dir} -> {case_dir})') dir_util.copy_tree( str(input_dir), str(case_dir), ) if config['blockMesh'].getboolean('enable'): log.info('Running blockMesh') blockmesh_log = logging.getLogger('blockMesh') proc = sp.Popen( ('blockMesh'), cwd=case_dir, stdout=sp.PIPE, stderr=sp.PIPE, text=True, ) for line in proc.stdout: blockmesh_log.info(line[:-1]) for line in proc.stderr: blockmesh_log.error(line[:-1]) code = proc.wait() if code != 0: log.error('blockMesh failed') sys.exit(code) log.info(f'blockMesh finished successfully') if config['snappyHexMesh'].getboolean('enable'): log.info('Running snappyHexMesh') snappy_log = logging.getLogger('snappyHexMesh') proc = sp.Popen( ('snappyHexMesh', '-overwrite'), cwd=case_dir, stdout=sp.PIPE, stderr=sp.PIPE, text=True, ) for line in proc.stdout: snappy_log.info(line[:-1]) for line in proc.stderr: snappy_log.error(line[:-1]) code = proc.wait() if code != 0: log.error('snappyHexMesh failed') sys.exit(code) log.info(f'snappyHexMesh finished successfully') log.info('Copying 0.org -> 0') dir_util.copy_tree( str(case_dir.joinpath('0.org')), str(case_dir.joinpath('0')), ) if config['setFields'].getboolean('enable'): log.info('Running setFields') setfields_log = logging.getLogger('setFields') proc = sp.Popen( ('setFields'), cwd=case_dir, stdout=sp.PIPE, stderr=sp.PIPE, text=True, ) for line in proc.stdout: setfields_log.info(line[:-1]) for line in proc.stderr: setfields_log.info(line[:-1]) code = proc.wait() if code != 0: log.error('setFields failed') sys.exit(code) log.info(f'setFields finished successfully') if config['olaFlow'].getboolean('enable'): cmd = ('olaFlow') if config['parallel'].getboolean('enable'): cmd = ( 'mpirun', '-np', config['parallel'].getint('threads'), 'olaFlow', '-parallel' ) decpar_log = logging.getLogger('decomposePar') proc = sp.Popen( ('decomposePar'), cwd=case_dir, stdout=sp.PIPE, stderr=sp.PIPE, text=True, ) for line in proc.stdout: decpar_log.info(line[:-1]) for line in proc.stderr: decpar_log.error(line[:-1]) code = proc.wait() if code != 0: log.error('decomposePar failed') sys.exit(code) log.info(f'decomposePar finished successfully') log.info('Running olaFlow') olaflow_log = logging.getLogger('olaFlow') proc = sp.Popen( cmd, cwd=case_dir, stdout=sp.PIPE, stderr=sp.PIPE, text=True, ) for line in proc.stdout: olaflow_log.info(line[:-1]) for line in proc.stderr: olaflow_log.error(line[:-1]) code = proc.wait() if code != 0: log.error('olaFlow failed') sys.exit(code) log.info(f'olaFlow finished successfully') if config['parallel'].getboolean('enable') \ and config['reconstructPar'].getboolean('enable'): recpar_log = logging.getLogger('reconstructPar') proc = sp.Popen( ('reconstructPar'), cwd=case_dir, stdout=sp.PIPE, stderr=sp.PIPE, text=True, ) for line in proc.stdout: recpar_log.info(line[:-1]) for line in proc.stderr: recpar_log.error(line[:-1]) code = proc.wait() if code != 0: log.error('reconstructPar failed') sys.exit(code) log.info(f'reconstructPar finished successfully') log.info(f'Deleting processor directories') for proc_dir in case_dir.glob(r'processor*'): log.info(f'Deleting {proc_dir}') dir_util.remove_tree(str(proc_dir)) _t1 = time() log.info(f'Program ended successfully after {timedelta(seconds=_t1-_t0)}')