MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
MarkovGslSolver.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2003-2011 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include "header.h"
11 #include <gsl/gsl_errno.h>
12 #include <gsl/gsl_odeiv.h>
13 #include "MarkovGslSolver.h"
14 
16 {
17  static SrcFinfo1< vector< double > > stateOut( "stateOut",
18  "Sends updated state to the MarkovChannel class." );
19  return &stateOut;
20 }
21 
23 {
25  // Field definitions
28  "isInitialized",
29  "True if the message has come in to set solver parameters.",
31  );
32  static ValueFinfo< MarkovGslSolver, string > method( "method",
33  "Numerical method to use.",
36  );
37  static ValueFinfo< MarkovGslSolver, double > relativeAccuracy(
38  "relativeAccuracy",
39  "Accuracy criterion",
42  );
43  static ValueFinfo< MarkovGslSolver, double > absoluteAccuracy(
44  "absoluteAccuracy",
45  "Another accuracy criterion",
48  );
49  static ValueFinfo< MarkovGslSolver, double > internalDt(
50  "internalDt",
51  "internal timestep to use.",
54  );
55 
57  // DestFinfo definitions
59  static DestFinfo init( "init",
60  "Initialize solver parameters.",
61  new OpFunc1< MarkovGslSolver, vector< double > >
63  );
64 
65  static DestFinfo handleQ( "handleQ",
66  "Handles information regarding the instantaneous rate matrix from "
67  "the MarkovRateTable class.",
68  new OpFunc1< MarkovGslSolver, vector< vector< double > > >( &MarkovGslSolver::handleQ) );
69 
70  static DestFinfo process( "process",
71  "Handles process call",
73  static DestFinfo reinit( "reinit",
74  "Handles reinit call",
77  // Shared definitions
79  static Finfo* procShared[] = {
80  &process, &reinit
81  };
82  static SharedFinfo proc( "proc",
83  "Shared message for process and reinit",
84  procShared, sizeof( procShared ) / sizeof( const Finfo* )
85  );
86 
87  static Finfo* MarkovGslFinfos[] =
88  {
89  &isInitialized, // ValueFinfo
90  &method, // ValueFinfo
91  &relativeAccuracy, // ValueFinfo
92  &absoluteAccuracy, // ValueFinfo
93  &internalDt, // ValueFinfo
94  &init, // DestFinfo
95  &handleQ, // DestFinfo
96  &proc, // SharedFinfo
97  stateOut(), // SrcFinfo
98  };
99 
100  static string doc[] =
101  {
102  "Name", "MarkovGslSolver",
103  "Author", "Vishaka Datta S, 2011, NCBS",
104  "Description", "Solver for Markov Channel."
105  };
106 
107  static Dinfo< MarkovGslSolver > dinfo;
109  "MarkovGslSolver",
111  MarkovGslFinfos,
112  sizeof(MarkovGslFinfos)/sizeof(Finfo *),
113  &dinfo,
114  doc,
115  sizeof(doc) / sizeof(string)
116  );
117 
118  return &MarkovGslSolverCinfo;
119 }
120 
122 
124 // Basic class function definitions
126 
128 {
129  isInitialized_ = 0;
130  method_ = "rk5";
131  gslStepType_ = gsl_odeiv_step_rkf45;
132  gslStep_ = 0;
133  nVars_ = 0;
134  absAccuracy_ = 1.0e-8;
135  relAccuracy_ = 1.0e-8;
136  internalStepSize_ = 1.0e-6;
137  stateGsl_ = 0;
138  gslEvolve_ = NULL;
139  gslControl_ = NULL;
140 }
141 
143 {
144  if ( gslEvolve_ )
145  gsl_odeiv_evolve_free( gslEvolve_ );
146  if ( gslControl_ )
147  gsl_odeiv_control_free( gslControl_ );
148  if ( gslStep_ )
149  gsl_odeiv_step_free( gslStep_ );
150 
151  if ( stateGsl_ )
152  delete[] stateGsl_;
153 }
154 
155 int MarkovGslSolver::evalSystem( double t, const double* state, double* f, void *params)
156 {
157  vector< vector< double > >* Q = static_cast< vector< vector< double > >* >( params );
158  unsigned int nVars = Q->size();
159 
160  //Matrix being accessed along columns, which is a very bad thing in terms of
161  //cache optimality. Transposing the matrix during reinit() would be a good idea.
162  for ( unsigned int i = 0; i < nVars; ++i)
163  {
164  f[i] = 0;
165  for ( unsigned int j = 0; j < nVars; ++j)
166  f[i] += state[j] * ((*Q)[j][i]);
167  }
168 
169  return GSL_SUCCESS;
170 }
171 
173 // Field function definitions
175 
177 {
178  return isInitialized_;
179 }
180 
182 {
183  return method_;
184 }
185 
186 void MarkovGslSolver::setMethod( string method )
187 {
188  method_ = method;
189  gslStepType_ = 0;
190 
191  if ( method == "rk2" ) {
192  gslStepType_ = gsl_odeiv_step_rk2;
193  } else if ( method == "rk4" ) {
194  gslStepType_ = gsl_odeiv_step_rk4;
195  } else if ( method == "rk5" ) {
196  gslStepType_ = gsl_odeiv_step_rkf45;
197  } else if ( method == "rkck" ) {
198  gslStepType_ = gsl_odeiv_step_rkck;
199  } else if ( method == "rk8pd" ) {
200  gslStepType_ = gsl_odeiv_step_rk8pd;
201  } else if ( method == "rk2imp" ) {
202  gslStepType_ = gsl_odeiv_step_rk2imp;
203  } else if ( method == "rk4imp" ) {
204  gslStepType_ = gsl_odeiv_step_rk4imp;
205  } else if ( method == "bsimp" ) {
206  gslStepType_ = gsl_odeiv_step_rk4imp;
207  cout << "Warning: implicit Bulirsch-Stoer method not yet implemented: needs Jacobian\n";
208  } else if ( method == "gear1" ) {
209  gslStepType_ = gsl_odeiv_step_gear1;
210  } else if ( method == "gear2" ) {
211  gslStepType_ = gsl_odeiv_step_gear2;
212  } else {
213  cout << "Warning: MarkovGslSolver::innerSetMethod: method '" <<
214  method << "' not known, using rk5\n";
215  gslStepType_ = gsl_odeiv_step_rkf45;
216  }
217 }
218 
220 {
221  return relAccuracy_;
222 }
223 
225 {
227 }
228 
230 {
231  return absAccuracy_;
232 }
234 {
236 }
237 
239 {
240  return internalStepSize_;
241 }
242 
244 {
246 }
247 
249 // Dest function definitions
251 
252 //Handles data from MarkovChannel class.
253 void MarkovGslSolver::init( vector< double > initialState )
254 {
255  nVars_ = initialState.size();
256 
257  if ( stateGsl_ == 0 )
258  stateGsl_ = new double[ nVars_ ];
259 
260  state_ = initialState;
261  initialState_ = initialState;
262 
263  Q_.resize( nVars_ );
264 
265  for ( unsigned int i = 0; i < nVars_; ++i )
266  Q_[i].resize( nVars_, 0.0 );
267 
268  isInitialized_ = 1;
269 
270  assert( gslStepType_ != 0 );
271  if ( gslStep_ )
272  gsl_odeiv_step_free(gslStep_);
273 
274  gslStep_ = gsl_odeiv_step_alloc( gslStepType_, nVars_ );
275  assert( gslStep_ != 0 );
276 
277  if ( !gslEvolve_ )
278  gslEvolve_ = gsl_odeiv_evolve_alloc(nVars_);
279  else
280  gsl_odeiv_evolve_reset(gslEvolve_);
281 
282  assert(gslEvolve_ != 0);
283 
284  if ( !gslControl_ )
285  gslControl_ = gsl_odeiv_control_y_new( absAccuracy_, relAccuracy_ );
286  else
287  gsl_odeiv_control_init(gslControl_,absAccuracy_, relAccuracy_, 1, 0);
288 
289  assert(gslControl_!= 0);
290 
292  gslSys_.jacobian = 0;
293  gslSys_.dimension = nVars_;
294  gslSys_.params = static_cast< void * >( &Q_ );
295 }
296 
298 //MsgDest functions.
301 {
302  double nextt = info->currTime + info->dt;
303  double t = info->currTime;
304  double sum = 0;
305 
306  for ( unsigned int i = 0; i < nVars_; ++i )
307  stateGsl_[i] = state_[i];
308 
309  while ( t < nextt ) {
310  int status = gsl_odeiv_evolve_apply (
312  &t, nextt,
314 
315  //Simple idea borrowed from Dieter Jaeger's implementation of a Markov
316  //channel to deal with potential round-off error.
317  sum = 0;
318  for ( unsigned int i = 0; i < nVars_; i++ )
319  sum += stateGsl_[i];
320 
321  for ( unsigned int i = 0; i < nVars_; i++ )
322  stateGsl_[i] /= sum;
323 
324  if ( status != GSL_SUCCESS )
325  break;
326  }
327 
328  for ( unsigned int i = 0; i < nVars_; ++i )
329  state_[i] = stateGsl_[i];
330 
331  stateOut()->send( e, state_ );
332 }
333 
335 {
337  if ( initialState_.empty() )
338  {
339  cerr << "MarkovGslSolver::reinit : "
340  "Initial state has not been set. Solver has not been initialized."
341  "Call init() before running.\n";
342  }
343 
344  stateOut()->send( e, state_ );
345 }
346 
347 void MarkovGslSolver::handleQ( vector< vector< double > > Q )
348 {
349  Q_ = Q;
350 }
uint32_t value
Definition: moosemodule.h:42
void setInternalDt(double value)
void reinit(const Eref &e, ProcPtr info)
static const Cinfo * MarkovGslSolverCinfo
double currTime
Definition: ProcInfo.h:19
static int evalSystem(double, const double *, double *, void *)
Definition: Dinfo.h:60
gsl_odeiv_step * gslStep_
vector< vector< double > > Q_
void setMethod(string method)
vector< double > state_
double internalStepSize_
gsl_odeiv_system gslSys_
gsl_odeiv_evolve * gslEvolve_
double getInternalDt() const
void init(vector< double >)
void process(const Eref &e, ProcPtr info)
static SrcFinfo1< vector< double > > * stateOut()
void setRelativeAccuracy(double value)
double dt
Definition: ProcInfo.h:18
const gsl_odeiv_step_type * gslStepType_
Definition: OpFunc.h:27
Definition: Eref.h:26
double getAbsoluteAccuracy() const
string getMethod() const
void handleQ(vector< vector< double > >)
bool getIsInitialized() const
void setAbsoluteAccuracy(double value)
vector< vector< T > > resize(vector< vector< T > >table, unsigned int n, T init)
gsl_odeiv_control * gslControl_
static const Cinfo * initCinfo()
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
unsigned int nVars_
Definition: Cinfo.h:18
vector< double > initialState_
double getRelativeAccuracy() const
Definition: Finfo.h:12