From a5b1d1f7f67f52604de88667f63bff20098add04 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Thu, 7 Feb 2013 23:40:40 +0000 Subject: [PATCH] [Reactor] Added ability to set the CVODES "MaxErrTestFails" variable Increasing this value (from the default of 7) will sometimes allow CVODES to find solutions to problems that previously caused it to fail. --- include/cantera/numerics/CVodesIntegrator.h | 2 ++ include/cantera/numerics/Integrator.h | 5 +++++ include/cantera/zeroD/ReactorNet.h | 8 ++++++++ interfaces/cython/cantera/_cantera.pxd | 1 + interfaces/cython/cantera/reactor.pyx | 8 ++++++++ src/numerics/CVodeInt.h | 1 + src/numerics/CVodesIntegrator.cpp | 12 ++++++++++++ src/zeroD/ReactorNet.cpp | 3 ++- 8 files changed, 39 insertions(+), 1 deletion(-) 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);