[Reactor] Fix segfaults in updateMassFlowRate due to unset parameters

The downstream and upstream Reactors, the "master" flow controller, and the
coefficient arrays were being read without checking that they had been
initialized.

Fixes #278.
This commit is contained in:
Ray Speth 2015-06-18 12:18:59 -04:00
parent cd545af5ed
commit c0fa589b8c
3 changed files with 32 additions and 4 deletions

View file

@ -54,7 +54,7 @@ public:
}
virtual bool ready() {
return FlowDevice::ready() && m_master != 0;
return FlowDevice::ready() && m_master != 0 && m_coeffs.size() == 1;
}
void setMaster(FlowDevice* master) {
@ -62,6 +62,10 @@ public:
}
virtual void updateMassFlowRate(doublereal time) {
if (!ready()) {
throw CanteraError("PressureController::updateMassFlowRate",
"Device is not ready; some parameters have not been set.");
}
doublereal master_mdot = m_master->massFlowRate(time);
m_mdot = master_mdot + m_coeffs[0]*(in().pressure() -
out().pressure());
@ -72,7 +76,8 @@ protected:
FlowDevice* m_master;
};
//! Supply a mass flow rate that is a function of the pressure drop across the valve.
//! Supply a mass flow rate that is a function of the pressure drop across the
//! valve.
/*!
* The default behavior is a linearly proportional to the pressure difference.
* Note that real valves do not have this behavior, so this class does not
@ -86,11 +91,15 @@ public:
}
virtual bool ready() {
return FlowDevice::ready() && m_coeffs.size() >= 1;
return FlowDevice::ready() && (m_coeffs.size() == 1 || m_func);
}
/// Compute the currrent mass flow rate, based on the pressure difference.
virtual void updateMassFlowRate(doublereal time) {
if (!ready()) {
throw CanteraError("Valve::updateMassFlowRate",
"Device is not ready; some parameters have not been set.");
}
double delta_P = in().pressure() - out().pressure();
if (m_func) {
m_mdot = m_func->eval(delta_P);

View file

@ -517,7 +517,7 @@ cdef extern from "cantera/zeroD/Wall.h":
cdef extern from "cantera/zeroD/flowControllers.h":
cdef cppclass CxxFlowDevice "Cantera::FlowDevice":
CxxFlowDevice()
double massFlowRate(double)
double massFlowRate(double) except +
cbool install(CxxReactorBase&, CxxReactorBase&)
void setFunction(CxxFunc1*)
void setParameters(int, double*)

View file

@ -457,6 +457,25 @@ class TestReactor(utilities.CanteraTest):
dP = self.r1.thermo.P - outlet_reservoir.thermo.P
self.assertNear(mdot(t) + 1e-5 * dP, pc.mdot(t))
def test_pressure_controller_errors(self):
self.make_reactors()
res = ct.Reservoir(self.gas1)
mfc = ct.MassFlowController(res, self.r1, mdot=0.6)
p = ct.PressureController(self.r1, self.r2, master=mfc, K=0.5)
with self.assertRaises(RuntimeError):
p = ct.PressureController(self.r1, self.r2, K=0.5)
p.mdot(0.0)
with self.assertRaises(RuntimeError):
p = ct.PressureController(self.r1, self.r2, master=mfc)
p.mdot(0.0)
with self.assertRaises(RuntimeError):
p = ct.PressureController(self.r1, self.r2)
p.mdot(0.0)
def test_set_initial_time(self):
self.make_reactors(P1=10*ct.one_atm, X1='AR:1.0', X2='O2:1.0')
self.net.rtol = 1e-12