Skip to content

Commit

Permalink
Fix build with sundials 7 (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
jschueller authored May 17, 2024
1 parent f1e87df commit 214dbd6
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 77 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
--- CHANGELOG ---

--- Assimulo-3.5.1 ---
* Fixed build with sundials 7.x

--- Assimulo-3.5.0 ---
* Changed "numpy.float" to equivalent "numpy.float64" due to DeprecationWarnings in numpy >= 1.20.
* Improved examples with sparse jacobians by omitting the zeros in the jacobians.
Expand Down
7 changes: 4 additions & 3 deletions examples/kinsol_ors.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
import os
import nose
import numpy as np
import scipy as sp
import scipy.sparse as sps
import scipy.sparse.linalg as spsl
import scipy.io as spi
from assimulo.solvers import KINSOL
from assimulo.problem import Algebraic_Problem
import warnings
Expand All @@ -36,7 +37,7 @@ def run_example(with_plots=True):
Iterative Methods for Sparse Linear Systems.
"""
#Read the original matrix
A_original = sp.io.mmread(os.path.join(file_path,"kinsol_ors_matrix.mtx"))
A_original = spi.mmread(os.path.join(file_path,"kinsol_ors_matrix.mtx"))

#Scale the original matrix
A = sps.spdiags(1.0/A_original.diagonal(), 0, len(A_original.diagonal()), len(A_original.diagonal())) * A_original
Expand All @@ -51,7 +52,7 @@ def run_example(with_plots=True):
U = D-F
Prec = L.dot(U)

solvePrec = sps.linalg.factorized(Prec)
solvePrec = spsl.factorized(Prec)

#Create the RHS
b = A.dot(np.ones(A.shape[0]))
Expand Down
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,8 @@ def cython_extensionlists(self):

if self.SUNDIALS_version >= (3,0,0):
ext_list[-1].libraries = ["sundials_cvodes", "sundials_nvecserial", "sundials_idas", "sundials_sunlinsoldense", "sundials_sunlinsolspgmr", "sundials_sunmatrixdense", "sundials_sunmatrixsparse"]
if self.SUNDIALS_version >= (7,0,0):
ext_list[-1].libraries.extend(["sundials_core"])
else:
ext_list[-1].libraries = ["sundials_cvodes", "sundials_nvecserial", "sundials_idas"]
if self.sundials_with_superlu and self.with_SLU: #If SUNDIALS is compiled with support for SuperLU
Expand All @@ -523,6 +525,8 @@ def cython_extensionlists(self):
ext_list[-1].include_dirs = [np.get_include(), "assimulo","assimulo"+os.sep+"lib", self.incdirs]
ext_list[-1].library_dirs = [self.libdirs]
ext_list[-1].libraries = ["sundials_kinsol", "sundials_nvecserial"]
if self.SUNDIALS_version >= (7,0,0):
ext_list[-1].libraries.extend(["sundials_core"])

if self.sundials_with_superlu and self.with_SLU: #If SUNDIALS is compiled with support for SuperLU
ext_list[-1].include_dirs.append(self.SLUincdir)
Expand Down Expand Up @@ -665,7 +669,7 @@ def fortran_extensionlists(self):
NAME = "Assimulo"
AUTHOR = u"C. Winther (Andersson), C. Führer, J. Åkesson, M. Gäfvert"
AUTHOR_EMAIL = "[email protected]"
VERSION = "trunk" if version_number_arg == "Default" else version_number_arg
VERSION = "3.5.0-dev" if version_number_arg == "Default" else version_number_arg
LICENSE = "LGPL"
URL = "http://www.jmodelica.org/assimulo"
DOWNLOAD_URL = "http://www.jmodelica.org/assimulo"
Expand Down
14 changes: 10 additions & 4 deletions src/lib/sundials_callbacks.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ from numpy cimport PyArray_DATA
cdef N_Vector N_VNewEmpty_Euclidean(long int n) noexcept:
IF SUNDIALS_VERSION >= (6,0,0):
cdef SUNDIALS.SUNContext ctx = NULL
cdef void * comm = NULL
IF SUNDIALS_VERSION >= (7,0,0):
cdef SUNDIALS.SUNComm comm = 0
ELSE:
cdef void* comm = NULL
SUNDIALS.SUNContext_Create(comm, &ctx)
cdef N_Vector v = N_VNew_Serial(n, ctx)
ELSE:
Expand All @@ -39,7 +42,10 @@ cdef inline N_Vector arr2nv(x) noexcept:
cdef void* data_ptr=PyArray_DATA(ndx)
IF SUNDIALS_VERSION >= (6,0,0):
cdef SUNDIALS.SUNContext ctx = NULL
cdef void * comm = NULL
IF SUNDIALS_VERSION >= (7,0,0):
cdef SUNDIALS.SUNComm comm = 0
ELSE:
cdef void* comm = NULL
SUNDIALS.SUNContext_Create(comm, &ctx)
cdef N_Vector v = N_VNew_Serial(n, ctx)
ELSE:
Expand All @@ -63,7 +69,7 @@ cdef inline void arr2nv_inplace(x, N_Vector out) noexcept:
cdef void* data_ptr=PyArray_DATA(ndx)
memcpy((<N_VectorContent_Serial>out.content).data, data_ptr, n*sizeof(realtype))

cdef inline np.ndarray nv2arr(N_Vector v) noexcept:
cdef inline np.ndarray nv2arr(N_Vector v):
cdef long int n = (<N_VectorContent_Serial>v.content).length
cdef realtype* v_data = (<N_VectorContent_Serial>v.content).data
cdef np.ndarray[realtype, ndim=1, mode='c'] x=np.empty(n)
Expand All @@ -82,7 +88,7 @@ cdef inline void nv2mat_inplace(int Ns, N_Vector *v, np.ndarray o) noexcept:
for j in range(Nf):
o[j,i] = (<N_VectorContent_Serial>v[i].content).data[j]

cdef inline realtype2arr(realtype *data, int n) noexcept:
cdef inline realtype2arr(realtype *data, int n):
"""Create new numpy array from realtype*"""
cdef np.ndarray[realtype, ndim=1, mode='c'] x=np.empty(n)
memcpy(PyArray_DATA(x), data, n*sizeof(realtype))
Expand Down
69 changes: 34 additions & 35 deletions src/lib/sundials_callbacks_kinsol.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -256,41 +256,40 @@ ELSE:
#print("<functionNorm: %g, scaledStepLength: %g, tolerance: %g>"%(fnorm, snorm, pData.TOL))


cdef void kin_info(const char *module, const char *function, char *msg, void *eh_data) noexcept:
cdef ProblemDataEquationSolver pData = <ProblemDataEquationSolver>eh_data
cdef int flag
cdef realtype fnorm

if str(function) == "KINSol" and "fnorm" in str(msg):
#fnorm = float(msg.split("fnorm = ")[-1].strip())
flag = SUNDIALS.KINGetFuncNorm(pData.KIN_MEM, &fnorm)
pData.nl_fnorm.append(fnorm)

pData.log.append([module, function, msg])

#print("KinsolInfo <calling_function:%s>"%function)
#print("<message: %s>"%msg)
"""
# Get the number of iterations
KINGetNumNonlinSolvIters(kin_mem, &nniters)
/* Only output an iteration under certain conditions:
* 1. nle_solver_log > 2
* 2. The calling function is either KINSolInit or KINSol
* 3. The message string starts with "nni"
*
* This approach gives one printout per iteration
if ("KINSolInit" in function or "KINSol" in function) and "nni" in msg:
print("<iteration_index:%d>"%nniters)
print("ivs", N_VGetArrayPointer(kin_mem->kin_uu), block->n))
print("<scaled_residual_norm:%E>", kin_mem->kin_fnorm))
print("residuals",
realtype* f = N_VGetArrayPointer(kin_mem->kin_fval);
f[i]*residual_scaling_factors[i])
"""

cdef void kin_info(const char *module, const char *function, char *msg, void *eh_data) noexcept:
cdef ProblemDataEquationSolver pData = <ProblemDataEquationSolver>eh_data
cdef int flag
cdef realtype fnorm

if str(function) == "KINSol" and "fnorm" in str(msg):
#fnorm = float(msg.split("fnorm = ")[-1].strip())
flag = SUNDIALS.KINGetFuncNorm(pData.KIN_MEM, &fnorm)
pData.nl_fnorm.append(fnorm)

pData.log.append([module, function, msg])

#print("KinsolInfo <calling_function:%s>"%function)
#print("<message: %s>"%msg)
"""
# Get the number of iterations
KINGetNumNonlinSolvIters(kin_mem, &nniters)
/* Only output an iteration under certain conditions:
* 1. nle_solver_log > 2
* 2. The calling function is either KINSolInit or KINSol
* 3. The message string starts with "nni"
*
* This approach gives one printout per iteration
if ("KINSolInit" in function or "KINSol" in function) and "nni" in msg:
print("<iteration_index:%d>"%nniters)
print("ivs", N_VGetArrayPointer(kin_mem->kin_uu), block->n))
print("<scaled_residual_norm:%E>", kin_mem->kin_fnorm))
print("residuals",
realtype* f = N_VGetArrayPointer(kin_mem->kin_fval);
f[i]*residual_scaling_factors[i])
"""

cdef class ProblemDataEquationSolver:
cdef:
Expand Down
12 changes: 9 additions & 3 deletions src/lib/sundials_includes.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ IF SUNDIALS_VERSION >= (6,0,0):
ctypedef _SUNContext * SUNContext
cdef struct _SUNContext:
pass
int SUNContext_Create(void* comm, SUNContext* ctx) noexcept
IF SUNDIALS_VERSION >= (7,0,0):
ctypedef int SUNComm
int SUNContext_Create(SUNComm comm, SUNContext* ctx) noexcept
ELSE:
int SUNContext_Create(void* comm, SUNContext* ctx) noexcept

IF SUNDIALS_VERSION >= (7,0,0):
cdef extern from "sundials/sundials_context.h":
Expand All @@ -48,6 +52,8 @@ IF SUNDIALS_VERSION >= (6,0,0):
cdef extern from "sundials/sundials_types.h":
ctypedef double sunrealtype
ctypedef bint sunbooleantype
IF SUNDIALS_VERSION >= (7,0,0):
cdef int SUN_COMM_NULL
ctypedef double realtype
ctypedef bint booleantype
ELSE:
Expand Down Expand Up @@ -494,7 +500,7 @@ ELSE:
N_Vector tmp2, N_Vector tmp3) noexcept
int CVSlsSetSparseJacFn(void *cvode_mem, CVSlsSparseJacFn jac) noexcept
int CVSlsGetNumJacEvals(void *cvode_mem, long int *njevals) noexcept
cdef inline tuple version() noexcept: return (2,6,0)
cdef inline tuple version(): return (2,6,0)
IF SUNDIALS_WITH_SUPERLU:
cdef extern from "cvodes/cvodes_superlumt.h":
int CVSuperLUMT(void *cvode_mem, int numthreads, int n, int nnz) noexcept
Expand Down Expand Up @@ -579,7 +585,7 @@ cdef extern from "idas/idas.h":
int IDAGetNumResEvals(void *ida_mem, long int *nrevals) #Number of res evals
IF SUNDIALS_VERSION >= (4,0,0):
int IDAGetNumJacEvals(void *ida_mem, long int *njevals) #Number of jac evals
int IDAGetNumResEvals(void *ida_mem, long int *nrevalsLS) #Number of res evals due to jac evals
int IDAGetNumLinResEvals(void *ida_mem, long int *nrevalsLS) #Number of res evals due to jac evals
ELSE:
int IDADlsGetNumJacEvals(void *ida_mem, long int *njevals) #Number of jac evals
int IDADlsGetNumResEvals(void *ida_mem, long int *nrevalsLS) #Number of res evals due to jac evals
Expand Down
4 changes: 2 additions & 2 deletions src/solvers/dasp3.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class DASP3ODE(Explicit_ODE):
.. math::
\\frac{\mathrm{d}y}{\mathrm{d}t} &= f(t,y,z) \;\;\; \\text{(N equations)} \\\\
\\varepsilon\\frac{\mathrm{d}z}{\mathrm{d}t} &= G(t,y,z)\;\;\; \\text{(M equations)}
\\frac{\\mathrm{d}y}{\\mathrm{d}t} &= f(t,y,z) \\;\\;\\; \\text{(N equations)} \\\\
\\varepsilon\\frac{\\mathrm{d}z}{\\mathrm{d}t} &= G(t,y,z)\\;\\;\\; \\text{(M equations)}
If is assumed that the first system is non-stiff and that
the stiffness of the second system is due to the parameter
Expand Down
10 changes: 8 additions & 2 deletions src/solvers/kinsol.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ cdef class KINSOL(Algebraic):
cdef int flag #Used for return
IF SUNDIALS_VERSION >= (6,0,0):
cdef SUNDIALS.SUNContext ctx = NULL
cdef void * comm = NULL
IF SUNDIALS_VERSION >= (7,0,0):
cdef SUNDIALS.SUNComm comm = SUNDIALS.SUN_COMM_NULL
ELSE:
cdef void* comm = NULL
SUNDIALS.SUNContext_Create(comm, &ctx)

self.y_temp = arr2nv(self.y)
Expand Down Expand Up @@ -230,7 +233,10 @@ cdef class KINSOL(Algebraic):
cpdef add_linear_solver(self):
IF SUNDIALS_VERSION >= (6,0,0):
cdef SUNDIALS.SUNContext ctx = NULL
cdef void * comm = NULL
IF SUNDIALS_VERSION >= (7,0,0):
cdef SUNDIALS.SUNComm comm = SUNDIALS.SUN_COMM_NULL
ELSE:
cdef void* comm = NULL
SUNDIALS.SUNContext_Create(comm, &ctx)
if self.options["linear_solver"] == "DENSE":
IF SUNDIALS_VERSION >= (3,0,0):
Expand Down
2 changes: 1 addition & 1 deletion src/solvers/odepack.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class LSODAR(Explicit_ODE):
.. math::
\dot{y} = f(t,y), \quad y(t_0) = y_0.
\\dot{y} = f(t,y), \\quad y(t_0) = y_0.
LSODAR automatically switches between using an ADAMS method
or an BDF method and is also able to monitor events.
Expand Down
14 changes: 7 additions & 7 deletions src/solvers/radau5.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import numpy as np
import scipy as sp
import scipy.linalg as spl
import scipy.sparse as sps

from assimulo.exception import (
Expand Down Expand Up @@ -707,9 +707,9 @@ def newton(self,t,y):
self._g = self._gamma/self.h
self._B = self._g*self.I - self._jac

self._P1,self._L1,self._U1 = sp.linalg.lu(self._B) #LU decomposition
self._P2,self._L2,self._U2 = sp.linalg.lu(self._a*self.I-self._jac)
self._P3,self._L3,self._U3 = sp.linalg.lu(self._b*self.I-self._jac)
self._P1,self._L1,self._U1 = spl.lu(self._B) #LU decomposition
self._P2,self._L2,self._U2 = spl.lu(self._a*self.I-self._jac)
self._P3,self._L3,self._U3 = spl.lu(self._b*self.I-self._jac)

self._needLU = False

Expand Down Expand Up @@ -1526,9 +1526,9 @@ def newton(self,t,y,yd):
self._g = self._gamma/self.h
self._B = self._g*self.M - self._jac

self._P1,self._L1,self._U1 = sp.linalg.lu(self._B) #LU decomposition
self._P2,self._L2,self._U2 = sp.linalg.lu(self._a*self.M-self._jac)
self._P3,self._L3,self._U3 = sp.linalg.lu(self._b*self.M-self._jac)
self._P1,self._L1,self._U1 = spl.lu(self._B) #LU decomposition
self._P2,self._L2,self._U2 = spl.lu(self._a*self.M-self._jac)
self._P3,self._L3,self._U3 = spl.lu(self._b*self.M-self._jac)

self._needLU = False

Expand Down
2 changes: 1 addition & 1 deletion src/solvers/runge_kutta.py
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ class RungeKutta4(Explicit_ODE):
.. math::
\dot{y} = f(t,y), \quad y(t_0) = y_0 .
\\dot{y} = f(t,y), \\quad y(t_0) = y_0 .
Using a Runge-Kutta method of order 4, the approximation is defined as
follow,
Expand Down
Loading

0 comments on commit 214dbd6

Please sign in to comment.