Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
76bcee0
Minor: Fix a Cython declaration in a Reaction method.
rwest Aug 2, 2024
34fd3e9
Save cantera files that were made from chemkin files to a separate fo…
rwest Jun 6, 2024
51751a8
Rename yml to yaml_rms, because it was specific to RMS
Nora-Khalil Jun 15, 2022
dd22638
Enable Cantera-YAML writing.
Nora-Khalil Jun 13, 2022
b80ea9f
Reworking the Elements blocks in cantera yaml writer.
rwest Aug 2, 2024
dd4bbf9
add yaml writer test to compare yaml file generated by RMG and the ya…
Mar 3, 2025
45d12ad
Simplify species_to_dict for writing cantera yaml.
rwest Mar 21, 2024
7091bff
Rename generate_cantera_files to generate_cantera_files_from_chemkin
rwest Feb 5, 2026
f5ee609
Add (or restore?) a TestCanteraOutputConversion test
rwest Feb 12, 2026
0bd98e6
Functional test comparing Cantera YAML outputs to Chemkin-converted YAML
rwest Feb 6, 2026
02190e8
YAML: Reaction comparison can do irreversible reactions
rwest Feb 6, 2026
7978bf3
Enhance reaction comparison by adding checks for reaction counts and …
rwest Feb 6, 2026
9424388
Simplify CompareYaml and YamlAnalyst arguments
rwest Feb 6, 2026
9202fb9
Move test_make_cantera_input_file into ..._from_ck and make a ..._dir…
rwest Feb 12, 2026
76213bc
Tweak test_yaml
rwest Feb 6, 2026
94f20fd
Update test_yaml.py to use new YAML test files for comparison
rwest Feb 6, 2026
38fe4b8
A stub cantera_yamlTest.py file for testing the cantera yaml features.
rwest Feb 7, 2026
5e6d6a2
Work on the yaml_canteraTest.
rwest Feb 7, 2026
6b93b73
Work on yaml_canteraTest.py. Check phases.
rwest Feb 8, 2026
ed9f9a2
TEMP? mainTest functional test now copies the yaml files into the tes…
rwest Feb 8, 2026
e40cb1f
[yaml_cantera] Make phase names mach ck2yaml version.
rwest Feb 8, 2026
ba61438
[yaml_cantera] Fix where transport data comments are put
rwest Feb 8, 2026
207deaa
[yaml_canteraTest] More testing of phase definitions.
rwest Feb 8, 2026
f30bbff
[yaml_canteraTest] Test the Elements block
rwest Feb 8, 2026
b7a37cf
[yaml_cantera] Outputs more condensed, with flow_style for some lists.
rwest Feb 8, 2026
e3b48ff
Update the cantera yaml test data files.
rwest Feb 8, 2026
5bdfdcb
[yaml_cantera] Add test for species definition matching.
rwest Feb 10, 2026
bf05491
[yaml_canteraTest] fix species test for NASA polynomial collapse.
rwest Feb 10, 2026
86e83dc
Converted cantera SI units to the units specified in write_cantera
LekiaAnonim Feb 11, 2026
c7e0f2e
yaml comparer: Added a normalization method for equation with third-b…
LekiaAnonim Feb 11, 2026
d7a15f3
yaml comparer: use cantera to compare rate
LekiaAnonim Feb 11, 2026
402a98f
Fix YAML serialization of Cantera objects by converting AnyMap to dict
rwest Feb 12, 2026
cace76e
TEMP? Newly created yaml files for testing.
rwest Feb 12, 2026
63e3240
Enhance compare_yaml_outputs
rwest Feb 13, 2026
7c986fb
yaml_canteraTest compares yaml files made in mainTest
rwest Feb 13, 2026
e713aad
Making a new tool compare_cantera_yaml
rwest Feb 15, 2026
6b3b01b
Refactor Cantera YAML comparison tool with enhanced features
rwest Feb 16, 2026
3e66264
The compare_cantera_yaml script now uses logging.
rwest Feb 16, 2026
7a43ebf
At end of model generation, compare direct yaml and ck2yaml outputs.
rwest Feb 16, 2026
1e3f15c
Added a Cantera writer module
alongd Dec 13, 2025
2436bd1
Move Alon's cantera writer to yaml_cantera2
rwest Feb 16, 2026
91dae8d
Rename Alon's CanteraWriter class to CanteraWriter2
rwest Feb 16, 2026
f8053db
Tests: Cantera writer
alongd Dec 13, 2025
d6efcc0
Rename (file and contents) Alon's yaml_cantera2Test
rwest Feb 16, 2026
4b4109e
Add surface chemistry support to Cantera YAML export
alongd Jan 10, 2026
bcc6e54
Updates output subdirectory name to 'cantera2'
rwest Feb 16, 2026
db234e0
[yaml_cantera] makes a copy of the latest chem.yaml each iteration
rwest Feb 16, 2026
5bd0d91
Attach the CanteraWriter2
rwest Feb 16, 2026
13d730e
compare_cantera_yaml copes with different reaction block specification
rwest Feb 16, 2026
a0c1478
Correct units for transport properties in CanteraWriter2
rwest Feb 16, 2026
6b74406
Fix transport properties in CanteraWriter2
rwest Feb 16, 2026
1b022ef
[CanteraWriter2] Write transport and thermo notes where they belong.
rwest Feb 16, 2026
e80b539
[CanteraWriter2] fix conversion of dipole monte into Debye
rwest Feb 16, 2026
4844f90
Fix attempt for 'E' in atom dictionary
alongd Feb 19, 2026
78e37ee
Revert "Fix attempt for 'E' in atom dictionary"
rwest Feb 20, 2026
435f99b
[yaml_cantera2] Fixing 'E' electron count for charged species.
rwest Feb 20, 2026
31f26aa
Rename 'yaml_cantera' to 'yaml_cantera1'.
rwest Feb 20, 2026
3465102
[RMG/main] get_git_commit now returns strings not bytes
rwest Feb 20, 2026
edac9f0
[yaml_cantera2] Detailed logging of the yaml generator
rwest Feb 20, 2026
b2e6b4f
[yaml_cantera1] Detailed logging of the yaml generator
rwest Feb 20, 2026
01970ac
Revert "Converted cantera SI units to the units specified in write_ca…
rwest Feb 21, 2026
4c1f13e
[yaml_cantera1] Report things in cantera default internal units.
rwest Feb 21, 2026
e607b4c
[yaml_cantera1] Add coverage-dependent thermo to CanteraWriter1
rwest Apr 8, 2026
3257e77
[yaml_cantera2] Add coverage-dependent thermo to CanteraWriter2
rwest Apr 8, 2026
59a78fc
Move coverage-dependent thermo into Species.to_cantera()
rwest Apr 8, 2026
e8557f2
[yaml_cantera2] use label if it's a Species (should save time)
rwest Apr 9, 2026
f116464
[yaml_cantera2] write species list in order of index
rwest Apr 9, 2026
e7ca0da
[yaml_cantera2] fix unit test (detecting the generator field)
rwest Apr 9, 2026
09f98d0
Fix species rename from thermo library for reaction-generated species
rwest Apr 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rmgpy/reaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -1447,7 +1447,7 @@ def is_balanced(self):
from rmgpy.molecule.element import element_list
from rmgpy.molecule.fragment import CuttingLabel, Fragment

