Cantera
Loading...
Searching...
No Matches
FlowDevice.cpp
Go to the documentation of this file.
1//! @file FlowDevice.cpp
2
3// This file is part of Cantera. See License.txt in the top-level directory or
4// at https://cantera.org/license.txt for license and copyright information.
5
10#include <limits>
11
12namespace Cantera
13{
14
15FlowDevice::FlowDevice(shared_ptr<ReactorBase> r0, shared_ptr<ReactorBase> r1,
16 const string& name) : ConnectorNode(r0, r1, name)
17{
18 if (!m_nodes.first || !m_nodes.second) {
19 throw CanteraError("FlowDevice::FlowDevice",
20 "Reactors must be provided to FlowDevice constructor.");
21 }
22 m_in = r0.get();
23 m_out = r1.get();
24 m_in->addOutlet(*this);
25 m_out->addInlet(*this);
26
27 // construct adapters between inlet and outlet species
28 const ThermoPhase& mixin = *m_in->phase()->thermo();
29 const ThermoPhase& mixout = *m_out->phase()->thermo();
30
31 m_nspin = mixin.nSpecies();
32 m_nspout = mixout.nSpecies();
33 string nm;
34 size_t ki, ko;
35 for (ki = 0; ki < m_nspin; ki++) {
36 nm = mixin.speciesName(ki);
37 ko = mixout.speciesIndex(nm, false);
38 m_in2out.push_back(ko);
39 }
40 for (ko = 0; ko < m_nspout; ko++) {
41 nm = mixout.speciesName(ko);
42 ki = mixin.speciesIndex(nm, false);
43 m_out2in.push_back(ki);
44 }
45}
46
48{
49 double delta_P = in().pressure() - out().pressure();
50 if (m_pfunc) {
51 return m_pfunc->eval(delta_P);
52 }
53 return delta_P;
54}
55
57{
58 if (m_tfunc) {
59 return m_tfunc->eval(m_time);
60 }
61 return 1.;
62}
63
65{
66 if (k >= m_nspout) {
67 return 0.0;
68 }
69 size_t ki = m_out2in[k];
70 if (ki == npos) {
71 return 0.0;
72 }
73 return m_mdot * m_in->massFraction(ki);
74}
75
76void FlowDevice::addMassFlowRateJacobian(SparseTriplets& trips, size_t row,
77 double coeff, bool includePressureSpecies)
78{
79 double alpha = massFlowRate_ddP();
80 if (alpha == 0.0) {
81 return;
82 }
83 // Chain rule for mdot(P_in - P_out): the flow device supplies dmdot/dDeltaP,
84 // while reactors supply dP/dy for their state variables.
85 m_in->addPressureJacobian(trips, row, coeff * alpha, includePressureSpecies);
86 m_out->addPressureJacobian(trips, row, -coeff * alpha, includePressureSpecies);
87}
88
90 SparseTriplets& trips, size_t row, size_t k, double coeff,
91 bool includeComposition, bool includePressureSpecies)
92{
93 if (k >= m_nspout) {
94 return;
95 }
96 size_t ki = m_out2in[k];
97 if (ki == npos) {
98 return;
99 }
100 double Yin = m_in->massFraction(ki);
101 // FlowDevice transports species as mdot * Y_in. Mole reactors store n_k, so the
102 // upstream reactor converts dY_in/dy to dY_in/dn_j as needed.
103 addMassFlowRateJacobian(trips, row, coeff * Yin, includePressureSpecies);
104 if (includeComposition && m_mdot != 0.0) {
105 m_in->addSpeciesMassFractionJacobian(trips, row, ki, coeff * m_mdot);
106 }
107}
108
110{
111 return m_in->enthalpy_mass();
112}
113
114double FlowDevice::pressureFunction_ddP(double deltaP) const
115{
116 if (!m_pfunc) {
117 return 1.0;
118 }
119 try {
120 return m_pfunc->derivative()->eval(deltaP);
121 } catch (CanteraError&) {
122 // Fall back to central finite difference for functions without analytic
123 // derivatives (for example, Tabulated1 with nearest-neighbor interpolation,
124 // or user-defined Func1 subclasses).
125 double eps = std::sqrt(std::numeric_limits<double>::epsilon())
126 * std::max(1.0, std::abs(deltaP));
127 return (m_pfunc->eval(deltaP + eps) - m_pfunc->eval(deltaP - eps))
128 / (2.0 * eps);
129 }
130}
131
132void FlowDevice::addInletEnthalpyJacobian(SparseTriplets& trips, size_t row,
133 double coeff, bool includeComposition)
134{
135 if (m_mdot != 0.0) {
136 m_in->addEnthalpyJacobian(trips, row, coeff * m_mdot, includeComposition);
137 }
138}
139
140}
Header file for class ThermoPhase, the base class for phases with thermodynamic properties,...
Base class for exceptions thrown by Cantera classes.
Base class for walls and flow devices connecting reactors.
double outletSpeciesMassFlowRate(size_t k)
Mass flow rate (kg/s) of outlet species k.
void addInletEnthalpyJacobian(SparseTriplets &trips, size_t row, double coeff, bool includeComposition=true)
Add Jacobian terms for the inlet enthalpy dependence on upstream state.
virtual void addMassFlowRateJacobian(SparseTriplets &trips, size_t row, double coeff, bool includePressureSpecies=true)
Add Jacobian terms proportional to derivatives of the mass flow rate.
double m_time
Current reactor network time.
Definition FlowDevice.h:227
double enthalpy_mass()
specific enthalpy
ReactorBase & in() const
Return a reference to the upstream reactor.
Definition FlowDevice.h:150
void addOutletSpeciesMassFlowRateJacobian(SparseTriplets &trips, size_t row, size_t k, double coeff, bool includeComposition=true, bool includePressureSpecies=true)
Add Jacobian terms proportional to derivatives of outletSpeciesMassFlowRate(k).
const ReactorBase & out() const
Return a const reference to the downstream reactor.
Definition FlowDevice.h:155
double evalTimeFunction()
Return current value of the time function.
virtual double massFlowRate_ddP() const
Derivative of mass flow rate with respect to pressure difference.
Definition FlowDevice.h:61
shared_ptr< Func1 > m_tfunc
Function set by setTimeFunction; used by updateMassFlowRate.
Definition FlowDevice.h:221
double evalPressureFunction()
Return current value of the pressure function.
shared_ptr< Func1 > m_pfunc
Function set by setPressureFunction; used by updateMassFlowRate.
Definition FlowDevice.h:218
double pressureFunction_ddP(double deltaP) const
Return the derivative of the pressure function at deltaP.
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
const size_t npos
index returned by functions to indicate "no position"
Definition ct_defs.h:183