diff --git a/include/cantera/numerics/CVodesIntegrator.h b/include/cantera/numerics/CVodesIntegrator.h index 6c3b27cf4..68907df7d 100644 --- a/include/cantera/numerics/CVodesIntegrator.h +++ b/include/cantera/numerics/CVodesIntegrator.h @@ -70,6 +70,7 @@ public: virtual void setMaxStepSize(double hmax); virtual void setMinStepSize(double hmin); virtual void setMaxSteps(int nmax); + virtual void setMaxErrTestFails(int n); virtual void setBandwidth(int N_Upper, int N_Lower) { m_mupper = N_Upper; m_mlower = N_Lower; @@ -111,6 +112,7 @@ private: size_t m_nabs; double m_hmax, m_hmin; int m_maxsteps; + int m_maxErrTestFails; FuncData* m_fdata; N_Vector* m_yS; size_t m_np; diff --git a/include/cantera/numerics/Integrator.h b/include/cantera/numerics/Integrator.h index 3cb79dd05..a6c810785 100644 --- a/include/cantera/numerics/Integrator.h +++ b/include/cantera/numerics/Integrator.h @@ -184,6 +184,11 @@ public: warn("setMinStepSize"); } + //! Set the maximum permissible number of error test failures + virtual void setMaxErrTestFails(int n) { + warn("setMaxErrTestFails"); + } + virtual void setMaxSteps(int nmax) { warn("setMaxStep"); } diff --git a/include/cantera/zeroD/ReactorNet.h b/include/cantera/zeroD/ReactorNet.h index bc6a8989f..be47162da 100644 --- a/include/cantera/zeroD/ReactorNet.h +++ b/include/cantera/zeroD/ReactorNet.h @@ -46,6 +46,13 @@ public: m_init = false; } + //! Set the maximum number of error test failures permitted by the CVODES + //! integrator in a single time step. + void setMaxErrTestFails(int nmax) { + m_maxErrTestFails = nmax; + m_init = false; + } + void setTolerances(doublereal rtol, doublereal atol) { if (rtol >= 0.0) { m_rtol = rtol; @@ -189,6 +196,7 @@ protected: doublereal m_rtol, m_rtolsens; doublereal m_atols, m_atolsens; doublereal m_maxstep; + int m_maxErrTestFails; bool m_verbose; size_t m_ntotpar; std::vector m_nparams; diff --git a/interfaces/cython/cantera/_cantera.pxd b/interfaces/cython/cantera/_cantera.pxd index 9dcbfdb3b..3a9406706 100644 --- a/interfaces/cython/cantera/_cantera.pxd +++ b/interfaces/cython/cantera/_cantera.pxd @@ -322,6 +322,7 @@ cdef extern from "cantera/zeroD/ReactorNet.h": double rtol() double atol() void setMaxTimeStep(double) + void setMaxErrTestFails(int) cbool verbose() void setVerbose(cbool) size_t neq() diff --git a/interfaces/cython/cantera/reactor.pyx b/interfaces/cython/cantera/reactor.pyx index dbc28de3f..75199579a 100644 --- a/interfaces/cython/cantera/reactor.pyx +++ b/interfaces/cython/cantera/reactor.pyx @@ -729,6 +729,14 @@ cdef class ReactorNet: """ self.net.setMaxTimeStep(t) + property max_err_test_fails: + """ + The maximum number of error test failures permitted by the CVODES + integrator in a single time step. + """ + def __set__(self, n): + self.net.setMaxErrTestFails(n) + property rtol: """ The relative error tolerance used while integrating the reactor diff --git a/src/numerics/CVodeInt.h b/src/numerics/CVodeInt.h index 01c62cfda..dea0a8608 100644 --- a/src/numerics/CVodeInt.h +++ b/src/numerics/CVodeInt.h @@ -60,6 +60,7 @@ public: virtual void setMaxStepSize(double hmax); virtual void setMinStepSize(double hmin); virtual void setMaxSteps(int nmax); + virtual void setMaxErrTestFails(int nmax) {} private: diff --git a/src/numerics/CVodesIntegrator.cpp b/src/numerics/CVodesIntegrator.cpp index 3e3002b5b..16e0dbb55 100644 --- a/src/numerics/CVodesIntegrator.cpp +++ b/src/numerics/CVodesIntegrator.cpp @@ -129,6 +129,7 @@ CVodesIntegrator::CVodesIntegrator() : m_hmax(0.0), m_hmin(0.0), m_maxsteps(20000), + m_maxErrTestFails(0), m_fdata(0), m_np(0), m_mupper(0), m_mlower(0), @@ -239,6 +240,14 @@ void CVodesIntegrator::setMaxSteps(int nmax) } } +void CVodesIntegrator::setMaxErrTestFails(int n) +{ + m_maxErrTestFails = n; + if (m_cvode_mem) { + CVodeSetMaxErrTestFails(m_cvode_mem, n); + } +} + void CVodesIntegrator::setIterator(IterType t) { if (t == Newton_Iter) { @@ -467,6 +476,9 @@ void CVodesIntegrator::applyOptions() if (m_hmin > 0) { CVodeSetMinStep(m_cvode_mem, m_hmin); } + if (m_maxErrTestFails > 0) { + CVodeSetMaxErrTestFails(m_cvode_mem, m_maxErrTestFails); + } } void CVodesIntegrator::integrate(double tout) diff --git a/src/zeroD/ReactorNet.cpp b/src/zeroD/ReactorNet.cpp index c08cc9a23..19af2a929 100644 --- a/src/zeroD/ReactorNet.cpp +++ b/src/zeroD/ReactorNet.cpp @@ -14,7 +14,7 @@ ReactorNet::ReactorNet() : Cantera::FuncEval(), m_nr(0), m_nreactors(0), m_integ(0), m_time(0.0), m_init(false), m_nv(0), m_rtol(1.0e-9), m_rtolsens(1.0e-4), m_atols(1.0e-15), m_atolsens(1.0e-4), - m_maxstep(-1.0), + m_maxstep(-1.0), m_maxErrTestFails(0), m_verbose(false), m_ntotpar(0) { #ifdef DEBUG_MODE @@ -133,6 +133,7 @@ void ReactorNet::initialize() m_integ->setTolerances(m_rtol, neq(), DATA_PTR(m_atol)); m_integ->setSensitivityTolerances(m_rtolsens, m_atolsens); m_integ->setMaxStepSize(m_maxstep); + m_integ->setMaxErrTestFails(m_maxErrTestFails); if (m_verbose) { sprintf(buf, "Number of equations: %s\n", int2str(neq()).c_str()); writelog(buf);