Esempio n. 1
0
    def __init__(self,
                 problem: Problem,
                 *,
                 compute_sens: bool = False,
                 abstol: float = 1e-10,
                 reltol: float = 1e-10,
                 sens_mode: Optional[str] = None,
                 scaling_factors: Optional[np.ndarray] = None,
                 constraints: Optional[np.ndarray] = None,
                 solver='BDF'):
        self._problem = problem
        self._user_data = problem.make_user_data()

        n_states = self._problem.n_states
        n_params = self._problem.n_params

        self._state_buffer = sunode.empty_vector(n_states)
        self._state_buffer.data[:] = 0
        self._jac = check(lib.SUNDenseMatrix(n_states, n_states))
        self._constraints = constraints

        if solver == 'BDF':
            solver_kind = lib.CV_BDF
        elif solver == 'ADAMS':
            solver_kind = lib.CV_ADAMS
        else:
            assert False
        self._ode = check(lib.CVodeCreate(solver_kind))
        rhs = problem.make_sundials_rhs()
        check(lib.CVodeInit(self._ode, rhs.cffi, 0., self._state_buffer.c_ptr))

        self._set_tolerances(abstol, reltol)
        if self._constraints is not None:
            assert constraints.shape == (n_states, )
            self._constraints_vec = sunode.from_numpy(constraints)
            check(
                lib.CVodeSetConstraints(self._ode,
                                        self._constraints_vec.c_ptr))

        self._make_linsol()

        user_data_p = ffi.cast(
            'void *', ffi.addressof(ffi.from_buffer(self._user_data.data)))
        check(lib.CVodeSetUserData(self._ode, user_data_p))

        self._compute_sens = compute_sens
        if compute_sens:
            sens_rhs = self._problem.make_sundials_sensitivity_rhs()
            self._init_sens(sens_rhs, sens_mode)
Esempio n. 2
0
    def _init_backward(self, checkpoint_n, interpolation):
        check(lib.CVodeAdjInit(self._ode, checkpoint_n, interpolation))

        # Initialized by CVodeCreateB
        backward_ode = ffi.new('int*')
        check(
            lib.CVodeCreateB(self._ode, self._adjoint_solver_type,
                             backward_ode))
        self._odeB = backward_ode[0]

        self._state_bufferB = sunode.empty_vector(self._problem.n_states)
        check(
            lib.CVodeInitB(self._ode, self._odeB, self._adj_rhs.cffi, 0.,
                           self._state_bufferB.c_ptr))

        # TODO
        check(lib.CVodeSStolerancesB(self._ode, self._odeB, 1e-10, 1e-10))

        linsolver = check(
            lib.SUNLinSol_Dense(self._state_bufferB.c_ptr, self._jacB))
        check(
            lib.CVodeSetLinearSolverB(self._ode, self._odeB, linsolver,
                                      self._jacB))

        self._jac_funcB = self._problem.make_sundials_adjoint_jac_dense()
        check(lib.CVodeSetJacFnB(self._ode, self._odeB, self._jac_funcB.cffi))

        user_data_p = ffi.cast(
            'void *', ffi.addressof(ffi.from_buffer(self._user_data.data)))
        check(lib.CVodeSetUserDataB(self._ode, self._odeB, user_data_p))

        self._quad_buffer = sunode.empty_vector(self._problem.n_params)
        self._quad_buffer_out = sunode.empty_vector(self._problem.n_params)
        check(
            lib.CVodeQuadInitB(self._ode, self._odeB, self._quad_rhs.cffi,
                               self._quad_buffer.c_ptr))

        check(lib.CVodeQuadSStolerancesB(self._ode, self._odeB, 1e-10, 1e-10))
        check(lib.CVodeSetQuadErrConB(self._ode, self._odeB, 1))
Esempio n. 3
0
    def _init_sens(self, sens_rhs, sens_mode, scaling_factors=None) -> None:
        if sens_mode == 'simultaneous':
            sens_mode = lib.CV_SIMULTANEOUS
        elif sens_mode == 'staggered':
            sens_mode = lib.CV_STAGGERED
        elif sens_mode == 'staggered1':
            raise ValueError('staggered1 not implemented.')
        else:
            raise ValueError(
                'sens_mode must be one of "simultaneous" and "staggered".')

        self._sens_mode = sens_mode

        n_params = self._problem.n_params
        yS = check(lib.N_VCloneVectorArray(n_params, self._state_buffer.c_ptr))
        vecs = [sunode.vector.Vector(yS[i]) for i in range(n_params)]
        for vec in vecs:
            vec.data[:] = 0
        self._sens_buffer_array = yS
        self._sens_buffers = vecs

        check(
            lib.CVodeSensInit(self._ode, n_params, sens_mode, sens_rhs.cffi,
                              yS))

        if scaling_factors is not None:
            if scaling_factors.shape != (n_params, ):
                raise ValueError('Invalid shape of scaling_factors.')
            self._scaling_factors = scaling_factors
            NULL_D = ffi.cast('double *', 0)
            NULL_I = ffi.cast('int *', 0)
            pbar_p = ffi.cast(
                'double *',
                ffi.addressof(ffi.from_buffer(scaling_factors.data)))
            check(lib.CVodeSetSensParams(self._ode, NULL_D, pbar_p, NULL_I))

        check(lib.CVodeSensEEtolerances(self._ode))  # TODO
        check(lib.CVodeSetSensErrCon(self._ode, 1))  # TODO
Esempio n. 4
0
        self._ode = check(lib.CVodeCreate(self._solver_type))
        check(lib.CVodeInit(self._ode, rhs.cffi, 0., self._state_buffer.c_ptr))

        self._set_tolerances(abstol, reltol)
        if self._constraints is not None:
            self._constraints = np.broadcast_to(constraints,
                                                (n_states, )).copy()
            self._constraints_vec = sunode.from_numpy(self._constraints)
            check(
                lib.CVodeSetConstraints(self._ode,
                                        self._constraints_vec.c_ptr))

        self._make_linsol()

        user_data_p = ffi.cast(
            'void *', ffi.addressof(ffi.from_buffer(self._user_data.data)))
        check(lib.CVodeSetUserData(self._ode, user_data_p))

        if interpolation == 'polynomial':
            interpolation = lib.CV_POLYNOMIAL
        elif interpolation == 'hermite':
            interpolation = lib.CV_HERMITE
        else:
            assert False
        self._init_backward(checkpoint_n, interpolation)

    def _init_backward(self, checkpoint_n, interpolation):
        check(lib.CVodeAdjInit(self._ode, checkpoint_n, interpolation))

        # Initialized by CVodeCreateB
        backward_ode = ffi.new('int*')