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__)