[1]:
import logging
import pprint
from molmass import Formula
from atmodeller import (
ChemicalSpecies,
EquilibriumModel,
SpeciesNetwork,
ThermodynamicState,
debug_logger,
)
from atmodeller.thermodata.core import CondensateActivity
logger = debug_logger()
logger.setLevel(logging.INFO)
# For more output use DEBUG
# logger.setLevel(logging.DEBUG)
Atmodeller initialized with double precision (float64)
Gas Mixing
This notebook is available at notebooks/gas_mixing.ipynb and is easiest to obtain by downloading the source code.
In gas mixing experiments, a predefined gaseous mixture is injected into a chamber and allowed to equilibrate thermodynamically under controlled temperature-pressure conditions. In this example, we consider a gas mixture that equilibrates in the presence of solid carbon (graphite).
[2]:
# Enforce the stability of graphite
# Since in this example we do not provide carbon in the injected gas stream, we cannot solve for
# the stability of any carbon-bearing products because in order to do so requires specification of
# the mass of carbon in the system.
activity = CondensateActivity(1.0)
C_cr = ChemicalSpecies.create_condensed("C", activity=activity, solve_for_stability=False)
# Define allowable gas species at equilibrium
H2_g = ChemicalSpecies.create_gas("H2")
N2_g = ChemicalSpecies.create_gas("N2")
CH4_g = ChemicalSpecies.create_gas("CH4")
CHN_g = ChemicalSpecies.create_gas("CHN")
H_g = ChemicalSpecies.create_gas("H")
species = SpeciesNetwork((C_cr, H2_g, N2_g, CH4_g, CHN_g, H_g))
model = EquilibriumModel(species)
# Set the temperature and pressure
state = ThermodynamicState(temperature=1773.15, melt_fraction=0, pressure=1)
# Define the mole fractions of input gases
mole_fractions = {"H2": 0.5, "N2": 0.5}
# Define the composition of the input gas mixture by mass
mass_constraints = {key: value * Formula(key).mass for key, value in mole_fractions.items()}
# Solve
model.solve(state=state, mass_constraints=mass_constraints, solver="basic")
# The abundance of C cannot be solved for, so the output result for the number density of graphite
# should be ignored.
output = model.output
solution = output.quick_look()
logger.info("solution = %s", pprint.pformat(solution))
# Optionally dump the output to Excel
# output.to_excel("gas_mixing")
[19:34:59 - atmodeller.classes - INFO ] - species_network = ('C_cd: CondensateActivity, NoSolubility', 'H2_g: IdealGas, NoSolubility', 'N2_g: IdealGas, NoSolubility', 'CH4_g: IdealGas, NoSolubility', 'CHN_g: IdealGas, NoSolubility', 'H_g: IdealGas, NoSolubility')
[19:34:59 - atmodeller.classes - INFO ] - Thermodynamic data requires temperatures between 200 K and 6000 K
[19:34:59 - atmodeller.classes - INFO ] - reactions = {0: '1.0 C_cd + 2.0 H2_g = 1.0 CH4_g',
1: '1.0 C_cd + 0.5 H2_g + 0.5 N2_g = 1.0 CHN_g',
2: '0.5 H2_g = 1.0 H_g'}
[19:35:03 - atmodeller.classes - INFO ] - Solve (basic) complete: 1 (100.00%) successful model(s)
[19:35:03 - atmodeller.classes - INFO ] - Multistart summary: 1 (100.00%) models(s) required 1 attempt(s)
[19:35:03 - atmodeller.classes - INFO ] - Solver steps (max) = 53
[19:35:04 - atmodeller - INFO ] - solution = {'CH4_g': array(0.000212698488103),
'CH4_g_activity': array(0.000212698488103),
'CHN_g': array(0.003057989685365),
'CHN_g_activity': array(0.003057989685365),
'C_cd': array(5.185286445067471e+18),
'C_cd_activity': array(1.),
'H2_g': array(0.498000976078994),
'H2_g_activity': array(0.498000976078993),
'H_g': array(0.000201308461558),
'H_g_activity': array(0.000201308461558),
'N2_g': array(0.49852702728598),
'N2_g_activity': array(0.498527027285979)}