mirror of
https://github.com/Cantera/cantera.git
synced 2025-02-25 18:55:29 -06:00
236 lines
8.2 KiB
Python
236 lines
8.2 KiB
Python
import unittest
|
|
|
|
import numpy as np
|
|
|
|
import cantera as ct
|
|
from . import utilities
|
|
|
|
|
|
class EquilTestCases:
|
|
def __init__(self, solver):
|
|
self.solver = solver
|
|
|
|
def check(self, gas, **moles):
|
|
nTotal = sum(moles.values())
|
|
for name, X in moles.items():
|
|
self.assertAlmostEqual(gas[name].X[0], X/nTotal)
|
|
|
|
def test_equil_complete_stoichiometric(self):
|
|
"""
|
|
Equilibrium should correspond to complete combustion
|
|
"""
|
|
gas = ct.Solution("equilibrium.yaml", "complete")
|
|
gas.TPX = 298, 100000, 'CH4:1.0, O2:2.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=0, O2=0, H2O=2, CO2=1)
|
|
|
|
def test_equil_complete_lean(self):
|
|
"""
|
|
Equilibrium should correspond to complete combustion (with excess O2)
|
|
CH4 + 3 O2 -> CO2 + 2 H2O + O2
|
|
"""
|
|
gas = ct.Solution("equilibrium.yaml", "complete")
|
|
gas.TPX = 298, 100000, 'CH4:1.0, O2:3.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=0, O2=1, H2O=2, CO2=1)
|
|
|
|
def test_equil_incomplete_stoichiometric(self):
|
|
gas = ct.Solution("equilibrium.yaml", "incomplete")
|
|
gas.TPX = 301, 100000, 'CH4:1.0, O2:2.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=0, O2=0, H2O=2, CO2=1)
|
|
|
|
def test_equil_incomplete_lean(self):
|
|
gas = ct.Solution("equilibrium.yaml", "incomplete")
|
|
gas.TPX = 301, 100000, 'CH4:1.0, O2:3.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=0, O2=1, H2O=2, CO2=1)
|
|
|
|
def test_equil_gri_stoichiometric(self):
|
|
gas = ct.Solution('gri30.yaml', transport_model=None)
|
|
gas.TPX = 301, 100000, 'CH4:1.0, O2:2.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=0, O2=0, H2O=2, CO2=1)
|
|
|
|
def test_equil_gri_lean(self):
|
|
gas = ct.Solution('gri30.yaml', transport_model=None)
|
|
gas.TPX = 301, 100000, 'CH4:1.0, O2:3.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=0, O2=1, H2O=2, CO2=1)
|
|
|
|
def test_equil_overconstrained1(self):
|
|
gas = ct.Solution("equilibrium.yaml", "overconstrained-1")
|
|
gas.TPX = 301, 100000, 'CH4:1.0, O2:1.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=1, O2=1)
|
|
|
|
def test_equil_overconstrained2(self):
|
|
gas = ct.Solution("equilibrium.yaml", "overconstrained-2")
|
|
gas.TPX = 301, 100000, 'CH4:1.0, O2:1.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=1, O2=1)
|
|
|
|
|
|
class ChemEquilTest(EquilTestCases, utilities.CanteraTest):
|
|
def __init__(self, *args, **kwargs):
|
|
EquilTestCases.__init__(self, 'element_potential')
|
|
unittest.TestCase.__init__(self, *args, **kwargs)
|
|
|
|
|
|
class MultiphaseEquilTest(EquilTestCases, utilities.CanteraTest):
|
|
def __init__(self, *args, **kwargs):
|
|
EquilTestCases.__init__(self, 'gibbs')
|
|
unittest.TestCase.__init__(self, *args, **kwargs)
|
|
|
|
@unittest.expectedFailure
|
|
def test_equil_gri_stoichiometric(self):
|
|
gas = ct.Solution('gri30.yaml', transport_model=None)
|
|
gas.TPX = 301, 100000, 'CH4:1.0, O2:2.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=0, O2=0, H2O=2, CO2=1)
|
|
|
|
@unittest.expectedFailure
|
|
def test_equil_gri_lean(self):
|
|
gas = ct.Solution('gri30.yaml', transport_model=None)
|
|
gas.TPX = 301, 100000, 'CH4:1.0, O2:3.0'
|
|
gas.equilibrate('TP', self.solver)
|
|
self.check(gas, CH4=0, O2=1, H2O=2, CO2=1)
|
|
|
|
|
|
class EquilExtraElements(utilities.CanteraTest):
|
|
def setUp(self):
|
|
s = """
|
|
phases:
|
|
- name: gas
|
|
thermo: ideal-gas
|
|
elements: [H, Ar, C, O, Cl, N]
|
|
species: [{gri30.yaml/species: [AR, N2, CH4, O2, CO2, H2O, CO, H2, OH]}]
|
|
"""
|
|
self.gas = ct.Solution(yaml=s)
|
|
self.gas.TP = 300, 101325
|
|
self.gas.set_equivalence_ratio(0.8, 'CH4', 'O2:1.0, N2:3.76')
|
|
|
|
def test_auto(self):
|
|
# Succeeds after falling back to VCS
|
|
self.gas.equilibrate('TP')
|
|
self.assertNear(self.gas['CH4'].X[0], 0.0)
|
|
|
|
@unittest.expectedFailure
|
|
def test_element_potential(self):
|
|
self.gas.equilibrate('TP', solver='element_potential')
|
|
self.assertNear(self.gas['CH4'].X[0], 0.0)
|
|
|
|
def test_gibbs(self):
|
|
self.gas.equilibrate('TP', solver='gibbs')
|
|
self.assertNear(self.gas['CH4'].X[0], 0.0)
|
|
|
|
def test_vcs(self):
|
|
self.gas.equilibrate('TP', solver='vcs')
|
|
self.assertNear(self.gas['CH4'].X[0], 0.0)
|
|
|
|
|
|
class VCS_EquilTest(EquilTestCases, utilities.CanteraTest):
|
|
def __init__(self, *args, **kwargs):
|
|
EquilTestCases.__init__(self, 'vcs')
|
|
unittest.TestCase.__init__(self, *args, **kwargs)
|
|
|
|
|
|
class TestKOH_Equil(utilities.CanteraTest):
|
|
"Test roughly based on examples/multiphase/plasma_equilibrium.py"
|
|
def setUp(self):
|
|
self.phases = ct.import_phases("KOH.yaml",
|
|
['K_solid', 'K_liquid', 'KOH_a', 'KOH_b', 'KOH_liquid',
|
|
'K2O2_solid', 'K2O_solid', 'KO2_solid', 'ice', 'liquid_water',
|
|
'KOH_plasma'])
|
|
self.mix = ct.Mixture(self.phases)
|
|
|
|
def test_equil_TP(self):
|
|
temperatures = range(350, 5000, 300)
|
|
data = np.zeros((len(temperatures), self.mix.n_species+1))
|
|
data[:,0] = temperatures
|
|
|
|
for i,T in enumerate(temperatures):
|
|
self.mix.T = T
|
|
self.mix.P = ct.one_atm
|
|
self.mix.species_moles = 'K:1.03, H2:2.12, O2:0.9'
|
|
self.mix.equilibrate('TP', solver='vcs')
|
|
|
|
data[i,1:] = self.mix.species_moles
|
|
|
|
self.compare(data, self.test_data_path / "koh-equil-TP.csv")
|
|
|
|
@utilities.slow_test
|
|
def test_equil_HP(self):
|
|
temperatures = range(350, 5000, 300)
|
|
data = np.zeros((len(temperatures), self.mix.n_species+2))
|
|
data[:,0] = temperatures
|
|
|
|
# The outer iteration for the temperature *should* be able to
|
|
# converge from further away, but in practice, it can't. (Of course,
|
|
# changing this value requires replacing the reference output)
|
|
dT = 1
|
|
self.mix.P = ct.one_atm
|
|
|
|
for i,T in enumerate(temperatures):
|
|
self.mix.species_moles = 'K:1.03, H2:2.12, O2:0.9'
|
|
self.mix.T = T - dT
|
|
self.mix.equilibrate('TP', solver='vcs')
|
|
self.mix.T = T
|
|
self.mix.equilibrate('HP', solver='vcs')
|
|
|
|
data[i,1] = self.mix.T # equilibrated temperature
|
|
data[i,2:] = self.mix.species_moles
|
|
|
|
self.compare(data, self.test_data_path / "koh-equil-HP.csv")
|
|
|
|
|
|
class TestEquil_GasCarbon(utilities.CanteraTest):
|
|
"Test rougly based on examples/multiphase/adiabatic.py"
|
|
def setUp(self):
|
|
self.gas = ct.Solution('gri30.yaml', transport_model=None)
|
|
self.carbon = ct.Solution("graphite.yaml")
|
|
self.fuel = 'CH4'
|
|
self.mix_phases = [(self.gas, 1.0), (self.carbon, 0.0)]
|
|
self.n_species = self.gas.n_species + self.carbon.n_species
|
|
|
|
def solve(self, solver, **kwargs):
|
|
n_points = 12
|
|
T = 300
|
|
P = 101325
|
|
data = np.zeros((n_points, 2+self.n_species))
|
|
phi = np.linspace(0.3, 3.5, n_points)
|
|
for i in range(n_points):
|
|
self.gas.set_equivalence_ratio(phi[i], self.fuel,
|
|
{'O2': 1.0, 'N2': 3.76})
|
|
mix = ct.Mixture(self.mix_phases)
|
|
mix.T = T
|
|
mix.P = P
|
|
|
|
# equilibrate the mixture adiabatically at constant P
|
|
mix.equilibrate('HP', solver=solver, max_steps=1000, **kwargs)
|
|
data[i,:2] = (phi[i], mix.T)
|
|
data[i,2:] = mix.species_moles
|
|
|
|
self.compare(data, self.test_data_path / "gas-carbon-equil.csv")
|
|
|
|
@utilities.slow_test
|
|
def test_gibbs(self):
|
|
self.solve('gibbs')
|
|
|
|
@utilities.slow_test
|
|
def test_vcs(self):
|
|
self.solve('vcs')
|
|
|
|
def test_vcs_est(self):
|
|
self.solve('vcs', estimate_equil=-1)
|
|
|
|
|
|
class Test_IdealSolidSolnPhase_Equil(utilities.CanteraTest):
|
|
def test_equil(self):
|
|
gas = ct.ThermoPhase("IdealSolidSolnPhaseExample.yaml")
|
|
gas.TPX = 500, ct.one_atm, 'C2H2-graph: 1.0'
|
|
|
|
gas.equilibrate('TP', solver='element_potential')
|
|
self.assertNear(gas['C-graph'].X[0], 2.0 / 3.0)
|
|
self.assertNear(gas['H2-solute'].X[0], 1.0 / 3.0)
|