Skip to content

Commit

Permalink
[Thermo] Clarify extra items from iterables
Browse files Browse the repository at this point in the history
Make sure that ndarrays are one-dimensional. Move check for bare string.
Clarify error messages. Reduce indentation. Add tests for creating extra
items from bare strings and ndarrays.
  • Loading branch information
bryanwweber committed Jul 6, 2020
1 parent 1cc53b4 commit 8786b51
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 34 deletions.
32 changes: 16 additions & 16 deletions interfaces/cython/cantera/composite.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,9 +529,6 @@ def __init__(self, phase, shape=(0,), states=None, extra=None, meta=None):

self._extra = OrderedDict()

if isinstance(extra, str):
extra = [extra]

if isinstance(extra, dict):
for name, v in extra.items():
if name in reserved:
Expand All @@ -546,28 +543,31 @@ def __init__(self, phase, shape=(0,), states=None, extra=None, meta=None):
raise ValueError("Unable to map extra SolutionArray "
"input named {!r}".format(name))
elif extra is not None:
if isinstance(extra, np.ndarray):
extra = extra.flatten()
elif isinstance(extra, str):
extra = [extra]

try:
iter_extra = iter(extra)
except TypeError :
raise ValueError(
"Extra properties can be created by passing an iterable "
"of names for the properties, if the SolutionArray is not initially "
"empty. If you want to supply initial values for the properties, use "
"a dictionary whose keys are the names of the properties and values "
"are the initial values.") from None
"of names for the properties. If you want to supply initial "
"values for the properties, use a dictionary whose keys are "
"the names of the properties and values are the initial "
"values.") from None

for name in iter_extra:
if isinstance(name, str):
if name in reserved:
raise ValueError(
"Unable to create extra column '{}': name is already "
"used by SolutionArray objects.".format(name))
self._extra[name] = np.empty(self._shape)

else:
if not isinstance(name, str):
raise TypeError(
"Unable to create extra column, passed value {}: "
"Unable to create extra column, passed value '{!r}' "
"is not a string".format(name))
if name in reserved:
raise ValueError(
"Unable to create extra column '{}': name is already "
"used by SolutionArray objects.".format(name))
self._extra[name] = np.empty(self._shape)

if meta is None:
self._meta = {}
Expand Down
33 changes: 15 additions & 18 deletions interfaces/cython/cantera/test/test_thermo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,10 @@ def test_extra_reserved_names(self):
with self.assertRaisesRegex(ValueError, "name is already used"):
ct.SolutionArray(self.gas, extra={"creation_rates": 0})

def test_extra_create_by_string(self):
states = ct.SolutionArray(self.gas, extra="prop")
self.assertEqual(states.prop.shape, (0,))

def test_assign_to_slice(self):
states = ct.SolutionArray(self.gas, 7, extra={'prop': range(7)})
array = np.arange(7)
Expand All @@ -1729,24 +1733,17 @@ def test_assign_to_slice(self):
array_mod = np.array([0, -5, 2, 0, 1, 5, 6])
self.assertArrayNear(states.prop, array_mod)

def test_extra2(self):
states = ct.SolutionArray(self.gas, shape=(5, 9), extra=["prop1", "prop2"])
self.assertEqual(states.prop1.shape, (5, 9))
states1 = ct.SolutionArray(self.gas, shape=(0, 0, 0), extra="prop1")
self.assertEqual(states1.prop1.shape, (0, 0, 0))

def test_extra3(self):
states2 = ct.SolutionArray(self.gas, shape=(2, 6, 9), extra="prop1")
self.assertEqual(states2.prop1.shape, (2, 6, 9))

def test_extra4(self):
states3 = ct.SolutionArray(self.gas, shape=(2, 6, 9), extra=("prop1", "prop2", "prop3"))
self.assertEqual(states3.prop3.shape, (2, 6, 9))

def test_extra5(self):
def test_extra_create_by_ndarray(self):
properties_array = np.array(["prop1", "prop2", "prop3"])
states4 = ct.SolutionArray(self.gas, shape=(2, 6, 9), extra=properties_array)
self.assertEqual(states4.prop2.shape, (2, 6, 9))
states = ct.SolutionArray(self.gas, shape=(2, 6, 9), extra=properties_array)
self.assertEqual(states.prop1.shape, (2, 6, 9))
self.assertEqual(states.prop2.shape, (2, 6, 9))
self.assertEqual(states.prop3.shape, (2, 6, 9))
# Ensure that a 2-dimensional array is flattened
properties_array = np.array((["prop1"], ["prop2"]))
states = ct.SolutionArray(self.gas, extra=properties_array)
self.assertEqual(states.prop1.shape, (0,))
self.assertEqual(states.prop2.shape, (0,))

def test_append(self):
states = ct.SolutionArray(self.gas, 5)
Expand All @@ -1766,7 +1763,7 @@ def test_append(self):

self.gas.TPX = 300, 1e4, 'O2:0.5, AR:0.5'
HPY = self.gas.HPY
self.gas.TPX = 1200, 5e5, 'O2:0.3, AR:0.7' # to make sure it gets changed
self.gas.TPX = 1200, 5e5, 'O2:0.3, AR:0.7' # to make sure it gets changed
states.append(HPY=HPY)
self.assertEqual(states.cp_mass.shape, (8,))
self.assertNear(states.P[-1], 1e4)
Expand Down

0 comments on commit 8786b51

Please sign in to comment.