Skip to content

Commit

Permalink
set normalize default argument
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidAkinpelu authored and speth committed Jul 9, 2021
1 parent 8e68471 commit 1420a4c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 80 deletions.
81 changes: 29 additions & 52 deletions interfaces/cython/cantera/composite.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ def __call__(self, *species):
return SolutionArray(self._phase[species], states=self._states,
extra=self._extra)

def append(self, state=None, normalize=None, **kwargs):
def append(self, state=None, normalize=True, **kwargs):
"""
Append an element to the array with the specified state. Elements can
only be appended in cases where the array of states is one-dimensional.
Expand All @@ -650,14 +650,9 @@ def append(self, state=None, normalize=None, **kwargs):
mystates.append(T=300, P=101325, X={'O2':1.0, 'N2':3.76})
By default, the mass or mole fractions will be non-normalized
if appending a `state` or numpy array specifying `X` or `Y`.
When appending a state, the mass or mole fractions are always
non-normalized. For states setters, if the non-normalized
form is desired, the ``normalize`` argument can be set to ``True``.
For example::
mystates.append(T=300, P=101325, Y=gas.Y - 0.1, normalize=True)
By default, the mass or mole fractions will be normalized i.e negative values
are truncated and the mass or mole fractions sum up to 1.0. If this
is not desired, the ``normalize`` argument can be set to ``False``.
"""
if len(self._shape) != 1:
raise IndexError("Can only append to 1D SolutionArray")
Expand Down Expand Up @@ -690,23 +685,15 @@ def append(self, state=None, normalize=None, **kwargs):
raise KeyError(
"'{}' does not specify a full thermodynamic state".format(attr)
)
if attr[-1] == "X":
if not normalize and isinstance(value[-1], np.ndarray):
if normalize or attr.endswith("Q"):
setattr(self._phase, attr, value)
else:
if attr.endswith("X"):
self._phase.set_unnormalized_mole_fractions(value[-1])
attr = attr[:-1]
value = value[:-1]
setattr(self._phase, attr, value)
else:
setattr(self._phase, attr, value)
elif attr[-1] == "Y":
if not normalize and isinstance(value[-1], np.ndarray):
elif attr.endswith("Y"):
self._phase.set_unnormalized_mass_fractions(value[-1])
attr = attr[:-1]
value = value[:-1]
setattr(self._phase, attr, value)
else:
setattr(self._phase, attr, value)
else:
attr = attr[:-1]
value = value[:-1]
setattr(self._phase, attr, value)

else:
Expand All @@ -717,21 +704,14 @@ def append(self, state=None, normalize=None, **kwargs):
"{} is not a valid combination of properties for setting "
"the thermodynamic state".format(tuple(kwargs))
) from None
if attr[-1] == "X":
if not normalize and isinstance(kwargs["X"], np.ndarray):
if normalize or attr.endswith("Q"):
setattr(self._phase, attr, list(kwargs.values()))
else:
if attr.endswith("X"):
self._phase.set_unnormalized_mole_fractions(kwargs.pop("X"))
attr = attr[:-1]
setattr(self._phase, attr, list(kwargs.values()))
else:
setattr(self._phase, attr, list(kwargs.values()))
elif attr[-1] == "Y":
if not normalize and isinstance(kwargs["Y"], np.ndarray):
elif attr.endswith("Y"):
self._phase.set_unnormalized_mass_fractions(kwargs.pop("Y"))
attr = attr[:-1]
setattr(self._phase, attr, list(kwargs.values()))
else:
setattr(self._phase, attr, list(kwargs.values()))
else:
attr = attr[:-1]
setattr(self._phase, attr, list(kwargs.values()))

for name, value in self._extra.items():
Expand Down Expand Up @@ -791,7 +771,7 @@ def equilibrate(self, *args, **kwargs):
self._phase.equilibrate(*args, **kwargs)
self._states[index][:] = self._phase.state

