mirror of
https://github.com/Cantera/cantera.git
synced 2025-02-25 18:55:29 -06:00
Remove deprecated Python code
This commit is contained in:
parent
9d520d5278
commit
ab46f66601
@ -20,7 +20,7 @@ InterfaceKinetics
|
||||
Reactions
|
||||
---------
|
||||
|
||||
These classes contain the definition of a single reaction, independent of a specific
|
||||
This class contains the definition of a single reaction, independent of a specific
|
||||
`Kinetics` object. Reaction rate evaluation is handled by `ReactionRate` objects.
|
||||
|
||||
Reaction
|
||||
@ -28,26 +28,6 @@ Reaction
|
||||
.. autoclass:: Reaction
|
||||
:no-undoc-members:
|
||||
|
||||
ThreeBodyReaction
|
||||
^^^^^^^^^^^^^^^^^
|
||||
.. autoclass:: ThreeBodyReaction
|
||||
:no-undoc-members:
|
||||
|
||||
FalloffReaction
|
||||
^^^^^^^^^^^^^^^
|
||||
.. autoclass:: FalloffReaction
|
||||
:no-undoc-members:
|
||||
|
||||
ChemicallyActivatedReaction
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
.. autoclass:: ChemicallyActivatedReaction
|
||||
:no-undoc-members:
|
||||
|
||||
CustomReaction
|
||||
^^^^^^^^^^^^^^
|
||||
.. autoclass:: CustomReaction
|
||||
:no-undoc-members:
|
||||
|
||||
|
||||
Reaction Rates
|
||||
--------------
|
||||
|
@ -35,30 +35,10 @@ ImpingingJet
|
||||
^^^^^^^^^^^^
|
||||
.. autoclass:: ImpingingJet
|
||||
|
||||
IonFreeFlame
|
||||
^^^^^^^^^^^^
|
||||
.. autoclass:: IonFreeFlame
|
||||
|
||||
.. autoattribute:: E
|
||||
.. autoattribute:: electric_field_enabled
|
||||
.. automethod:: solve
|
||||
|
||||
IonBurnerFlame
|
||||
^^^^^^^^^^^^^^
|
||||
.. autoclass:: IonBurnerFlame
|
||||
|
||||
.. autoattribute:: E
|
||||
.. autoattribute:: electric_field_enabled
|
||||
.. automethod:: solve
|
||||
|
||||
Flow Domains
|
||||
------------
|
||||
|
||||
IdealGasFlow
|
||||
^^^^^^^^^^^^
|
||||
.. autoclass:: IdealGasFlow(thermo)
|
||||
:inherited-members:
|
||||
|
||||
FreeFlow
|
||||
^^^^^^^^
|
||||
.. autoclass:: FreeFlow(thermo)
|
||||
@ -67,9 +47,6 @@ AxisymmetricFlow
|
||||
^^^^^^^^^^^^^^^^
|
||||
.. autoclass:: AxisymmetricFlow(thermo)
|
||||
|
||||
IonFlow
|
||||
^^^^^^^
|
||||
.. autoclass:: IonFlow(thermo)
|
||||
|
||||
Boundaries
|
||||
----------
|
||||
|
@ -469,24 +469,6 @@ cdef class ReactingSurface1D(Boundary1D):
|
||||
def __get__(self):
|
||||
return self.surface
|
||||
|
||||
def set_kinetics(self, Kinetics kin):
|
||||
"""Set the kinetics manager (surface reaction mechanism object).
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; set `Kinetics` when instantiating
|
||||
`ReactingSurface1D` instead.
|
||||
"""
|
||||
warnings.warn("ReactingSurface1D.set_kinetics: Method to be removed after "
|
||||
"Cantera 3.0; set 'Kinetics' when instantiating 'ReactingSurface1D' "
|
||||
"instead.", DeprecationWarning)
|
||||
if pystr(kin.kinetics.kineticsType()) not in ("surface", "edge"):
|
||||
raise TypeError('Kinetics object must be derived from '
|
||||
'InterfaceKinetics.')
|
||||
self.surf.setKinetics(kin.base.kinetics())
|
||||
self.surface = kin
|
||||
self.surface._references[self._weakref_proxy] = True
|
||||
|
||||
property coverage_enabled:
|
||||
"""Controls whether or not to solve the surface coverage equations."""
|
||||
def __set__(self, value):
|
||||
@ -738,82 +720,6 @@ cdef class AxisymmetricFlow(_FlowBase):
|
||||
_domain_type = "axisymmetric-flow"
|
||||
|
||||
|
||||
cdef class IdealGasFlow(_FlowBase):
|
||||
"""
|
||||
An ideal gas flow domain. Functions `set_free_flow` and
|
||||
`set_axisymmetric_flow` can be used to set different type of flow.
|
||||
|
||||
For the type of axisymmetric flow, the equations solved are the similarity
|
||||
equations for the flow in a finite-height gap of infinite radial extent.
|
||||
The solution variables are:
|
||||
|
||||
*velocity*
|
||||
axial velocity
|
||||
*spread_rate*
|
||||
radial velocity divided by radius
|
||||
*T*
|
||||
temperature
|
||||
*lambda*
|
||||
(1/r)(dP/dr)
|
||||
*Y_k*
|
||||
species mass fractions
|
||||
|
||||
It may be shown that if the boundary conditions on these variables are
|
||||
independent of radius, then a similarity solution to the exact governing
|
||||
equations exists in which these variables are all independent of radius.
|
||||
This solution holds only in in low-Mach-number limit, in which case
|
||||
(dP/dz) = 0, and lambda is a constant. (Lambda is treated as a spatially-
|
||||
varying solution variable for numerical reasons, but in the final solution
|
||||
it is always independent of z.) As implemented here, the governing
|
||||
equations assume an ideal gas mixture. Arbitrary chemistry is allowed, as
|
||||
well as arbitrary variation of the transport properties.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Class to be removed after Cantera 3.0; replaced by `FreeFlow`,
|
||||
`AxisymmetricFlow` and `UnstrainedFlow`.
|
||||
"""
|
||||
_domain_type = "gas-flow"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn("Class 'IdealGasFlow' to be removed after Cantera 3.0; use "
|
||||
"'FreeFlow', 'AxisymmetricFlow' or 'UnstrainedFlow' instead.",
|
||||
DeprecationWarning)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
cdef class IonFlow(_FlowBase):
|
||||
"""
|
||||
An ion flow domain.
|
||||
|
||||
In an ion flow domain, the electric drift is added to the diffusion flux
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Class to be removed after Cantera 3.0; replaced by `FreeFlow`,
|
||||
`AxisymmetricFlow` and `UnstrainedFlow`.
|
||||
"""
|
||||
_domain_type = "ion-flow"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn("Class 'IonFlow' to be removed after Cantera 3.0; use 'FreeFlow',"
|
||||
" 'AxisymmetricFlow' or 'UnstrainedFlow' instead.",
|
||||
DeprecationWarning)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def set_solving_stage(self, stage):
|
||||
"""
|
||||
Set the mode for handling ionized species:
|
||||
|
||||
- ``stage == 1``: the fluxes of charged species are set to zero
|
||||
- ``stage == 2``: the electric field equation is solved, and the drift flux for
|
||||
ionized species is evaluated
|
||||
"""
|
||||
warnings.warn("IonFlow.set_solving_stage: Method to be removed after Cantera "
|
||||
"3.0; use 'solving_stage' property instead.", DeprecationWarning)
|
||||
self.solving_stage = stage
|
||||
|
||||
|
||||
cdef class Sim1D:
|
||||
"""
|
||||
Class Sim1D is a container for one-dimensional domains. It also holds the
|
||||
@ -1057,89 +963,12 @@ cdef class Sim1D:
|
||||
dom, comp = self._get_indices(domain, component)
|
||||
self.sim.setFlatProfile(dom, comp, value)
|
||||
|
||||
def restore_data(self, domain, states, other_cols, meta):
|
||||
"""
|
||||
Restore a ``domain`` from underlying data. This method is used as
|
||||
a service function for import via `FlameBase.from_solution_array`.
|
||||
|
||||
Derived classes set default values for ``domain`` and ``other``, where
|
||||
defaults describe flow domain and essential non-thermodynamic solution
|
||||
components of the configuration, respectively. An alternative ``domain``
|
||||
(such as inlet, outlet, etc.), can be specified either by name or the
|
||||
corresponding Domain1D object itself.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0. Unused after moving `SolutionArray`
|
||||
interface to the C++ core, except for `FlameBase.from_solution_array`,
|
||||
which itself is deprecated due to a pending removal of ``h5py`` support.
|
||||
"""
|
||||
warnings.warn("Sim1D.restore_data: Method to be removed after Cantera 3.0.",
|
||||
DeprecationWarning)
|
||||
idom = self.domain_index(domain)
|
||||
dom = self.domains[idom]
|
||||
T, P, Y = states
|
||||
if isinstance(P, np.ndarray) and P.size:
|
||||
P = P[0]
|
||||
|
||||
if isinstance(dom, _FlowBase):
|
||||
grid = other_cols['grid']
|
||||
dom.grid = grid
|
||||
xi = (grid - grid[0]) / (grid[-1] - grid[0])
|
||||
self._get_initial_solution()
|
||||
|
||||
# restore temperature and 'other' profiles
|
||||
self.set_profile('T', xi, T)
|
||||
for key, val in other_cols.items():
|
||||
if key in ['grid', 'qdot']:
|
||||
pass
|
||||
elif key in dom.component_names:
|
||||
self.set_profile(key, xi, val)
|
||||
|
||||
# restore species profiles
|
||||
for i, spc in enumerate(self.gas.species_names):
|
||||
self.set_profile(spc, xi, Y[:, i])
|
||||
|
||||
# restore pressure
|
||||
self.P = P
|
||||
|
||||
# restore settings
|
||||
dom.settings = meta
|
||||
|
||||
elif isinstance(dom, Inlet1D):
|
||||
self.gas.TPY = T, P, Y
|
||||
dom.T = T
|
||||
self.P = P
|
||||
dom.Y = Y
|
||||
dom.mdot = other_cols['velocity'] * self.gas.density
|
||||
|
||||
elif isinstance(dom, (Outlet1D, OutletReservoir1D,
|
||||
SymmetryPlane1D, Surface1D)):
|
||||
pass
|
||||
|
||||
elif isinstance(dom, ReactingSurface1D):
|
||||
dom.surface.TPY = T, P, Y
|
||||
|
||||
else:
|
||||
msg = ("Import of '{}' is not implemented")
|
||||
raise NotImplementedError(msg.format(type(self).__name__))
|
||||
|
||||
def show(self):
|
||||
""" print the current solution. """
|
||||
if not self._initialized:
|
||||
self.set_initial_guess()
|
||||
self.sim.show()
|
||||
|
||||
def show_solution(self):
|
||||
"""
|
||||
print the current solution.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; replaced by `show`.
|
||||
"""
|
||||
self.show()
|
||||
|
||||
def set_time_step(self, stepsize, n_steps):
|
||||
"""Set the sequence of time steps to try when Newton fails.
|
||||
|
||||
|
@ -2184,7 +2184,7 @@ def main(argv):
|
||||
|
||||
longOptions = ['input=', 'thermo=', 'transport=', 'surface=', 'name=',
|
||||
'extra=', 'output=', 'permissive', 'help', 'debug',
|
||||
'single-intermediate-temperature', 'quiet', 'no-validate', 'id=']
|
||||
'single-intermediate-temperature', 'quiet', 'no-validate']
|
||||
|
||||
try:
|
||||
optlist, args = getopt.getopt(argv, 'dh', longOptions)
|
||||
@ -2213,13 +2213,6 @@ def main(argv):
|
||||
quiet = '--quiet' in options
|
||||
transport_file = options.get('--transport')
|
||||
surface_file = options.get('--surface')
|
||||
|
||||
if '--id' in options:
|
||||
phase_name = options.get('--id', 'gas')
|
||||
logger.warning("\nDeprecationWarning: "
|
||||
"Option '--id=...' is replaced by '--name=...' and will be "
|
||||
"removed after Cantera 3.0.\n")
|
||||
else:
|
||||
phase_name = options.get('--name', 'gas')
|
||||
|
||||
if not input_file and not thermo_file:
|
||||
|
@ -8,25 +8,6 @@ import csv as _csv
|
||||
import importlib.metadata
|
||||
import warnings
|
||||
|
||||
_h5py = None
|
||||
def _import_h5py():
|
||||
"""
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Function to be removed after Cantera 3.0, as ``h5py`` support will be removed.
|
||||
"""
|
||||
# defer h5py import
|
||||
global _h5py
|
||||
if _h5py is not None:
|
||||
return
|
||||
|
||||
try:
|
||||
importlib.metadata.version('h5py')
|
||||
except importlib.metadata.PackageNotFoundError:
|
||||
raise ImportError('Method requires a working h5py installation.')
|
||||
else:
|
||||
import h5py as _h5py
|
||||
|
||||
|
||||
_pandas = None
|
||||
def _import_pandas():
|
||||
@ -588,10 +569,9 @@ class SolutionArray(SolutionArrayBase):
|
||||
# From Kinetics
|
||||
'n_total_species', 'n_reactions', 'n_phases', 'reaction_phase_index',
|
||||
'kinetics_species_index', 'reaction', 'reactions', 'modify_reaction',
|
||||
'multiplier', 'set_multiplier', 'reaction_equations',
|
||||
'reactant_stoich_coeff', 'product_stoich_coeff',
|
||||
'reactant_stoich_coeffs', 'product_stoich_coeffs', 'product_stoich_coeffs3',
|
||||
'reactant_stoich_coeffs3', 'product_stoich_coeffs_reversible',
|
||||
'multiplier', 'set_multiplier', 'reaction_equations', 'reactant_stoich_coeff',
|
||||
'product_stoich_coeff', 'reactant_stoich_coeffs', 'product_stoich_coeffs',
|
||||
'product_stoich_coeffs_reversible',
|
||||
# from Transport
|
||||
'transport_model',
|
||||
]
|
||||
@ -1189,30 +1169,6 @@ class SolutionArray(SolutionArrayBase):
|
||||
|
||||
return dict(data)
|
||||
|
||||
def write_csv(self, filename, cols=None, *args, **kwargs):
|
||||
"""
|
||||
Write a CSV file named ``filename`` containing the data specified by
|
||||
``cols``. The first row of the CSV file will contain column labels.
|
||||
|
||||
Additional arguments are passed on to `collect_data`. This method works
|
||||
only with 1D `SolutionArray` objects.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; superseded by `save`. Note that
|
||||
`write_csv` does not support escaping of commas within string entries.
|
||||
"""
|
||||
warnings.warn("SolutionArray.write_csv: Superseded by 'save' and will be removed "
|
||||
"after Cantera 3.0.", DeprecationWarning, stacklevel=2)
|
||||
data_dict = self.collect_data(*args, cols=cols, tabular=True, **kwargs)
|
||||
data = np.hstack([d[:, np.newaxis] for d in data_dict.values()])
|
||||
labels = list(data_dict.keys())
|
||||
with open(filename, 'w', newline='') as outfile:
|
||||
writer = _csv.writer(outfile)
|
||||
writer.writerow(labels)
|
||||
for row in data:
|
||||
writer.writerow(row)
|
||||
|
||||
def read_csv(self, filename, normalize=True):
|
||||
"""
|
||||
Read a CSV file named ``filename`` and restore data to the `SolutionArray`
|
||||
@ -1356,219 +1312,6 @@ class SolutionArray(SolutionArrayBase):
|
||||
self.shape = self._api_shape()
|
||||
return meta
|
||||
|
||||
def write_hdf(self, filename, *args, cols=None, group=None, subgroup=None,
|
||||
attrs={}, mode='a', append=False,
|
||||
compression=None, compression_opts=None, **kwargs):
|
||||
"""
|
||||
Write data specified by ``cols`` to an HDF container file named ``filename``.
|
||||
Note that it is possible to write multiple data entries to a single HDF
|
||||
container file, where ``group`` is used to differentiate data.
|
||||
|
||||
An example for the default HDF file structure is:::
|
||||
|
||||
/ Group
|
||||
/group0 Group
|
||||
/group0/some_attr Attribute
|
||||
...
|
||||
/group0/T Dataset
|
||||
...
|
||||
/group0/phase Group
|
||||
/group0/phase/name Attribute
|
||||
/group0/phase/source Attribute
|
||||
|
||||
where ``group0`` is the default name for the top level HDF entry. In
|
||||
addition to datasets, information stored in `SolutionArray.meta` is
|
||||
saved in the form of HDF attributes. An additional intermediate layer may
|
||||
be created using the ``subgroup`` argument.
|
||||
|
||||
:param filename:
|
||||
Name of the HDF container file; typical file extensions are
|
||||
``.hdf``, ``.hdf5`` or ``.h5``.
|
||||
:param cols:
|
||||
A list of any properties of the solution being exported.
|
||||
:param group:
|
||||
Identifier for the group in the container file. If no subgroup is
|
||||
specified, a group represents a `SolutionArray`. If 'None', group
|
||||
names default to 'groupN', with N being the number of pre-existing
|
||||
groups within the HDF container file.
|
||||
:param subgroup:
|
||||
Name identifier for an optional subgroup, with subgroups
|
||||
representing individual `SolutionArray` objects. If 'None', no
|
||||
subgroup is created.
|
||||
:param attrs:
|
||||
Dictionary of user-defined attributes added at the group level
|
||||
(typically used in conjunction with a subgroup argument).
|
||||
:param mode:
|
||||
Mode *h5py* uses to open the output file {'a' to read/write if file
|
||||
exists, create otherwise (default); 'w' to create file, truncate if
|
||||
exists; 'r+' to read/write, file must exist}.
|
||||
:param append:
|
||||
If False, the content of a pre-existing group is deleted before
|
||||
writing the `SolutionArray` in the first position. If True, the
|
||||
current `SolutionArray` objects is appended to the group.
|
||||
:param compression:
|
||||
Pre-defined *h5py* compression filters {None, 'gzip', 'lzf', 'szip'}
|
||||
used for data compression.
|
||||
:param compression_opts:
|
||||
Options for the *h5py* compression filter; for 'gzip', this
|
||||
corresponds to the compression level {None, 0-9}.
|
||||
:return:
|
||||
Group identifier used for storing HDF data.
|
||||
|
||||
Arguments ``compression`` and ``compression_opts`` are mapped to parameters
|
||||
for `h5py.create_dataset`; in both cases, the choices of ``None`` results
|
||||
in default values set by *h5py*.
|
||||
|
||||
Additional arguments (that is, ``*args`` and ``**kwargs``) are passed on to
|
||||
`collect_data`; see `collect_data` for further information. This method
|
||||
requires a working installation of *h5py* (``h5py`` can be installed using
|
||||
pip or conda).
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; use `save` instead. Note that
|
||||
the call is redirected to `save` in order to prevent the creation of a file
|
||||
with legacy HDF format.
|
||||
"""
|
||||
warnings.warn("SolutionArray.write_hdf: To be removed after Cantera 3.0; use "
|
||||
"'save' instead.\n Note that the call is redirected to 'save' in order to "
|
||||
"prevent the creation of a file with legacy HDF format;\nas a consequence, "
|
||||
"some options are no longer supported.", DeprecationWarning, stacklevel=2)
|
||||
|
||||
if group is None:
|
||||
raise KeyError("Missing required parameter 'group'.")
|
||||
self.save(filename, name=group, sub=subgroup)
|
||||
return group
|
||||
|
||||
def read_hdf(self, filename, group=None, subgroup=None, force=False, normalize=True):
|
||||
"""
|
||||
Read a dataset from a HDF container file and restore data to the
|
||||
`SolutionArray` object. This method allows for recreation of data
|
||||
previously exported by `write_hdf`.
|
||||
|
||||
:param filename: name of the HDF container file; typical file extensions
|
||||
are ``.hdf``, ``.hdf5`` or ``.h5``.
|
||||
:param group: Identifier for the group in the container file. A group
|
||||
may contain a `SolutionArray` object or additional subgroups.
|
||||
:param subgroup:
|
||||
Optional name identifier for a subgroup representing a `SolutionArray`
|
||||
object to be read. If 'None', no subgroup is assumed to exist.
|
||||
:param force: If False, matching `SolutionArray` source identifiers are
|
||||
enforced (for example, the input file used for the creation of the
|
||||
underlying `Solution` object), with an error being raised if the current
|
||||
source does not match the original source. If True, the error is
|
||||
suppressed.
|
||||
:param normalize: Passed on to `restore_data`. If True, mole or mass
|
||||
fractions are normalized so that they sum up to 1.0. If False, mole
|
||||
or mass fractions are not normalized.
|
||||
:return: User-defined attributes provided to describe the group holding
|
||||
the `SolutionArray` information.
|
||||
|
||||
The method imports data using `restore_data` and requires a working
|
||||
installation of *h5py* (``h5py`` can be installed using pip or conda).
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; use `restore` instead. After
|
||||
Cantera 3.0, HDF import using ``h5py`` will be replaced by native
|
||||
support based on C++ ``HighFive`` and ``HDF5`` libraries.
|
||||
"""
|
||||
if _h5py is None:
|
||||
_import_h5py()
|
||||
|
||||
warnings.warn("SolutionArray.read_hdf: Method to be removed after Cantera 3.0; "
|
||||
"use 'restore' instead.", DeprecationWarning, stacklevel=2)
|
||||
|
||||
with _h5py.File(filename, 'r') as hdf:
|
||||
|
||||
groups = list(hdf.keys())
|
||||
if not len(groups):
|
||||
group = ''
|
||||
elif group is None:
|
||||
group = groups[0]
|
||||
|
||||
if not (group in hdf.keys()):
|
||||
msg = ("HDF file does not contain group '{}'; "
|
||||
"available groups are: {}")
|
||||
raise IOError(msg.format(group, list(hdf.keys())))
|
||||
|
||||
# load root and attributes
|
||||
root = hdf[group]
|
||||
|
||||
# identify subgroup
|
||||
if subgroup is not None:
|
||||
sub_names = [key for key, value in root.items()
|
||||
if isinstance(value, _h5py.Group)]
|
||||
if not len(sub_names):
|
||||
msg = "HDF group '{}' does not contain valid data"
|
||||
raise IOError(msg.format(group))
|
||||
|
||||
if subgroup not in sub_names:
|
||||
msg = ("HDF file does not contain data set '{}' within "
|
||||
"group '{}'; available data sets are: {}")
|
||||
raise IOError(msg.format(subgroup, group, sub_names))
|
||||
dgroup = root[subgroup]
|
||||
else:
|
||||
dgroup = root
|
||||
|
||||
root_attrs = dict(root.attrs.items())
|
||||
|
||||
def strip_ext(source):
|
||||
"""Strip extension if source identifies a file name"""
|
||||
out = source
|
||||
for ext in ('.yml', '.yaml'):
|
||||
if source.endswith(ext):
|
||||
out = '.'.join(source.split('.')[:-1])
|
||||
break
|
||||
return out
|
||||
|
||||
# load metadata
|
||||
meta = dict(dgroup.attrs.items())
|
||||
for name, value in dgroup.items():
|
||||
# support one level of recursion
|
||||
if isinstance(value, _h5py.Group):
|
||||
meta[name] = dict(value.attrs.items())
|
||||
|
||||
if "generator" in root_attrs or "generator" in meta:
|
||||
raise IOError("Unable to read Cantera 3.0 HDF format with deprecated "
|
||||
"'read_hdf' method; use 'restore' instead.")
|
||||
|
||||
# ensure that mechanisms are matching
|
||||
if "phase" in dgroup:
|
||||
sol_source = strip_ext(dgroup['phase'].attrs['source']).split("/")[-1]
|
||||
source = strip_ext(self.source)
|
||||
if sol_source != source and not force:
|
||||
msg = ("Sources of thermodynamic phases do not match: '{}' vs "
|
||||
"'{}'; use option 'force' to override this error.")
|
||||
raise IOError(msg.format(sol_source, source))
|
||||
|
||||
self.meta = meta
|
||||
|
||||
# load data
|
||||
data = {}
|
||||
for name, value in dgroup.items():
|
||||
if isinstance(value, _h5py.Group):
|
||||
continue
|
||||
elif value.dtype.type == np.bytes_:
|
||||
data[name] = np.array(value).astype('U')
|
||||
else:
|
||||
data[name] = np.array(value)
|
||||
|
||||
try:
|
||||
self.restore_data(data, normalize)
|
||||
except ValueError as error:
|
||||
if "surface" in self._phase.thermo_model:
|
||||
# legacy HDF format uses TDX state information, which is incomplete
|
||||
# for surfaces phases (should be TPX or TPY as density is constant)
|
||||
raise IOError(
|
||||
f"Unable to load surface phase '{subgroup}' from legacy HDF "
|
||||
"format (incomplete phase definition); use 'restore' instead."
|
||||
) from None
|
||||
else:
|
||||
raise error
|
||||
|
||||
return root_attrs
|
||||
|
||||
def __reduce__(self):
|
||||
raise NotImplementedError('SolutionArray object is not picklable')
|
||||
|
||||
|
@ -220,41 +220,3 @@ cdef class Tabulated1(Func1):
|
||||
cdef string cxx_string = stringify(f"tabulated-{method}")
|
||||
self._func = CxxNewFunc1(cxx_string, arr)
|
||||
self.func = self._func.get()
|
||||
|
||||
|
||||
cdef class TabulatedFunction(Tabulated1):
|
||||
"""
|
||||
A `TabulatedFunction` object representing a tabulated function is defined by
|
||||
sample points and corresponding function values. Inputs are specified by
|
||||
two iterable objects containing sample point location and function values.
|
||||
Between sample points, values are evaluated based on the optional argument
|
||||
``method``; options are ``'linear'`` (linear interpolation, default) or
|
||||
``'previous'`` (nearest previous value). Outside the sample interval, the
|
||||
value at the closest end point is returned.
|
||||
|
||||
Examples for `TabulatedFunction` objects are::
|
||||
|
||||
>>> t1 = TabulatedFunction([0, 1, 2], [2, 1, 0])
|
||||
>>> [t1(v) for v in [-0.5, 0, 0.5, 1.5, 2, 2.5]]
|
||||
[2.0, 2.0, 1.5, 0.5, 0.0, 0.0]
|
||||
|
||||
>>> t2 = TabulatedFunction(np.array([0, 1, 2]), np.array([2, 1, 0]))
|
||||
>>> [t2(v) for v in [-0.5, 0, 0.5, 1.5, 2, 2.5]]
|
||||
[2.0, 2.0, 1.5, 0.5, 0.0, 0.0]
|
||||
|
||||
The optional ``method`` keyword argument changes the type of interpolation
|
||||
from the ``'linear'`` default to ``'previous'``::
|
||||
|
||||
>>> t3 = TabulatedFunction([0, 1, 2], [2, 1, 0], method='previous')
|
||||
>>> [t3(v) for v in [-0.5, 0, 0.5, 1.5, 2, 2.5]]
|
||||
[2.0, 2.0, 2.0, 1.0, 0.0, 0.0]
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed after Cantera 3.0. Renamed to `Tabulated1`.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn(
|
||||
"TabulatedFunction: To be removed after Cantera 3.0. "
|
||||
"Renamed to 'Tabulated1'.", DeprecationWarning)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
@ -288,25 +288,6 @@ cdef class Kinetics(_SolutionBase):
|
||||
return get_from_sparse(self.kinetics.reactantStoichCoeffs(),
|
||||
self.n_total_species, self.n_reactions)
|
||||
|
||||
property reactant_stoich_coeffs3:
|
||||
"""
|
||||
The array of reactant stoichiometric coefficients. Element ``[k,i]`` of
|
||||
this array is the reactant stoichiometric coefficient of species ``k`` in
|
||||
reaction ``i``.
|
||||
|
||||
For sparse output, set ``ct.use_sparse(True)``.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0. Replaceable by
|
||||
`Kinetics.reactant_stoich_coeffs`
|
||||
"""
|
||||
def __get__(self):
|
||||
warnings.warn("Kinetics.reactant_stoich_coeffs3: To be removed after "
|
||||
"Cantera 3.0; use property 'reactant_stoich_coeffs' instead.",
|
||||
DeprecationWarning)
|
||||
return self.reactant_stoich_coeffs
|
||||
|
||||
property product_stoich_coeffs:
|
||||
"""
|
||||
The array of product stoichiometric coefficients. Element ``[k,i]`` of
|
||||
@ -323,25 +304,6 @@ cdef class Kinetics(_SolutionBase):
|
||||
return get_from_sparse(self.kinetics.productStoichCoeffs(),
|
||||
self.n_total_species, self.n_reactions)
|
||||
|
||||
property product_stoich_coeffs3:
|
||||
"""
|
||||
The array of product stoichiometric coefficients. Element ``[k,i]`` of
|
||||
this array is the product stoichiometric coefficient of species ``k`` in
|
||||
reaction ``i``.
|
||||
|
||||
For sparse output, set ``ct.use_sparse(True)``.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0. Replaceable by
|
||||
`Kinetics.product_stoich_coeffs`
|
||||
"""
|
||||
def __get__(self):
|
||||
warnings.warn("Kinetics.product_stoich_coeffs3: Method to be removed after "
|
||||
"Cantera 3.0; use property 'product_stoich_coeffs' instead.",
|
||||
DeprecationWarning)
|
||||
return self.product_stoich_coeffs
|
||||
|
||||
property product_stoich_coeffs_reversible:
|
||||
"""
|
||||
The array of product stoichiometric coefficients of reversible reactions.
|
||||
|
@ -14,8 +14,6 @@ from . import __version__, __git_commit__, hdf_support
|
||||
class FlameBase(Sim1D):
|
||||
""" Base class for flames with a single flow domain """
|
||||
__slots__ = ('gas',)
|
||||
#: deprecated and to be removed after Cantera 3.0 here and elsewhere (unused)
|
||||
_other = ()
|
||||
|
||||
def __init__(self, domains, gas, grid=None):
|
||||
"""
|
||||
@ -33,41 +31,6 @@ class FlameBase(Sim1D):
|
||||
self.gas = gas
|
||||
self.flame.P = gas.P
|
||||
|
||||
def other_components(self, domain=None):
|
||||
"""
|
||||
The method returns simulation components that are specific to a class
|
||||
derived from `FlameBase` or a specific ``domain`` within the `FlameBase`
|
||||
simulation object. Entries may include:
|
||||
|
||||
* ``grid``: grid point positions along the flame [m]
|
||||
* ``velocity``: normal velocity [m/s]
|
||||
* ``spread_rate``: tangential velocity gradient [1/s]
|
||||
* ``lambda``: radial pressure gradient [N/m^4]
|
||||
* ``eField``: electric field strength
|
||||
|
||||
:param domain:
|
||||
Index of a specific domain within the `Sim1D.domains`
|
||||
list. The default is to return other columns of the `Sim1D` object.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0. After moving SolutionArray HDF
|
||||
export to the C++ core, this method is unused.
|
||||
"""
|
||||
warnings.warn("FlameBase.other_components: Method to be removed after "
|
||||
"Cantera 3.0 (unused).", DeprecationWarning, stacklevel=2)
|
||||
if domain is None:
|
||||
return self._other
|
||||
|
||||
dom = self.domains[self.domain_index(domain)]
|
||||
if isinstance(dom, Inlet1D):
|
||||
return tuple([e for e in self._other
|
||||
if e not in {'grid', 'lambda', 'eField'}])
|
||||
elif isinstance(dom, (FreeFlow, AxisymmetricFlow, IdealGasFlow)):
|
||||
return self._other
|
||||
else:
|
||||
return ()
|
||||
|
||||
def set_refine_criteria(self, ratio=10.0, slope=0.8, curve=0.8, prune=0.0):
|
||||
"""
|
||||
Set the criteria used for grid refinement.
|
||||
@ -373,25 +336,6 @@ class FlameBase(Sim1D):
|
||||
vals[i] = self.gas.elemental_mole_fraction(m)
|
||||
return vals
|
||||
|
||||
def solution(self, component, point=None):
|
||||
"""
|
||||
Get the solution at one point or for the full flame domain (if
|
||||
``point=None``) for the specified ``component``. The ``component`` can be
|
||||
specified by name or index.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed after Cantera 3.0 to avoid conflation with `Solution`.
|
||||
Replaceable by `profile` or `value`.
|
||||
"""
|
||||
warnings.warn("FlameBase.solution: To be removed after Cantera 3.0. "
|
||||
"Replaceable by 'profile' or 'value'.", DeprecationWarning,
|
||||
stacklevel=2)
|
||||
if point is None:
|
||||
return self.profile(self.flame, component)
|
||||
else:
|
||||
return self.value(self.flame, component, point)
|
||||
|
||||
def set_gas_state(self, point):
|
||||
"""
|
||||
Set the state of the the `Solution` object used for calculations
|
||||
@ -404,34 +348,6 @@ class FlameBase(Sim1D):
|
||||
self.gas.set_unnormalized_mass_fractions(Y)
|
||||
self.gas.TP = self.value(self.flame, 'T', point), self.P
|
||||
|
||||
def write_csv(self, filename, species='X', quiet=True, normalize=True):
|
||||
"""
|
||||
Write the velocity, temperature, density, and species profiles
|
||||
to a CSV file.
|
||||
|
||||
:param filename:
|
||||
Output file name
|
||||
:param species:
|
||||
Attribute to use obtaining species profiles, for example ``X`` for
|
||||
mole fractions or ``Y`` for mass fractions.
|
||||
:param normalize:
|
||||
Boolean flag to indicate whether the mole/mass fractions should
|
||||
be normalized.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; superseded by `save`.
|
||||
"""
|
||||
warnings.warn("FlameBase.write_csv: Superseded by 'save'. To be removed "
|
||||
"after Cantera 3.0.", DeprecationWarning, stacklevel=2)
|
||||
|
||||
# save data
|
||||
cols = ('extra', 'T', 'D', species)
|
||||
self.to_array(normalize=normalize).write_csv(filename, cols=cols)
|
||||
|
||||
if not quiet:
|
||||
print("Solution saved to '{0}'.".format(filename))
|
||||
|
||||
def to_array(self, domain=None, normalize=False):
|
||||
"""
|
||||
Retrieve domain data as a `SolutionArray` object.
|
||||
@ -452,24 +368,6 @@ class FlameBase(Sim1D):
|
||||
dest.shape = dest._api_shape()
|
||||
return dest
|
||||
|
||||
def to_solution_array(self, domain=None, normalize=True):
|
||||
"""
|
||||
Return the solution vector as a `SolutionArray` object.
|
||||
|
||||
Derived classes define default values for *other*.
|
||||
|
||||
By default, the mass or mole fractions will be normalized i.e they
|
||||
sum up to 1.0. If this is not desired, the ``normalize`` argument
|
||||
can be set to ``False``.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; superseded by `to_array`.
|
||||
"""
|
||||
warnings.warn("FlameBase.to_solution_array: To be removed after Cantera 3.0. "
|
||||
"Replaceable by 'to_array'.", DeprecationWarning, stacklevel=2)
|
||||
return self.to_array(domain, normalize)
|
||||
|
||||
def from_array(self, arr, domain=None):
|
||||
"""
|
||||
Restore the solution vector from a `SolutionArray` object.
|
||||
@ -487,30 +385,6 @@ class FlameBase(Sim1D):
|
||||
domain = self.domains[self.domain_index(domain)]
|
||||
domain._from_array(arr)
|
||||
|
||||
def from_solution_array(self, arr, domain=None):
|
||||
"""
|
||||
Restore the solution vector from a `SolutionArray` object.
|
||||
|
||||
Derived classes define default values for *other*.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; replaced by `from_array`.
|
||||
"""
|
||||
warnings.warn("FlameBase.from_solution_array: To be removed after Cantera 3.0. "
|
||||
"Replaced by 'from_array'.", DeprecationWarning, stacklevel=2)
|
||||
if domain is None:
|
||||
domain = self.flame
|
||||
else:
|
||||
domain = self.domains[self.domain_index(domain)]
|
||||
other = self.other_components(domain)
|
||||
|
||||
states = arr.TPY
|
||||
other_cols = {e: getattr(arr, e) for e in other
|
||||
if e in arr.extra}
|
||||
meta = arr.meta
|
||||
super().restore_data(domain, states, other_cols, meta)
|
||||
|
||||
def to_pandas(self, species='X', normalize=True):
|
||||
"""
|
||||
Return the solution vector as a `pandas.DataFrame`.
|
||||
@ -529,203 +403,6 @@ class FlameBase(Sim1D):
|
||||
cols = ('extra', 'T', 'D', species)
|
||||
return self.to_array(normalize=normalize).to_pandas(cols=cols)
|
||||
|
||||
def from_pandas(self, df, restore_boundaries=True, settings=None):
|
||||
"""
|
||||
Restore the solution vector from a `pandas.DataFrame`; currently disabled
|
||||
(`save`/`restore` should be used as an alternative).
|
||||
|
||||
:param df:
|
||||
`pandas.DataFrame` containing data to be restored
|
||||
:param restore_boundaries:
|
||||
Boolean flag to indicate whether boundaries should be restored
|
||||
(default is ``True``)
|
||||
:param settings:
|
||||
dictionary containing simulation settings
|
||||
(see `FlameBase.settings`)
|
||||
|
||||
This method is intended for loading of data that were previously
|
||||
exported by `to_pandas`. The method uses `from_array` and
|
||||
requires a working *pandas* installation. The package ``pandas`` can be
|
||||
installed using pip or conda.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; not implemented.
|
||||
"""
|
||||
# @todo: Discuss implementation that allows for restoration of boundaries
|
||||
raise NotImplementedError("Use 'save'/'restore' as alternatives; "
|
||||
"method to be removed after Cantera 3.0.")
|
||||
|
||||
def write_hdf(self, filename, *args, group=None, species='X', mode='a',
|
||||
description=None, compression=None, compression_opts=0,
|
||||
quiet=True, normalize=True, **kwargs):
|
||||
"""
|
||||
Write the solution vector to a HDF container file.
|
||||
|
||||
The `write_hdf` method preserves the structure of a `FlameBase`-derived
|
||||
object (such as `FreeFlame`). Each simulation is saved as a *group*,
|
||||
whereas individual domains are saved as subgroups. In addition to
|
||||
datasets, information on `Sim1D.settings` and `Domain1D.settings` is
|
||||
saved in form of HDF attributes. The internal HDF file structure is
|
||||
illustrated for a `FreeFlame` output as:::
|
||||
|
||||
/ Group
|
||||
/group0 Group
|
||||
/group0/Sim1D_type Attribute
|
||||
...
|
||||
/group0/flame Group
|
||||
/group0/flame/Domain1D_type Attribute
|
||||
...
|
||||
/group0/flame/T Dataset
|
||||
...
|
||||
/group0/flame/phase Group
|
||||
/group0/products Group
|
||||
/group0/products/Domain1D_type Attribute
|
||||
...
|
||||
/group0/products/T Dataset
|
||||
...
|
||||
/group0/products/phase Group
|
||||
/group0/reactants Group
|
||||
/group0/reactants/Domain1D_type Attribute
|
||||
...
|
||||
/group0/reactants/T Dataset
|
||||
...
|
||||
/group0/reactants/phase Group
|
||||
|
||||
where ``group0`` is the default name for the top level HDF entry, and
|
||||
``reactants``, ``flame`` and ``products`` correspond to domain names.
|
||||
Note that it is possible to save multiple solutions to a single HDF
|
||||
container file.
|
||||
|
||||
:param filename:
|
||||
HDF container file containing data to be restored
|
||||
:param group:
|
||||
Identifier for the group in the container file. A group may contain
|
||||
multiple `SolutionArray` objects.
|
||||
:param species:
|
||||
Attribute to use obtaining species profiles, for example ``X`` for
|
||||
mole fractions or ``Y`` for mass fractions.
|
||||
:param mode:
|
||||
Mode *h5py* uses to open the output file {'a' to read/write if file
|
||||
exists, create otherwise (default); 'w' to create file, truncate if
|
||||
exists; 'r+' to read/write, file must exist}.
|
||||
:param description:
|
||||
Custom comment describing the dataset to be stored.
|
||||
:param compression:
|
||||
Pre-defined *h5py* compression filters {None, 'gzip', 'lzf', 'szip'}
|
||||
used for data compression.
|
||||
:param compression_opts:
|
||||
Options for the *h5py* compression filter; for 'gzip', this
|
||||
corresponds to the compression level {None, 0-9}.
|
||||
:param quiet:
|
||||
Suppress message confirming successful file output.
|
||||
:param normalize:
|
||||
Boolean flag to indicate whether the mole/mass fractions should
|
||||
be normalized (default is ``True``)
|
||||
|
||||
Additional arguments (that is, ``*args`` and ``**kwargs``) are passed on to
|
||||
`SolutionArray.collect_data`. The method exports data using
|
||||
`SolutionArray.write_hdf` via `to_solution_array` and requires a working
|
||||
installation of *h5py* (``h5py`` can be installed using pip or conda).
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; use `save` instead. Note that
|
||||
the call is redirected to `save` in order to prevent the creation of a file
|
||||
with deprecated HDF format.
|
||||
"""
|
||||
warnings.warn("FlameBase.write_hdf: To be removed after Cantera 3.0; use "
|
||||
"'save' instead.\nNote that the call is redirected to 'save' in order to "
|
||||
"prevent the creation of a file with deprecated HDF format.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
||||
self.save(filename, name=group, description=description,
|
||||
compression=compression_opts)
|
||||
|
||||
def read_hdf(self, filename, group=None, restore_boundaries=True, normalize=True):
|
||||
"""
|
||||
Restore the solution vector from a HDF container file.
|
||||
|
||||
:param filename:
|
||||
HDF container file containing data to be restored
|
||||
:param group:
|
||||
String identifying the HDF group containing the data
|
||||
:param restore_boundaries:
|
||||
Boolean flag to indicate whether boundaries should be restored
|
||||
(default is ``True``)
|
||||
:param normalize:
|
||||
Boolean flag to indicate whether the mole/mass fractions should
|
||||
be normalized (default is ``True``)
|
||||
|
||||
The method imports data using `SolutionArray.read_hdf` via
|
||||
`from_array` and requires a working installation of *h5py*
|
||||
(``h5py`` can be installed using pip or conda).
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Method to be removed after Cantera 3.0; superseded by `restore`.
|
||||
"""
|
||||
warnings.warn("FlameBase.read_hdf: To be removed after Cantera 3.0; use "
|
||||
"'restore' instead.", DeprecationWarning, stacklevel=2)
|
||||
|
||||
if restore_boundaries:
|
||||
domains = range(3)
|
||||
else:
|
||||
domains = [1]
|
||||
|
||||
for d in domains:
|
||||
arr = SolutionArray(self.phase(d), extra=self.other_components(d))
|
||||
meta = arr.read_hdf(filename, group=group,
|
||||
subgroup=self.domains[d].name, normalize=normalize)
|
||||
self.from_solution_array(arr, domain=d)
|
||||
|
||||
self.settings = meta
|
||||
|
||||
return meta
|
||||
|
||||
@property
|
||||
def settings(self):
|
||||
"""
|
||||
Return a dictionary listing simulation settings
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed after Cantera 3.0. The getter is replaceable by
|
||||
`Domain1D.settings`; for the setter, use setters for individual settings.
|
||||
"""
|
||||
warnings.warn("FlameBase.settings: to be removed after Cantera 3.0. Access "
|
||||
"settings from domains instead.", DeprecationWarning, stacklevel=2)
|
||||
out = {'Sim1D_type': type(self).__name__}
|
||||
out['transport_model'] = self.transport_model
|
||||
out['energy_enabled'] = self.energy_enabled
|
||||
out['soret_enabled'] = self.soret_enabled
|
||||
out['radiation_enabled'] = self.radiation_enabled
|
||||
out['fixed_temperature'] = self.fixed_temperature
|
||||
out.update(self.get_refine_criteria())
|
||||
out['max_time_step_count'] = self.max_time_step_count
|
||||
out['max_grid_points'] = self.get_max_grid_points(self.flame)
|
||||
|
||||
return out
|
||||
|
||||
@settings.setter
|
||||
def settings(self, s):
|
||||
warnings.warn("FlameBase.settings: To be removed after Cantera 3.0. Use "
|
||||
"individual setters instead.", DeprecationWarning, stacklevel=2)
|
||||
# simple setters
|
||||
attr = {'transport_model',
|
||||
'energy_enabled', 'soret_enabled', 'radiation_enabled',
|
||||
'fixed_temperature',
|
||||
'max_time_step_count', 'max_grid_points'}
|
||||
attr = attr & set(s.keys())
|
||||
for key in attr:
|
||||
setattr(self, key, s[key])
|
||||
|
||||
# refine criteria
|
||||
refine = {k: v for k, v in s.items()
|
||||
if k in ['ratio', 'slope', 'curve', 'prune']}
|
||||
if refine:
|
||||
self.set_refine_criteria(**refine)
|
||||
|
||||
@property
|
||||
def electric_field_enabled(self):
|
||||
""" Get/Set whether or not to solve the Poisson's equation."""
|
||||
@ -842,7 +519,6 @@ for _attr in ['forward_rates_of_progress', 'reverse_rates_of_progress', 'net_rat
|
||||
class FreeFlame(FlameBase):
|
||||
"""A freely-propagating flat flame."""
|
||||
__slots__ = ('inlet', 'flame', 'outlet')
|
||||
_other = ('grid', 'velocity')
|
||||
|
||||
def __init__(self, gas, grid=None, width=None):
|
||||
"""
|
||||
@ -1033,27 +709,9 @@ class FreeFlame(FlameBase):
|
||||
return self.solve_adjoint(perturb, self.gas.n_reactions, dgdx) / Su0
|
||||
|
||||
|
||||
class IonFreeFlame(FreeFlame):
|
||||
"""A freely-propagating flame with ionized gas.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Class to be removed after Cantera 3.0; absorbed by `FreeFlame`.
|
||||
"""
|
||||
__slots__ = ('inlet', 'flame', 'outlet')
|
||||
_other = ('grid', 'velocity', 'eField') # only used by deprecated methods
|
||||
|
||||
def __init__(self, gas, grid=None, width=None):
|
||||
warnings.warn(
|
||||
"'IonFreeFlame' is deprecated and will be removed after Cantera 3.0;",
|
||||
"replaceable by 'FreeFlame'.", DeprecationWarning, stacklevel=2)
|
||||
super().__init__(gas, grid, width)
|
||||
|
||||
|
||||
class BurnerFlame(FlameBase):
|
||||
"""A burner-stabilized flat flame."""
|
||||
__slots__ = ('burner', 'flame', 'outlet')
|
||||
_other = ('grid', 'velocity')
|
||||
|
||||
def __init__(self, gas, grid=None, width=None):
|
||||
"""
|
||||
@ -1187,27 +845,9 @@ class BurnerFlame(FlameBase):
|
||||
self.set_steady_callback(original_callback)
|
||||
|
||||
|
||||
class IonBurnerFlame(BurnerFlame):
|
||||
"""A burner-stabilized flat flame with ionized gas.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Class to be removed after Cantera 3.0; absorbed by `BurnerFlame`.
|
||||
"""
|
||||
__slots__ = ('burner', 'flame', 'outlet')
|
||||
_other = ('grid', 'velocity', 'eField') # only used by deprecated methods
|
||||
|
||||
def __init__(self, gas, grid=None, width=None):
|
||||
warnings.warn(
|
||||
"'IonBurnerFlame' is deprecated and will be removed after Cantera 3.0; ",
|
||||
"replaceable by 'BurnerFlame'.", DeprecationWarning, stacklevel=2)
|
||||
super().__init__(gas, grid, width)
|
||||
|
||||
|
||||
class CounterflowDiffusionFlame(FlameBase):
|
||||
""" A counterflow diffusion flame """
|
||||
__slots__ = ('fuel_inlet', 'flame', 'oxidizer_inlet')
|
||||
_other = ('grid', 'velocity', 'spread_rate', 'lambda')
|
||||
|
||||
def __init__(self, gas, grid=None, width=None):
|
||||
"""
|
||||
@ -1536,7 +1176,6 @@ class CounterflowDiffusionFlame(FlameBase):
|
||||
class ImpingingJet(FlameBase):
|
||||
"""An axisymmetric flow impinging on a surface at normal incidence."""
|
||||
__slots__ = ('inlet', 'flame', 'surface')
|
||||
_other = ('grid', 'velocity', 'spread_rate', 'lambda')
|
||||
|
||||
def __init__(self, gas, grid=None, width=None, surface=None):
|
||||
"""
|
||||
@ -1625,7 +1264,6 @@ class ImpingingJet(FlameBase):
|
||||
class CounterflowPremixedFlame(FlameBase):
|
||||
""" A premixed counterflow flame """
|
||||
__slots__ = ('reactants', 'flame', 'products')
|
||||
_other = ('grid', 'velocity', 'spread_rate', 'lambda')
|
||||
|
||||
def __init__(self, gas, grid=None, width=None):
|
||||
"""
|
||||
@ -1727,7 +1365,6 @@ class CounterflowTwinPremixedFlame(FlameBase):
|
||||
shooting into each other.
|
||||
"""
|
||||
__slots__ = ('reactants', 'flame', 'products')
|
||||
_other = ('grid', 'velocity', 'spread_rate', 'lambda')
|
||||
|
||||
def __init__(self, gas, grid=None, width=None):
|
||||
"""
|
||||
|
@ -1322,12 +1322,7 @@ cdef class Reaction:
|
||||
"""
|
||||
|
||||
def __cinit__(self, reactants=None, products=None, rate=None, *,
|
||||
equation=None, init=True, efficiencies=None,
|
||||
Kinetics kinetics=None, third_body=None):
|
||||
if kinetics:
|
||||
warnings.warn("Reaction: Parameter 'kinetics' is no longer used and will "
|
||||
"be removed after Cantera 3.0.", DeprecationWarning)
|
||||
|
||||
equation=None, init=True, third_body=None):
|
||||
if not init:
|
||||
return
|
||||
|
||||
@ -1364,13 +1359,6 @@ cdef class Reaction:
|
||||
_third_body = third_body
|
||||
elif isinstance(third_body, str):
|
||||
_third_body = ThirdBody(third_body)
|
||||
elif efficiencies:
|
||||
warnings.warn(
|
||||
"Reaction: Argument 'efficiencies' is deprecated and will be removed "
|
||||
"after Cantera 3.0. Use ThirdBody instead.", DeprecationWarning)
|
||||
third_body = "M"
|
||||
_third_body = ThirdBody(third_body)
|
||||
_third_body.efficiencies = efficiencies
|
||||
|
||||
if reactants and products:
|
||||
# create from reactant and product compositions
|
||||
@ -1521,19 +1509,10 @@ cdef class Reaction:
|
||||
``{'CH4':1, 'OH':1}``, or as a composition string, for example
|
||||
``'CH4:1, OH:1'``.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Setter for reactants is deprecated and will be removed after Cantera 3.0.
|
||||
Use constructor instead.
|
||||
.. versionchanged:: 3.1 This is a read-only property
|
||||
"""
|
||||
def __get__(self):
|
||||
return comp_map_to_dict(self.reaction.reactants)
|
||||
def __set__(self, reactants):
|
||||
warnings.warn(
|
||||
"'Reaction.reactants' setter is deprecated and will be removed after "
|
||||
"Cantera 3.0.\nInstantiate using constructor instead.",
|
||||
DeprecationWarning)
|
||||
self.reaction.reactants = comp_map(reactants)
|
||||
|
||||
property products:
|
||||
"""
|
||||
@ -1542,19 +1521,10 @@ cdef class Reaction:
|
||||
``{'CH3':1, 'H2O':1}``, or as a composition string, for example
|
||||
``'CH3:1, H2O:1'``.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Setter for products is deprecated and will be removed after Cantera 3.0.
|
||||
Use constructor instead.
|
||||
.. versionchanged:: 3.1 This is a read-only property
|
||||
"""
|
||||
def __get__(self):
|
||||
return comp_map_to_dict(self.reaction.products)
|
||||
def __set__(self, products):
|
||||
warnings.warn(
|
||||
"'Reaction.products' setter is deprecated and will be removed after "
|
||||
"Cantera 3.0.\nInstantiate using constructor instead.",
|
||||
DeprecationWarning)
|
||||
self.reaction.products = comp_map(products)
|
||||
|
||||
def __contains__(self, species):
|
||||
return species in self.reactants or species in self.products
|
||||
@ -1703,73 +1673,6 @@ cdef class Reaction:
|
||||
return ThirdBody.wrap(self.reaction.thirdBody()).name
|
||||
return None
|
||||
|
||||
property efficiencies:
|
||||
"""
|
||||
Get/Set a `dict` defining non-default third-body efficiencies for this reaction,
|
||||
where the keys are the species names and the values are the efficiencies.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed after Cantera 3.0. Access via `third_body` property and
|
||||
`ThirdBody` object instead.
|
||||
"""
|
||||
def __get__(self):
|
||||
warnings.warn(
|
||||
"Reaction.efficiencies: Property is deprecated and will be removed "
|
||||
"after Cantera 3.0. Access via ThirdBody instead.", DeprecationWarning)
|
||||
if self.third_body is None:
|
||||
raise ValueError("Reaction does not involve third body collider")
|
||||
return self.third_body.efficiencies
|
||||
def __set__(self, eff):
|
||||
warnings.warn(
|
||||
"Reaction.efficiencies: Property is deprecated and will be removed "
|
||||
"after Cantera 3.0. Access via ThirdBody instead.", DeprecationWarning)
|
||||
if self.third_body is None:
|
||||
raise ValueError("Reaction does not involve third body collider")
|
||||
self.third_body.efficiencies = comp_map(eff)
|
||||
|
||||
property default_efficiency:
|
||||
"""
|
||||
Get/Set the default third-body efficiency for this reaction, used for species
|
||||
not in `efficiencies`.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed after Cantera 3.0. Access via `third_body` property and
|
||||
`ThirdBody` object instead.
|
||||
"""
|
||||
def __get__(self):
|
||||
warnings.warn(
|
||||
"Reaction.default_efficiency: Property is deprecated and will be "
|
||||
"removed after Cantera 3.0. Use ThirdBody instead.", DeprecationWarning)
|
||||
if self.third_body is None:
|
||||
raise ValueError("Reaction does not involve third body collider")
|
||||
return self.third_body.default_efficiency
|
||||
def __set__(self, default_eff):
|
||||
warnings.warn(
|
||||
"Reaction.default_efficiency: Property is deprecated and will be "
|
||||
"removed after Cantera 3.0. Use ThirdBody instead.", DeprecationWarning)
|
||||
if self.third_body is None:
|
||||
raise ValueError("Reaction does not involve third body collider")
|
||||
self.third_body.default_efficiency = default_eff
|
||||
|
||||
def efficiency(self, species):
|
||||
"""
|
||||
Get the efficiency of the third body named ``species`` considering both
|
||||
the default efficiency and species-specific efficiencies.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed after Cantera 3.0. Access via `third_body` property and
|
||||
`ThirdBody` object instead.
|
||||
"""
|
||||
warnings.warn(
|
||||
"Reaction.efficiency: Method is deprecated and will be removed after "
|
||||
"Cantera 3.0. Use ThirdBody instead.", DeprecationWarning)
|
||||
if self.third_body is None:
|
||||
raise ValueError("Reaction does not involve third body collider")
|
||||
return self.third_body.efficiency(stringify(species))
|
||||
|
||||
|
||||
cdef class Arrhenius:
|
||||
r"""
|
||||
@ -1837,99 +1740,3 @@ cdef copyArrhenius(CxxArrheniusRate* rate):
|
||||
r = Arrhenius(rate.preExponentialFactor(), rate.temperatureExponent(),
|
||||
rate.activationEnergy())
|
||||
return r
|
||||
|
||||
|
||||
cdef class ThreeBodyReaction(Reaction):
|
||||
"""
|
||||
A reaction with a non-reacting third body "M" that acts to add or remove
|
||||
energy from the reacting species.
|
||||
|
||||
An example for the definition of an `ThreeBodyReaction` object is given as::
|
||||
|
||||
rxn = ThreeBodyReaction(
|
||||
equation="2 O + M <=> O2 + M",
|
||||
rate={"A": 1.2e+17, "b": -1.0, "Ea": 0.0},
|
||||
efficiencies={"H2": 2.4, "H2O": 15.4, "AR": 0.83},
|
||||
kinetics=gas)
|
||||
|
||||
The YAML description corresponding to this reaction is::
|
||||
|
||||
equation: 2 O + M <=> O2 + M
|
||||
type: three-body
|
||||
rate-constant: {A: 1.2e+17 cm^6/mol^2/s, b: -1.0, Ea: 0.0 cal/mol}
|
||||
efficiencies: {H2: 2.4, H2O: 15.4, AR: 0.83}
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Class to be removed after Cantera 3.0. Absorbed by `Reaction`.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn("ThreeBodyReaction: Class to be removed after Cantera 3.0; "
|
||||
"no specialization necessary.", DeprecationWarning)
|
||||
|
||||
|
||||
cdef class FalloffReaction(Reaction):
|
||||
"""
|
||||
A reaction that is first-order in [M] at low pressure, like a third-body
|
||||
reaction, but zeroth-order in [M] as pressure increases.
|
||||
|
||||
An example for the definition of a `FalloffReaction` object is given as::
|
||||
|
||||
rxn = FalloffReaction(
|
||||
equation="2 OH (+ M) <=> H2O2 (+ M)",
|
||||
rate=ct.TroeRate(low=ct.Arrhenius(2.3e+12, -0.9, -7112800.0),
|
||||
high=ct.Arrhenius(7.4e+10, -0.37, 0),
|
||||
falloff_coeffs=[0.7346, 94.0, 1756.0, 5182.0]),
|
||||
efficiencies={"AR": 0.7, "H2": 2.0, "H2O": 6.0},
|
||||
kinetics=gas)
|
||||
|
||||
The YAML description corresponding to this reaction is::
|
||||
|
||||
equation: 2 OH (+ M) <=> H2O2 (+ M) # Reaction 3
|
||||
type: falloff
|
||||
low-P-rate-constant: {A: 2.3e+12, b: -0.9, Ea: -1700.0 cal/mol}
|
||||
high-P-rate-constant: {A: 7.4e+10, b: -0.37, Ea: 0.0 cal/mol}
|
||||
Troe: {A: 0.7346, T3: 94.0, T1: 1756.0, T2: 5182.0}
|
||||
efficiencies: {AR: 0.7, H2: 2.0, H2O: 6.0}
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Class to be removed after Cantera 3.0. Absorbed by `Reaction`.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn("FalloffReaction: Class to be removed after Cantera 3.0; "
|
||||
"no specialization necessary.", DeprecationWarning)
|
||||
|
||||
cdef class ChemicallyActivatedReaction(FalloffReaction):
|
||||
"""
|
||||
A reaction where the rate decreases as pressure increases due to collisional
|
||||
stabilization of a reaction intermediate. Like a `FalloffReaction`, except
|
||||
that the forward rate constant is written as being proportional to the low-
|
||||
pressure rate constant.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn("ChemicallyActivatedReaction: Class to be removed after Cantera "
|
||||
"3.0; no specialization necessary.", DeprecationWarning)
|
||||
|
||||
cdef class CustomReaction(Reaction):
|
||||
"""
|
||||
A reaction which follows mass-action kinetics with a custom reaction rate.
|
||||
|
||||
An example for the definition of a `CustomReaction` object is given as::
|
||||
|
||||
rxn = CustomReaction(
|
||||
equation="H2 + O <=> H + OH",
|
||||
rate=lambda T: 38.7 * T**2.7 * exp(-3150.15428/T),
|
||||
kinetics=gas)
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Class to be removed after Cantera 3.0. Absorbed by `Reaction`.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn("CustomReaction: Class to be removed after Cantera 3.0; no "
|
||||
"specialization necessary.", DeprecationWarning)
|
||||
|
@ -646,25 +646,6 @@ cdef class ExtensibleReactor(Reactor):
|
||||
def __set__(self, n):
|
||||
self.accessor.setNEq(n)
|
||||
|
||||
property vdot:
|
||||
"""
|
||||
Get/Set the net rate of volume change (for example, from moving walls) [m^3/s]
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed in Cantera 3.0; renamed to `expansion_rate`.
|
||||
"""
|
||||
def __get__(self):
|
||||
warnings.warn(
|
||||
"ExtensibleReactor.vdot: To be removed in Cantera 3.0; "
|
||||
"renamed to 'expansion_rate'.", DeprecationWarning)
|
||||
return self.accessor.expansionRate()
|
||||
def __set__(self, vdot):
|
||||
warnings.warn(
|
||||
"ExtensibleReactor.vdot: To be removed in Cantera 3.0; "
|
||||
"renamed to 'expansion_rate'.", DeprecationWarning)
|
||||
self.accessor.setExpansionRate(vdot)
|
||||
|
||||
@property
|
||||
def expansion_rate(self):
|
||||
"""
|
||||
@ -678,25 +659,6 @@ cdef class ExtensibleReactor(Reactor):
|
||||
def expansion_rate(self, vdot):
|
||||
self.accessor.setExpansionRate(vdot)
|
||||
|
||||
property qdot:
|
||||
"""
|
||||
Get/Set the net heat transfer rate (for example, through walls) [W]
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed in Cantera 3.0; renamed to `heat_rate`.
|
||||
"""
|
||||
def __get__(self):
|
||||
warnings.warn(
|
||||
"ExtensibleReactor.qdot: To be removed in Cantera 3.0; "
|
||||
"renamed to 'heat_rate'.", DeprecationWarning)
|
||||
return self.accessor.heatRate()
|
||||
def __set__(self, qdot):
|
||||
warnings.warn(
|
||||
"ExtensibleReactor.qdot: To be removed in Cantera 3.0; "
|
||||
"renamed to 'heat_rate'.", DeprecationWarning)
|
||||
self.accessor.setHeatRate(qdot)
|
||||
|
||||
@property
|
||||
def heat_rate(self):
|
||||
"""
|
||||
@ -963,18 +925,6 @@ cdef class WallBase:
|
||||
"""
|
||||
return self.wall.expansionRate()
|
||||
|
||||
def vdot(self, double t):
|
||||
"""
|
||||
The rate of volumetric change [m^3/s] associated with the wall
|
||||
at time ``t``. A positive value corresponds to the left-hand reactor
|
||||
volume increasing, and the right-hand reactor volume decreasing.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed after Cantera 3.0; replaceable by ``expansion_rate``.
|
||||
"""
|
||||
return self.wall.vdot(t)
|
||||
|
||||
@property
|
||||
def heat_rate(self):
|
||||
"""
|
||||
@ -986,18 +936,6 @@ cdef class WallBase:
|
||||
"""
|
||||
return self.wall.heatRate()
|
||||
|
||||
def qdot(self, double t):
|
||||
"""
|
||||
Total heat flux [W] through the wall at time ``t``. A positive value
|
||||
corresponds to heat flowing from the left-hand reactor to the
|
||||
right-hand one.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed after Cantera 3.0; replaceable by ``heat_rate``.
|
||||
"""
|
||||
return self.wall.Q(t)
|
||||
|
||||
|
||||
cdef class Wall(WallBase):
|
||||
r"""
|
||||
@ -1073,20 +1011,6 @@ cdef class Wall(WallBase):
|
||||
self._velocity_func = f
|
||||
(<CxxWall*>(self.wall)).setVelocity(f.func)
|
||||
|
||||
def set_velocity(self, v):
|
||||
"""
|
||||
The wall velocity [m/s]. May be either a constant or an arbitrary
|
||||
function of time. See `Func1`.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Replaced by the ``velocity`` property.
|
||||
"""
|
||||
warnings.warn(
|
||||
"Wall.set_velocity: To be removed after Cantera 3.0; replaced by property "
|
||||
"'velocity'.", DeprecationWarning)
|
||||
self.velocity = v
|
||||
|
||||
@property
|
||||
def heat_flux(self):
|
||||
"""
|
||||
@ -1108,20 +1032,6 @@ cdef class Wall(WallBase):
|
||||
self._heat_flux_func = f
|
||||
(<CxxWall*>self.wall).setHeatFlux(f.func)
|
||||
|
||||
def set_heat_flux(self, q):
|
||||
"""
|
||||
Heat flux [W/m^2] across the wall. May be either a constant or
|
||||
an arbitrary function of time. See `Func1`.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Replaced by the ``heat_flux`` property.
|
||||
"""
|
||||
warnings.warn(
|
||||
"Wall.set_heat_flux: To be removed after Cantera 3.0; replaced by property "
|
||||
"'heat_flux'.", DeprecationWarning)
|
||||
self.heat_flux = q
|
||||
|
||||
|
||||
cdef class FlowDevice:
|
||||
"""
|
||||
@ -1205,26 +1115,6 @@ cdef class FlowDevice:
|
||||
self._rate_func = f
|
||||
self.dev.setPressureFunction(f.func)
|
||||
|
||||
def set_pressure_function(self, k):
|
||||
r"""
|
||||
Set the relationship between mass flow rate and the pressure drop across a
|
||||
flow device. The mass flow rate [kg/s] is calculated given the pressure
|
||||
drop [Pa] and a coefficient set by a flow device specific function.
|
||||
The calculation of mass flow rate depends to the flow device.
|
||||
|
||||
>>> F = FlowDevice(res1, reactor1)
|
||||
>>> F.set_pressure_function(lambda dP: dP**2)
|
||||
|
||||
where FlowDevice is either a Valve or PressureController object.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
To be removed after Cantera 3.0. Use property ``pressure_function`` instead.
|
||||
"""
|
||||
warnings.warn(
|
||||
"FlowDevice.set_pressure_function: To be removed after Cantera 3.0; "
|
||||
"replaced by 'pressure_function'.", DeprecationWarning)
|
||||
self.pressure_function = k
|
||||
|
||||
@property
|
||||
def time_function(self):
|
||||
r"""
|
||||
@ -1252,25 +1142,6 @@ cdef class FlowDevice:
|
||||
self._time_func = g
|
||||
self.dev.setTimeFunction(g.func)
|
||||
|
||||
def set_time_function(self, k):
|
||||
r"""
|
||||
Set the time dependence of a flow device. The mass flow rate [kg/s] is
|
||||
calculated for a flow device, and multiplied by a function of time.
|
||||
The calculation of mass flow rate depends to the flow device.
|
||||
|
||||
>>> F = FlowDevice(res1, reactor1)
|
||||
>>> F.set_time_function(lambda t: exp(-10 * (t - 0.5)**2))
|
||||
|
||||
where FlowDevice is either a Valve or MassFlowController object.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
To be removed after Cantera 3.0. Use property ``time_function`` instead.
|
||||
"""
|
||||
warnings.warn(
|
||||
"FlowDevice.set_time_function: To be removed after Cantera 3.0; "
|
||||
"replaced by 'time_function'.", DeprecationWarning)
|
||||
self.time_function = k
|
||||
|
||||
|
||||
cdef class MassFlowController(FlowDevice):
|
||||
r"""
|
||||
@ -1452,20 +1323,6 @@ cdef class PressureController(FlowDevice):
|
||||
def primary(self, FlowDevice d):
|
||||
(<CxxPressureController*>self.dev).setPrimary(d.dev)
|
||||
|
||||
def set_master(self, FlowDevice d):
|
||||
"""
|
||||
Set the "master" `FlowDevice` used to compute this device's mass flow
|
||||
rate.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
To be removed after Cantera 3.0; replaced by property ``primary``.
|
||||
"""
|
||||
warnings.warn(
|
||||
"PressureController.set_master: To be removed after Cantera 3.0; "
|
||||
"replaced by 'primary'.", DeprecationWarning)
|
||||
self.primary = d
|
||||
|
||||
|
||||
cdef class ReactorNet:
|
||||
"""
|
||||
@ -1556,19 +1413,6 @@ cdef class ReactorNet:
|
||||
def initial_time(self, double t):
|
||||
self.net.setInitialTime(t)
|
||||
|
||||
def set_initial_time(self, double t):
|
||||
"""
|
||||
Set the initial time. Restarts integration from this time using the
|
||||
current state as the initial condition. Default: 0.0 s.
|
||||
|
||||
.. deprecated:: 3.0
|
||||
To be removed after Cantera 3.0. Use property ``initial_time`` instead.
|
||||
"""
|
||||
warnings.warn(
|
||||
"ReactorNet.set_initial_time: To be removed after Cantera 3.0. "
|
||||
"Use property 'initial_time' instead.", DeprecationWarning)
|
||||
self.initial_time = t
|
||||
|
||||
property max_time_step:
|
||||
"""
|
||||
Get/set the maximum time step *t* [s] that the integrator is
|
||||
|
@ -54,26 +54,6 @@ cdef class _SolutionBase:
|
||||
|
||||
def _cinit(self, infile="", name="", adjacent=(), origin=None, yaml=None,
|
||||
thermo=None, species=(), kinetics=None, reactions=(), **kwargs):
|
||||
|
||||
if 'phaseid' in kwargs:
|
||||
if name is not '':
|
||||
raise AttributeError('duplicate specification of phase name')
|
||||
|
||||
warnings.warn(
|
||||
"_SolutionBase: Support for keyword 'phaseid' to be removed after "
|
||||
"Cantera 3.0. Replaceable by keyword 'name'.", DeprecationWarning)
|
||||
name = kwargs['phaseid']
|
||||
|
||||
if 'phases' in kwargs:
|
||||
if len(adjacent)>0:
|
||||
raise AttributeError(
|
||||
'duplicate specification of adjacent phases')
|
||||
|
||||
warnings.warn(
|
||||
"_SolutionBase: Support for keyword 'phases' to be removed after "
|
||||
"Cantera 3.0. Replaceable by keyword 'adjacent'.", DeprecationWarning)
|
||||
adjacent = kwargs['phases']
|
||||
|
||||
# Shallow copy of an existing Solution (for slicing support)
|
||||
cdef _SolutionBase other
|
||||
if origin is not None:
|
||||
|
@ -13,12 +13,7 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
ct.composite._import_h5py()
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from cantera.composite import _pandas, _h5py
|
||||
from cantera.composite import _pandas
|
||||
from . import utilities
|
||||
|
||||
|
||||
@ -476,58 +471,6 @@ class TestSolutionArrayIO(utilities.CanteraTest):
|
||||
for key, value in a.meta.items():
|
||||
assert b.meta[key] == value
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
def test_write_csv_legacy(self):
|
||||
states = ct.SolutionArray(self.gas, 7)
|
||||
states.TPX = np.linspace(300, 1000, 7), 2e5, 'H2:0.5, O2:0.4'
|
||||
states.equilibrate('HP')
|
||||
|
||||
outfile = self.test_work_path / "solutionarray.csv"
|
||||
states.write_csv(outfile)
|
||||
|
||||
data = np.genfromtxt(outfile, names=True, delimiter=',')
|
||||
self.assertEqual(len(data), 7)
|
||||
self.assertEqual(len(data.dtype), self.gas.n_species + 2)
|
||||
self.assertIn('Y_H2', data.dtype.fields)
|
||||
|
||||
b = ct.SolutionArray(self.gas)
|
||||
b.read_csv(outfile)
|
||||
self.check_arrays(states, b)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
def test_write_csv_single_row(self):
|
||||
gas = ct.Solution("gri30.yaml")
|
||||
states = ct.SolutionArray(gas)
|
||||
states.append(T=300., P=ct.one_atm, X="CH4:0.5, O2:0.4")
|
||||
states.equilibrate("HP")
|
||||
|
||||
outfile = self.test_work_path / "solutionarray.csv"
|
||||
states.write_csv(outfile)
|
||||
|
||||
b = ct.SolutionArray(gas)
|
||||
b.read_csv(outfile)
|
||||
self.check_arrays(states, b)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
def test_write_csv_str_column(self):
|
||||
states = ct.SolutionArray(self.gas, 3, extra={'spam': 'eggs'})
|
||||
|
||||
outfile = self.test_work_path / "solutionarray.csv"
|
||||
states.write_csv(outfile)
|
||||
|
||||
b = ct.SolutionArray(self.gas, extra={'spam'})
|
||||
b.read_csv(outfile)
|
||||
self.assertEqual(list(states.spam), list(b.spam))
|
||||
self.check_arrays(states, b)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
def test_write_csv_multidim_column(self):
|
||||
states = ct.SolutionArray(self.gas, 3, extra={'spam': np.zeros((3, 5,))})
|
||||
|
||||
outfile = self.test_work_path / "solutionarray.csv"
|
||||
with self.assertRaisesRegex(NotImplementedError, 'not supported'):
|
||||
states.write_csv(outfile)
|
||||
|
||||
def test_write_csv(self):
|
||||
outfile = self.test_work_path / "solutionarray_new.csv"
|
||||
outfile.unlink(missing_ok=True)
|
||||
@ -718,12 +661,6 @@ class TestLegacyHDF(utilities.CanteraTest):
|
||||
def setUp(self):
|
||||
self.gas = ct.Solution('h2o2.yaml', transport_model=None)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.skipif("h5py" not in ct.hdf_support(), reason="h5py is not installed")
|
||||
def test_legacy_hdf_str_column_h5py(self):
|
||||
self.run_read_legacy_hdf_str_column(legacy=True)
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="Unable to read fixed length strings from HDF")
|
||||
@pytest.mark.skipif("native" not in ct.hdf_support(),
|
||||
reason="Cantera compiled without HDF support")
|
||||
@ -747,61 +684,18 @@ class TestLegacyHDF(utilities.CanteraTest):
|
||||
b.restore(infile, "group0")
|
||||
assert all(arr.spam == b.spam)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.skipif("h5py" not in ct.hdf_support(), reason="h5py is not installed")
|
||||
def test_legacy_hdf_multidim_h5py(self):
|
||||
self.run_read_legacy_hdf_multidim(legacy=True)
|
||||
|
||||
@pytest.mark.skipif("native" not in ct.hdf_support(),
|
||||
reason="Cantera compiled without HDF support")
|
||||
@pytest.mark.filterwarnings("ignore:.*legacy HDF.*:UserWarning")
|
||||
def test_legacy_hdf_multidim(self):
|
||||
self.run_read_legacy_hdf_multidim()
|
||||
|
||||
def run_read_legacy_hdf_multidim(self, legacy=False):
|
||||
# recreate states used to create legacy HDF file
|
||||
arr = ct.SolutionArray(self.gas, 3, extra={'spam': [[1, 2], [3, 4], [5, 6]]})
|
||||
b = ct.SolutionArray(self.gas, extra={'spam'})
|
||||
infile = self.test_data_path / f"solutionarray_multi_legacy.h5"
|
||||
|
||||
if legacy:
|
||||
b.read_hdf(infile)
|
||||
else:
|
||||
b.restore(infile, "group0")
|
||||
self.assertArrayNear(arr.spam, b.spam)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.skipif(ct.hdf_support() != {"native", "h5py"},
|
||||
reason="Both HDF support modes needed")
|
||||
def test_deprecated_write_read_hdf(self):
|
||||
# recreate states used to create legacy HDF file
|
||||
arr = ct.SolutionArray(self.gas, 3, extra={'spam': [[1, 2], [3, 4], [5, 6]]})
|
||||
outfile = self.test_work_path / "solutionarray_deprecated.h5"
|
||||
outfile.unlink(missing_ok=True)
|
||||
|
||||
with pytest.raises(KeyError, match="Missing required parameter 'group'"):
|
||||
arr.write_hdf(outfile, "group0")
|
||||
|
||||
with pytest.warns(DeprecationWarning, match="use 'save' instead"):
|
||||
# New HDF format is written regardless via 'save'
|
||||
arr.write_hdf(outfile, group="group0")
|
||||
|
||||
b = ct.SolutionArray(self.gas)
|
||||
with pytest.raises(IOError, match="use 'restore' instead"):
|
||||
# New HDF format should not be read with 'read_hdf'
|
||||
with pytest.warns(DeprecationWarning, match="use 'restore' instead"):
|
||||
# DeprecationWarning is triggered before IOError is raised
|
||||
b.read_hdf(outfile, group="group0")
|
||||
|
||||
meta = b.restore(outfile, "group0")
|
||||
assert meta["generator"] == "Cantera SolutionArray"
|
||||
self.assertArrayNear(arr.spam, b.spam)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.skipif("h5py" not in ct.hdf_support(), reason="h5py is not installed")
|
||||
def test_legacy_hdf_h5py(self):
|
||||
self.run_legacy_hdf(legacy=True)
|
||||
|
||||
@pytest.mark.skipif("native" not in ct.hdf_support(),
|
||||
reason="Cantera compiled without HDF support")
|
||||
@pytest.mark.filterwarnings("ignore:.*legacy HDF.*:UserWarning")
|
||||
@ -818,9 +712,6 @@ class TestLegacyHDF(utilities.CanteraTest):
|
||||
|
||||
infile = self.test_data_path / f"solutionarray_fancy_legacy.h5"
|
||||
b = ct.SolutionArray(self.gas)
|
||||
if legacy:
|
||||
attr = b.read_hdf(infile)
|
||||
else:
|
||||
attr = b.restore(infile, "group0")
|
||||
self.assertArrayNear(states.T, b.T)
|
||||
self.assertArrayNear(states.P, b.P)
|
||||
@ -831,11 +722,6 @@ class TestLegacyHDF(utilities.CanteraTest):
|
||||
self.assertEqual(b.meta['hello'], 'world')
|
||||
self.assertEqual(attr['foobar'], 'spam and eggs')
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.skipif("h5py" not in ct.hdf_support(), reason="h5py is not installed")
|
||||
def test_read_legacy_hdf_no_norm_h5py(self):
|
||||
self.run_read_legacy_hdf_no_norm(legacy=True)
|
||||
|
||||
@pytest.mark.skipif("native" not in ct.hdf_support(),
|
||||
reason="Cantera compiled without HDF support")
|
||||
@pytest.mark.filterwarnings("ignore:.*legacy HDF.*:UserWarning")
|
||||
@ -858,18 +744,10 @@ class TestLegacyHDF(utilities.CanteraTest):
|
||||
self.assertArrayNear(states.P, b.P, rtol=1e-7)
|
||||
self.assertArrayNear(states.X, b.X, rtol=1e-7)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.skipif("h5py" not in ct.hdf_support(), reason="h5py is not installed")
|
||||
def test_import_no_norm_water_h5py(self):
|
||||
self.run_import_no_norm_water(legacy=True)
|
||||
|
||||
@pytest.mark.skipif("native" not in ct.hdf_support(),
|
||||
reason="Cantera compiled without HDF support")
|
||||
@pytest.mark.filterwarnings("ignore:.*legacy HDF.*:UserWarning")
|
||||
def test_import_no_norm_water(self):
|
||||
self.run_import_no_norm_water()
|
||||
|
||||
def run_import_no_norm_water(self, legacy=False):
|
||||
# recreate states used to create legacy HDF file
|
||||
w = ct.Water()
|
||||
w.TQ = 300, 0.5
|
||||
@ -878,28 +756,11 @@ class TestLegacyHDF(utilities.CanteraTest):
|
||||
w_new = ct.Water()
|
||||
infile = self.test_data_path / "solutionarray_water_legacy.h5"
|
||||
c = ct.SolutionArray(w_new)
|
||||
if legacy:
|
||||
c.read_hdf(infile, normalize=False)
|
||||
else:
|
||||
c.restore(infile, "group0")
|
||||
self.assertArrayNear(states.T, c.T, rtol=1e-7)
|
||||
self.assertArrayNear(states.P, c.P, rtol=1e-7)
|
||||
self.assertArrayNear(states.Q, c.Q, rtol=1e-7)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.skipif(ct.hdf_support() != {"native", "h5py"},
|
||||
reason="Both HDF support modes needed")
|
||||
def test_new_hdf_h5py_exception(self):
|
||||
outfile = self.test_work_path / f"solutionarray_new.h5"
|
||||
outfile.unlink(missing_ok=True)
|
||||
|
||||
states = ct.SolutionArray(self.gas, 3, extra={'spam': [[1, 2], [3, 4], [5, 6]]})
|
||||
states.save(outfile, "arr")
|
||||
|
||||
b = ct.SolutionArray(self.gas, extra={'spam'})
|
||||
with pytest.raises(IOError, match="Cantera 3.0 HDF format"):
|
||||
b.read_hdf(outfile, "arr") # h5py file should not read new format
|
||||
|
||||
|
||||
class TestRestoreIdealGas(utilities.CanteraTest):
|
||||
""" Test restoring of the IdealGas class """
|
||||
|
@ -84,8 +84,6 @@ class TestOnedim(utilities.CanteraTest):
|
||||
ct.ReactingSurface1D(gas, foo="bar")
|
||||
interface = ct.Solution("diamond.yaml", "diamond_100")
|
||||
surf = ct.ReactingSurface1D(interface)
|
||||
with pytest.warns(DeprecationWarning, match="Method to be removed"):
|
||||
surf.set_kinetics(interface)
|
||||
|
||||
def test_invalid_property(self):
|
||||
gas1 = ct.Solution("h2o2.yaml")
|
||||
@ -293,8 +291,6 @@ class TestFreeFlame(utilities.CanteraTest):
|
||||
flow = self.sim.to_array(normalize=True)
|
||||
self.assertArrayNear(self.sim.grid, flow.grid)
|
||||
self.assertArrayNear(self.sim.T, flow.T)
|
||||
for k in flow.extra:
|
||||
self.assertIn(k, self.sim._other)
|
||||
|
||||
f2 = ct.FreeFlame(self.gas)
|
||||
f2.from_array(flow)
|
||||
@ -640,8 +636,8 @@ class TestFreeFlame(utilities.CanteraTest):
|
||||
# Skipped because they are constant, irrelevant, or otherwise not desired
|
||||
"P", "Te", "atomic_weights", "charges", "electric_potential", "max_temp",
|
||||
"min_temp", "molecular_weights", "product_stoich_coeffs",
|
||||
"product_stoich_coeffs3", "product_stoich_coeffs_reversible",
|
||||
"reactant_stoich_coeffs", "reactant_stoich_coeffs3", "reference_pressure",
|
||||
"product_stoich_coeffs", "product_stoich_coeffs_reversible",
|
||||
"reactant_stoich_coeffs", "reactant_stoich_coeffs", "reference_pressure",
|
||||
"state", "u", "v",
|
||||
# Skipped because they are 2D (conversion not implemented)
|
||||
"binary_diff_coeffs", "creation_rates_ddX", "destruction_rates_ddX",
|
||||
@ -732,22 +728,6 @@ class TestFreeFlame(utilities.CanteraTest):
|
||||
k1 = gas1.species_index(species)
|
||||
self.assertArrayNear(Y1[k1], Y2[k2])
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
def test_write_csv_legacy(self):
|
||||
filename = self.test_work_path / "onedim-write_csv.csv"
|
||||
# In Python >= 3.8, this can be replaced by the missing_ok argument
|
||||
if filename.is_file():
|
||||
filename.unlink()
|
||||
|
||||
self.create_sim(2e5, 350, 'H2:1.0, O2:2.0', mech="h2o2.yaml")
|
||||
self.sim.write_csv(filename)
|
||||
data = ct.SolutionArray(self.gas)
|
||||
data.read_csv(filename)
|
||||
self.assertArrayNear(data.grid, self.sim.grid)
|
||||
self.assertArrayNear(data.T, self.sim.T)
|
||||
k = self.gas.species_index('H2')
|
||||
self.assertArrayNear(data.X[:, k], self.sim.X[k, :])
|
||||
|
||||
def test_write_csv(self):
|
||||
filename = self.test_work_path / "onedim-save.csv"
|
||||
filename.unlink(missing_ok=True)
|
||||
@ -761,20 +741,11 @@ class TestFreeFlame(utilities.CanteraTest):
|
||||
k = self.gas.species_index('H2')
|
||||
self.assertArrayNear(data.X[:, k], self.sim.X[k, :])
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@utilities.unittest.skipIf("h5py" not in ct.hdf_support(), "h5py not installed")
|
||||
def test_restore_legacy_hdf_h5py(self):
|
||||
self.run_restore_legacy_hdf(True)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.filterwarnings("ignore:.*legacy HDF.*:UserWarning")
|
||||
@pytest.mark.skipif("native" not in ct.hdf_support(),
|
||||
reason="Cantera compiled without HDF support")
|
||||
def test_restore_legacy_hdf(self):
|
||||
self.run_restore_legacy_hdf()
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
def run_restore_legacy_hdf(self, legacy=False):
|
||||
# Legacy input file was created using the Cantera 2.6 Python test suite:
|
||||
# - restore_legacy.h5 -> test_onedim.py::TestFreeFlame::test_write_hdf
|
||||
filename = self.test_data_path / f"freeflame_legacy.h5"
|
||||
@ -783,9 +754,6 @@ class TestFreeFlame(utilities.CanteraTest):
|
||||
desc = 'mixture-averaged simulation'
|
||||
|
||||
f = ct.FreeFlame(self.gas)
|
||||
if legacy:
|
||||
meta = f.read_hdf(filename)
|
||||
else:
|
||||
meta = f.restore(filename, "group0")
|
||||
assert meta['description'] == desc
|
||||
assert meta['cantera_version'] == "2.6.0"
|
||||
@ -795,12 +763,10 @@ class TestFreeFlame(utilities.CanteraTest):
|
||||
|
||||
@pytest.mark.skipif("native" not in ct.hdf_support(),
|
||||
reason="Cantera compiled without HDF support")
|
||||
@pytest.mark.filterwarnings("ignore:.*_FlowBase.settings.*Cantera 3.0.*:DeprecationWarning")
|
||||
def test_save_restore_hdf(self):
|
||||
# save and restore with native format (HighFive only)
|
||||
self.run_save_restore("h5")
|
||||
|
||||
@pytest.mark.filterwarnings("ignore:.*_FlowBase.settings.*Cantera 3.0.*:DeprecationWarning")
|
||||
def test_save_restore_yaml(self):
|
||||
self.run_save_restore("yaml")
|
||||
|
||||
@ -820,33 +786,6 @@ class TestFreeFlame(utilities.CanteraTest):
|
||||
|
||||
self.check_save_restore(f)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.skipif(ct.hdf_support() != {"native", "h5py"},
|
||||
reason="Both HDF support modes needed")
|
||||
def test_deprecated_write_read_hdf(self):
|
||||
filename = self.test_work_path / f"freeflame_deprecated.h5"
|
||||
filename.unlink(missing_ok=True)
|
||||
|
||||
self.run_mix(phi=1.1, T=350, width=2.0, p=2.0, refine=False)
|
||||
desc = 'mixture-averaged simulation'
|
||||
with pytest.warns(DeprecationWarning, match="use 'save' instead"):
|
||||
self.sim.write_hdf(filename, group="group0", description=desc, loglevel=0)
|
||||
|
||||
f = ct.FreeFlame(self.gas)
|
||||
with pytest.raises(IOError, match="use 'restore' instead"):
|
||||
# New HDF format should not be read with 'read_hdf'
|
||||
with pytest.warns(DeprecationWarning, match="use 'restore' instead"):
|
||||
# DeprecationWarning is triggered before IOError is raised
|
||||
f.read_hdf(filename, group="group0")
|
||||
|
||||
meta = f.restore(filename, "group0")
|
||||
assert meta['description'] == desc
|
||||
assert meta['generator'] == "Cantera SolutionArray"
|
||||
assert meta['cantera-version'] == ct.__version__
|
||||
assert meta['git-commit'] == f"'{ct.__git_commit__}'"
|
||||
|
||||
self.check_save_restore(f)
|
||||
|
||||
def check_save_restore(self, f):
|
||||
# pytest.approx is used as equality for floats cannot be guaranteed for loaded
|
||||
# HDF5 files if they were created on a different OS and/or architecture
|
||||
@ -1599,16 +1538,6 @@ class TestImpingingJet(utilities.CanteraTest):
|
||||
def test_reacting_surface_case3(self):
|
||||
self.run_reacting_surface(xch4=0.2, tsurf=800.0, mdot=0.1, width=0.2)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@utilities.unittest.skipIf("h5py" not in ct.hdf_support(), "h5py not installed")
|
||||
def test_restore_legacy_hdf_h5py(self):
|
||||
filename = self.test_data_path / f"impingingjet_legacy.h5"
|
||||
jet = ct.ImpingingJet(gas=self.gas, surface=self.surf_phase)
|
||||
with pytest.raises(IOError, match="Unable to load surface phase"):
|
||||
# legacy HDF format uses TDX state information, which is incomplete for
|
||||
# surfaces
|
||||
jet.read_hdf(filename)
|
||||
|
||||
@pytest.mark.usefixtures("allow_deprecated")
|
||||
@pytest.mark.skipif("native" not in ct.hdf_support(),
|
||||
reason="Cantera compiled without HDF support")
|
||||
|
Loading…
Reference in New Issue
Block a user