[Python] Make more use of Interface.adjacent

This commit is contained in:
Ray Speth 2024-06-16 21:35:13 -04:00 committed by Ray Speth
parent eec37ffcd8
commit f5a0176c28
8 changed files with 53 additions and 90 deletions

View File

@ -202,21 +202,15 @@ ct.add_directory('~/cantera/my_data_files')
Cantera input files are plain text files, and can be created with any text editor. See Cantera input files are plain text files, and can be created with any text editor. See
the page [](input-tutorial) for more information. the page [](input-tutorial) for more information.
A Cantera input file may contain more than one phase specification, or may contain A Cantera input file may contain more than one phase specification, and may contain
specifications of interfaces (surfaces). Here we import definitions of two bulk phases specifications of interfaces (surfaces and edges). Here we import a surface phase and
and the interface between them from file `diamond.yaml`: the two adjacent bulk phases from the file `diamond.yaml`:
% TODO: Demonstrate the syntax that starts with creating the Interface
```{code-cell} python ```{code-cell} python
gas2 = ct.Solution('diamond.yaml', 'gas') diamond_surf = ct.Interface('diamond.yaml' , 'diamond_100')
diamond = ct.Solution('diamond.yaml', 'diamond') diamond_surf.adjacent
diamond_surf = ct.Interface('diamond.yaml' , 'diamond_100',
[gas2, diamond])
``` ```
Note that the bulk (3D) phases that participate in the surface reactions must also be
passed as arguments to {py:class}`Interface`.
## Converting CK-format files ## Converting CK-format files
See the page [](ck2yaml-tutorial) for information on how to convert from CK-format to See the page [](ck2yaml-tutorial) for information on how to convert from CK-format to

View File

@ -140,10 +140,9 @@ import matplotlib.pyplot as plt
# Import the reaction mechanism for Ammonia synthesis/decomposition on Ru-Ba/YSZ catalyst # Import the reaction mechanism for Ammonia synthesis/decomposition on Ru-Ba/YSZ catalyst
mechfile = "example_data/ammonia-Ru-Ba-YSZ-CSM-2019.yaml" mechfile = "example_data/ammonia-Ru-Ba-YSZ-CSM-2019.yaml"
# Import the models for gas-phase # Import the models for surface-phase and gas
gas = ct.Solution(mechfile, "gas") surf = ct.Interface(mechfile, "Ru_surface")
# Import the model for surface-phase gas = surf.adjacent["gas"]
surf = ct.Interface(mechfile, "Ru_surface", [gas])
# Other parameters # Other parameters
n_gas = gas.n_species # number of gas species n_gas = gas.n_species # number of gas species

View File

@ -46,13 +46,11 @@ dt = 1.0
t = tc + 273.15 # convert to Kelvin t = tc + 273.15 # convert to Kelvin
# import the gas model and set the initial conditions # import the phase models and set the initial conditions
gas = ct.Solution(yaml_file, 'gas') surf = ct.Interface(yaml_file, 'Pt_surf')
gas.TPX = t, ct.one_atm, 'CH4:1, O2:1.5, AR:0.1'
# import the surface model
surf = ct.Interface(yaml_file, 'Pt_surf', [gas])
surf.TP = t, ct.one_atm surf.TP = t, ct.one_atm
gas = surf.adjacent['gas']
gas.TPX = t, ct.one_atm, 'CH4:1, O2:1.5, AR:0.1'
rlen = length/(NReactors-1) rlen = length/(NReactors-1)
rvol = area * rlen * porosity rvol = area * rlen * porosity

View File

@ -157,9 +157,7 @@ class TestPickle(utilities.CanteraTest):
self.assertEqual(gas2.transport_model, "multicomponent") self.assertEqual(gas2.transport_model, "multicomponent")
def test_pickle_interface(self): def test_pickle_interface(self):
gas = ct.Solution("diamond.yaml", "gas") interface = ct.Interface("diamond.yaml", "diamond_100")
solid = ct.Solution("diamond.yaml", "diamond")
interface = ct.Interface("diamond.yaml", "diamond_100", (gas, solid))
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
with open(self.test_work_path / "interface.pkl", "wb") as pkl: with open(self.test_work_path / "interface.pkl", "wb") as pkl:

