Source code for cansen.cansen

# Standard libraries
import sys
from multiprocessing import Pool

# Local imports
from . import utils
from .printer import Tee
from .run_cases import SimulationCase, MultiSimulationCase
from ._version import __version__


[docs]def worker(sim_index_tup): """Worker for multiprocessing of cases. :param sim_index_tup: Tuple containing the MultiSimulationCase object to be run and the index of current case for status messages. :return res: List of simulation results. """ sim, index = sim_index_tup sim.run_simulation() # store results if sim.keywords.get('eqRatio') is None: res = [sim.ignition_time, sim.keywords['pressure'], sim.keywords['temperature']] else: # store equivalence ratio if possible res = [sim.ignition_time, sim.keywords['pressure'], sim.keywords['temperature'], sim.keywords['eqRatio']] print('Done with ' + str(index)) return res
[docs]def main(filenames, convert, multi, num_proc, version): """The main driver function of CanSen. :param filenames: Dictionary of filenames related to the simulation. :param convert: Boolean indicating that the user wishes only to convert the input mechanism and quit. :param multi: Boolean indicating multiple cases to be run. :param num_proc: Number of processors to use for multiprocessing. :param version: Version string of CanSen. """ # Open the text output file from the printer module output_filename = filenames['output_filename'] out = None if multi: out = open(output_filename, 'w') else: out = Tee(output_filename, 'w') if not multi: # Print version information to screen at the start of the problem print("This is CanSen, the SENKIN-like wrapper for Cantera, " "written in Python.\nVersion: {!s}\n".format(version)) # Convert the mechanism if it is in CHEMKIN format. If ``convert`` # is True, exit the simulation. mech_filename = filenames['mech_filename'] thermo_filename = filenames['thermo_filename'] if mech_filename.endswith('.inp'): mech_filename = utils.convert_mech(mech_filename, thermo_filename) if convert: print('User requested conversion only. Goodbye.') sys.exit(0) # Run the simulation if multi: # Preprocess the input file to separate the various cases. input_files = utils.process_multi_input(filenames['input_filename']) # Create a pool based on the number of processors if num_proc is not None: pool = Pool(processes=num_proc) else: # use available number of processors by default pool = Pool() jobs = [] results = [] # prepare all cases for i, temp_file in enumerate(input_files): local_names = filenames.copy() local_names['input_filename'] = temp_file sim = MultiSimulationCase(local_names) jobs.append([sim, i]) jobs = tuple(jobs) results = pool.map(worker, jobs) # not adding more proceses pool.close() # ensure all finished pool.join() # clean up utils.remove_files(input_files) # write output print('# Ignition delay [s], Pressure [atm], Temperature [K], ' 'Equivalence ratio', file=out) for res in results: if len(res) == 3: line = '{:.8e} {:.2f} {:.1f}'.format(*res) elif len(res) == 4: line = '{:.8e} {:.2f} {:.1f} {:.2f}'.format(*res) print(line, file=out) else: sim = SimulationCase(filenames) sim.run_simulation() # Clean up out.close()
[docs]def cansen(argv): """CanSen - the SENKIN-like wrapper for Cantera written in Python. Usage: -i: Specify the simulation input file in SENKIN format. Required. -o: Specify the text output file. Optional, default: ``output.out`` -x: Specify the binary save output file. Optional, default: ``save.hdf`` -c: Specify the chemistry input file, in either CHEMKIN, Cantera CTI or CTML format. Optional, default: ``chem.xml`` -d: Specify the thermodynamic database. Optional if the thermodynamic database is specified in the chemistry input file. Otherwise, required. --convert: Convert the input mechanism to CTI format and quit. If ``--convert`` is specified, the SENKIN input file is optional. -m, --multi: Run multiple cases from the input file. Optional. If ``-m`` is used, must specify number of processors to be used (e.g., ``-m 4``). If ``--multi`` is specified, CanSen uses the available number of processors by default. -h, --help: Print this help message and quit. """ ret = utils.cli_parser(argv) filenames = ret[0] convert = ret[1] multi = ret[2] num_proc = ret[3] main(filenames, convert, multi, num_proc, __version__)