36#include "CvodeAdaptor.hpp"
40#include "TimeStepper.hpp"
47#include <sundials/sundials_nvector.h>
49#if CHASTE_SUNDIALS_VERSION < 70000
50#include <cvode/cvode_direct.h>
52#include <sundials/sundials_types.h>
53#include <sunlinsol/sunlinsol_dense.h>
54#include <sunmatrix/sunmatrix_dense.h>
56#if CHASTE_SUNDIALS_VERSION >= 60000
57#include "CvodeContextManager.hpp"
78 assert(pData !=
nullptr);
81 static std::vector<realtype> ydot_vec;
91 std::cerr <<
"CVODE RHS Exception: " << e.GetMessage() << std::endl
120int CvodeRootAdaptor(realtype t,
N_Vector y, realtype* pGOut,
void* pData)
122 assert(pData !=
nullptr);
133 std::cerr <<
"CVODE Root Exception: " << e.GetMessage() << std::endl
175#if CHASTE_SUNDIALS_VERSION >= 70000
176void CvodeErrorHandler(
int errorCode,
const char* module,
const char* function,
177 const char* message, SUNErrCode errCode,
void* pData, SUNContext sunContext)
179void CvodeErrorHandler(
int errorCode,
const char* module,
const char* function,
180 char* message,
void* pData)
183 std::stringstream err;
184 err <<
"CVODE Error " << errorCode <<
" in module " <<
module
185 << " function " << function << ": " << message;
186 std::cerr <<
"*" << err.str() << std::endl
193 std::vector<double>& rInitialY,
198 assert(maxStep > 0.0);
201#if CHASTE_SUNDIALS_VERSION >= 60000
202 N_Vector initial_values = N_VMake_Serial(rInitialY.size(), &(rInitialY[0]), CvodeContextManager::Instance()->GetSundialsContext());
204 N_Vector initial_values = N_VMake_Serial(rInitialY.size(), &(rInitialY[0]));
206 assert(NV_DATA_S(initial_values) == &(rInitialY[0]));
207 assert(!NV_OWN_DATA_S(initial_values));
217 for (
unsigned i = 0; i < size; i++)
230#if CHASTE_SUNDIALS_VERSION >= 60000
231 mpCvodeMem = CVodeCreate(CV_BDF, CvodeContextManager::Instance()->GetSundialsContext());
241#if CHASTE_SUNDIALS_VERSION >= 70000
242 SUNContext_PushErrHandler(CvodeContextManager::Instance()->GetSundialsContext(), CvodeErrorHandler,
nullptr);
244 CVodeSetErrHandlerFn(
mpCvodeMem, CvodeErrorHandler,
nullptr);
252 CVodeInit(
mpCvodeMem, CvodeRhsAdaptor, startTime, initial_values);
258 CVodeRootInit(
mpCvodeMem, 1, CvodeRootAdaptor);
262#if CHASTE_SUNDIALS_VERSION >= 60000
263 mpSundialsDenseMatrix = SUNDenseMatrix(rInitialY.size(), rInitialY.size(), CvodeContextManager::Instance()->GetSundialsContext());
268#if CHASTE_SUNDIALS_VERSION >= 60000
289 CVodeReInit(
mpCvodeMem, startTime, initial_values);
304#if CHASTE_SUNDIALS_VERSION >= 60000
305 mpSundialsDenseMatrix = SUNDenseMatrix(rInitialY.size(), rInitialY.size(), CvodeContextManager::Instance()->GetSundialsContext());
310#if CHASTE_SUNDIALS_VERSION >= 60000
385 std::stringstream err;
386 char* p_flag_name = CVodeGetReturnFlagName(flag);
387 err << msg <<
": " << p_flag_name;
389 std::cerr << err.str() << std::endl
395 std::vector<double>& rYValues,
401 assert(endTime > startTime);
402 assert(timeSampling > 0.0);
407 EXCEPTION(
"(Solve with sampling) Stopping event is true for initial condition");
410 SetupCvode(pOdeSystem, rYValues, startTime, maxStep);
412 TimeStepper stepper(startTime, endTime, timeSampling);
413#if CHASTE_SUNDIALS_VERSION >= 60000
414 N_Vector yout = N_VMake_Serial(rYValues.size(), &(rYValues[0]), CvodeContextManager::Instance()->GetSundialsContext());
416 N_Vector yout = N_VMake_Serial(rYValues.size(), &(rYValues[0]));
423 solutions.
rGetTimes().push_back(startTime);
431 assert(ierr == CV_SUCCESS);
440 CvodeError(ierr,
"CVODE failed to solve system");
445 if (ierr == CV_ROOT_RETURN)
459 assert(ierr == CV_SUCCESS);
468 std::vector<double>& rYValues,
473 assert(endTime > startTime);
478 EXCEPTION(
"(Solve) Stopping event is true for initial condition");
481 SetupCvode(pOdeSystem, rYValues, startTime, maxStep);
483#if CHASTE_SUNDIALS_VERSION >= 60000
484 N_Vector yout = N_VMake_Serial(rYValues.size(), &(rYValues[0]), CvodeContextManager::Instance()->GetSundialsContext());
486 N_Vector yout = N_VMake_Serial(rYValues.size(), &(rYValues[0]));
490 int ierr = CVodeSetStopTime(
mpCvodeMem, endTime);
491 assert(ierr == CV_SUCCESS);
495 ierr = CVode(
mpCvodeMem, endTime, yout, &tend, CV_NORMAL);
500 CvodeError(ierr,
"CVODE failed to solve system");
502 if (ierr == CV_ROOT_RETURN)
508 assert(NV_DATA_S(yout) == &(rYValues[0]));
509 assert(!NV_OWN_DATA_S(yout));
516 assert(ierr == CV_SUCCESS);
525#if CHASTE_SUNDIALS_VERSION >= 60000
526 mpSundialsContextManager(CvodeContextManager::Instance()),
530 mLastInternalStepSize(-0.0),
532 mCheckForRoots(false),
533 mLastSolutionState(nullptr),
534 mLastSolutionTime(0.0),
536 mForceMinimalReset(false)
538 mpSundialsDenseMatrix(nullptr),
539 mpSundialsLinearSolver(nullptr)
555 for (
unsigned i = 0; i < size; i++)
#define EXCEPTION(message)
#define CHASTE_CLASS_EXPORT(T)
void DeleteVector(VECTOR &rVec)
void CreateVectorIfEmpty(VECTOR &rVec, unsigned size)
void SetVectorComponent(VECTOR &rVec, unsigned index, double value)
double GetVectorComponent(const VECTOR &rVec, unsigned index)
unsigned GetVectorSize(const VECTOR &rVec)
void CopyFromStdVector(const std::vector< double > &rSrc, VECTOR &rDest)
void CopyToStdVector(const VECTOR &rSrc, std::vector< double > &rDest)
bool mStoppingEventOccurred
virtual double CalculateRootFunction(double time, const std::vector< double > &rY)
virtual void EvaluateYDerivatives(double time, const std::vector< double > &rY, std::vector< double > &rDY)=0
virtual bool CalculateStoppingEvent(double time, const std::vector< double > &rY)
boost::shared_ptr< const AbstractOdeSystemInformation > GetSystemInformation() const
unsigned GetNumberOfStateVariables() const
static bool WithinAnyTolerance(double number1, double number2, double relTol=DBL_EPSILON, double absTol=DBL_EPSILON, bool printError=false)
double GetAbsoluteTolerance()
void CvodeError(int flag, const char *msg)
void SetMinimalReset(bool minimalReset)
N_Vector mLastSolutionState
SUNLinearSolver mpSundialsLinearSolver
void SetMaxSteps(long int numSteps)
void SetForceReset(bool autoReset)
void CheckForStoppingEvents()
OdeSolution Solve(AbstractOdeSystem *pOdeSystem, std::vector< double > &rYValues, double startTime, double endTime, double maxStep, double timeSampling)
double mLastInternalStepSize
void RecordStoppingPoint(double stopTime, N_Vector yEnd)
void SetupCvode(AbstractOdeSystem *pOdeSystem, std::vector< double > &rInitialY, double startTime, double maxStep)
double GetRelativeTolerance()
SUNMatrix mpSundialsDenseMatrix
void SetTolerances(double relTol=1e-4, double absTol=1e-6)
CvodeAdaptor(double relTol=1e-4, double absTol=1e-6)
void SetNumberOfTimeSteps(unsigned numTimeSteps)
std::vector< std::vector< double > > & rGetSolutions()
std::vector< double > & rGetTimes()
void SetOdeSystemInformation(boost::shared_ptr< const AbstractOdeSystemInformation > pOdeSystemInfo)
unsigned GetTotalTimeStepsTaken() const
void AdvanceOneTimeStep()
double GetNextTime() const
unsigned EstimateTimeSteps() const
AbstractOdeSystem * pSystem
std::vector< realtype > * pY