Skip to content

Commit 3f36650

Browse files
anthony-walkerspeth
authored andcommitted
Add tests, fix bugs, remove added unused code in cython and cpp
1 parent e8bd6dd commit 3f36650

File tree

10 files changed

+111
-51
lines changed

10 files changed

+111
-51
lines changed

include/cantera/zeroD/FlowDevice.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ class FlowDevice : public ConnectorNode
189189
//! @since New in %Cantera 3.0.
190190
//!
191191
virtual void buildNetworkJacobian(vector<Eigen::Triplet<double>>& jacVector) {
192-
throw NotImplementedError(type() + "::buildNetworkJacobian");
192+
if (!m_jac_calculated) {
193+
throw NotImplementedError(type() + "::buildNetworkJacobian");
194+
}
193195
}
194196

195197
//! Specify the jacobian terms have been calculated and should not be recalculated.

include/cantera/zeroD/IdealGasConstPressureMoleReactor.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,6 @@ class IdealGasConstPressureMoleReactor : public ConstPressureMoleReactor
4343

4444
bool preconditionerSupported() const override { return true; };
4545

46-
double temperatureDerivative() override { return 1; };
47-
48-
double temperatureRadiationDerivative() override {
49-
return 4 * std::pow(temperature(), 3);
50-
}
51-
5246
double moleDerivative(size_t index) override;
5347

5448
double moleRadiationDerivative(size_t index) override;

include/cantera/zeroD/IdealGasMoleReactor.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,6 @@ class IdealGasMoleReactor : public MoleReactor
4545

4646
bool preconditionerSupported() const override {return true;};
4747

48-
double temperatureDerivative() override { return 1; };
49-
50-
double temperatureRadiationDerivative() override {
51-
return 4 * std::pow(temperature(), 3);
52-
}
53-
5448
double moleDerivative(size_t index) override;
5549

5650
double moleRadiationDerivative(size_t index) override;

interfaces/cython/cantera/_utils.pxd

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,4 @@ cdef anymap_to_py(CxxAnyMap& m)
119119
cdef CxxAnyValue python_to_anyvalue(item, name=*) except *
120120
cdef anyvalue_to_python(string name, CxxAnyValue& v)
121121

122-
cdef vector[CxxEigenTriplet] python_to_triplets(triplets) except *
123-
cdef triplets_to_python(vector[CxxEigenTriplet]& triplets)
124-
125122
cdef CxxEigenTriplet get_triplet(row, col, val) except *

interfaces/cython/cantera/_utils.pyx

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -527,41 +527,10 @@ cdef vector[vector[string]] list2_string_to_anyvalue(data):
527527
v[i][j] = stringify(jtem)
528528
return v
529529

530-
cdef vector[CxxEigenTriplet] python_to_triplets(triplets):
531-
# check that triplet dimensions are met
532-
trip_shape = np.shape(triplets)
533-
assert len(trip_shape) == 2
534-
assert trip_shape[1] == 3
535-
cdef vector[CxxEigenTriplet] trips
536-
# c++ variables
537-
cdef size_t row
538-
cdef size_t col
539-
cdef double val
540-
cdef CxxEigenTriplet* trip_ptr
541-
for r, c, v in triplets:
542-
row = r
543-
col = c
544-
val = v
545-
trip_ptr = new CxxEigenTriplet(row, col, val)
546-
trips.push_back(dereference(trip_ptr))
547-
return trips
548-
549530
cdef CxxEigenTriplet get_triplet(row, col, val):
550531
cdef CxxEigenTriplet* trip_ptr = new CxxEigenTriplet(row, col, val)
551532
return dereference(trip_ptr)
552533

553-
cdef triplets_to_python(vector[CxxEigenTriplet]& triplets):
554-
values = []
555-
cdef size_t row
556-
cdef size_t col
557-
cdef double val
558-
for t in triplets:
559-
row = t.row()
560-
col = t.col()
561-
val = t.value()
562-
values.append((row, col, val))
563-
return values
564-
565534
def _py_to_any_to_py(dd):
566535
# used for internal testing purposes only
567536
cdef string name = stringify("test")