View File

@ -220,8 +220,8 @@ class KineticsFromReactions(utilities.CanteraTest):
gas2.net_production_rates) gas2.net_production_rates)
def test_surface(self): def test_surface(self):
gas = ct.Solution("ptcombust.yaml", "gas") surf1 = ct.Interface("ptcombust.yaml", "Pt_surf")
surf1 = ct.Interface("ptcombust.yaml", "Pt_surf", [gas]) gas = surf1.adjacent["gas"]
surf_species = ct.Species.list_from_file("ptcombust.yaml") surf_species = ct.Species.list_from_file("ptcombust.yaml")
reactions = ct.Reaction.list_from_file("ptcombust.yaml", surf1) reactions = ct.Reaction.list_from_file("ptcombust.yaml", surf1)
@ -295,8 +295,7 @@ class KineticsFromReactions(utilities.CanteraTest):
gas2.net_production_rates) gas2.net_production_rates)
def test_coverage_dependence_flags(self): def test_coverage_dependence_flags(self):
gas = ct.Solution("ptcombust.yaml", "gas") surf = ct.Interface("ptcombust.yaml", "Pt_surf")
surf = ct.Interface("ptcombust.yaml", "Pt_surf", [gas])
surf.TP = 900, ct.one_atm surf.TP = 900, ct.one_atm
surf.coverages = {"PT(S)":1} surf.coverages = {"PT(S)":1}
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
@ -306,11 +305,7 @@ class KineticsFromReactions(utilities.CanteraTest):
surf.net_rates_of_progress_ddCi surf.net_rates_of_progress_ddCi
def test_electrochemistry_flags(self): def test_electrochemistry_flags(self):
# Phases anode_int = ct.Interface("lithium_ion_battery.yaml", "edge_anode_electrolyte")
mech = "lithium_ion_battery.yaml"
anode, cathode, metal, electrolyte = ct.import_phases(
mech, ["anode", "cathode", "electron", "electrolyte"])
anode_int = ct.Interface(mech, "edge_anode_electrolyte", adjacent=[anode, metal, electrolyte])
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
anode_int.net_rates_of_progress_ddCi anode_int.net_rates_of_progress_ddCi
# set skip and try to get jacobian again # set skip and try to get jacobian again
@ -537,8 +532,7 @@ class KineticsRepeatability(utilities.CanteraTest):
for err in err_msg: for err in err_msg:
with pytest.warns(UserWarning, match=err): with pytest.warns(UserWarning, match=err):
gas = ct.Solution("sticking_coeff_check.yaml") ct.Interface("sticking_coeff_check.yaml", "Pt_surf")
ct.Interface("sticking_coeff_check.yaml", "Pt_surf", [gas])
def check_raises(yaml, err_msg, line): def check_raises(yaml, err_msg, line):
@ -958,19 +952,20 @@ class TestSofcKinetics(utilities.CanteraTest):
return x0 return x0
# Anode-side phases # Anode-side phases
gas_a, anode_bulk, oxide_a = ct.import_phases(mech, tpb_a = ct.Interface(mech, "tpb")
['gas', 'metal', 'oxide_bulk',]) anode_surf = tpb_a.adjacent["metal_surface"]
anode_surf = ct.Interface(mech, 'metal_surface', [gas_a]) gas_a = anode_surf.adjacent["gas"]
oxide_surf_a = ct.Interface(mech, 'oxide_surface', [gas_a, oxide_a]) oxide_surf_a = tpb_a.adjacent["oxide_surface"]
tpb_a = ct.Interface(mech, 'tpb', [anode_bulk, anode_surf, oxide_surf_a]) oxide_a = oxide_surf_a.adjacent["oxide_bulk"]
anode_bulk = tpb_a.adjacent["metal"]
# Cathode-side phases # Cathode-side phases
gas_c, cathode_bulk, oxide_c = ct.import_phases(mech, tpb_c = ct.Interface(mech, "tpb")
['gas', 'metal', 'oxide_bulk']) cathode_surf = tpb_c.adjacent["metal_surface"]
cathode_surf = ct.Interface(mech, 'metal_surface', [gas_c]) gas_c = cathode_surf.adjacent["gas"]
oxide_surf_c = ct.Interface(mech, 'oxide_surface', [gas_c, oxide_c]) oxide_surf_c = tpb_c.adjacent["oxide_surface"]
tpb_c = ct.Interface(mech, 'tpb', [cathode_bulk, cathode_surf, oxide_c = oxide_surf_c.adjacent["oxide_bulk"]
oxide_surf_c]) cathode_bulk = tpb_c.adjacent["metal"]
kElectron_a = tpb_a.kinetics_species_index("electron") kElectron_a = tpb_a.kinetics_species_index("electron")
def anode_curr(E): def anode_curr(E):
@ -1127,13 +1122,10 @@ class TestLithiumIonBatteryKinetics(utilities.CanteraTest):
assert np.allclose(data, ref, rtol=1e-7) assert np.allclose(data, ref, rtol=1e-7)
def test_interface_current(self): def test_interface_current(self):
file = "lithium_ion_battery.yaml" anode_int = ct.Interface("lithium_ion_battery.yaml", "edge_anode_electrolyte")
anode = anode_int.adjacent["anode"]
# The 'elde' electrode phase is needed as a source/sink for electrons: elect = anode_int.adjacent["electron"]
anode = ct.Solution(file, "anode") elyte = anode_int.adjacent["electrolyte"]
elect = ct.Solution(file, "electron")
elyte = ct.Solution(file, "electrolyte")
anode_int = ct.Interface(file, "edge_anode_electrolyte", [anode, elect, elyte])
anode.X = [0.9, 0.1] anode.X = [0.9, 0.1]
elyte.X = [0.4, 0.3, 0.15, 0.15] elyte.X = [0.4, 0.3, 0.15, 0.15]
@ -1554,8 +1546,8 @@ class TestReaction(utilities.CanteraTest):
def test_interface(self): def test_interface(self):
surf_species = ct.Species.list_from_file("ptcombust.yaml") surf_species = ct.Species.list_from_file("ptcombust.yaml")
gas = ct.Solution("ptcombust.yaml", "gas") surf1 = ct.Interface("ptcombust.yaml", "Pt_surf")
surf1 = ct.Interface("ptcombust.yaml", "Pt_surf", [gas]) gas = surf1.adjacent["gas"]
rate = ct.InterfaceArrheniusRate(3.7e20, 0, 67.4e6) rate = ct.InterfaceArrheniusRate(3.7e20, 0, 67.4e6)
rate.coverage_dependencies = {'H(S)': (0, 0, -6e6)} rate.coverage_dependencies = {'H(S)': (0, 0, -6e6)}
@ -1733,10 +1725,8 @@ class TestReaction(utilities.CanteraTest):
self.assertNear(A2 * T**b2 * np.exp(-Ta2 / T), gas.forward_rate_constants[0]) self.assertNear(A2 * T**b2 * np.exp(-Ta2 / T), gas.forward_rate_constants[0])
def test_modify_interface(self): def test_modify_interface(self):
gas = ct.Solution("ptcombust.yaml", "gas") surf = ct.Interface("ptcombust.yaml", "Pt_surf")
surf = ct.Interface("ptcombust.yaml", "Pt_surf", [gas])
surf.coverages = 'O(S):0.1, PT(S):0.5, H(S):0.4' surf.coverages = 'O(S):0.1, PT(S):0.5, H(S):0.4'
gas.TP = surf.TP
R = surf.reaction(1) R = surf.reaction(1)
R.rate.coverage_dependencies = {'O(S)': (0.0, 0.0, -3e6)} R.rate.coverage_dependencies = {'O(S)': (0.0, 0.0, -3e6)}
@ -1762,10 +1752,8 @@ class TestReaction(utilities.CanteraTest):
surf.add_reaction(rxn) surf.add_reaction(rxn)
def test_modify_sticking(self): def test_modify_sticking(self):
gas = ct.Solution("ptcombust.yaml", "gas") surf = ct.Interface("ptcombust.yaml", "Pt_surf")
surf = ct.Interface("ptcombust.yaml", "Pt_surf", [gas])
surf.coverages = "O(S):0.1, PT(S):0.5, H(S):0.4" surf.coverages = "O(S):0.1, PT(S):0.5, H(S):0.4"
gas.TP = surf.TP
R = surf.reaction(2) R = surf.reaction(2)
R.rate = ct.StickingArrheniusRate(0.25, 0, 0) # original sticking coefficient = 1.0 R.rate = ct.StickingArrheniusRate(0.25, 0, 0) # original sticking coefficient = 1.0
@ -1777,14 +1765,11 @@ class TestReaction(utilities.CanteraTest):
def test_motz_wise(self): def test_motz_wise(self):
# Motz & Wise off for all reactions # Motz & Wise off for all reactions
gas1 = ct.Solution("ptcombust.yaml", "gas") surf1 = ct.Interface("ptcombust.yaml", "Pt_surf")
surf1 = ct.Interface("ptcombust.yaml", "Pt_surf", [gas1])
surf1.coverages = 'O(S):0.1, PT(S):0.5, H(S):0.4' surf1.coverages = 'O(S):0.1, PT(S):0.5, H(S):0.4'
gas1.TP = surf1.TP
# Motz & Wise correction on for some reactions # Motz & Wise correction on for some reactions
gas2 = ct.Solution("ptcombust-motzwise.yaml", "gas") surf2 = ct.Interface("ptcombust-motzwise.yaml", "Pt_surf")
surf2 = ct.Interface("ptcombust-motzwise.yaml", "Pt_surf", [gas2])
surf2.TPY = surf1.TPY surf2.TPY = surf1.TPY
k1 = surf1.forward_rate_constants k1 = surf1.forward_rate_constants
@ -1843,15 +1828,11 @@ class TestReaction(utilities.CanteraTest):
def test_BMmotz_wise(self): def test_BMmotz_wise(self):
# Motz & Wise off for all reactions # Motz & Wise off for all reactions
gas1 = ct.Solution("blowers-masel.yaml", "gas", transport_model=None) surf1 = ct.Interface("blowers-masel.yaml", "Pt_surf")
gas1.TPX = 300, ct.one_atm, {"CH4": 0.095, "O2": 0.21, "AR": 0.79}
surf1 = ct.Interface("blowers-masel.yaml", "Pt_surf", [gas1])
surf1.coverages = 'O(S):0.1, PT(S):0.5, H(S):0.4' surf1.coverages = 'O(S):0.1, PT(S):0.5, H(S):0.4'
gas1.TP = surf1.TP
# Motz & Wise correction on for some reactions # Motz & Wise correction on for some reactions
gas2 = ct.Solution("blowers-masel.yaml", "gas") surf2 = ct.Interface("blowers-masel.yaml", "Pt_motz_wise")
surf2 = ct.Interface("blowers-masel.yaml", "Pt_motz_wise", [gas2])
surf2.TPY = surf1.TPY surf2.TPY = surf1.TPY
k1 = surf1.forward_rate_constants k1 = surf1.forward_rate_constants

