00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef BACKWARDEULERIVPODESOLVER_HPP_
00030 #define BACKWARDEULERIVPODESOLVER_HPP_
00031
00032 #include "AbstractOneStepIvpOdeSolver.hpp"
00033 #include "AbstractOdeSystemWithAnalyticJacobian.hpp"
00034
00035 #include "ChasteSerialization.hpp"
00036 #include <boost/serialization/base_object.hpp>
00037
00038 #include "AbstractOneStepIvpOdeSolver.hpp"
00039
00044 class BackwardEulerIvpOdeSolver : public AbstractOneStepIvpOdeSolver
00045 {
00046 private:
00048 friend class boost::serialization::access;
00055 template<class Archive>
00056 void serialize(Archive & archive, const unsigned int version)
00057 {
00058
00059 archive & boost::serialization::base_object<AbstractOneStepIvpOdeSolver>(*this);
00060
00061 archive & mNumericalJacobianEpsilon;
00062 archive & mForceUseOfNumericalJacobian;
00063 }
00064
00066 unsigned mSizeOfOdeSystem;
00067
00069 double mNumericalJacobianEpsilon;
00070
00075 bool mForceUseOfNumericalJacobian;
00076
00077
00078
00079
00080
00081
00082
00084 double* mResidual;
00085
00087 double** mJacobian;
00088
00090 double* mUpdate;
00091
00101 void ComputeResidual(AbstractOdeSystem* pAbstractOdeSystem,
00102 double timeStep,
00103 double time,
00104 std::vector<double>& rCurrentYValues,
00105 std::vector<double>& rCurrentGuess);
00106
00116 void ComputeJacobian(AbstractOdeSystem* pAbstractOdeSystem,
00117 double timeStep,
00118 double time,
00119 std::vector<double>& rCurrentYValues,
00120 std::vector<double>& rCurrentGuess);
00121
00128 void SolveLinearSystem();
00129
00137 double ComputeNorm(double* pVector);
00138
00148 void ComputeNumericalJacobian(AbstractOdeSystem* pAbstractOdeSystem,
00149 double timeStep,
00150 double time,
00151 std::vector<double>& rCurrentYValues,
00152 std::vector<double>& rCurrentGuess);
00153
00154 protected:
00155
00169 void CalculateNextYValue(AbstractOdeSystem* pAbstractOdeSystem,
00170 double timeStep,
00171 double time,
00172 std::vector<double>& rCurrentYValues,
00173 std::vector<double>& rNextYValues);
00174
00175 public:
00176
00182 BackwardEulerIvpOdeSolver(unsigned sizeOfOdeSystem);
00183
00187 ~BackwardEulerIvpOdeSolver();
00188
00195 void SetEpsilonForNumericalJacobian(double epsilon);
00196
00201 void ForceUseOfNumericalJacobian();
00202
00208 unsigned GetSystemSize() const {return mSizeOfOdeSystem;};
00209 };
00210
00211 #include "SerializationExportWrapper.hpp"
00212 CHASTE_CLASS_EXPORT(BackwardEulerIvpOdeSolver)
00213
00214 namespace boost
00215 {
00216 namespace serialization
00217 {
00222 template<class Archive>
00223 inline void save_construct_data(
00224 Archive & ar, const BackwardEulerIvpOdeSolver * t, const unsigned int file_version)
00225 {
00226 const unsigned system_size = t->GetSystemSize();
00227 ar & system_size;
00228 }
00229
00236 template<class Archive>
00237 inline void load_construct_data(
00238 Archive & ar, BackwardEulerIvpOdeSolver * t, const unsigned int file_version)
00239 {
00240 unsigned ode_system_size;
00241 ar >> ode_system_size;
00242 ::new(t)BackwardEulerIvpOdeSolver(ode_system_size);
00243 }
00244 }
00245 }
00246
00247 #endif