Skip to content

Commit 205567a

Browse files
Build jacobian structure defined for walls and flow devices
1 parent d2985a2 commit 205567a

16 files changed

+508
-10
lines changed

include/cantera/zeroD/FlowDevice.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "cantera/base/ct_defs.h"
1010
#include "cantera/base/global.h"
1111
#include "cantera/base/ctexceptions.h"
12+
#include "cantera/numerics/eigen_sparse.h"
1213

1314
namespace Cantera
1415
{
@@ -114,7 +115,47 @@ class FlowDevice
114115
m_time = time;
115116
}
116117

118+
/*! Build the Jacobian terms specific to the flow device for the given connected reactor.
119+
* @param r a pointer to the calling reactor
120+
* @param jacVector a vector of triplets to be added to the jacobian for the reactor
121+
* @warning This function is an experimental part of the %Cantera API and may be changed
122+
* or removed without notice.
123+
* @since New in %Cantera 3.0.
124+
*/
125+
virtual void buildReactorJacobian(ReactorBase* r, vector<Eigen::Triplet<double>>& jacVector) {
126+
throw NotImplementedError(type() + "::buildReactorJacobian");
127+
}
128+
129+
/*! Build the Jacobian terms specific to the flow device for the network. These terms
130+
* will be adjusted to the networks indexing system outside of the reactor.
131+
* @param jacVector a vector of triplets to be added to the jacobian for the reactor
132+
* @warning This function is an experimental part of the %Cantera API and may be changed
133+
* or removed without notice.
134+
* @since New in %Cantera 3.0.
135+
*/
136+
virtual void buildNetworkJacobian(vector<Eigen::Triplet<double>>& jacVector) {
137+
throw NotImplementedError(type() + "::buildNetworkJacobian");
138+
}
139+
140+
/*! Specify the jacobian terms have been calculated and should not be recalculated.
141+
* @warning This function is an experimental part of the %Cantera API and may be changed
142+
* or removed without notice.
143+
* @since New in %Cantera 3.0.
144+
*/
145+
void jacobianCalculated() { m_jac_calculated = true; };
146+
147+
/*! Specify that jacobian terms have not been calculated and should be recalculated.
148+
* @warning This function is an experimental part of the %Cantera API and may be changed
149+
* or removed without notice.
150+
* @since New in %Cantera 3.0.
151+
*/
152+
void jacobianNotCalculated() { m_jac_calculated = false; };
153+
117154
protected:
155+
//! a variable to switch on and off so calculations are not doubled by the calling
156+
//! reactor or network
157+
bool m_jac_calculated = false;
158+
118159
double m_mdot = Undef;
119160

120161
//! Function set by setPressureFunction; used by updateMassFlowRate

include/cantera/zeroD/IdealGasConstPressureMoleReactor.h

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

5050
bool preconditionerSupported() const override { return true; };
5151

52+
double temperatureDerivative() override { return 1; };
53+
54+
double temperatureRadiationDerivative() override {
55+
return 4 * std::pow(temperature(), 3);
56+
}
57+
58+
double moleDerivative(size_t index) override;
59+
60+
double moleRadiationDerivative(size_t index) override;
61+
62+
size_t speciesOffset() const override { return m_sidx; };
63+
5264
protected:
5365
vector<double> m_hk; //!< Species molar enthalpies
5466
};

include/cantera/zeroD/IdealGasMoleReactor.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ 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+
54+
double moleDerivative(size_t index) override;
55+
56+
double moleRadiationDerivative(size_t index) override;
57+
58+
size_t speciesOffset() const override { return m_sidx; };
59+
4860
protected:
4961
vector<double> m_uk; //!< Species molar internal energies
5062
};

include/cantera/zeroD/MoleReactor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define CT_MOLEREACTOR_H
88

99
#include "Reactor.h"
10+
#include "cantera/zeroD/Wall.h"
1011

