Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 38 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,44 @@ jobs:
- name: Test Cantera
run: scons test

run-examples:
name: Run the Python examples using bash
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
name: Checkout the repository
with:
submodules: recursive
- name: Setup Python
uses: actions/setup-python@v1
with:
python-version: '3.8'
architecture: x64
- name: Install Apt dependencies
run: sudo apt-get install libboost-dev gfortran graphviz liblapack-dev libblas-dev
- name: Upgrade pip
run: python3 -m pip install -U pip setuptools wheel
- name: Install Python dependencies
run: python3 -m pip install ruamel.yaml scons numpy cython h5py pandas matplotlib scipy
- name: Build Cantera
run: python3 `which scons` build -j2
- name: Run the examples
# See https://unix.stackexchange.com/a/392973 for an explanation of the -exec part
run: |
find interfaces/cython/cantera/examples -type f -iname "*.py" \
-exec sh -c 'for n; do echo "$n" | tee -a results.txt && python3 "$n" >> results.txt || exit 1; done' sh {} +
env:
Comment thread
bryanwweber marked this conversation as resolved.
PYTHONPATH: build/python
PYTHONWARNINGS: error
MPLBACKEND: Agg
- name: Save the results file for inspection
uses: actions/upload-artifact@v2
with:
path: results.txt
# Run this step if the job was successful or failed, but not if it was cancelled
# Using always() would run this step if the job was cancelled as well.
if: failure() || success()

multiple-sundials:
name: Sundials ${{ matrix.sundials-ver }}
runs-on: ubuntu-latest
Expand Down
28 changes: 14 additions & 14 deletions data/sofc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: |-
species thermochemistry ARE NOT REAL VALUES - they are chosen only
for the purposes of this example.

Defines bulk (i.e., 3D) phases - a gas, a metal, and an oxide.
Defines bulk (that is, 3D) phases - a gas, a metal, and an oxide.
The gas contains only the minimum number of species needed to model
operation on hydrogen. The species definitions are imported from
gri30.yaml. The initial composition is set to hydrogen + 5% water, but
Expand All @@ -26,22 +26,22 @@ description: |-
charge balances on the metal, then we would require a more complex
model. Note that there is no work function for this metal.

Note: the "const_cp" species thermo model is used throughout this
Note: the 'const_cp' species thermo model is used throughout this
file (with the exception of the gaseous species, which use NASA
polynomials imported from gri30.cti). The const_cp model assumes a
polynomials imported from gri30.yaml). The const_cp model assumes a
constant specific heat, which by default is zero. Parameters that
can be specified are cp0, t0, h0, and s0. If omitted, t0 = 300 K, h0
= 0, and s0 = 0. The thermo properties are computed as follows: h =
h0 + cp0*(t - t0), s = s0 + cp0*ln(t/t0). For work at a single
temperature, it is sufficient to specify only h0.
can be specified are cp0, t0, h0, and s0. If omitted, t0 = 300 K,
h0 = 0, and s0 = 0. The thermo properties are computed as follows:
h = h0 + cp0*(t - t0), s = s0 + cp0*ln(t/t0).
For work at a single temperature, it is sufficient to specify only h0.

The 'oxide_bulk' phase is a very simple model for the bulk phase. We only
consider the oxygen sublattice. The only species we define are a
lattice oxygen, and an oxygen vacancy. Again, the density is a
required input, but is not used here, so may be set arbitrarily.

The vacancy will be modeled as truly vacant - it contains no atoms,
has no charge, and has zero enthalpy and entropy. This is different
has no charge, and has zero enthalpy and entropy. This is different
from the usual convention in which the vacancy properties are are
expressed relative to the perfect crystal lattice. For example, in
the usual convention, an oxygen vacancy has charge +2. But the
Expand All @@ -65,7 +65,7 @@ description: |-
'mol' and 'cm' were specified in the units directive below as the
units for quantity and length, respectively.
2. The 'reactions' field specifies that all reaction entries in this file
that have are in the 'metal_surface-reactions' field are reactions belonging
that are in the 'metal_surface-reactions' field are reactions belonging
to this surface mechanism.

On the oxide surface, we consider four species:
Expand All @@ -74,11 +74,11 @@ description: |-
3. OH'(ox) - a surface hydroxyl with charge -1
4. H2O(ox) - physisorbed neutral water

The 'tpb' phase is th etriple phase boundary between the metal, oxide, and gas. A
single species is specified, but it is not used, since all reactions
only involve species on either side of the tpb. Note that the site
density is in mol/cm. But since no reactions involve TPB species,
this parameter is unused.
The triple phase boundary (TPB) between the metal, oxide, and gas is
specified in the 'tpb' phase. A single species is specified, but it
is not used, since all reactions only involve species on either side
of the TPB. Note that the site density is in mol/cm. But since no
reactions involve TPB species, this parameter is unused.

generator: cti2yaml
cantera-version: 2.5.0a3
Expand Down
4 changes: 2 additions & 2 deletions include/cantera/kinetics/RateCoeffMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ class Rate1