def restore_data(self, data, normalize=False):
def restore_data(self, data, normalize=True):
"""
Restores a `SolutionArray` based on *data* specified in an ordered
dictionary. Thus, this method allows to restore data exported by
Expand All @@ -800,18 +780,16 @@ def restore_data(self, data, normalize=False):
:param data: Dictionary holding data to be restored, where keys
refer to thermodynamic states (e.g. ``T``, ``density``) or extra
entries, and values contain corresponding data.
:param normalize: 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.
The receiving `SolutionArray` either has to be empty or should have
matching dimensions. Essential state properties and extra entries
are detected automatically whereas stored information of calculated
properties is omitted. If the receiving `SolutionArray` has extra
entries already specified, only those will be imported; if *labels*
does not contain those entries, an error is raised.
If the data contains mass or mole fractions they will be set
without normalizing their sum to 1.0 by default. If this is
not desired, the ``normalize`` argument can be set to ``True``
to force the data to sum to 1.0.
"""

# check arguments
Expand Down Expand Up @@ -950,19 +928,19 @@ def join(species):
self._shape = (rows,)

# restore data
if normalize or mode[-1] == "Q":
if normalize or mode.endswith("Q"):
for i in self._indices:
setattr(self._phase, mode, [st[i, ...] for st in state_data])
self._states[i] = self._phase.state
else:
for i in self._indices:
if mode[-1] == "X":
if mode.endswith("X"):
self._phase.set_unnormalized_mole_fractions(
[st[i, ...] for st in state_data][2]
)
setattr(self._phase, mode[:2],
[st[i, ...] for st in state_data[:2]])
elif mode[-1] == "Y":
elif mode.endswith("Y"):
self._phase.set_unnormalized_mass_fractions(
[st[i, ...] for st in state_data][2]
)
Expand Down Expand Up @@ -1110,7 +1088,7 @@ def read_csv(self, filename, normalize=True):
previously exported by `write_csv`.
The ``normalize`` argument is passed on to `restore_data` to normalize
mole or mass fractions, if desired. By default, ``normalize`` is ``True``.
mole or mass fractions. By default, ``normalize`` is ``True``.
"""
if np.lib.NumpyVersion(np.__version__) < "1.14.0":
# bytestring needs to be converted for columns containing strings
Expand Down Expand Up @@ -1156,8 +1134,7 @@ def from_pandas(self, df, normalize=True):
installation. The package 'pandas' can be installed using pip or conda.
The ``normalize`` argument is passed on to `restore_data` to normalize
mole or mass fractions, if desired. By default, ``normalize`` is ``True``..
mole or mass fractions. By default, ``normalize`` is ``True``.
"""

