Fix building Cantera against Sundials 4.x library

The changelog of Sundials 4.0.0 states:

"With the introduction of SUNNonlinSol modules, the input parameter iter
to CVodeCreate has been removed along with the function CVodeSetIterType
and the constants CV_NEWTON and CV_FUNCTIONAL.
Similarly, the ITMETH parameter has been removed from the Fortran interface
function FCVMALLOC. Instead of specifying the nonlinear iteration type
when creating the CVODE(S) memory structure, CVODE(S) uses
the SUNNONLINSOL_NEWTON module implementation of a Newton iteration by default."

so the appropreate conditional changes are added to control
the code execution via CT_SUNDIALS_VERSION preprocessor variable
to omit the parameters of Sundials solver that are no longer required.
This commit is contained in:
band-a-prend 2019-07-25 00:22:34 +03:00 committed by Ray Speth
parent 3b948e17d4
commit 6a8d7f7de3
7 changed files with 62 additions and 32 deletions

View file

@ -1038,23 +1038,29 @@ env['has_demangle'] = conf.CheckDeclaration("boost::core::demangle",
import SCons.Conftest, SCons.SConf
context = SCons.SConf.CheckContext(conf)
ret = SCons.Conftest.CheckLib(context,
['sundials_cvodes'],
header='#include "cvodes/cvodes.h"',
language='C++',
call='CVodeCreate(CV_BDF, CV_NEWTON);',
autoadd=False,
extra_libs=env['blas_lapack_libs'])
if ret:
# Check initially for Sundials<=3.2 and then for Sundials>=4.0
for cvode_call in ['CVodeCreate(CV_BDF, CV_NEWTON);','CVodeCreate(CV_BDF);']:
ret = SCons.Conftest.CheckLib(context,
['sundials_cvodes'],
header='#include "cvodes/cvodes.h"',
language='C++',
call=cvode_call,
autoadd=False,
extra_libs=env['blas_lapack_libs'])
# CheckLib returns False to indicate success
if not ret:
if env['system_sundials'] == 'default':
env['system_sundials'] = 'y'
break
# Execute if the cycle ends without 'break'
else:
if env['system_sundials'] == 'default':
env['system_sundials'] = 'n'
elif env['system_sundials'] == 'y':
config_error('Expected system installation of Sundials, but it could '
'not be found.')
elif env['system_sundials'] == 'default':
env['system_sundials'] = 'y'
# Checkout Sundials submodule if needed
if (env['system_sundials'] == 'n' and
@ -1091,7 +1097,7 @@ if env['system_sundials'] == 'y':
# Ignore the minor version, e.g. 2.4.x -> 2.4
env['sundials_version'] = '.'.join(sundials_version.split('.')[:2])
if env['sundials_version'] not in ('2.4','2.5','2.6','2.7','3.0','3.1','3.2'):
if env['sundials_version'] not in ('2.4','2.5','2.6','2.7','3.0','3.1','3.2','4.0','4.1'):
print("""ERROR: Sundials version %r is not supported.""" % env['sundials_version'])
sys.exit(1)
print("""INFO: Using system installation of Sundials version %s.""" % sundials_version)

View file

@ -51,7 +51,9 @@ public:
m_maxord = n;
}
virtual void setMethod(MethodType t);
virtual void setIterator(IterType t);
#if CT_SUNDIALS_VERSION < 40
virtual void setIterator(IterType t);
#endif
virtual void setMaxStepSize(double hmax);
virtual void setMinStepSize(double hmin);
virtual void setMaxSteps(int nmax);

View file

@ -175,10 +175,12 @@ public:
warn("setMethodType");
}
//! Set the linear iterator.
virtual void setIterator(IterType t) {
warn("setInterator");
}
#if CT_SUNDIALS_VERSION < 40
//! Set the linear iterator.
virtual void setIterator(IterType t) {
warn("setInterator");
}
#endif
//! Set the maximum step size
virtual void setMaxStepSize(double hmax) {

View file

@ -84,7 +84,9 @@ ImplicitSurfChem::ImplicitSurfChem(
// numerically, and use a Newton linear iterator
m_integ->setMethod(BDF_Method);
m_integ->setProblemType(DENSE + NOJAC);
m_integ->setIterator(Newton_Iter);
#if CT_SUNDIALS_VERSION < 40
m_integ->setIterator(Newton_Iter);
#endif
m_work.resize(ntmax);
}

View file

@ -89,7 +89,9 @@ CVodesIntegrator::CVodesIntegrator() :
m_type(DENSE+NOJAC),
m_itol(CV_SS),
m_method(CV_BDF),
m_iter(CV_NEWTON),
#if CT_SUNDIALS_VERSION < 40
m_iter(CV_NEWTON),
#endif
m_maxord(0),
m_reltol(1.e-9),
m_abstols(1.e-15),
@ -227,16 +229,18 @@ void CVodesIntegrator::setMaxErrTestFails(int n)
}
}
void CVodesIntegrator::setIterator(IterType t)
{
if (t == Newton_Iter) {
m_iter = CV_NEWTON;
} else if (t == Functional_Iter) {
m_iter = CV_FUNCTIONAL;
} else {
throw CanteraError("CVodesIntegrator::setIterator", "unknown iterator");
#if CT_SUNDIALS_VERSION < 40
void CVodesIntegrator::setIterator(IterType t)
{
if (t == Newton_Iter) {
m_iter = CV_NEWTON;
} else if (t == Functional_Iter) {
m_iter = CV_FUNCTIONAL;
} else {
throw CanteraError("CVodesIntegrator::setIterator", "unknown iterator");
}
}
}
#endif
void CVodesIntegrator::sensInit(double t0, FuncEval& func)
{
@ -298,7 +302,11 @@ void CVodesIntegrator::initialize(double t0, FuncEval& func)
//! Specify the method and the iteration type. Cantera Defaults:
//! CV_BDF - Use BDF methods
//! CV_NEWTON - use Newton's method
m_cvode_mem = CVodeCreate(m_method, m_iter);
#if CT_SUNDIALS_VERSION < 40
m_cvode_mem = CVodeCreate(m_method, m_iter);
#else
m_cvode_mem = CVodeCreate(m_method);
#endif
if (!m_cvode_mem) {
throw CanteraError("CVodesIntegrator::initialize",
"CVodeCreate failed.");
@ -412,7 +420,11 @@ void CVodesIntegrator::applyOptions()
#if CT_SUNDIALS_VERSION >= 30
SUNLinSolFree((SUNLinearSolver) m_linsol);
SUNMatDestroy((SUNMatrix) m_linsol_matrix);
m_linsol_matrix = SUNBandMatrix(N, nu, nl, nu+nl);
#if CT_SUNDIALS_VERSION < 40
m_linsol_matrix = SUNBandMatrix(N, nu, nl, nu+nl);
#else
m_linsol_matrix = SUNBandMatrix(N, nu, nl);
#endif
if (m_linsol_matrix == nullptr) {
throw CanteraError("CVodesIntegrator::applyOptions",
"Unable to create SUNBandMatrix of size {} with bandwidths "

View file

@ -446,7 +446,11 @@ void IDA_Solver::init(doublereal t0)
#if CT_SUNDIALS_VERSION >= 30
SUNLinSolFree((SUNLinearSolver) m_linsol);
SUNMatDestroy((SUNMatrix) m_linsol_matrix);
m_linsol_matrix = SUNBandMatrix(N, nu, nl, nu+nl);
#if CT_SUNDIALS_VERSION < 40
m_linsol_matrix = SUNBandMatrix(N, nu, nl, nu+nl);
#else
m_linsol_matrix = SUNBandMatrix(N, nu, nl);
#endif
if (m_linsol_matrix == nullptr) {
throw CanteraError("IDA_Solver::init",
"Unable to create SUNBandMatrix of size {} with bandwidths "

View file

@ -28,7 +28,9 @@ ReactorNet::ReactorNet() :
// numerically, and use a Newton linear iterator
m_integ->setMethod(BDF_Method);
m_integ->setProblemType(DENSE + NOJAC);
m_integ->setIterator(Newton_Iter);
#if CT_SUNDIALS_VERSION < 40
m_integ->setIterator(Newton_Iter);
#endif
}
void ReactorNet::setInitialTime(double time)