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
00030 #ifndef ABSTRACTBACKWARDEULERCARDIACCELL_HPP_
00031 #define ABSTRACTBACKWARDEULERCARDIACCELL_HPP_
00032
00033 #include <boost/serialization/access.hpp>
00034 #include <boost/serialization/is_abstract.hpp>
00035 #include <boost/serialization/base_object.hpp>
00036
00037 #include "AbstractCardiacCell.hpp"
00038
00039 #include <cassert>
00040 #include <cmath>
00041
00056 template<unsigned SIZE>
00057 class AbstractBackwardEulerCardiacCell : public AbstractCardiacCell
00058 {
00059 private:
00061 friend class boost::serialization::access;
00068 template<class Archive>
00069 void serialize(Archive & archive, const unsigned int version)
00070 {
00071
00072 archive & boost::serialization::base_object<AbstractCardiacCell>(*this);
00073 }
00074 public:
00075
00091 AbstractBackwardEulerCardiacCell(
00092 unsigned numberOfStateVariables,
00093 unsigned voltageIndex,
00094 boost::shared_ptr<AbstractStimulusFunction> pIntracellularStimulus);
00095
00097 virtual ~AbstractBackwardEulerCardiacCell();
00098
00105 virtual void ComputeResidual(const double rCurrentGuess[SIZE], double rResidual[SIZE])=0;
00106
00113 virtual void ComputeJacobian(const double rCurrentGuess[SIZE], double rJacobian[SIZE][SIZE])=0;
00114
00126 virtual OdeSolution Compute(double tStart, double tEnd);
00127
00137 virtual void ComputeExceptVoltage(double tStart, double tEnd);
00138
00139 private:
00140 #define COVERAGE_IGNORE
00141
00148 void EvaluateYDerivatives(double time, const std::vector<double> &rY, std::vector<double> &rDY)
00149 {
00150 NEVER_REACHED;
00151 }
00152 #undef COVERAGE_IGNORE
00153
00154 protected:
00163 virtual void ComputeOneStepExceptVoltage(double tStart)=0;
00164
00172 virtual void UpdateTransmembranePotential(double time)=0;
00173 };
00174
00175
00176
00177
00178
00179
00180
00181
00182 template <unsigned SIZE>
00183 AbstractBackwardEulerCardiacCell<SIZE>::AbstractBackwardEulerCardiacCell(
00184 unsigned numberOfStateVariables,
00185 unsigned voltageIndex,
00186 boost::shared_ptr<AbstractStimulusFunction> pIntracellularStimulus)
00187 : AbstractCardiacCell(boost::shared_ptr<AbstractIvpOdeSolver>(),
00188 numberOfStateVariables,
00189 voltageIndex,
00190 pIntracellularStimulus)
00191 {}
00192
00193 template <unsigned SIZE>
00194 AbstractBackwardEulerCardiacCell<SIZE>::~AbstractBackwardEulerCardiacCell()
00195 {}
00196
00197 template <unsigned SIZE>
00198 OdeSolution AbstractBackwardEulerCardiacCell<SIZE>::Compute(double tStart, double tEnd)
00199 {
00200
00201
00202
00203
00204
00205 double _n_steps = (tEnd - tStart) / mDt;
00206 unsigned n_steps = (unsigned) round(_n_steps);
00207 assert(fabs(tStart+n_steps*mDt - tEnd) < 1e-12);
00208
00209
00210 OdeSolution solutions;
00211 solutions.SetNumberOfTimeSteps(n_steps);
00212 solutions.rGetSolutions().push_back(rGetStateVariables());
00213 solutions.rGetTimes().push_back(tStart);
00214
00215
00216 double curr_time;
00217 for (unsigned i=0; i<n_steps; i++)
00218 {
00219 curr_time = tStart + i*mDt;
00220
00221
00222 UpdateTransmembranePotential(curr_time);
00223
00224
00225 ComputeOneStepExceptVoltage(curr_time);
00226
00227
00228 solutions.rGetSolutions().push_back(rGetStateVariables());
00229 solutions.rGetTimes().push_back(curr_time+mDt);
00230
00231
00232 VerifyStateVariables();
00233 }
00234
00235 return solutions;
00236 }
00237
00238 template <unsigned SIZE>
00239 void AbstractBackwardEulerCardiacCell<SIZE>::ComputeExceptVoltage(double tStart, double tEnd)
00240 {
00241
00242
00243
00244 double _n_steps = (tEnd - tStart) / mDt;
00245 unsigned n_steps = (unsigned) round(_n_steps);
00246 assert(fabs(tStart+n_steps*mDt - tEnd) < 1e-12);
00247
00248
00249 double curr_time;
00250 for (unsigned i=0; i<n_steps; i++)
00251 {
00252 curr_time = tStart + i*mDt;
00253
00254
00255 ComputeOneStepExceptVoltage(curr_time);
00256
00257
00258 VerifyStateVariables();
00259 }
00260 }
00261
00262 namespace boost
00263 {
00264 namespace serialization
00265 {
00271 template<unsigned SIZE>
00272 struct is_abstract<AbstractBackwardEulerCardiacCell<SIZE> >
00273 {
00275 typedef mpl::bool_<true> type;
00277 BOOST_STATIC_CONSTANT(bool, value=true);
00278 };
00279 }
00280 }
00281
00282
00283 #endif