View File

@ -1713,8 +1713,8 @@ class TestStagnationFlame(utilities.CanteraTest):
class TestImpingingJet(utilities.CanteraTest): class TestImpingingJet(utilities.CanteraTest):
def setUp(self): def setUp(self):
self.gas = ct.Solution("ptcombust-simple.yaml", "gas") self.surf_phase = ct.Interface("ptcombust-simple.yaml", "Pt_surf")
self.surf_phase = ct.Interface("ptcombust-simple.yaml", "Pt_surf", [self.gas]) self.gas = self.surf_phase.adjacent["gas"]
def create_reacting_surface(self, comp, tsurf, tinlet, width): def create_reacting_surface(self, comp, tsurf, tinlet, width):
self.gas.TPX = tinlet, ct.one_atm, comp self.gas.TPX = tinlet, ct.one_atm, comp

View File

@ -1965,10 +1965,8 @@ class TestSurfaceKinetics(utilities.CanteraTest):
def make_reactors(self): def make_reactors(self):
self.net = ct.ReactorNet() self.net = ct.ReactorNet()
self.gas = ct.Solution('diamond.yaml', 'gas') self.interface = ct.Interface('diamond.yaml', 'diamond_100')
self.solid = ct.Solution('diamond.yaml', 'diamond') self.gas = self.interface.adjacent['gas']
self.interface = ct.Interface('diamond.yaml', 'diamond_100',
(self.gas, self.solid))
self.gas.TPX = None, 1.0e3, 'H:0.002, H2:1, CH4:0.01, CH3:0.0002' self.gas.TPX = None, 1.0e3, 'H:0.002, H2:1, CH4:0.01, CH3:0.0002'
self.r1 = ct.IdealGasReactor(self.gas) self.r1 = ct.IdealGasReactor(self.gas)
self.r1.volume = 0.01 self.r1.volume = 0.01
@ -2094,9 +2092,8 @@ class TestReactorSensitivities(utilities.CanteraTest):
def test_sensitivities2(self): def test_sensitivities2(self):
net = ct.ReactorNet() net = ct.ReactorNet()
gas1 = ct.Solution("diamond.yaml", "gas") interface = ct.Interface("diamond.yaml", "diamond_100")
solid = ct.Solution("diamond.yaml", "diamond") gas1 = interface.adjacent["gas"]
interface = ct.Interface("diamond.yaml", "diamond_100", (gas1, solid))
r1 = ct.IdealGasReactor(gas1) r1 = ct.IdealGasReactor(gas1)
net.add_reactor(r1) net.add_reactor(r1)
net.atol_sensitivity = 1e-10 net.atol_sensitivity = 1e-10
@ -2256,9 +2253,8 @@ class TestReactorSensitivities(utilities.CanteraTest):
@utilities.slow_test @utilities.slow_test
def test_parameter_order3(self): def test_parameter_order3(self):
# Test including reacting surfaces # Test including reacting surfaces
gas1 = ct.Solution("diamond.yaml", "gas") interface = ct.Interface("diamond.yaml", "diamond_100")
solid = ct.Solution("diamond.yaml", "diamond") gas1 = interface.adjacent["gas"]
interface = ct.Interface("diamond.yaml", "diamond_100", (gas1, solid))
gas2 = ct.Solution('h2o2.yaml', transport_model=None) gas2 = ct.Solution('h2o2.yaml', transport_model=None)
@ -2659,8 +2655,8 @@ class PureFluidReactorTest(utilities.CanteraTest):
class AdvanceCoveragesTest(utilities.CanteraTest): class AdvanceCoveragesTest(utilities.CanteraTest):
def setup(self, model="ptcombust.yaml", gas_phase="gas", interface_phase="Pt_surf"): def setup(self, model="ptcombust.yaml", gas_phase="gas", interface_phase="Pt_surf"):
# create gas and interface # create gas and interface
self.gas = ct.Solution(model, gas_phase) self.surf = ct.Interface(model, interface_phase)
self.surf = ct.Interface(model, interface_phase, [self.gas]) self.gas = self.surf.adjacent["gas"]
def test_advance_coverages_parameters(self): def test_advance_coverages_parameters(self):
# create gas and interface # create gas and interface

View File

@ -1114,10 +1114,7 @@ class TestThermo(utilities.CanteraTest):
class TestInterfacePhase(utilities.CanteraTest): class TestInterfacePhase(utilities.CanteraTest):
def setUp(self): def setUp(self):
self.gas = ct.Solution("diamond.yaml", "gas") self.interface = ct.Interface("diamond.yaml", "diamond_100")
self.solid = ct.Solution("diamond.yaml", "diamond")
self.interface = ct.Interface("diamond.yaml", "diamond_100",
(self.gas, self.solid))
def test_properties(self): def test_properties(self):
self.interface.site_density = 100 self.interface.site_density = 100