Chaste Release::3.1
BackwardEulerIvpOdeSolver.hpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #ifndef BACKWARDEULERIVPODESOLVER_HPP_
00037 #define BACKWARDEULERIVPODESOLVER_HPP_
00038 
00039 #include "AbstractOneStepIvpOdeSolver.hpp"
00040 #include "AbstractOdeSystemWithAnalyticJacobian.hpp"
00041 
00042 #include "ChasteSerialization.hpp"
00043 #include <boost/serialization/base_object.hpp>
00044 
00045 #include "AbstractOneStepIvpOdeSolver.hpp"
00046 
00051 class BackwardEulerIvpOdeSolver  : public AbstractOneStepIvpOdeSolver
00052 {
00053 private:
00055     friend class boost::serialization::access;
00062     template<class Archive>
00063     void serialize(Archive & archive, const unsigned int version)
00064     {
00065         // This calls serialize on the base class.
00066         archive & boost::serialization::base_object<AbstractOneStepIvpOdeSolver>(*this);
00067         //archive & mSizeOfOdeSystem; - this done in save and load construct now.
00068         archive & mNumericalJacobianEpsilon;
00069         archive & mForceUseOfNumericalJacobian;
00070     }
00071 
00073     unsigned mSizeOfOdeSystem;
00074 
00076     double mNumericalJacobianEpsilon;
00077 
00082     bool mForceUseOfNumericalJacobian;
00083 
00084     /*
00085      * NOTE: we use (unsafe) double pointers here rather than
00086      * std::vectors because using std::vectors would lead to a
00087      * slow down by a factor of about 4.
00088      */
00089 
00091     double* mResidual;
00092 
00094     double** mJacobian;
00095 
00097     double* mUpdate;
00098 
00108     void ComputeResidual(AbstractOdeSystem* pAbstractOdeSystem,
00109                          double timeStep,
00110                          double time,
00111                          std::vector<double>& rCurrentYValues,
00112                          std::vector<double>& rCurrentGuess);
00113 
00123     void ComputeJacobian(AbstractOdeSystem* pAbstractOdeSystem,
00124                          double timeStep,
00125                          double time,
00126                          std::vector<double>& rCurrentYValues,
00127                          std::vector<double>& rCurrentGuess);
00128 
00135     void SolveLinearSystem();
00136 
00144     double ComputeNorm(double* pVector);
00145 
00155     void ComputeNumericalJacobian(AbstractOdeSystem* pAbstractOdeSystem,
00156                                   double timeStep,
00157                                   double time,
00158                                   std::vector<double>& rCurrentYValues,
00159                                   std::vector<double>& rCurrentGuess);
00160 
00161 protected:
00162 
00176     void CalculateNextYValue(AbstractOdeSystem* pAbstractOdeSystem,
00177                              double timeStep,
00178                              double time,
00179                              std::vector<double>& rCurrentYValues,
00180                              std::vector<double>& rNextYValues);
00181 
00182 public:
00183 
00189     BackwardEulerIvpOdeSolver(unsigned sizeOfOdeSystem);
00190 
00194     ~BackwardEulerIvpOdeSolver();
00195 
00202     void SetEpsilonForNumericalJacobian(double epsilon);
00203 
00208     void ForceUseOfNumericalJacobian();
00209 
00215      unsigned GetSystemSize() const {return mSizeOfOdeSystem;};
00216 };
00217 
00218 #include "SerializationExportWrapper.hpp"
00219 CHASTE_CLASS_EXPORT(BackwardEulerIvpOdeSolver)
00220 
00221 namespace boost
00222 {
00223 namespace serialization
00224 {
00229 template<class Archive>
00230 inline void save_construct_data(
00231     Archive & ar, const BackwardEulerIvpOdeSolver * t, const unsigned int file_version)
00232 {
00233     const unsigned system_size = t->GetSystemSize();
00234     ar & system_size;
00235 }
00236 
00243 template<class Archive>
00244 inline void load_construct_data(
00245     Archive & ar, BackwardEulerIvpOdeSolver * t, const unsigned int file_version)
00246 {
00247      unsigned ode_system_size;
00248      ar >> ode_system_size;
00249      ::new(t)BackwardEulerIvpOdeSolver(ode_system_size);
00250 }
00251 }
00252 } // namespace ...
00253 
00254 #endif /*BACKWARDEULERIVPODESOLVER_HPP_*/