data = df.to_numpy(dtype=float)
Expand Down Expand Up @@ -1311,14 +1288,14 @@ def read_hdf(self, filename, group=None, subgroup=None, force=False, normalize=T
`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).
The ``normalize`` argument is passed on to `restore_data` to normalize
mole or mass fractions, if desired. By default, ``normalize`` is ``True``.
"""
if isinstance(_h5py, ImportError):
raise _h5py
Expand Down
36 changes: 15 additions & 21 deletions interfaces/cython/cantera/onedim.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ def set_gas_state(self, point):
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=False):
def write_csv(self, filename, species='X', quiet=True, normalize=True):
"""
Write the velocity, temperature, density, and species profiles
to a CSV file.
Expand All @@ -389,7 +389,7 @@ def write_csv(self, filename, species='X', quiet=True, normalize=False):
mole fractions or ``Y`` for mass fractions.
:param normalize:
Boolean flag to indicate whether the mole/mass fractions should
be normalized (default is ``False``)
be normalized.
"""

# save data
Expand All @@ -399,16 +399,15 @@ def write_csv(self, filename, species='X', quiet=True, normalize=False):
if not quiet:
print("Solution saved to '{0}'.".format(filename))

def to_solution_array(self, domain=None, normalize=False):
def to_solution_array(self, domain=None, normalize=True):
"""
Return the solution vector as a `SolutionArray` object.
Derived classes define default values for *other*.
If the data contains mass or mole fractions they will be set
without normalizing their sum to 1.0 by default. If this is
not desired, the ``normalize`` argument can be set to
``True`` to force the data to sum to 1.0.
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``.
"""
if domain is None:
domain = self.flame
Expand All @@ -425,17 +424,12 @@ def to_solution_array(self, domain=None, normalize=False):
arr.TPY = states
else:
if len(states) == 3:
if n_points==1:
arr._phase.set_unnormalized_mass_fractions(states[2])
arr._phase.TP = states[0], states[1]
arr._states[0] = arr._phase.state
else:
for i in range(n_points):
arr._phase.set_unnormalized_mass_fractions(states[2][i])
arr._phase.TP = states[0][i], states[1]
arr._states[i] = arr._phase.state
for i in range(n_points):
arr._phase.set_unnormalized_mass_fractions(states[2][i])
arr._phase.TP = np.atleast_1d(states[0])[i], states[1]
arr._states[i] = arr._phase.state
else:
arr.TPY = states
arr.TP = states
return arr
else:
return SolutionArray(self.phase(domain), meta=meta)
Expand All @@ -458,7 +452,7 @@ def from_solution_array(self, arr, domain=None):
meta = arr.meta
super().restore_data(domain, states, other_cols, meta)

def to_pandas(self, species='X', normalize=False):
def to_pandas(self, species='X', normalize=True):
"""
Return the solution vector as a `pandas.DataFrame`.
Expand All @@ -467,7 +461,7 @@ def to_pandas(self, species='X', normalize=False):
mole fractions or ``Y`` for mass fractions.
:param normalize:
Boolean flag to indicate whether the mole/mass fractions should
be normalized (default is ``False``)
be normalized (default is ``True``)
This method uses `to_solution_array` and requires a working pandas
installation. Use pip or conda to install `pandas` to enable this
Expand Down Expand Up @@ -501,7 +495,7 @@ def from_pandas(self, df, restore_boundaries=True, settings=None):

def write_hdf(self, filename, *args, group=None, species='X', mode='a',
description=None, compression=None, compression_opts=None,
quiet=True, normalize=False, **kwargs):
quiet=True, normalize=True, **kwargs):
"""
Write the solution vector to a HDF container file.
Expand Down Expand Up @@ -564,7 +558,7 @@ def write_hdf(self, filename, *args, group=None, species='X', mode='a',
Suppress message confirming successful file output.
:param normalize:
Boolean flag to indicate whether the mole/mass fractions should
be normalized (default is ``False``)
be normalized (default is ``True``)
Additional arguments (i.e. *args* and *kwargs*) are passed on to
`SolutionArray.collect_data`. The method exports data using
Expand Down
16 changes: 9 additions & 7 deletions interfaces/cython/cantera/test/test_composite.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,10 @@ def test_append_no_norm_data(self):
self.assertArrayNear(states[0].Y, gas.Y)

def test_import_no_norm_data(self):
outfile = pjoin(self.test_work_dir, "solutionarray.h5")
if os.path.exists(outfile):
os.remove(outfile)
outfile = self.test_work_path / "solutionarray.h5"
# In Python >= 3.8, this can be replaced by the missing_ok argument
if outfile.is_file():
outfile.unlink()

gas = ct.Solution("h2o2.yaml")
gas.set_unnormalized_mole_fractions(np.full(gas.n_species, 0.3))
Expand Down Expand Up @@ -454,9 +455,10 @@ def check(a, b):
check(a, b)

def test_import_no_norm_water(self):
outfile = pjoin(self.test_work_dir, "solutionarray.h5")
if os.path.exists(outfile):
os.remove(outfile)
outfile = self.test_work_path / "solutionarray.h5"
# In Python >= 3.8, this can be replaced by the missing_ok argument
if outfile.is_file():
outfile.unlink()

w = ct.Water()
w.TQ = 300, 0.5
Expand All @@ -465,7 +467,7 @@ def test_import_no_norm_water(self):

w_new = ct.Water()
c = ct.SolutionArray(w_new)
c.read_hdf(outfile)
c.read_hdf(outfile, normalize=False)
self.assertArrayNear(states.T, c.T)
self.assertArrayNear(states.P, c.P)
self.assertArrayNear(states.Q, c.Q)
Expand Down

0 comments on commit 1420a4c

Please sign in to comment.