diff --git a/SConstruct b/SConstruct index 891711e56..46e650c59 100644 --- a/SConstruct +++ b/SConstruct @@ -408,19 +408,11 @@ config_options = [ """Command to use for building the Sphinx documentation.""", 'sphinx-build', PathVariable.PathAccept), EnumVariable( - 'use_sundials', - """Cantera uses the CVODE or CVODES ODE integrator to time-integrate - reactor network ODE's and for various other purposes. An older - version of CVODE comes with Cantera, but it is possible to use the - latest version as well, which now supports sensitivity analysis - (CVODES). CVODES is a part of the 'sundials' package from Lawrence - Livermore National Laboratory. Sundials is not distributed with - Cantera, but it is free software that may be downloaded and - installed separately. If you leave USE_SUNDIALS = 'default', then it - will be used if you have it, and if not the older CVODE will be - used. Or set USE_SUNDIALS to 'y' or 'n' to force using it or not. - Note that sensitivity analysis with Cantera requires use of - sundials. See: http://www.llnl.gov/CASC/sundials.""", + 'system_sundials', + """Select whether to use Sundials from a system installation ('y'), from + a git submodule ('n'), or to decide automatically ('default'). + Specifying 'sundials_include' or 'sundials_libdir' changes the + default to 'y'.""", 'default', ('default', 'y', 'n')), PathVariable( 'sundials_include', @@ -435,16 +427,6 @@ config_options = [ Not needed if the libraries are installed in a standard location, e.g. /usr/lib.""", '', PathVariable.PathAccept), - PathVariable( - 'sundials_license', - """Path to the sundials LICENSE file. Needed so that it can be included - when bundling Sundials.""", - '', PathVariable.PathAccept), - BoolVariable( - 'install_sundials', - """Determines whether Sundials library and header files are installed - alongside Cantera. Intended for use when installing on Windows.""", - os.name == 'nt'), ('blas_lapack_libs', """Cantera comes with Fortran (or C) versions of those parts of BLAS and LAPACK it requires. But performance may be better if you use a version @@ -662,16 +644,13 @@ if env['boost_inc_dir']: if env['blas_lapack_dir']: env.Append(LIBPATH=[env['blas_lapack_dir']]) -if (env['use_sundials'] == 'default' and - (env['sundials_include'] or env['sundials_libdir'])): - env['use_sundials'] = 'y' - -if env['use_sundials'] in ('y','default'): +if env['system_sundials'] in ('y','default'): if env['sundials_include']: env.Append(CPPPATH=[env['sundials_include']]) + env['system_sundials'] = 'y' if env['sundials_libdir']: env.Append(LIBPATH=[env['sundials_libdir']]) - + env['system_sundials'] = 'y' # BLAS / LAPACK configuration if env['blas_lapack_libs'] != '': @@ -821,12 +800,42 @@ ret = SCons.Conftest.CheckLib(context, call='CVodeCreate(CV_BDF, CV_NEWTON);', autoadd=False, extra_libs=env['blas_lapack_libs']) -env['HAS_SUNDIALS'] = not ret # CheckLib returns False to indicate success +if ret: + # CheckLib returns False to indicate success + 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 + not os.path.exists('ext/sundials/include/cvodes/cvodes.h')): + if not os.path.exists('.git'): + config_error('Sundials is missing. Install source in ext/sundials.') + + try: + code = subprocess.call(['git','submodule','update','--init', + '--recursive','ext/sundials']) + except Exception: + code = -1 + if code: + config_error('Sundials not found and submodule checkout failed.\n' + 'Try manually checking out the submodule with:\n\n' + ' git submodule update --init --recursive ext/sundials\n') + + env['NEED_LIBM'] = not conf.CheckLibWithHeader(None, 'math.h', 'C', 'double x; log(x);', False) env['LIBM'] = ['m'] if env['NEED_LIBM'] else [] -if env['HAS_SUNDIALS'] and env['use_sundials'] != 'n': +if env['system_sundials'] == 'y': + for subdir in ('sundials','nvector','cvodes','ida'): + removeDirectory('include/cantera/ext/'+subdir) + # Determine Sundials version sundials_version_source = get_expression_value(['"sundials/sundials_config.h"'], 'QUOTE(SUNDIALS_PACKAGE_VERSION)') @@ -837,7 +846,10 @@ if env['HAS_SUNDIALS'] and env['use_sundials'] != 'n': # Ignore the minor version, e.g. 2.4.x -> 2.4 env['sundials_version'] = '.'.join(sundials_version.split('.')[:2]) - print """INFO: Using Sundials version %s.""" % sundials_version + if env['sundials_version'] not in ('2.4','2.5','2.6'): + 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 #Determine whether or not Sundials was built with BLAS/LAPACK if LooseVersion(env['sundials_version']) < LooseVersion('2.6'): @@ -858,6 +870,11 @@ if env['HAS_SUNDIALS'] and env['use_sundials'] != 'n': if not env['has_sundials_lapack'] and not env['BUILD_BLAS_LAPACK']: print ('WARNING: External BLAS/LAPACK has been specified for Cantera ' 'but Sundials was built without this support.') +else: # env['system_sundials'] == 'n' + print """INFO: Using private installation of Sundials version 2.6.""" + env['sundials_version'] = '2.6' + env['has_sundials_lapack'] = int(not env['BUILD_BLAS_LAPACK']) + # Try to find a working Fortran compiler: env['FORTRANSYSLIBS'] = [] @@ -1073,19 +1090,6 @@ if env['matlab_toolbox'] == 'y': sys.exit(1) -# Sundials Settings -if env['use_sundials'] == 'default': - if env['HAS_SUNDIALS']: - env['use_sundials'] = 'y' - else: - print "INFO: Sundials was not found. Building with minimal ODE solver capabilities." - env['use_sundials'] = 'n' -elif env['use_sundials'] == 'y' and not env['HAS_SUNDIALS']: - config_error("Unable to find Sundials headers and / or libraries.") -elif env['use_sundials'] == 'y' and env['sundials_version'] not in ('2.4','2.5','2.6'): - print """ERROR: Sundials version %r is not supported.""" % env['sundials_version'] - sys.exit(1) - # ********************************************** # *** Set additional configuration variables *** # ********************************************** @@ -1206,11 +1210,7 @@ if env['python_package'] == 'none' and env['python3_package'] == 'n': else: configh['HAS_NO_PYTHON'] = None -cdefine('HAS_SUNDIALS', 'use_sundials', 'y') -if env['use_sundials'] == 'y': - configh['SUNDIALS_VERSION'] = env['sundials_version'].replace('.','') -else: - configh['SUNDIALS_VERSION'] = 0 +configh['SUNDIALS_VERSION'] = env['sundials_version'].replace('.','') if env.get('has_sundials_lapack') and not env['BUILD_BLAS_LAPACK']: configh['SUNDIALS_USE_LAPACK'] = 1 @@ -1295,18 +1295,6 @@ if addInstallActions: # Data files install('$inst_datadir', mglob(env, 'build/data', 'cti', 'xml')) - # Copy sundials library and header files - if env['install_sundials']: - for subdir in ['cvode','cvodes','ida','idas','kinsol','nvector','sundials']: - if os.path.exists(pjoin(env['sundials_include'], subdir)): - install(env.RecursiveInstall, pjoin('$inst_incdir', '..', subdir), - pjoin(env['sundials_include'], subdir)) - if os.path.exists(env['sundials_license']): - install('$inst_incdir/../sundials', env['sundials_license']) - libprefix = '' if os.name == 'nt' else 'lib' - install('$inst_libdir', mglob(env, env['sundials_libdir'], - '^{0}sundials_*'.format(libprefix))) - ### List of libraries needed to link to Cantera ### linkLibs = ['cantera'] @@ -1314,7 +1302,7 @@ linkLibs = ['cantera'] ### List of shared libraries needed to link applications to Cantera linkSharedLibs = ['cantera_shared'] -if env['use_sundials'] == 'y': +if env['system_sundials'] == 'y': env['sundials_libs'] = ['sundials_cvodes', 'sundials_ida', 'sundials_nvecserial'] linkLibs.extend(('sundials_cvodes', 'sundials_ida', 'sundials_nvecserial')) linkSharedLibs.extend(('sundials_cvodes', 'sundials_ida', 'sundials_nvecserial')) diff --git a/doc/sphinx/compiling.rst b/doc/sphinx/compiling.rst index 63aae9b27..5c4194d48 100644 --- a/doc/sphinx/compiling.rst +++ b/doc/sphinx/compiling.rst @@ -505,8 +505,8 @@ Optional Programs * Sundials - * Required to enable some features such as sensitivity analysis. - * Strongly recommended if using reactor network or 1D simulation capabilities. + * Optional. If Sundials is not installed, it will be automatically downloaded + and the necessary portions will be compiled and installed with Cantera. * https://computation.llnl.gov/casc/sundials/download/download.html * Known to work with versions 2.4, 2.5 and 2.6. * To use Sundials with Cantera on a Linux/Unix system, it must be compiled diff --git a/doc/sphinx/install.rst b/doc/sphinx/install.rst index 9cd47e692..7f70ee8f4 100644 --- a/doc/sphinx/install.rst +++ b/doc/sphinx/install.rst @@ -189,7 +189,7 @@ you can skip any steps which have already been completed. brew tap homebrew/science brew update - brew install python scons sundials + brew install python scons - Verify that your path is set up to use Homebrew's version of Python by running:: diff --git a/doc/sphinx/scons-options.txt b/doc/sphinx/scons-options.txt index a0baa9f72..2a1c18d7d 100644 --- a/doc/sphinx/scons-options.txt +++ b/doc/sphinx/scons-options.txt @@ -149,21 +149,12 @@ running 'scons build'. The format of this file is: Command to use for building the Sphinx documentation. - default: 'sphinx-build' -* use_sundials: [ default | y | n ] - Cantera uses the CVODE or CVODES ODE integrator to time-integrate - reactor network ODE's and for various other purposes. An older - version of CVODE comes with Cantera, but it is possible to use the - latest version as well, which now supports sensitivity analysis - (CVODES). CVODES is a part of the 'sundials' package from Lawrence - Livermore National Laboratory. Sundials is not distributed with - Cantera, but it is free software that may be downloaded and - installed separately. If you leave USE_SUNDIALS = 'default', then it - will be used if you have it, and if not the older CVODE will be - used. Or set USE_SUNDIALS to 'y' or 'n' to force using it or not. - Note that sensitivity analysis with Cantera requires use of - sundials. See: http://www.llnl.gov/CASC/sundials. +* system_sundials: [ default | y | n ] + Select whether to use Sundials from a system installation ('y'), + from a git submodule ('n'), or to decide automatically ('default'). + Specifying 'sundials_include' or 'sundials_libdir' changes the + default to 'y'. - default: 'default' - - actual: 'y' * sundials_include: [ /path/to/sundials_include ] The directory where the Sundials header files are installed. This @@ -178,16 +169,6 @@ running 'scons build'. The format of this file is: /usr/lib. - default: '' -* sundials_license: [ /path/to/sundials_license ] - Path to the sundials LICENSE file. Needed so that it can be included - when bundling Sundials. - - default: '' - -* install_sundials: [ yes | no ] - Determines whether Sundials library and header files are installed - alongside Cantera. Intended for use when installing on Windows. - - default: 'yes' - * blas_lapack_libs: [ string ] Cantera comes with Fortran (or C) versions of those parts of BLAS and LAPACK it requires. But performance may be better if you use a diff --git a/ext/SConscript b/ext/SConscript index 4d52791f7..1ca3ab333 100644 --- a/ext/SConscript +++ b/ext/SConscript @@ -34,12 +34,6 @@ def prep_f2c(env): return localenv -def prep_sundials(env): - localenv = prep_default(env) - localenv.Prepend(CPPPATH=Dir('#ext/cvode/include')) - return localenv - - def prep_gtest(env): localenv = prep_default(env) localenv.Prepend(CPPPATH=[Dir('#ext/googletest'), @@ -85,14 +79,38 @@ else: libs.append(('blas', ['f'], prep_default)) libs.append(('lapack', ['f'], prep_default)) -if env['use_sundials'] == 'n': - libs.append(('cvode/source', ['c'], prep_sundials)) - for subdir, extensions, prepFunction in libs: localenv = prepFunction(env) objects = localenv.SharedObject(mglob(localenv, subdir, *extensions)) libraryTargets.extend(objects) +if env['system_sundials'] == 'n': + localenv = prep_default(env) + localenv.Prepend(CPPPATH=Dir('#include/cantera/ext')) + + # Generate sundials_config.h + sundials_configh = {} + if env['OS'] != 'Windows': + sundials_configh['SUNDIALS_USE_GENERIC_MATH'] = 1 + if not env['BUILD_BLAS_LAPACK']: + sundials_configh['SUNDIALS_BLAS_LAPACK'] = 1 + localenv.AlwaysBuild(env.Command('#include/cantera/ext/sundials/sundials_config.h', + 'sundials_config.h.in', + ConfigBuilder(sundials_configh))) + + # Copy sundials header files into common include directory + for subdir in ('sundials', 'nvector', 'cvodes', 'ida'): + for header in mglob(env, 'sundials/include/'+subdir, 'h'): + build(localenv.Command('#include/cantera/ext/%s/%s' % (subdir, header.name), + '#ext/sundials/include/%s/%s' % (subdir, header.name), + Copy('$TARGET', '$SOURCE'))) + + # Compile Sundials source files + for subdir in ('sundials', 'nvec_ser', 'cvodes', 'ida'): + libraryTargets.extend(localenv.SharedObject( + [f for f in mglob(localenv, 'sundials/src/'+subdir, 'c') + if '_klu' not in f.name and '_superlumt' not in f.name])) + # Google Test: Used internally for Cantera unit tests. if not env['system_googletest']: localenv = prep_gtest(env) diff --git a/ext/sundials_config.h.in b/ext/sundials_config.h.in new file mode 100644 index 000000000..cdd40a016 --- /dev/null +++ b/ext/sundials_config.h.in @@ -0,0 +1,7 @@ +/* Minimal set of SUNDIALS configuration variables */ +#define SUNDIALS_PACKAGE_VERSION 2.6.2 +#define SUNDIALS_F77_FUNC(name,NAME) name ## _ +#define SUNDIALS_DOUBLE_PRECISION 1 +%(SUNDIALS_USE_GENERIC_MATH)s +%(SUNDIALS_BLAS_LAPACK)s +#define SUNDIALS_EXPORT diff --git a/include/cantera/base/config.h.in b/include/cantera/base/config.h.in index 2549c17ef..77b424ffa 100644 --- a/include/cantera/base/config.h.in +++ b/include/cantera/base/config.h.in @@ -33,7 +33,6 @@ typedef int ftnlen; // Fortran hidden string length type %(FTN_TRAILING_UNDERSCORE)s -%(HAS_SUNDIALS)s %(SUNDIALS_VERSION)s //-------- LAPACK / BLAS --------- diff --git a/include/cantera/numerics/CVodesIntegrator.h b/include/cantera/numerics/CVodesIntegrator.h index 4fc9692d9..52f997f6d 100644 --- a/include/cantera/numerics/CVodesIntegrator.h +++ b/include/cantera/numerics/CVodesIntegrator.h @@ -9,8 +9,6 @@ #include "cantera/numerics/Integrator.h" #include "cantera/base/ctexceptions.h" -#ifdef HAS_SUNDIALS - #include "sundials/sundials_nvector.h" namespace Cantera @@ -30,7 +28,7 @@ public: /** * Wrapper class for 'cvodes' integrator from LLNL. * - * @see FuncEval.h. Classes that use CVodeInt: + * @see FuncEval.h. Classes that use CVodesIntegrator: * ImplicitChem, ImplicitSurfChem, Reactor */ class CVodesIntegrator : public Integrator @@ -120,10 +118,4 @@ private: } // namespace -#else - -#error No sundials! - -#endif - #endif diff --git a/include/cantera/numerics/IDA_Solver.h b/include/cantera/numerics/IDA_Solver.h index 36f4f2ec1..fba21d963 100644 --- a/include/cantera/numerics/IDA_Solver.h +++ b/include/cantera/numerics/IDA_Solver.h @@ -10,8 +10,6 @@ #include "DAE_Solver.h" -#if HAS_SUNDIALS - #include "sundials/sundials_nvector.h" // These constants are defined internally in the IDA package, ida.c @@ -305,4 +303,3 @@ protected: } #endif -#endif diff --git a/interfaces/cython/cantera/test/test_reactor.py b/interfaces/cython/cantera/test/test_reactor.py index 61db7919b..61a827225 100644 --- a/interfaces/cython/cantera/test/test_reactor.py +++ b/interfaces/cython/cantera/test/test_reactor.py @@ -783,11 +783,6 @@ class TestConstPressureReactor(utilities.CanteraTest): self.integrate() def test_with_surface_reactions(self): - if (not ct.__sundials_version__ and - self.reactorClass == ct.ConstPressureReactor): - raise unittest.SkipTest("Disabled until there is an interface for " - "setting the max_err_test_fails parameter for the old CVODE") - self.create_reactors(add_surf=True) self.net1.atol = self.net2.atol = 1e-18 self.net1.rtol = self.net2.rtol = 1e-9 @@ -817,9 +812,6 @@ class TestFlowReactor(utilities.CanteraTest): self.assertNear(v0, r.speed) self.assertNear(r.distance, v0 * t) - @unittest.skipUnless(ct.__sundials_version__, - "Disabled until there is an interface for setting the " - "max_err_test_fails parameter for the old CVODE") def test_reacting(self): g = ct.Solution('gri30.xml') g.TPX = 1400, 20*101325, 'CO:1.0, H2O:1.0' @@ -946,8 +938,6 @@ class TestWallKinetics(utilities.CanteraTest): self.assertFalse(bool(bad), bad) -@unittest.skipUnless(ct.__sundials_version__, - "Sensitivity calculations require Sundials") class TestReactorSensitivities(utilities.CanteraTest): def test_sensitivities1(self): net = ct.ReactorNet() diff --git a/interfaces/cython/cantera/utils.pyx b/interfaces/cython/cantera/utils.pyx index 906aa19c5..d37f645d9 100644 --- a/interfaces/cython/cantera/utils.pyx +++ b/interfaces/cython/cantera/utils.pyx @@ -26,10 +26,7 @@ def add_directory(directory): """ Add a directory to search for Cantera data files. """ CxxAddDirectory(stringify(directory)) -if get_sundials_version(): - __sundials_version__ = '.'.join(str(get_sundials_version())) -else: - __sundials_version__ = None +__sundials_version__ = '.'.join(str(get_sundials_version())) __version__ = pystr(get_cantera_version()) diff --git a/platform/posix/SConscript b/platform/posix/SConscript index df80dc2c5..4e910d169 100644 --- a/platform/posix/SConscript +++ b/platform/posix/SConscript @@ -42,11 +42,7 @@ pc_incdirs.extend(localenv['extra_inc_dirs']) localenv['mak_extra_libdirs'] = ' '.join('-L%s' % s for s in localenv['extra_lib_dirs']) pc_libdirs.extend(localenv['extra_lib_dirs']) -if env['use_sundials'] == 'n': - localenv['mak_sundials_libs'] = '-lcvode' - localenv['mak_sundials_libdir'] = '' - localenv['mak_sundials_include'] = '' -else: +if localenv['system_sundials']: # Add links to the sundials environment localenv['mak_sundials_libs'] = ' '.join('-l%s' % s for s in localenv['sundials_libs']) diff --git a/src/SConscript b/src/SConscript index 6fa2e158a..60397dfdd 100644 --- a/src/SConscript +++ b/src/SConscript @@ -14,20 +14,12 @@ def equilSetup(env, subdir, extensions): env.Append(CPPPATH=['#ext/f2c_libs']) return defaultSetup(env, subdir, extensions) -def numericsSetup(env, subdir, extensions): - if env['use_sundials'] == 'y': - remove = 'CVodeInt.cpp' - else: - remove = 'CVodesIntegrator.cpp' - return [s for s in mglob(env, subdir, *extensions) - if s.name != remove] - # (subdir, (file extensions), (extra setup(env))) libs = [('base', ['cpp'], baseSetup), ('thermo', ['cpp'], defaultSetup), ('tpx', ['cpp'], defaultSetup), ('equil', ['cpp','c'], equilSetup), - ('numerics', ['cpp'], numericsSetup), + ('numerics', ['cpp'], defaultSetup), ('kinetics', ['cpp'], defaultSetup), ('transport', ['cpp'], defaultSetup), ('oneD', ['cpp'], defaultSetup), @@ -37,7 +29,7 @@ libs = [('base', ['cpp'], baseSetup), for subdir, extensions, setup in libs: localenv = env.Clone() - localenv.Prepend(CPPPATH=Dir('#include')) + localenv.Prepend(CPPPATH=[Dir('#include'), Dir('#include/cantera/ext')]) localenv.Append(CCFLAGS=env['warning_flags']) source = setup(localenv, subdir, extensions) objects = localenv.SharedObject(source) @@ -56,7 +48,7 @@ env['cantera_staticlib'] = lib # Windows and OS X require shared libraries at link time if localenv['OS'] in ('Darwin', 'Windows', 'Cygwin'): localenv.Append(LIBS=localenv['FORTRANSYSLIBS']) - if (localenv['use_sundials'] == 'y'): + if (localenv['system_sundials'] == 'y'): localenv.Append(LIBS=localenv['sundials_libs'], LIBPATH=localenv['sundials_libdir']) if localenv['blas_lapack_libs']: diff --git a/src/numerics/CVodeInt.cpp b/src/numerics/CVodeInt.cpp deleted file mode 100644 index 98e80d72c..000000000 --- a/src/numerics/CVodeInt.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/** - * @file CVodeInt.cpp - */ - -// Copyright 2001 California Institute of Technology - -#include "CVodeInt.h" -using namespace std; - -// CVODE includes -#include "../../ext/cvode/include/llnltyps.h" -#include "../../ext/cvode/include/llnlmath.h" -#include "../../ext/cvode/include/cvode.h" -#include "../../ext/cvode/include/cvdense.h" -#include "../../ext/cvode/include/cvdiag.h" -#include "../../ext/cvode/include/cvspgmr.h" -#include "../../ext/cvode/include/cvode.h" - -#include "cantera/base/stringUtils.h" - -extern "C" { - - /** - * Function called by CVODE to evaluate ydot given y. The CVODE - * integrator allows passing in a void* pointer to access - * external data. This pointer is cast to a pointer to a instance - * of class FuncEval. The equations to be integrated should be - * specified by deriving a class from FuncEval that evaluates the - * desired equations. - * @ingroup odeGroup - */ - static void cvode_rhs(integer N, real t, N_Vector y, N_Vector ydot, - void* f_data) - { - double* ydata = N_VDATA(y); - double* ydotdata = N_VDATA(ydot); - Cantera::FuncEval* f = (Cantera::FuncEval*)f_data; - f->eval(t, ydata, ydotdata, NULL); - } - - /** - * Function called by CVODE to evaluate the Jacobian matrix. - * (temporary) - * @ingroup odeGroup - */ - static void cvode_jac(integer N, DenseMat J, RhsFn f, void* f_data, - real t, N_Vector y, N_Vector fy, N_Vector ewt, real h, real uround, - void* jac_data, long int* nfePtr, N_Vector vtemp1, N_Vector vtemp2, - N_Vector vtemp3) - { - // get pointers to start of data - double* ydata = N_VDATA(y); - double* fydata = N_VDATA(fy); - double* ewtdata = N_VDATA(ewt); - double* ydot = N_VDATA(vtemp1); - Cantera::FuncEval* func = (Cantera::FuncEval*)f_data; - - int i,j; - double* col_j; - double ysave, dy; - for (j=0; j < N; j++) { - col_j = (J->data)[j]; - ysave = ydata[j]; - dy = 1.0/ewtdata[j]; - ydata[j] = ysave + dy; - dy = ydata[j] - ysave; - func->eval(t, ydata, ydot, NULL); - for (i=0; i < N; i++) { - col_j[i] = (ydot[i] - fydata[i])/dy; - } - ydata[j] = ysave; - } - } -} - -namespace Cantera -{ -CVodeInt::CVodeInt() : m_neq(0), - m_cvode_mem(0), - m_t0(0.0), - m_y(0), - m_abstol(0), - m_type(DENSE+NOJAC), - m_itol(0), - m_method(BDF), - m_iter(NEWTON), - m_maxord(0), - m_reltol(1.e-9), - m_abstols(1.e-15), - m_nabs(0), - m_hmax(0.0), - m_maxsteps(20000) -{ - m_ropt.resize(OPT_SIZE,0.0); - m_iopt = new long[OPT_SIZE]; - fill(m_iopt, m_iopt+OPT_SIZE,0); -} - -CVodeInt::~CVodeInt() -{ - if (m_cvode_mem) { - CVodeFree(m_cvode_mem); - } - if (m_y) { - N_VFree(m_y); - } - if (m_abstol) { - N_VFree(m_abstol); - } - delete[] m_iopt; -} - -double& CVodeInt::solution(size_t k) -{ - return N_VIth(m_y, int(k)); -} -double* CVodeInt::solution() -{ - return N_VDATA(m_y); -} - -void CVodeInt::setTolerances(double reltol, size_t n, double* abstol) -{ - m_itol = 1; - m_nabs = int(n); - if (m_nabs != m_neq) { - if (m_abstol) { - N_VFree(m_abstol); - } - m_abstol = N_VNew(m_nabs, 0); - } - for (int i=0; i