Chaste Commit::29c3c4ab2bee00ddd311a035a1e522c03cbe928a
AbstractCvodeSystem.hpp
1/*
2
3Copyright (c) 2005-2026, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, are permitted provided that the following conditions are met:
14 * Redistributions of source code must retain the above copyright notice,
15 this list of conditions and the following disclaimer.
16 * Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19 * Neither the name of the University of Oxford nor the names of its
20 contributors may be used to endorse or promote products derived from this
21 software without specific prior written permission.
22
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#ifndef _ABSTRACTCVODESYSTEM_HPP_
37#define _ABSTRACTCVODESYSTEM_HPP_
38
39#include <algorithm>
40#include <memory>
41#include <string>
42#include <vector>
43
44// This is only needed to prevent compilation errors on PETSc 2.2/Boost 1.33.1 combo
46
47// Chaste includes
48#include "AbstractParameterisedSystem.hpp"
49#include "CvodeContextManager.hpp"
50#include "Exception.hpp"
51#include "OdeSolution.hpp"
53
54// Serialiazation
55#include <boost/serialization/split_member.hpp>
56#include <boost/serialization/vector.hpp>
58#include "ClassIsAbstract.hpp"
59
60// CVODE headers
61#include <nvector/nvector_serial.h>
62
63#if CHASTE_SUNDIALS_VERSION < 70000
64#include <cvode/cvode_direct.h> /* access to CVDls interface */
65#endif
66#include <sundials/sundials_types.h> /* defs. of realtype, sunindextype */
67#include <sunlinsol/sunlinsol_dense.h> /* access to dense SUNLinearSolver */
68#include <sunmatrix/sunmatrix_dense.h> /* access to dense SUNMatrix */
69
70// CVODE changed their dense matrix type...
71#define CHASTE_CVODE_DENSE_MATRIX SUNMatrix
72
73// CVODE changed their way of referencing elements of a matrix. So we will copy their notation in examples.
74#define IJth(A, i, j) SM_ELEMENT_D(A, i, j)
75
131{
132private:
133 friend class TestAbstractCvodeSystem;
134
135 friend class boost::serialization::access;
142 template <class Archive>
143 void save(Archive& archive, const unsigned int version) const
144 {
145 // Despite the fact that 3 of these variables actually live in our base class,
146 // we still archive them here to maintain backwards compatibility,
147 // this doesn't hurt
149 archive& mUseAnalyticJacobian;
150
151 if (version >= 1u)
152 {
153 archive& mHasAnalyticJacobian;
154 }
155
156 // Convert from N_Vector to std::vector for serialization
157 const std::vector<double> state_vars = MakeStdVec(mStateVariables);
158 archive& state_vars;
159 const std::vector<double> params = MakeStdVec(mParameters);
160 archive& params;
161 archive& rGetParameterNames();
162
163 archive& mLastSolutionTime;
164 archive& mForceReset;
165 archive& mForceMinimalReset;
166 archive& mRelTol;
167 archive& mAbsTol;
168 archive& mMaxSteps;
169 archive& mLastInternalStepSize;
170
171 // We don't bother archiving CVODE's internal data, because it is missing then we'll just
172 // get a new solver being initialised after a save/load.
173
174 // This is always set up by subclass constructors, and is essentially
175 // 'static' data, so shouldn't go in the archive.
176 //archive &mpSystemInfo;
177 }
184 template <class Archive>
185 void load(Archive& archive, const unsigned int version)
186 {
188 archive& mUseAnalyticJacobian;
189
190 // This is pretty much what the code was saying before.
192 if (version >= 1u)
193 { // Overwrite if it has been archived though
194 archive& mHasAnalyticJacobian;
195 }
196
197 std::vector<double> state_vars;
198 archive& state_vars;
200
201 std::vector<double> parameters;
202 archive& parameters;
203
204 std::vector<std::string> param_names;
205 archive& param_names;
206 archive& mLastSolutionTime;
207 archive& mForceReset;
208 archive& mForceMinimalReset;
209 archive& mRelTol;
210 archive& mAbsTol;
211 archive& mMaxSteps;
212 archive& mLastInternalStepSize;
213
214 // We don't bother archiving CVODE's internal data, because it is missing then we'll just
215 // get a new solver being initialised after a save/load.
216
217 // Do some checking on the parameters
218 CheckParametersOnLoad(parameters, param_names);
219 }
220 BOOST_SERIALIZATION_SPLIT_MEMBER()
221
222
229 void SetupCvode(N_Vector initialConditions,
230 realtype tStart,
231 realtype maxDt);
232
237 void RecordStoppingPoint(double stopTime);
238
240 void FreeCvodeMemory();
241
252 void CvodeError(int flag, const char* msg, const double& rTime,
253 const double& rStartTime, const double& rEndTime);
254
257
260
263
266
270 SUNLinearSolver mpSundialsLinearSolver;
271
272protected:
275
278
280 double mRelTol;
281
283 double mAbsTol;
284
287
288#if CHASTE_SUNDIALS_VERSION >= 60000
293 std::shared_ptr<CvodeContextManager> mpSundialsContextManager;
294#endif
295
300 long int mMaxSteps;
301
304
309 void Init();
310
311public:
317 AbstractCvodeSystem(unsigned numberOfStateVariables);
318
322 virtual ~AbstractCvodeSystem();
323
331 virtual void EvaluateYDerivatives(realtype time,
332 const N_Vector y,
333 N_Vector ydot)
334 = 0;
335
351 virtual void EvaluateAnalyticJacobian(realtype time, N_Vector y, N_Vector ydot,
352 CHASTE_CVODE_DENSE_MATRIX jacobian,
353 N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
354 {
355 EXCEPTION("No analytic Jacobian has been defined for this system.");
356 }
357
368 void SetForceReset(bool autoReset);
369
378 void SetMinimalReset(bool minimalReset);
379
386 bool GetMinimalReset();
387
394 bool GetForceReset();
395
406 void ResetSolver();
407
427 OdeSolution Solve(realtype tStart,
428 realtype tEnd,
429 realtype maxDt,
430 realtype tSamp);
431
447 void Solve(realtype tStart,
448 realtype tEnd,
449 realtype maxDt);
450
457 void SetMaxSteps(long int numSteps);
458
463 long int GetMaxSteps();
464
472 void SetTolerances(double relTol = 1e-5, double absTol = 1e-7);
473
477 double GetRelativeTolerance();
478
482 double GetAbsoluteTolerance();
483
487 double GetLastStepSize();
488
489 /* NB This needs making into a doxygen comment if you bring the method back in.
490 *
491 * An alternative approach to stopping events; currently only useful with CVODE.
492 * CVODE can search for roots (zeros) of this function while solving the ODE system,
493 * and home in on them to find sign transitions to high precision.
494 *
495 * The default implementation here fakes a root function using CalculateStoppingEvent.
496 *
497 * @param time the current time
498 * @param rY the current values of the state variables
499 */
500 // virtual double CalculateRootFunction(double time, const std::vector<double>& rY);
501
505 bool GetUseAnalyticJacobian() const;
506
510 bool HasAnalyticJacobian() const;
511
518 void ForceUseOfNumericalJacobian(bool useNumericalJacobian = true);
519
520 // The following method may be useful to identify problems with the Analytic Jacobians, if anything goes wrong,
521 // but #1795 seems to have got these working OK, so commented out for now.
522
523 // /*
524 // * Compare the calculated analytic jacobian to a numerical approximation, and throw if it looks silly.
525 // *
526 // * @param time the current time
527 // * @param y the current state variables
528 // * @param jacobian the analytic jacobian matrix
529 // * @param tmp1 working memory of the correct size provided by CVODE for temporary calculations
530 // * @param tmp2 working memory of the correct size provided by CVODE for temporary calculations
531 // * @param tmp3 working memory of the correct size provided by CVODE for temporary calculations
532 // */
533 // void CheckAnalyticJacobian(realtype time, N_Vector y, N_Vector ydot,
534 // CHASTE_CVODE_DENSE_MATRIX jacobian,
535 // N_Vector tmp1, N_Vector tmp2, N_Vector tmp3);
536};
537
539BOOST_CLASS_VERSION(AbstractCvodeSystem, 1u)
540
541#endif //_ABSTRACTCVODESYSTEM_HPP_
#define CLASS_IS_ABSTRACT(T)
#define EXCEPTION(message)
std::vector< double > MakeStdVec(N_Vector v)
void CopyFromStdVector(const std::vector< double > &rSrc, VECTOR &rDest)
void SetTolerances(double relTol=1e-5, double absTol=1e-7)
bool GetMinimalReset()
Get whether we want to run with minimal reset or not (no reinitialisation of the solver if variables ...
void SetForceReset(bool autoReset)
void load(Archive &archive, const unsigned int version)
void SetupCvode(N_Vector initialConditions, realtype tStart, realtype maxDt)
void CvodeError(int flag, const char *msg, const double &rTime, const double &rStartTime, const double &rEndTime)
void RecordStoppingPoint(double stopTime)
void SetMaxSteps(long int numSteps)
OdeSolution Solve(realtype tStart, realtype tEnd, realtype maxDt, realtype tSamp)
void ForceUseOfNumericalJacobian(bool useNumericalJacobian=true)
virtual void EvaluateYDerivatives(realtype time, const N_Vector y, N_Vector ydot)=0
void save(Archive &archive, const unsigned int version) const
SUNLinearSolver mpSundialsLinearSolver
virtual void EvaluateAnalyticJacobian(realtype time, N_Vector y, N_Vector ydot, CHASTE_CVODE_DENSE_MATRIX jacobian, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
void SetMinimalReset(bool minimalReset)
bool GetForceReset()
Get whether we will force a solver reset on every call to Solve()
void CheckParametersOnLoad(const std::vector< double > &rParameters, const std::vector< std::string > &rParameterNames)
const std::vector< std::string > & rGetParameterNames() const