interfaces/cython/cantera/delegator.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ from libc.stdlib cimport malloc
99
from libc.string cimport strcpy
1010

1111
from ._utils import CanteraError
12-
from ._utils cimport stringify, pystr, anymap_to_py, py_to_anymap, triplets_to_python, python_to_triplets, get_triplet
12+
from ._utils cimport stringify, pystr, anymap_to_py, py_to_anymap, get_triplet
1313
from .units cimport Units, UnitStack
1414
# from .reaction import ExtensibleRate, ExtensibleRateData
1515
from .reaction cimport (ExtensibleRate, ExtensibleRateData, CxxReaction,

src/zeroD/Reactor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ void Reactor::buildFlowJacobian(vector<Eigen::Triplet<double>>& jacVector)
684684
m_outlet[i]->buildReactorJacobian(this, jacVector);
685685
}
686686

687-
for (size_t i = 0; i <m_outlet.size(); i++) {
687+
for (size_t i = 0; i <m_inlet.size(); i++) {
688688
m_inlet[i]->buildReactorJacobian(this, jacVector);
689689
}
690690
}

src/zeroD/ReactorNet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ void ReactorNet::buildJacobian(vector<Eigen::Triplet<double>>& jacVector)
803803
}
804804
}
805805
// flow devices
806-
if (m_jac_skip_flow_devices) {
806+
if (!m_jac_skip_flow_devices) {
807807
// outlets
808808
for (size_t i = 0; i < r->nOutlets(); i++) {
809809
r->outlet(i).buildNetworkJacobian(jacVector);

test/python/test_reactor.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,61 @@ def test_finite_difference_jacobian(self):
182182
if name in constant:
183183
assert all(J[i, species_start:] == 0), (i, name)
184184

185+
def test_network_finite_difference_jacobian(self):
186+
self.make_reactors(T1=900, P1=101325, X1="H2:0.4, O2:0.4, N2:0.2")
187+
k1H2 = self.gas1.species_index("H2")
188+
k2H2 = self.gas1.species_index("H2")
189+
while self.r1.thermo.X[k1H2] > 0.3 or self.r2.thermo.X[k2H2] > 0.3:
190+
self.net.step()
191+
192+
J = self.net.finite_difference_jacobian
193+
assert J.shape == (self.net.n_vars, self.net.n_vars)
194+
195+
# state variables that should be constant, depending on reactor type
196+
constant = {"mass", "volume", "int_energy", "enthalpy", "pressure"}
197+
variable = {"temperature"}
198+
for i in range(3):
199+
name = self.r1.component_name(i)
200+
if name in constant:
201+
assert all(J[i,:] == 0), (i, name)
202+
elif name in variable:
203+
assert any(J[i,:] != 0)
204+
# check in second reactor
205+
name = self.r2.component_name(i)
206+
if name in constant:
207+
assert all(J[i + self.r1.n_vars,:] == 0), (i, name)
208+
elif name in variable:
209+
assert any(J[i + self.r1.n_vars,:] != 0)
210+
211+
# Disabling energy equation should zero these terms
212+
self.r1.energy_enabled = False
213+
self.r2.energy_enabled = False
214+
J = self.net.finite_difference_jacobian
215+
for i in range(3):
216+
name = self.r1.component_name(i)
217+
if name == "temperature":
218+
assert all(J[i,:] == 0)
219+
name = self.r2.component_name(i)
220+
if name == "temperature":
221+
assert all(J[i + self.r1.n_vars,:] == 0)
222+
223+
# Disabling species equations should zero these terms
224+
self.r1.energy_enabled = True
225+
self.r1.chemistry_enabled = False
226+
self.r2.energy_enabled = True
227+
self.r2.chemistry_enabled = False
228+
J = self.net.finite_difference_jacobian
229+
constant = set(self.gas1.species_names + self.gas2.species_names)
230+
r1_species_start = self.r1.component_index(self.gas1.species_name(0))
231+
r2_species_start = self.r2.component_index(self.gas2.species_name(0))
232+
for i in range(self.r1.n_vars):
233+
name = self.r1.component_name(i)
234+
if name in constant:
235+
assert all(J[i, r1_species_start:] == 0), (i, name)
236+
name = self.r2.component_name(i)
237+
if name in constant:
238+
assert all(J[i + self.r1.n_vars, (r2_species_start + self.r1.n_vars):] == 0), (i, name)
239+
185240
def test_timestepping(self):
186241
self.make_reactors()
187242

@@ -1429,14 +1484,26 @@ def create_reactors(self, **kwargs):
14291484
self.precon = ct.AdaptivePreconditioner()
14301485
self.net2.preconditioner = self.precon
14311486
self.net2.derivative_settings = {"skip-third-bodies":True, "skip-falloff":True,
1432-
"skip-coverage-dependence":True}
1487+
"skip-coverage-dependence":True, "skip-flow-devices": True}
14331488

14341489
def test_get_solver_type(self):
14351490
self.create_reactors()
14361491
assert self.precon.side == "right"
14371492
self.net2.initialize()
14381493
assert self.net2.linear_solver_type == "GMRES"
14391494

1495+
def test_mass_flow_jacobian(self):
1496+
self.create_reactors(add_mdot=True)
1497+
# reset derivative settings
1498+
self.net2.derivative_settings = {"skip-third-bodies":True, "skip-falloff":True,
1499+
"skip-coverage-dependence":True, "skip-flow-devices": False}
1500+
1501+
with pytest.raises(NotImplementedError, match="MassFlowController::buildReactorJacobian"):
1502+
J = self.net2.jacobian
1503+
1504+
with pytest.raises(NotImplementedError, match="MassFlowController::buildReactorJacobian"):
1505+
J = self.r2.jacobian
1506+
14401507
def test_heat_transfer_network(self):
14411508
# create first reactor
14421509
gas1 = ct.Solution("h2o2.yaml", "ohmech")

test/zeroD/test_zeroD.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,12 @@ TEST(JacobianTests, test_wall_jacobian_build)
358358
EXPECT_LT(it.col(), reactor2.neq());
359359
}
360360
}
361+
// check that switch works
362+
wallJac.clear();
363+
w.jacobianCalculated();
364+
w.buildNetworkJacobian(wallJac);
365+
EXPECT_EQ(wallJac.size(), 0);
366+
w.jacobianNotCalculated();
361367
// build jac for network terms
362368
wallJac.clear();
363369
w.buildNetworkJacobian(wallJac);
@@ -382,6 +388,37 @@ TEST(JacobianTests, test_wall_jacobian_build)
382388
}
383389
}
384390

