diff --git a/CHANGELOG.md b/CHANGELOG.md index 03b7339..6caa177 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added +- DOI for 1.0.4 + +### Fixed +- Syntax errors in readme.md +- Conda install instructions in install.md +- Corrected TRange columns in parser + +### Added +- Add check to reactions to test that all species exist +- Duplicate warning from falloff->chemically-activated TROE reactions for zero-parameters +- Add handling of non-unity default third body efficiency + +### Changed +- Bump internal version to 1.0.5.c + +## [1.0.5.b0] - 2017-06-02 +### Added - Added usergroup info to README and documentation ### Fixed @@ -16,7 +33,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Removed - Removed plotting scripts specific to first paper on pyJac - ## [1.0.4] - 2017-04-18 ### Added - Adds Travis config for automatic PyPI and conda builds diff --git a/docs/conf.py b/docs/conf.py index 13c2dab..d217b12 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -78,9 +78,11 @@ # built documents. # # The short X.Y version. -version = '1.0.3' +from pyjac import __version__ + +version = '.'.join(__version__.split('.')[:3]) # The full version, including alpha/beta/rc tags. -release = '1.0.3' +release = __version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -182,7 +184,7 @@ # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. html_sidebars = { diff --git a/pyjac/_version.py b/pyjac/_version.py index 5c01dc4..72cbc72 100644 --- a/pyjac/_version.py +++ b/pyjac/_version.py @@ -1,4 +1,4 @@ -__version_info__ = (1, 0, 5, 'b') +__version_info__ = (1, 0, 5, 'c') __version__ = '.'.join(map(str, __version_info__[:3])) if len(__version_info__) == 4: __version__ += __version_info__[-1] diff --git a/pyjac/core/mech_interpret.py b/pyjac/core/mech_interpret.py index 06a6d9e..33ce830 100644 --- a/pyjac/core/mech_interpret.py +++ b/pyjac/core/mech_interpret.py @@ -83,20 +83,11 @@ def read_mech(mech_filename, therm_filename): elems = [] reacs = [] specs = [] - - units = '' key = '' - # By default, need to read thermo database if file given. - if therm_filename: - therm_flag = True - with open(mech_filename, 'r') as file: # start line reading loop while True: - # remember last line position - last_line = file.tell() - line = file.readline() # end of file @@ -688,6 +679,17 @@ def read_mech(mech_filename, therm_filename): reacs[idx].cheb_par = np.reshape(reac.cheb_par, (n, m)) + # check that all species in reactions correspond to a known species + spec_names = set(spec.name for spec in specs) + for idx, reac in enumerate(reacs): + in_rxn = set(reac.reac + reac.prod) + for spec in in_rxn: + if spec not in spec_names: + logger = logging.getLogger(__name__) + logger.error('Reaction {} contains unknown species {}'.format( + idx, spec)) + sys.exit(-1) + # Split reversible reactions with explicit reverse parameters into # two irreversible reactions to match Cantera's behavior for reac in reacs[:]: @@ -839,7 +841,7 @@ def read_thermo(filename, elems, specs): spec.mw += e_num * elem_wt[e.lower()] # temperatures for species - T_spec = utils.read_str_num(line[45:73]) + T_spec = utils.read_str_num(line[45:74]) T_low = T_spec[0] T_high = T_spec[1] if len(T_spec) == 3: @@ -955,6 +957,37 @@ def read_mech_ct(filename=None, gas=None): # Cantera internally uses joules/kmol for activation energy E_fac = act_energy_fact['joules/kmole'] + def handle_effiencies(reac, ct_rxn): + """Convert Cantera `cantera.Reaction`'s third body efficienicies + to pyJac's internal format, and return updated reaction + + Parameters + ---------- + reac : `ReacInfo` + The pyJac reaction to update + ct_rxn : `Reaction` object + Corresponding cantera reaction to pull the third bodies from + + Returns + ------- + updated_reac: `ReacInfo` + The updated pyjac reaction with appropriate third body efficiencies + """ + + # See if single species acts as third body + if rxn.default_efficiency == 0.0 \ + and len(ct_rxn.efficiencies.keys()) == 1\ + and list(ct_rxn.efficiencies.values())[0] == 1\ + and reac.is_pdep: + reac.pdep_sp = list(rxn.efficiencies.keys())[0] + else: + for sp in gas.species_names: + if sp in ct_rxn.efficiencies: + reac.thd_body_eff.append([sp, ct_rxn.efficiencies[sp]]) + elif ct_rxn.default_efficiency != 1.0: + reac.thd_body_eff.append([sp, ct_rxn.default_efficiency]) + return reac + for rxn in gas.reactions(): if isinstance(rxn, ct.ThreeBodyReaction): @@ -969,10 +1002,7 @@ def read_mech_ct(filename=None, gas=None): rxn.rate.activation_energy * E_fac ) reac.thd_body = True - for thd_body in rxn.efficiencies: - reac.thd_body_eff.append([thd_body, - rxn.efficiencies[thd_body] - ]) + reac = handle_effiencies(reac, rxn) elif isinstance(rxn, ct.FalloffReaction) and \ not isinstance(rxn, ct.ChemicallyActivatedReaction): @@ -986,12 +1016,7 @@ def read_mech_ct(filename=None, gas=None): rxn.high_rate.activation_energy * E_fac ) reac.pdep = True - # See if single species acts as third body - if rxn.default_efficiency == 0.0: - reac.pdep_sp = list(rxn.efficiencies.keys())[0] - else: - for sp in rxn.efficiencies: - reac.thd_body_eff.append([sp, rxn.efficiencies[sp]]) + reac = handle_effiencies(reac, rxn) reac.low = [rxn.low_rate.pre_exponential_factor, rxn.low_rate.temperature_exponent, @@ -1010,7 +1035,7 @@ def read_mech_ct(filename=None, gas=None): do_warn = True if do_warn: logging.warn('Troe parameters in reaction {} modified to avoid' - ' division by zero!.'.format(len(reacs))) + ' division by zero!.'.format(len(reacs))) elif rxn.falloff.type == 'SRI': reac.sri = True reac.sri_par = rxn.falloff.parameters.tolist() @@ -1026,12 +1051,7 @@ def read_mech_ct(filename=None, gas=None): rxn.low_rate.activation_energy * E_fac ) reac.pdep = True - # See if single species acts as third body - if rxn.default_efficiency == 0.0: - reac.pdep_sp = list(rxn.efficiencies.keys())[0] - else: - for sp in rxn.efficiencies: - reac.thd_body_eff.append([sp, rxn.efficiencies[sp]]) + reac = handle_effiencies(reac, rxn) reac.high = [rxn.high_rate.pre_exponential_factor, rxn.high_rate.temperature_exponent, @@ -1041,6 +1061,16 @@ def read_mech_ct(filename=None, gas=None): if rxn.falloff.type == 'Troe': reac.troe = True reac.troe_par = rxn.falloff.parameters.tolist() + do_warn = False + if reac.troe_par[1] == 0: + reac.troe_par[1] = 1e-30 + do_warn = True + if reac.troe_par[2] == 0: + reac.troe_par[2] = 1e-30 + do_warn = True + if do_warn: + logging.warn('Troe parameters in reaction {} modified to avoid' + ' division by zero!.'.format(len(reacs))) elif rxn.falloff.type == 'SRI': reac.sri = True reac.sri_par = rxn.falloff.parameters.tolist()