1112
namespace Cantera
1213
{
@@ -38,6 +39,8 @@ class MoleReactor : public Reactor
3839

3940
string componentName(size_t k) override;
4041

42+
size_t energyIndex() const override { return m_eidx; };
43+
4144
protected:
4245
//! For each surface in the reactor, update vector of triplets with all relevant
4346
//! surface jacobian derivatives of species with respect to species
@@ -60,6 +63,9 @@ class MoleReactor : public Reactor
6063

6164
//! const value for the species start index
6265
const size_t m_sidx = 2;
66+
67+
//! index of state variable associated with energy
68+
const size_t m_eidx = 0;
6369
};
6470

6571
}

include/cantera/zeroD/Reactor.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,27 @@ class Reactor : public ReactorBase
232232
throw NotImplementedError(type() + "::buildJacobian");
233233
}
234234

235-
// virtual void jacobian()
235+
//! Calculate the Jacobian of a Reactor specialization for wall contributions.
236+
//! @param jacVector vector where jacobian triplets are added
237+
//! @warning Depending on the particular implementation, this may return an
238+
//! approximate Jacobian intended only for use in forming a preconditioner for
239+
//! iterative solvers.
240+
//! @ingroup derivGroup
241+
//!
242+
//! @warning This method is an experimental part of the %Cantera
243+
//! API and may be changed or removed without notice.
244+
virtual void buildWallJacobian(vector<Eigen::Triplet<double>>& jacVector);
245+
246+
//! Calculate flow contributions to the Jacobian of a Reactor specialization.
247+
//! @param jac_vector vector where jacobian triplets are added
248+
//! @warning Depending on the particular implementation, this may return an
249+
//! approximate Jacobian intended only for use in forming a preconditioner for
250+
//! iterative solvers.
251+
//! @ingroup derivGroup
252+
//!
253+
//! @warning This method is an experimental part of the %Cantera
254+
//! API and may be changed or removed without notice.
255+
virtual void buildFlowJacobian(vector<Eigen::Triplet<double>>& jacVector);
236256

237257
//! Calculate the reactor-specific Jacobian using a finite difference method.
238258
//!
@@ -325,6 +345,10 @@ class Reactor : public ReactorBase
325345

326346
//! Vector of triplets representing the jacobian
327347
vector<Eigen::Triplet<double>> m_jac_trips;
348+
//! Boolean to skip walls in jacobian
349+
bool m_jac_skip_walls = false;
350+
//! Boolean to skip flow devices in jacobian
351+
bool m_jac_skip_flow_devices = false;
328352
};
329353
}
330354

include/cantera/zeroD/ReactorBase.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,68 @@ class ReactorBase
248248
//! Set the ReactorNet that this reactor belongs to.
249249
void setNetwork(ReactorNet* net);
250250

251+
/*! Calculate the derivative of temperature with respect to the temperature in the
252+
* heat transfer equation based on the reactor specific equation of state.
253+
* This function should also transform the state of the derivative to that
254+
* appropriate for the jacobian's state/
255+
* @warning This function is an experimental part of the %Cantera API and may be changed
256+
* or removed without notice.
257+
* @since New in %Cantera 3.0.
258+
*/
259+
virtual double temperatureDerivative() {
260+
throw NotImplementedError("Reactor::temperatureDerivative");
261+
}
262+
263+
/*! Calculate the derivative of temperature with respect to the temperature in the
264+
* heat transfer radiation equation based on the reactor specific equation of state.
265+
* This function should also transform the state of the derivative to that
266+
* appropriate for the jacobian's state/
267+
* @warning This function is an experimental part of the %Cantera API and may be changed
268+
* or removed without notice.
269+
* @since New in %Cantera 3.0.
270+
*/
271+
virtual double temperatureRadiationDerivative() {
272+
throw NotImplementedError("Reactor::temperatureRadiationDerivative");
273+
}
274+
275+
/*! Calculate the derivative of T with respect to the ith species in the heat
276+
* transfer equation based on the reactor specific equation of state.
277+
* @param index index of the species the derivative is with respect too
278+
* @warning This function is an experimental part of the %Cantera API and may be changed
279+
* or removed without notice.
280+
* @since New in %Cantera 3.0.
281+
*/
282+
virtual double moleDerivative(size_t index) {
283+
throw NotImplementedError("Reactor::moleDerivative");
284+
}
285+
286+
/*! Calculate the derivative of T with respect to the ith species in the heat
287+
* transfer radiation equation based on the reactor specific equation of state.
288+
* @param index index of the species the derivative is with respect too
289+
* @warning This function is an experimental part of the %Cantera API and may be changed
290+
* or removed without notice.
291+
* @since New in %Cantera 3.0.
292+
*/
293+
virtual double moleRadiationDerivative(size_t index) {
294+
throw NotImplementedError("Reactor::moleRadiationDerivative");
295+
}
296+
297+
//! Return the index associated with energy of the system
298+
virtual size_t energyIndex() const { return m_eidx; };
299+
300+
//! Return the offset between species and state variables
301+
virtual size_t speciesOffset() const { return m_sidx; };
302+
251303
protected:
252304
//! Number of homogeneous species in the mixture
253305
size_t m_nsp = 0;
254306