cython.declare(reactant_elements=dict, product_elements=dict, molecule=Graph, atom=Vertex, element=Element,
cython.declare(reactant_elements=dict, product_elements=dict, molecule=Molecule, atom=Atom, element=Element,
reactants_net_charge=cython.int, products_net_charge=cython.int)

reactant_elements = {}
Expand Down
47 changes: 35 additions & 12 deletions rmgpy/rmg/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@
from rmgpy.stats import ExecutionStatsWriter
from rmgpy.thermo.thermoengine import submit
from rmgpy.tools.plot import plot_sensitivity
from rmgpy.tools.compare_cantera_yaml import compare_yaml_files, compare_yaml_files_and_report
from rmgpy.tools.uncertainty import Uncertainty, process_local_results
from rmgpy.yml import RMSWriter
from rmgpy.yaml_rms import RMSWriter
from rmgpy.yaml_cantera1 import CanteraWriter1
from rmgpy.yaml_cantera2 import CanteraWriter2

################################################################################

Expand Down Expand Up @@ -773,7 +776,8 @@ def register_listeners(self, requires_rms=False):
self.attach(ChemkinWriter(self.output_directory))

self.attach(RMSWriter(self.output_directory))

self.attach(CanteraWriter1(self.output_directory))
self.attach(CanteraWriter2(self.output_directory))
if self.generate_output_html:
self.attach(OutputHTMLWriter(self.output_directory))

Expand Down Expand Up @@ -1221,15 +1225,17 @@ def execute(self, initialize=True, **kwargs):

self.run_model_analysis()

# generate Cantera files chem.yaml & chem_annotated.yaml in a designated `cantera` output folder
# generate Cantera files chem.yaml & chem_annotated.yaml in designated Cantera output folders
try:
logging.info("Translating final chemkin file into Cantera yaml.")
translated_cantera_file = None
if any([s.contains_surface_site() for s in self.reaction_model.core.species]):
# Surface (catalytic) chemistry
self.generate_cantera_files(
translated_cantera_file = self.generate_cantera_files_from_chemkin(
os.path.join(self.output_directory, "chemkin", "chem-gas.inp"),
surface_file=(os.path.join(self.output_directory, "chemkin", "chem-surface.inp")),
)
self.generate_cantera_files(
self.generate_cantera_files_from_chemkin(
os.path.join(self.output_directory, "chemkin", "chem_annotated-gas.inp"),
surface_file=(os.path.join(self.output_directory, "chemkin", "chem_annotated-surface.inp")),
)
Expand Down Expand Up @@ -1262,8 +1268,22 @@ def execute(self, initialize=True, **kwargs):
_add_coverage_dependence_to_cantera_yaml(yaml_path, coverage_deps)

else: # gas phase only
self.generate_cantera_files(os.path.join(self.output_directory, "chemkin", "chem.inp"))
self.generate_cantera_files(os.path.join(self.output_directory, "chemkin", "chem_annotated.inp"))
translated_cantera_file = self.generate_cantera_files_from_chemkin(
os.path.join(self.output_directory, "chemkin", "chem.inp")
)
self.generate_cantera_files_from_chemkin(
os.path.join(self.output_directory, "chemkin", "chem_annotated.inp")
)

# Compare translated Cantera files and directly generated Cantera files

compare_yaml_files_and_report(translated_cantera_file,
os.path.join(self.output_directory, "cantera1", "chem.yaml"),
output=os.path.join(self.output_directory, "cantera1", "comparison_report.txt"))
compare_yaml_files_and_report(translated_cantera_file,
os.path.join(self.output_directory, "cantera2", "chem.yaml"),
output=os.path.join(self.output_directory, "cantera2", "comparison_report.txt"))

except EnvironmentError:
logging.exception("Could not generate Cantera files due to EnvironmentError. Check read\\write privileges in output directory.")
except Exception:
Expand Down Expand Up @@ -1834,14 +1854,15 @@ def process_reactions_to_species(self, obj):
raise TypeError("improper call, obj input was incorrect")
return potential_spcs

def generate_cantera_files(self, chemkin_file, **kwargs):
def generate_cantera_files_from_chemkin(self, chemkin_file, **kwargs):
"""
Convert a chemkin mechanism chem.inp file to a cantera mechanism file chem.yaml
and save it in the cantera directory
and save it in the cantera directory.
Returns the path to the generated cantera file.
"""
transport_file = os.path.join(os.path.dirname(chemkin_file), "tran.dat")
file_name = os.path.splitext(os.path.basename(chemkin_file))[0] + ".yaml"
out_name = os.path.join(self.output_directory, "cantera", file_name)
out_name = os.path.join(self.output_directory, "cantera_from_ck", file_name)
if "surface_file" in kwargs:
out_name = out_name.replace("-gas.", ".")
cantera_dir = os.path.dirname(out_name)
Expand All @@ -1859,6 +1880,7 @@ def generate_cantera_files(self, chemkin_file, **kwargs):
logging.exception("Error converting to Cantera format.")
logging.info("Trying again without transport data file.")
parser.convert_mech(chemkin_file, out_name=out_name, quiet=True, permissive=True, **kwargs)
return out_name

def initialize_reaction_threshold_and_react_flags(self):
num_core_species = len(self.reaction_model.core.species)
Expand Down Expand Up @@ -2146,8 +2168,9 @@ def get_git_commit(self, module_path):

if os.path.exists(os.path.join(module_path, "..", ".git")):
try:
return subprocess.check_output(["git", "log", "--format=%H%n%cd", "-1"], cwd=module_path).splitlines()
except:
head, date = subprocess.check_output(["git", "log", "--format=%H%n%cd", "-1"], cwd=module_path).splitlines()
return head.decode(), date.decode()
except (subprocess.CalledProcessError, OSError):
return "", ""
else:
return "", ""
Expand Down
5 changes: 3 additions & 2 deletions rmgpy/rmg/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,11 @@ def make_new_species(self, object, label="", reactive=True, check_existing=True,
spec.molecular_weight = Quantity(spec.molecule[0].get_molecular_weight() * 1000.0, "amu")

if generate_thermo:
self.generate_thermo(spec)
# Rename from thermo library label only if no user-provided label exists yet.
self.generate_thermo(spec, rename=not bool(spec.label))

# If the species still does not have a label, set initial label as the SMILES
# This may change later after getting thermo in self.generate_thermo()
# (applies when generate_thermo is False, or when no library match was found)
if not spec.label:
spec.label = spec.smiles

Expand Down
33 changes: 32 additions & 1 deletion rmgpy/species.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,13 +428,18 @@ def to_chemkin(self):
from rmgpy.chemkin import get_species_identifier
return get_species_identifier(self)

def to_cantera(self, use_chemkin_identifier=False):
def to_cantera(self, use_chemkin_identifier=False, all_species=None):
"""
Converts the RMG Species object to a Cantera Species object
with the appropriate thermo data.

If use_chemkin_identifier is set to False, the species label is used
instead. Be sure that species' labels are unique when setting it False.

If all_species is provided and this is a surface species with
coverage-dependent thermo, the coverage-dependencies are attached to
the Cantera Species object via update_user_data() so that they appear
in input_data and in Solution.write_yaml() output.
"""
import cantera as ct

Expand Down Expand Up @@ -475,6 +480,32 @@ def to_cantera(self, use_chemkin_identifier=False):
if self.transport_data:
ct_species.transport = self.transport_data.to_cantera()

# Attach coverage-dependent thermo if present.
# thermo_coverage_dependence keys are adjacency-list strings; we resolve
# them to species names here using all_species. The data is stored via
# update_user_data() so it appears in ct_species.input_data and in any
# YAML serialised by Cantera (e.g. Solution.write_yaml()).
if (all_species is not None
and self.contains_surface_site()
and self.thermo
and hasattr(self.thermo, 'thermo_coverage_dependence')
and self.thermo.thermo_coverage_dependence):
from rmgpy.molecule.molecule import Molecule
cov_deps = {}
for adj_list, parameters in self.thermo.thermo_coverage_dependence.items():
mol = Molecule().from_adjacency_list(adj_list)
for sp in all_species:
if sp.is_isomorphic(mol, strict=False):
dep_name = sp.to_chemkin() if use_chemkin_identifier else sp.label
cov_deps[dep_name] = {
'units': {'energy': 'J', 'quantity': 'mol'},
'enthalpy-coefficients': [v.value_si for v in parameters['enthalpy-coefficients']],
'entropy-coefficients': [v.value_si for v in parameters['entropy-coefficients']],
}
break
if cov_deps:
ct_species.update_user_data({'coverage-dependencies': cov_deps})

return ct_species

def has_statmech(self):
Expand Down
1 change: 0 additions & 1 deletion rmgpy/thermo/nasa.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,6 @@ cdef class NASA(HeatCapacityModel):
poly.change_base_entropy(deltaS)
return self

# need to modify this to include the thermo coverage dependence
def to_cantera(self):
"""
Return the cantera equivalent NasaPoly2 object from this NASA object.
Expand Down
Loading
Loading