/**
* Update the concentration-dependent parts of the rate coefficient, if any.
* Used by class SurfaceArrhenius to compute coverage-dependent *
* Used by class SurfaceArrhenius to compute coverage-dependent
* modifications to the Arrhenius parameters. The array c should contain
* whatever data the particular rate coefficient class needs to update its
* rates. Note that this method does not return anything. To get the
* rates. Note that this method does not return anything. To get the
* updated rates, method update must be called after the call to update_C.
*/
void update_C(const doublereal* c) {
Expand Down
2 changes: 1 addition & 1 deletion include/cantera/kinetics/RxnRates.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class SurfaceArrhenius
}

/**
* Update the value the rate constant.
* Update the value of the rate constant.
*
* This function returns the actual value of the rate constant. It can be
* safely called for negative values of the pre-exponential factor.
Expand Down
6 changes: 3 additions & 3 deletions include/cantera/kinetics/StoichManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace Cantera
* \f]
*
* where \f$ \nu^{(p)_{k,i}} \f$ is the product-side stoichiometric
* coefficient of species \a k in reaction \a i. This could be done be
* coefficient of species \a k in reaction \a i. This could be done by
* straightforward matrix multiplication, but would be inefficient, since most
* of the matrix elements of \f$ \nu^{(p)}_{k,i} \f$ are zero. We could do
* better by using sparse-matrix algorithms to compute this product.
Expand All @@ -61,12 +61,12 @@ namespace Cantera
* computing quantities that can be written as matrix multiplies.
*
* They are designed to explicitly unroll loops over species or reactions for
* Operations on reactions that require knowing the reaction stoichiometry.
* operations on reactions that require knowing the reaction stoichiometry.
*
* This module consists of class StoichManager, and classes C1, C2, and C3.
* Classes C1, C2, and C3 handle operations involving one, two, or three
* species, respectively, in a reaction. Instances are instantiated with a
* reaction number, and n species numbers (n = 1 for C1, etc.). All three
* reaction number, and n species numbers (n = 1 for C1, etc.). All three
* classes have the same interface.
*
* These classes are designed for use by StoichManager, and the operations
Expand Down
4 changes: 4 additions & 0 deletions include/cantera/oneD/Boundary1D.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ class ReactingSurf1D : public Boundary1D
m_enabled = docov;
}

bool coverageEnabled() {
return m_enabled;
}

virtual std::string componentName(size_t n) const;

virtual void init();
Expand Down
4 changes: 2 additions & 2 deletions include/cantera/thermo/EdgePhase.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ namespace Cantera
* thermodynamic object.
*
* All of the equations and formulations carry through from SurfPhase to this
* EdgePhase object. It should be noted however, that dimensional object with
* length dimensions, have their dimensions reduced by one.
* EdgePhase object. It should be noted that dimensional quantities with
* dimensions including a length have their dimensions reduced by one.
Comment thread
bryanwweber marked this conversation as resolved.
*
* @ingroup thermoprops
*/
Expand Down
1 change: 1 addition & 0 deletions interfaces/cython/cantera/_cantera.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,7 @@ cdef extern from "cantera/oneD/Boundary1D.h":
CxxRreactingSurf1D()
void setKineticsMgr(CxxInterfaceKinetics*) except +translate_exception
void enableCoverageEquations(cbool) except +translate_exception
cbool coverageEnabled()


cdef extern from "cantera/oneD/StFlow.h":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
import cantera as ct
import matplotlib.pyplot as plt

all_species = ct.Species.listFromFile('gri30.yaml')
input_file = 'gri30.yaml'
all_species = ct.Species.listFromFile(input_file)
species = []

# Filter species
Expand All @@ -36,7 +37,8 @@
print('Species: {0}'.format(', '.join(S.name for S in species)))

# Filter reactions, keeping only those that only involve the selected species
all_reactions = ct.Reaction.listFromFile('gri30.yaml')
ref_phase = ct.Solution(thermo='ideal-gas', kinetics='gas', species=all_species)
all_reactions = ct.Reaction.listFromFile(input_file, ref_phase)
reactions = []

print('\nReactions:')
Expand All @@ -51,8 +53,8 @@
print(R.equation)
print('\n')

gas1 = ct.Solution('gri30.yaml')
gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics',
gas1 = ct.Solution(input_file)
gas2 = ct.Solution(thermo='ideal-gas', kinetics='gas',
species=species, reactions=reactions)


