Skip to content

Commit

Permalink
[Thermo] Append to SolutionArray all at once
Browse files Browse the repository at this point in the history
Move append of extra values to the end of SolutionArray.append(). If the
append is done at the beginning of the function, the append can happen
even if the state is invalid. This would cause the length of the arrays
to become out of sync.
  • Loading branch information
bryanwweber committed Jul 6, 2020
1 parent 477cbed commit ef1fa99
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
16 changes: 16 additions & 0 deletions interfaces/cython/cantera/composite.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,16 @@ def append(self, state=None, **kwargs):
"'{}'".format(", ".join(missing_extra_kwargs))
)

# For the checks of the state below, the kwargs dictionary can
# only contain keywords that match properties of the state. Here
# we pop any kwargs that have to do with the extra items so they
# aren't included in that check. They are put into a temporary
# storage so that appending can be done at the end of the function
# all at once.
extra_temp = {}
for name in self._extra:
extra_temp[name] = kwargs.pop(name)

if state is not None:
self._phase.state = state

Expand All @@ -654,6 +664,12 @@ def append(self, state=None, **kwargs):

self._states.append(self._phase.state)
self._indices.append(len(self._indices))
for name, value in self._extra.items():
# Casting to a list before appending is ~5x faster than using
# np.append when appending a single item.
v = value.tolist()
v.append(extra_temp.pop(name))
self._extra[name] = np.array(v)
self._shape = (len(self._indices),)

@property
Expand Down
12 changes: 12 additions & 0 deletions interfaces/cython/cantera/test/test_thermo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1740,6 +1740,18 @@ def test_append(self):
self.assertNear(states.P[-1], 1e4)
self.assertNear(states.T[-1], 300)

def test_append_with_extra(self):
states = ct.SolutionArray(self.gas, 5, extra={"prop": "value"})
states.TPX = np.linspace(500, 1000, 5), 2e5, 'H2:0.5, O2:0.4'
self.assertEqual(states._shape, (5,))
states.append(T=1100, P=3e5, X="AR:1.0", prop="value2")
self.assertEqual(states.prop[-1], "value2")
self.assertEqual(states.prop.shape, (6,))
states.append(T=1100, P=3e5, X="AR:1.0", prop=100)
# NumPy converts to the existing type of the array
self.assertEqual(states.prop[-1], "100")
self.assertEqual(states.prop.shape, (7,))

def test_append_failures(self):
states = ct.SolutionArray(self.gas, 5, extra={"prop": "value"})
states.TPX = np.linspace(500, 1000, 5), 2e5, 'H2:0.5, O2:0.4'
Expand Down

0 comments on commit ef1fa99

Please sign in to comment.