41 #include "AbstractCvodeSystem.hpp" 45 #include "TimeStepper.hpp" 46 #include "CvodeAdaptor.hpp" 49 #include <cvode/cvode.h> 50 #include <sundials/sundials_nvector.h> 51 #include <cvode/cvode_dense.h> 74 int AbstractCvodeSystemRhsAdaptor(realtype t,
N_Vector y,
N_Vector ydot,
void *pData)
76 assert(pData !=
nullptr);
84 #if CHASTE_SUNDIALS_VERSION <= 20300 92 std::cerr <<
"CVODE RHS Exception: " << e.
GetMessage()
93 << std::endl << std::flush;
115 #if CHASTE_SUNDIALS_VERSION >= 20500 117 int AbstractCvodeSystemJacAdaptor(
long int N, realtype t,
N_Vector y,
N_Vector ydot, DlsMat jacobian,
118 #elif CHASTE_SUNDIALS_VERSION >= 20400
120 int AbstractCvodeSystemJacAdaptor(
int N, realtype t,
N_Vector y,
N_Vector ydot, DlsMat jacobian,
123 int AbstractCvodeSystemJacAdaptor(
long int N, DenseMat jacobian, realtype t,
N_Vector y,
N_Vector ydot,
127 assert(pData !=
nullptr);
135 std::cerr <<
"CVODE Jacobian Exception: " << e.
GetMessage() << std::endl << std::flush;
143 mLastSolutionState(nullptr),
144 mLastSolutionTime(0.0),
145 #if CHASTE_SUNDIALS_VERSION >=20400
152 mForceMinimalReset(false),
153 mHasAnalyticJacobian(false),
154 mUseAnalyticJacobian(false),
157 mLastInternalStepSize(0)
194 assert(tEnd >= tStart);
219 double cvode_stopped_at = stepper.
GetTime();
221 &cvode_stopped_at, CV_NORMAL);
228 assert(fabs(cvode_stopped_at - stepper.
GetNextTime()) < DBL_EPSILON);
234 solutions.
rGetTimes().push_back(cvode_stopped_at);
253 assert(tEnd >= tStart);
258 int ierr = CVodeSetStopTime(
mpCvodeMem, tEnd);
261 double cvode_stopped_at = tStart;
266 CvodeError(ierr,
"CVODE failed to solve system", cvode_stopped_at, tStart, tEnd);
269 assert(fabs(cvode_stopped_at - tEnd) < DBL_EPSILON);
364 assert(maxDt >= 0.0);
372 for (
unsigned i=0; i<size; i++)
389 CVodeSetErrHandlerFn(
mpCvodeMem, CvodeErrorHandler,
nullptr);
391 #if CHASTE_SUNDIALS_VERSION >= 20400 397 #if CHASTE_SUNDIALS_VERSION >= 20400 398 CVodeInit(
mpCvodeMem, AbstractCvodeSystemRhsAdaptor, tStart, initialConditions);
401 CVodeMalloc(
mpCvodeMem, AbstractCvodeSystemRhsAdaptor, tStart, initialConditions,
405 CVDense(
mpCvodeMem, NV_LENGTH_S(initialConditions));
409 #if CHASTE_SUNDIALS_VERSION >= 20400 410 CVDlsSetDenseJacFn(
mpCvodeMem, AbstractCvodeSystemJacAdaptor);
412 CVDenseSetJacFn(
mpCvodeMem, AbstractCvodeSystemJacAdaptor, (
void*)(
this));
419 #if CHASTE_SUNDIALS_VERSION >= 20400 420 CVodeReInit(
mpCvodeMem, tStart, initialConditions);
423 CVodeReInit(
mpCvodeMem, AbstractCvodeSystemRhsAdaptor, tStart, initialConditions,
451 for (
unsigned i=0; i<size; i++)
470 const double& rTime,
const double& rStartTime,
const double& rEndTime)
472 std::stringstream err;
473 char* p_flag_name = CVodeGetReturnFlagName(flag);
474 err << msg <<
": " << p_flag_name;
476 if (flag == CV_LSETUP_FAIL)
478 #if CHASTE_SUNDIALS_VERSION >= 20500 483 char* p_ls_flag_name;
484 #if CHASTE_SUNDIALS_VERSION >= 20400 486 p_ls_flag_name = CVDlsGetReturnFlagName(ls_flag);
489 p_ls_flag_name = CVDenseGetReturnFlagName(ls_flag);
491 err <<
" (LS flag=" << ls_flag <<
":" << p_ls_flag_name <<
")";
492 free(p_ls_flag_name);
495 err <<
"\nGot from time " << rStartTime <<
" to time " << rTime <<
", was supposed to finish at time " << rEndTime <<
"\n";
496 err <<
"\nState variables are now:\n";
499 for (
unsigned i=0; i<state_vars.size(); i++)
501 err <<
"\t" << state_var_names[i] <<
"\t:\t" << state_vars[i] << std::endl;
505 std::cerr << err.str() << std::endl << std::flush;
524 EXCEPTION(
"Analytic Jacobian requested, but this ODE system doesn't have one. You can check this with HasAnalyticJacobian().");
587 #endif // CHASTE_CVODE double GetAbsoluteTolerance()
void SetMinimalReset(bool minimalReset)
void SetTolerances(double relTol=1e-5, double absTol=1e-7)
std::vector< double > MakeStdVec(N_Vector v)
void CvodeError(int flag, const char *msg, const double &rTime, const double &rStartTime, const double &rEndTime)
static bool WithinAnyTolerance(double number1, double number2, double relTol=DBL_EPSILON, double absTol=DBL_EPSILON, bool printError=false)
std::vector< std::vector< double > > & rGetSolutions()
bool GetUseAnalyticJacobian() const
void RecordStoppingPoint(double stopTime)
#define EXCEPTION(message)
double mLastInternalStepSize
void SetupCvode(N_Vector initialConditions, realtype tStart, realtype maxDt)
const std::vector< std::string > & rGetStateVariableNames() const
void AdvanceOneTimeStep()
unsigned GetNumberOfStateVariables() const
N_Vector GetInitialConditions() const
void CreateVectorIfEmpty(VECTOR &rVec, unsigned size)
void SetOdeSystemInformation(boost::shared_ptr< const AbstractOdeSystemInformation > pOdeSystemInfo)
bool mUseAnalyticJacobian
bool HasAnalyticJacobian() const
virtual void EvaluateAnalyticJacobian(long int N, realtype time, N_Vector y, N_Vector ydot, CHASTE_CVODE_DENSE_MATRIX jacobian, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
void SetForceReset(bool autoReset)
virtual void EvaluateYDerivatives(realtype time, const N_Vector y, N_Vector ydot)=0
std::string GetMessage() const
void SetVectorComponent(VECTOR &rVec, unsigned index, double value)
unsigned GetTotalTimeStepsTaken() const
void SetMaxSteps(long int numSteps)
virtual void VerifyStateVariables()
virtual ~AbstractCvodeSystem()
std::vector< double > & rGetTimes()
unsigned EstimateTimeSteps() const
double GetRelativeTolerance()
boost::shared_ptr< AbstractOdeSystemInformation > mpSystemInfo
OdeSolution Solve(realtype tStart, realtype tEnd, realtype maxDt, realtype tSamp)
N_Vector mLastSolutionState
std::string CheckShortMessageContains(std::string expected) const
double GetNextTime() const
double GetVectorComponent(const VECTOR &rVec, unsigned index)
void ForceUseOfNumericalJacobian(bool useNumericalJacobian=true)
AbstractCvodeSystem(unsigned numberOfStateVariables)
bool mHasAnalyticJacobian
void SetNumberOfTimeSteps(unsigned numTimeSteps)
const std::vector< std::string > & rGetParameterNames() const
void DeleteVector(VECTOR &rVec)