Expand Down
9 changes: 5 additions & 4 deletions interfaces/cython/cantera/examples/kinetics/reaction_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
Requires: cantera >= 2.5.0
"""

import os
from subprocess import run
import sys
from pathlib import Path

import cantera as ct

Expand All @@ -33,14 +34,14 @@

dot_file = 'rxnpath.dot'
img_file = 'rxnpath.png'
img_path = os.path.join(os.getcwd(), img_file)
img_path = Path.cwd().joinpath(img_file)

diagram.write_dot(dot_file)
print(diagram.get_data())

print("Wrote graphviz input file to '{0}'.".format(os.path.join(os.getcwd(), dot_file)))
print("Wrote graphviz input file to '{0}'.".format(Path.cwd().joinpath(dot_file)))

os.system('dot {0} -Tpng -o{1} -Gdpi=200'.format(dot_file, img_file))
run('dot {0} -Tpng -o{1} -Gdpi=200'.format(dot_file, img_file).split())
print("Wrote graphviz output file to '{0}'.".format(img_path))

if "-view" in sys.argv:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
f.oxidizer_inlet.T = tin_o

# Set the boundary emissivities
f.set_boundary_emissivities(0.0, 0.0)
f.boundary_emissivities = 0.0, 0.0
# Turn radiation off
f.radiation_enabled = False

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,12 @@
f.solve(loglevel=0)
except ct.CanteraError as e:
print('Error: Did not converge at n =', n, e)
if np.max(f.T) > temperature_limit_extinction:
if not np.isclose(np.max(f.T), temperature_limit_extinction):
# Flame is still burning, so proceed to next strain rate
n_last_burning = n
if hdf_output:
group = 'extinction/{0:04d}'.format(n)
f.write_hdf(file_name, group=group, quiet=False,
description='extinction iteration'.format(n))
f.write_hdf(file_name, group=group, quiet=True)
else:
file_name = 'extinction_{0:04d}.xml'.format(n)
f.save(os.path.join(data_directory, file_name),
Expand All @@ -145,19 +144,32 @@
', reaction mechanism ' + reaction_mechanism)
T_max.append(np.max(f.T))
a_max.append(np.max(np.abs(np.gradient(f.velocity) / np.gradient(f.grid))))
print('Flame burning at alpha = {:8.4F}. Proceeding to the next iteration, '
'with delta_alpha = {}'.format(alpha[-1], delta_alpha))
elif ((T_max[-2] - T_max[-1] < delta_T_min) and (delta_alpha < delta_alpha_min)):
# If the temperature difference is too small and the minimum relative
# strain rate increase is reached, abort
if ((T_max[-2] - T_max[-1] < delta_T_min) &
(delta_alpha < delta_alpha_min)):
print('Flame extinguished at n = {0}.'.format(n),
'Abortion criterion satisfied.')
break
# strain rate increase is reached, save the last, non-burning, solution
# to the output file and break the loop
T_max.append(np.max(f.T))
a_max.append(np.max(np.abs(np.gradient(f.velocity) / np.gradient(f.grid))))
if hdf_output:
group = 'extinction/{0:04d}'.format(n)
f.write_hdf(file_name, group=group, quiet=True)
else:
file_name = 'extinction_{0:04d}.xml'.format(n)
f.save(os.path.join(data_directory, file_name), name='solution', loglevel=0)
print('Flame extinguished at alpha = {0:8.4F}.'.format(alpha[-1]),
'Abortion criterion satisfied.')
break
else:
# Procedure if flame extinguished but abortion criterion is not satisfied
print('Flame extinguished at n = {0}. Restoring n = {1} with '
'alpha = {2}'.format(n, n_last_burning, alpha[n_last_burning]))
# Reduce relative strain rate increase
delta_alpha = delta_alpha / delta_alpha_factor

print('Flame extinguished at alpha = {0:8.4F}. Restoring alpha = {1:8.4F} and '
'trying delta_alpha = {2}'.format(
alpha[-1], alpha[n_last_burning], delta_alpha))

# Restore last burning solution
if hdf_output:
group = 'extinction/{0:04d}'.format(n_last_burning)
Expand All @@ -168,7 +180,15 @@
name='solution', loglevel=0)


# Print some parameters at the extinction point
# Print some parameters at the extinction point, after restoring the last burning
# solution
if hdf_output:
group = 'extinction/{0:04d}'.format(n_last_burning)
f.read_hdf(file_name, group=group)
else:
file_name = 'extinction_{0:04d}.xml'.format(n_last_burning)
f.restore(os.path.join(data_directory, file_name),
name='solution', loglevel=0)
print('----------------------------------------------------------------------')
print('Parameters at the extinction point:')
print('Pressure p={0} bar'.format(f.P / 1e5))
Expand Down
5 changes: 4 additions & 1 deletion interfaces/cython/cantera/examples/onedim/flame_fixed_T.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import cantera as ct
import numpy as np
from pathlib import Path

################################################################
# parameter values
Expand Down Expand Up @@ -38,7 +39,9 @@

# read temperature vs. position data from a file.
# The file is assumed to have one z, T pair per line, separated by a comma.
zloc, tvalues = np.genfromtxt('tdata.dat', delimiter=',', comments='#').T
# The data file must be stored in the same folder as this script.
data_file = Path(__file__).parent.joinpath('tdata.dat')
zloc, tvalues = np.genfromtxt(str(data_file), delimiter=',', comments='#').T
zloc /= max(zloc)

# set the temperature profile to the values read in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
p = ct.one_atm
tburner = 600.0
reactants = 'CH4:1.0, O2:2.0, N2:7.52' # premixed gas composition
width = 0.5 # m
width = 0.05 # m
loglevel = 1 # amount of diagnostic output (0 to 5)

gas = ct.Solution('gri30_ion.yaml')
Expand Down
Loading