307+
//! species offset in the state vector
308+
const size_t m_sidx = 3;
309+
310+
//! index of state variable associated with energy
311+
const size_t m_eidx = 1;
312+
255313
ThermoPhase* m_thermo = nullptr;
256314
double m_vol = 1.0; //!< Current volume of the reactor [m^3]
257315
double m_enthalpy = 0.0; //!< Current specific enthalpy of the reactor [J/kg]

include/cantera/zeroD/ReactorNet.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,20 @@ class ReactorNet : public FuncEval
236236
//! reactor network.
237237
size_t globalComponentIndex(const string& component, size_t reactor=0);
238238

239+
//! Return the index corresponding to the start of the reactor specific state
240+
//! vector in the reactor with index *reactor* in the global state vector for the
241+
//! reactor network.
242+
size_t globalStartIndex(Reactor* curr_reactor) {
243+
for (size_t i = 0; i < m_reactors.size(); i++) {
244+
if (curr_reactor == m_reactors[i]) {
245+
return m_start[i];
246+
}
247+
}
248+
throw CanteraError("ReactorNet::globalStartIndex: ",
249+
curr_reactor->name(), " not found in network.");
250+
return npos;
251+
}
252+
239253
//! Return the name of the i-th component of the global state vector. The
240254
//! name returned includes both the name of the reactor and the specific
241255
//! component, for example `'reactor1: CH4'`.
@@ -396,6 +410,10 @@ class ReactorNet : public FuncEval
396410
//! "left hand side" of each governing equation
397411
vector<double> m_LHS;
398412
vector<double> m_RHS;
413+
414+
//! derivative settings
415+
bool m_jac_skip_walls = false;
416+
bool m_jac_skip_flow_devices = false;
399417
};
400418
}
401419

include/cantera/zeroD/Wall.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "cantera/base/ctexceptions.h"
1010
#include "cantera/zeroD/ReactorBase.h"
11+
#include "cantera/numerics/eigen_sparse.h"
1112

1213
namespace Cantera
1314
{
@@ -115,6 +116,46 @@ class WallBase
115116
m_time = time;
116117
}
117118