391+
TEST(JacobianTests, test_flow_jacobian_build)
392+
{
393+
// create reservoir reactor
394+
auto sol = newSolution("h2o2.yaml");
395+
sol->thermo()->setState_TPY(1000.0, OneAtm, "O2:1.0");
396+
Reservoir res;
397+
res.insert(sol);
398+
// create reactor
399+
IdealGasConstPressureMoleReactor reactor;
400+
reactor.insert(sol);
401+
reactor.setInitialVolume(1.0);
402+
// create the flow device
403+
MassFlowController mfc;
404+
mfc.install(res, reactor);
405+
mfc.setMassFlowCoeff(1.0);
406+
// setup reactor network and integrate
407+
ReactorNet network;
408+
network.addReactor(reactor);
409+
network.initialize();
410+
// manually get wall jacobian elements
411+
vector<Eigen::Triplet<double>> flowJac;
412+
// expect errors from building jacobians
413+
EXPECT_THROW(mfc.buildReactorJacobian(&reactor, flowJac), NotImplementedError);
414+
// check the jacobian calculated flag and throw/catch errors accordingly
415+
mfc.jacobianCalculated();
416+
mfc.buildNetworkJacobian(flowJac);
417+
EXPECT_EQ(flowJac.size(), 0);
418+
mfc.jacobianNotCalculated();
419+
EXPECT_THROW(mfc.buildNetworkJacobian(flowJac), NotImplementedError);
420+
}
421+
385422
int main(int argc, char** argv)
386423
{
387424
printf("Running main() from test_zeroD.cpp\n");

0 commit comments

Comments
 (0)