Skip to content

Commit

Permalink
[SCons/Numerics] Use ext/sundials if system Sundials not installed
Browse files Browse the repository at this point in the history
  • Loading branch information
speth committed Nov 23, 2015
1 parent 34e38ab commit b4a1fb2
Show file tree
Hide file tree
Showing 18 changed files with 99 additions and 561 deletions.
114 changes: 51 additions & 63 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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
Expand Down Expand Up @@ -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'] != '':
Expand Down Expand Up @@ -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)')
Expand All @@ -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'):
Expand All @@ -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'] = []
Expand Down Expand Up @@ -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 ***
# **********************************************
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1295,26 +1295,14 @@ 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']

### 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'))
Expand Down
4 changes: 2 additions & 2 deletions doc/sphinx/compiling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion doc/sphinx/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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::
Expand Down
29 changes: 5 additions & 24 deletions doc/sphinx/scons-options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
36 changes: 27 additions & 9 deletions ext/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions ext/sundials_config.h.in
Original file line number Diff line number Diff line change
@@ -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
1 change: 0 additions & 1 deletion include/cantera/base/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ typedef int ftnlen; // Fortran hidden string length type
%(FTN_TRAILING_UNDERSCORE)s


%(HAS_SUNDIALS)s
%(SUNDIALS_VERSION)s

//-------- LAPACK / BLAS ---------
Expand Down
10 changes: 1 addition & 9 deletions include/cantera/numerics/CVodesIntegrator.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
#include "cantera/numerics/Integrator.h"
#include "cantera/base/ctexceptions.h"

#ifdef HAS_SUNDIALS

#include "sundials/sundials_nvector.h"

namespace Cantera
Expand All @@ -30,7 +28,7 @@ class CVodesErr : public CanteraError
/**
* 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
Expand Down Expand Up @@ -120,10 +118,4 @@ class CVodesIntegrator : public Integrator

} // namespace

#else

#error No sundials!

#endif

#endif
3 changes: 0 additions & 3 deletions include/cantera/numerics/IDA_Solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -305,4 +303,3 @@ class IDA_Solver : public DAE_Solver
}

#endif
#endif
Loading

0 comments on commit b4a1fb2

Please sign in to comment.