119+
/*! Build the Jacobian terms specific to the flow device for the given connected reactor.
120+
* @param r a pointer to the calling reactor
121+
* @param jacVector a vector of triplets to be added to the jacobian for the reactor
122+
* @warning This function is an experimental part of the %Cantera API and may be
123+
* changed
124+
* or removed without notice.
125+
* @since New in %Cantera 3.0.
126+
*/
127+
virtual void buildReactorJacobian(ReactorBase* r, vector<Eigen::Triplet<double>>& jacVector) {
128+
throw NotImplementedError("WallBase::buildReactorJacobian");
129+
}
130+
131+
/*! Build the Jacobian terms specific to the flow device for the network. These terms
132+
* will be adjusted to the networks indexing system outside of the reactor.
133+
* @param jacVector a vector of triplets to be added to the jacobian for the reactor
134+
* @warning This function is an experimental part of the %Cantera API and may be
135+
* changed
136+
* or removed without notice.
137+
* @since New in %Cantera 3.0.
138+
*/
139+
virtual void buildNetworkJacobian(vector<Eigen::Triplet<double>>& jacVector) {
140+
throw NotImplementedError("WallBase::buildNetworkJacobian");
141+
}
142+
143+
/*! Specify the jacobian terms have been calculated and should not be recalculated.
144+
* @warning This function is an experimental part of the %Cantera API and may be
145+
* changed
146+
* or removed without notice.
147+
* @since New in %Cantera 3.0.
148+
*/
149+
void jacobianCalculated() { m_jac_calculated = true; };
150+
151+
/*! Specify that jacobian terms have not been calculated and should be recalculated.
152+
* @warning This function is an experimental part of the %Cantera API and may be
153+
* changed
154+
* or removed without notice.
155+
* @since New in %Cantera 3.0.
156+
*/
157+
void jacobianNotCalculated() { m_jac_calculated = false; };
158+
118159
protected:
119160
ReactorBase* m_left = nullptr;
120161
ReactorBase* m_right = nullptr;
@@ -123,6 +164,10 @@ class WallBase
123164
double m_time = 0.0;
124165

125166
double m_area = 1.0;
167+
168+
//! a variable to switch on and off so calculations are not doubled by the calling
169+
//! reactor or network
170+
bool m_jac_calculated = false;
126171
};
127172

128173
//! Represents a wall between between two ReactorBase objects.
@@ -255,6 +300,10 @@ class Wall : public WallBase
255300
return m_k;
256301
}
257302

303+
virtual void buildReactorJacobian(ReactorBase* r, vector<Eigen::Triplet<double>>& jacVector) override;
304+
305+
virtual void buildNetworkJacobian(vector<Eigen::Triplet<double>>& jacVector) override;
306+
258307
protected:
259308

260309
//! expansion rate coefficient

interfaces/cython/cantera/reactor.pxd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ cdef extern from "cantera/zerodim.h" namespace "Cantera":
202202
void setPreconditioner(shared_ptr[CxxPreconditionerBase] preconditioner)
203203
void setDerivativeSettings(CxxAnyMap&)
204204
CxxAnyMap solverStats() except +translate_exception
205+
CxxSparseMatrix jacobian() except +translate_exception
206+
CxxSparseMatrix finiteDifferenceJacobian() except +translate_exception
205207

206208
cdef extern from "cantera/zeroD/ReactorDelegator.h" namespace "Cantera":
207209
cdef cppclass CxxReactorAccessor "Cantera::ReactorAccessor":

interfaces/cython/cantera/reactor.pyx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,3 +1797,29 @@ cdef class ReactorNet:
17971797
"""
17981798
def __set__(self, settings):
17991799
self.net.setDerivativeSettings(py_to_anymap(settings))
1800+
1801+
property jacobian:
1802+
"""
1803+
Get the system Jacobian or an approximation thereof.
1804+
1805+
**Warning**: Depending on the particular implementation, this may return an
1806+
approximate Jacobian intended only for use in forming a preconditioner for
1807+
iterative solvers, excluding terms that would generate a fully-dense Jacobian.
1808+
1809+
**Warning**: This method is an experimental part of the Cantera API and may be
1810+
changed or removed without notice.
1811+
"""
1812+
def __get__(self):
1813+
return get_from_sparse(self.net.jacobian(), self.n_vars, self.n_vars)
1814+
1815+
property finite_difference_jacobian:
1816+
"""
1817+
Get the system Jacobian, calculated using a finite difference method.
1818+
1819+
**Warning:** this property is an experimental part of the Cantera API and
1820+
may be changed or removed without notice.
1821+
"""
1822+
def __get__(self):
1823+
return get_from_sparse(self.net.finiteDifferenceJacobian(),
1824+
self.n_vars, self.n_vars)
1825+

0 commit comments

Comments
 (0)