MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Ksolve.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-2010 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 #include "../basecode/header.h"
10 #ifdef USE_GSL
11 #include <gsl/gsl_errno.h>
12 #include <gsl/gsl_matrix.h>
13 #include <gsl/gsl_odeiv2.h>
14 #endif
15 
16 #include "OdeSystem.h"
17 #include "VoxelPoolsBase.h"
18 #include "VoxelPools.h"
19 #include "../mesh/VoxelJunction.h"
20 #include "ZombiePoolInterface.h"
21 
22 #include "RateTerm.h"
23 #include "FuncTerm.h"
24 #include "../basecode/SparseMatrix.h"
25 #include "KinSparseMatrix.h"
26 #include "Stoich.h"
27 #include "../shell/Shell.h"
28 
29 #include "../mesh/MeshEntry.h"
30 #include "../mesh/Boundary.h"
31 #include "../mesh/ChemCompt.h"
32 #include "Ksolve.h"
33 
34 #include <future>
35 #include <atomic>
36 #include <thread>
37 
38 const unsigned int OFFNODE = ~0;
39 
41 {
43  // Field definitions
45 
46  static ValueFinfo< Ksolve, string > method (
47  "method",
48  "Integration method, using GSL. So far only explict. Options are:"
49  "rk5: The default Runge-Kutta-Fehlberg 5th order adaptive dt method"
50  "gsl: alias for the above"
51  "rk4: The Runge-Kutta 4th order fixed dt method"
52  "rk2: The Runge-Kutta 2,3 embedded fixed dt method"
53  "rkck: The Runge-Kutta Cash-Karp (4,5) method"
54  "rk8: The Runge-Kutta Prince-Dormand (8,9) method" ,
57  );
58 
59  static ValueFinfo< Ksolve, double > epsAbs (
60  "epsAbs",
61  "Absolute permissible integration error range.",
64  );
65 
66  static ValueFinfo< Ksolve, double > epsRel (
67  "epsRel",
68  "Relative permissible integration error range.",
71  );
72 
73 
74  static ValueFinfo< Ksolve, Id > compartment(
75  "compartment",
76  "Compartment in which the Ksolve reaction system lives.",
79  );
80 
81  static ReadOnlyValueFinfo< Ksolve, unsigned int > numLocalVoxels(
82  "numLocalVoxels",
83  "Number of voxels in the core reac-diff system, on the "
84  "current solver. ",
86  );
87  static LookupValueFinfo<
88  Ksolve, unsigned int, vector< double > > nVec(
89  "nVec",
90  "vector of pool counts. Index specifies which voxel.",
93  );
94  static ValueFinfo< Ksolve, unsigned int > numAllVoxels(
95  "numAllVoxels",
96  "Number of voxels in the entire reac-diff system, "
97  "including proxy voxels to represent abutting compartments.",
100  );
101 
102 #if PARALLELIZE_KSOLVE_WITH_CPP11_ASYNC
103  static ValueFinfo< Ksolve, unsigned int > numThreads (
104  "numThreads",
105  "Number of threads to use (applicable in deterministic case)",
106  &Ksolve::setNumThreads,
107  &Ksolve::getNumThreads
108  );
109 #endif
110 
111  static ValueFinfo< Ksolve, unsigned int > numPools(
112  "numPools",
113  "Number of molecular pools in the entire reac-diff system, "
114  "including variable, function and buffered.",
117  );
118 
119  static ReadOnlyValueFinfo< Ksolve, double > estimatedDt(
120  "estimatedDt",
121  "Estimated timestep for reac system based on Euler error",
123  );
124  static ReadOnlyValueFinfo< Ksolve, Id > stoich(
125  "stoich",
126  "Id for stoichiometry object tied to this Ksolve",
128  );
129 
130 
132  // DestFinfo definitions
134 
135  static DestFinfo process( "process",
136  "Handles process call from Clock",
138  static DestFinfo reinit( "reinit",
139  "Handles reinit call from Clock",
141 
142  static DestFinfo initProc( "initProc",
143  "Handles initProc call from Clock",
145  static DestFinfo initReinit( "initReinit",
146  "Handles initReinit call from Clock",
148 
149  static DestFinfo voxelVol( "voxelVol",
150  "Handles updates to all voxels. Comes from parent "
151  "ChemCompt object.",
152  new OpFunc1< Ksolve, vector< double > >(
154  );
156  // Shared definitions
158  static Finfo* procShared[] =
159  {
160  &process, &reinit
161  };
162  static SharedFinfo proc( "proc",
163  "Shared message for process and reinit. These are used for "
164  "all regular Ksolve calculations including interfacing with "
165  "the diffusion calculations by a Dsolve.",
166  procShared, sizeof( procShared ) / sizeof( const Finfo* )
167  );
168  static Finfo* initShared[] =
169  {
170  &initProc, &initReinit
171  };
172  static SharedFinfo init( "init",
173  "Shared message for initProc and initReinit. This is used"
174  " when the system has cross-compartment reactions. ",
175  initShared, sizeof( initShared ) / sizeof( const Finfo* )
176  );
177 
178  static Finfo* ksolveFinfos[] =
179  {
180  &method, // Value
181  &epsAbs, // Value
182  &epsRel , // Value
183 #if PARALLELIZE_KSOLVE_WITH_CPP11_ASYNC
184  &numThreads, // Value
185 #endif
186  &compartment, // Value
187  &numLocalVoxels, // ReadOnlyValue
188  &nVec, // LookupValue
189  &numAllVoxels, // ReadOnlyValue
190  &numPools, // Value
191  &estimatedDt, // ReadOnlyValue
192  &stoich, // ReadOnlyValue
193  &voxelVol, // DestFinfo
194  &proc, // SharedFinfo
195  &init, // SharedFinfo
196  };
197 
198  static Dinfo< Ksolve > dinfo;
199  static Cinfo ksolveCinfo(
200  "Ksolve",
202  ksolveFinfos,
203  sizeof(ksolveFinfos)/sizeof(Finfo *),
204  &dinfo
205  );
206 
207  return &ksolveCinfo;
208 }
209 
211 
213 // Class definitions
215 
217  :
218 #if USE_GSL
219  method_( "rk5" ),
220 #elif USE_BOOST_ODE
221  method_( "rk5a" ),
222 #endif
223  epsAbs_( 1e-7 ),
224  epsRel_( 1e-7 ),
225 #if PARALLELIZE_KSOLVE_WITH_CPP11_ASYNC
226  numThreads_( 3 ),
227 #endif
228  pools_( 1 ),
229  startVoxel_( 0 ),
230  dsolve_(),
231  dsolvePtr_( 0 )
232 {
233  ;
234 }
235 
237 {
238  ;
239 }
240 
242 // Field Access functions
244 
245 string Ksolve::getMethod() const
246 {
247  return method_;
248 }
249 
250 void Ksolve::setMethod( string method )
251 {
252 #if USE_GSL
253  if ( method == "rk5" || method == "gsl" )
254  {
255  method_ = "rk5";
256  }
257  else if ( method == "rk4" || method == "rk2" ||
258  method == "rk8" || method == "rkck" )
259  {
260  method_ = method;
261  }
262  else
263  {
264  cout << "Warning: Ksolve::setMethod: '" << method <<
265  "' not known, using rk5\n";
266  method_ = "rk5";
267  }
268 #elif USE_BOOST_ODE
269  // TODO: Check for boost related methods.
270  method_ = method;
271 #endif
272 }
273 
274 double Ksolve::getEpsAbs() const
275 {
276  return epsAbs_;
277 }
278 
279 void Ksolve::setEpsAbs( double epsAbs )
280 {
281  if ( epsAbs < 0 )
282  epsAbs_ = 1.0e-4;
283  else
284  epsAbs_ = epsAbs;
285 }
286 
287 
288 double Ksolve::getEpsRel() const
289 {
290  return epsRel_;
291 }
292 
293 void Ksolve::setEpsRel( double epsRel )
294 {
295  if ( epsRel < 0 )
296  {
297  epsRel_ = 1.0e-6;
298  }
299  else
300  {
301  epsRel_ = epsRel;
302  }
303 }
304 
305 #if PARALLELIZE_KSOLVE_WITH_CPP11_ASYNC
306 void Ksolve::setNumThreads( unsigned int x )
307 {
308  numThreads_ = x;
309 }
310 
311 unsigned int Ksolve::getNumThreads( ) const
312 {
313  return numThreads_;
314 }
315 #endif
316 
318 {
319  return stoich_;
320 }
321 
322 #ifdef USE_GSL
323 void innerSetMethod( OdeSystem& ode, const string& method )
324 {
325  ode.method = method;
326  if ( method == "rk5" )
327  {
328  ode.gslStep = gsl_odeiv2_step_rkf45;
329  }
330  else if ( method == "rk4" )
331  {
332  ode.gslStep = gsl_odeiv2_step_rk4;
333  }
334  else if ( method == "rk2" )
335  {
336  ode.gslStep = gsl_odeiv2_step_rk2;
337  }
338  else if ( method == "rkck" )
339  {
340  ode.gslStep = gsl_odeiv2_step_rkck;
341  }
342  else if ( method == "rk8" )
343  {
344  ode.gslStep = gsl_odeiv2_step_rk8pd;
345  }
346  else
347  {
348  ode.gslStep = gsl_odeiv2_step_rkf45;
349  }
350 }
351 #endif
352 
353 void Ksolve::setStoich( Id stoich )
354 {
355  assert( stoich.element()->cinfo()->isA( "Stoich" ) );
356  stoich_ = stoich;
357  stoichPtr_ = reinterpret_cast< Stoich* >( stoich.eref().data() );
358  if ( !isBuilt_ )
359  {
360  OdeSystem ode;
361  ode.epsAbs = epsAbs_;
362  ode.epsRel = epsRel_;
363  // ode.initStepSize = getEstimatedDt();
364  ode.initStepSize = 0.01; // This will be overridden at reinit.
365  ode.method = method_;
366 #ifdef USE_GSL
367  ode.gslSys.dimension = stoichPtr_->getNumAllPools();
368  if ( ode.gslSys.dimension == 0 ) {
369  stoichPtr_ = 0;
370  return; // No pools, so don't bother.
371  }
372  innerSetMethod( ode, method_ );
373  ode.gslSys.function = &VoxelPools::gslFunc;
374  ode.gslSys.jacobian = 0;
375  innerSetMethod( ode, method_ );
376  unsigned int numVoxels = pools_.size();
377  for ( unsigned int i = 0 ; i < numVoxels; ++i )
378  {
379  ode.gslSys.params = &pools_[i];
380  pools_[i].setStoich( stoichPtr_, &ode );
381  // pools_[i].setIntDt( ode.initStepSize ); // We're setting it up anyway
382  }
383 #elif USE_BOOST_ODE
384  ode.dimension = stoichPtr_->getNumAllPools();
385  ode.boostSys.epsAbs = epsAbs_;
386  ode.boostSys.epsRel = epsRel_;
387  ode.boostSys.method = method_;
388  if ( ode.dimension == 0 )
389  return; // No pools, so don't bother.
390  unsigned int numVoxels = pools_.size();
391  for ( unsigned int i = 0 ; i < numVoxels; ++i )
392  {
393  ode.boostSys.params = &pools_[i];
394  pools_[i].setStoich( stoichPtr_, &ode );
395  }
396 #endif
397  isBuilt_ = true;
398  }
399 }
400 
402 {
403  return dsolve_;
404 }
405 
406 void Ksolve::setDsolve( Id dsolve )
407 {
408  if ( dsolve == Id () )
409  {
410  dsolvePtr_ = 0;
411  dsolve_ = Id();
412  }
413  else if ( dsolve.element()->cinfo()->isA( "Dsolve" ) )
414  {
415  dsolve_ = dsolve;
416  dsolvePtr_ = reinterpret_cast< ZombiePoolInterface* >(
417  dsolve.eref().data() );
418  }
419  else
420  {
421  cout << "Warning: Ksolve::setDsolve: Object '" << dsolve.path() <<
422  "' should be class Dsolve, is: " <<
423  dsolve.element()->cinfo()->name() << endl;
424  }
425 }
426 
427 unsigned int Ksolve::getNumLocalVoxels() const
428 {
429  return pools_.size();
430 }
431 
432 unsigned int Ksolve::getNumAllVoxels() const
433 {
434  return pools_.size(); // Need to redo.
435 }
436 
437 // If we're going to do this, should be done before the zombification.
438 void Ksolve::setNumAllVoxels( unsigned int numVoxels )
439 {
440  if ( numVoxels == 0 )
441  {
442  return;
443  }
444  pools_.resize( numVoxels );
445 }
446 
447 vector< double > Ksolve::getNvec( unsigned int voxel) const
448 {
449  static vector< double > dummy;
450  if ( voxel < pools_.size() )
451  {
452  return const_cast< VoxelPools* >( &( pools_[ voxel ] ) )->Svec();
453  }
454  return dummy;
455 }
456 
457 void Ksolve::setNvec( unsigned int voxel, vector< double > nVec )
458 {
459  if ( voxel < pools_.size() )
460  {
461  if ( nVec.size() != pools_[voxel].size() )
462  {
463  cout << "Warning: Ksolve::setNvec: size mismatch ( " <<
464  nVec.size() << ", " << pools_[voxel].size() << ")\n";
465  return;
466  }
467  double* s = pools_[voxel].varS();
468  for ( unsigned int i = 0; i < nVec.size(); ++i )
469  s[i] = nVec[i];
470  }
471 }
472 
473 
475 {
476  static const double EPSILON = 1e-15;
477  vector< double > s( stoichPtr_->getNumAllPools(), 1.0 );
478  vector< double > v( stoichPtr_->getNumRates(), 0.0 );
479  double maxVel = 0.0;
480  if ( pools_.size() > 0.0 )
481  {
482  pools_[0].updateReacVelocities( &s[0], v );
483  for ( vector< double >::iterator
484  i = v.begin(); i != v.end(); ++i )
485  if ( maxVel < *i )
486  maxVel = *i;
487  }
488  if ( maxVel < EPSILON )
489  return 0.1; // Based on typical sig pathway reac rates.
490  // Heuristic: the largest velocity times dt should be 10% of mol conc.
491  return 0.1 / maxVel;
492 }
493 
495 // Process operations.
497 void Ksolve::process( const Eref& e, ProcPtr p )
498 {
499  if ( isBuilt_ == false )
500  return;
501 
502  // First, handle incoming diffusion values, update S with those.
503  if ( dsolvePtr_ )
504  {
505  vector< double > dvalues( 4 );
506  dvalues[0] = 0;
507  dvalues[1] = getNumLocalVoxels();
508  dvalues[2] = 0;
509  dvalues[3] = stoichPtr_->getNumVarPools();
510 
511  dsolvePtr_->getBlock( dvalues );
512  // Second, set the prev_ value in DiffPoolVec
513  dsolvePtr_->setPrev();
514  setBlock( dvalues );
515  }
516 
517  size_t nvPools = pools_.size( );
518 
519 #ifdef PARALLELIZE_KSOLVE_WITH_CPP11_ASYNC
520  // Third, do the numerical integration for all reactions.
521  size_t grainSize = min( nvPools, 1 + (nvPools / numThreads_ ) );
522  size_t nWorkers = nvPools / grainSize;
523 
524  if( 1 == nWorkers || 1 == nvPools )
525  {
526  if( numThreads_ > 1 )
527  {
528 #ifndef NDEBUG
529  cout << "Debug: Reset to 1 threads " << endl;
530 #endif
531  numThreads_ = 1;
532  }
533 
534  for ( size_t i = 0; i < nvPools; i++ )
535  pools_[i].advance( p );
536  }
537  else
538  {
539  /*-----------------------------------------------------------------------------
540  * Somewhat complicated computation to compute the number of threads. 1
541  * thread per (at least) voxel pool is ideal situation.
542  *-----------------------------------------------------------------------------*/
543  //cout << "Grain size " << grainSize << " Workers : " << nWorkers << endl;
544  for (size_t i = 0; i < nWorkers; i++)
545  parallel_advance( i * grainSize, (i+1) * grainSize, nWorkers, p );
546  }
547 #else
548  for ( size_t i = 0; i < nvPools; i++ )
549  pools_[i].advance( p );
550 #endif
551 
552 
553  // Assemble and send the integrated values off for the Dsolve.
554  if ( dsolvePtr_ )
555  {
556  vector< double > kvalues( 4 );
557  kvalues[0] = 0;
558  kvalues[1] = getNumLocalVoxels();
559  kvalues[2] = 0;
560  kvalues[3] = stoichPtr_->getNumVarPools();
561  getBlock( kvalues );
562  dsolvePtr_->setBlock( kvalues );
563 
564  // Now use the values in the Dsolve to update junction fluxes
565  // for diffusion, channels, and xreacs
567  }
568 }
569 
570 
571 #if PARALLELIZE_KSOLVE_WITH_CPP11_ASYNC
572 
579 void Ksolve::parallel_advance(int begin, int end, size_t nWorkers, ProcPtr p)
580 {
581  std::atomic<int> idx( begin );
582  for (size_t cpu = 0; cpu != nWorkers; ++cpu)
583  {
584  std::async( std::launch::async
585  , [this, &idx, end, p]() {
586  for (;;)
587  {
588  int i = idx++;
589  if (i >= end)
590  break;
591  pools_[i].advance( p );
592  }
593  }
594  );
595  }
596 }
597 #endif
598 
599 
600 void Ksolve::reinit( const Eref& e, ProcPtr p )
601 {
602  if ( !stoichPtr_ )
603  return;
604 
605  if ( isBuilt_ )
606  {
607  for ( unsigned int i = 0 ; i < pools_.size(); ++i )
608  pools_[i].reinit( p->dt );
609  }
610  else
611  {
612  cout << "Warning:Ksolve::reinit: Reaction system not initialized\n";
613  return;
614  }
615 
616 #if PARALLELIZE_KSOLVE_WITH_CPP11_ASYNC
617  if( 1 < getNumThreads( ) )
618  cout << "Debug: User wants Ksolve with " << numThreads_ << " threads" << endl;
619 #endif
620 
621 }
622 
624 // init operations.
626 void Ksolve::initProc( const Eref& e, ProcPtr p )
627 {
628 }
629 
630 void Ksolve::initReinit( const Eref& e, ProcPtr p )
631 {
632  for ( unsigned int i = 0 ; i < pools_.size(); ++i )
633  pools_[i].reinit( p->dt );
634 }
635 
641 void Ksolve::updateRateTerms( unsigned int index )
642 {
643  if ( index == ~0U )
644  {
645  // unsigned int numCrossRates = stoichPtr_->getNumRates() - stoichPtr_->getNumCoreRates();
646  for ( unsigned int i = 0 ; i < pools_.size(); ++i )
647  {
648  // pools_[i].resetXreacScale( numCrossRates );
649  pools_[i].updateAllRateTerms( stoichPtr_->getRateTerms(),
651  }
652  }
653  else if ( index < stoichPtr_->getNumRates() )
654  {
655  for ( unsigned int i = 0 ; i < pools_.size(); ++i )
657  stoichPtr_->getNumCoreRates(), index );
658  }
659 }
660 
661 
663 // Solver ops
665 
666 unsigned int Ksolve::getPoolIndex( const Eref& e ) const
667 {
668  return stoichPtr_->convertIdToPoolIndex( e.id() );
669 }
670 
671 unsigned int Ksolve::getVoxelIndex( const Eref& e ) const
672 {
673  unsigned int ret = e.dataIndex();
674  if ( ret < startVoxel_ || ret >= startVoxel_ + pools_.size() )
675  return OFFNODE;
676  return ret - startVoxel_;
677 }
678 
680 // Zombie Pool Access functions
682 
683 void Ksolve::setN( const Eref& e, double v )
684 {
685  unsigned int vox = getVoxelIndex( e );
686  if ( vox != OFFNODE )
687  pools_[vox].setN( getPoolIndex( e ), v );
688 }
689 
690 double Ksolve::getN( const Eref& e ) const
691 {
692  unsigned int vox = getVoxelIndex( e );
693  if ( vox != OFFNODE )
694  return pools_[vox].getN( getPoolIndex( e ) );
695  return 0.0;
696 }
697 
698 void Ksolve::setNinit( const Eref& e, double v )
699 {
700  unsigned int vox = getVoxelIndex( e );
701  if ( vox != OFFNODE )
702  pools_[vox].setNinit( getPoolIndex( e ), v );
703 }
704 
705 double Ksolve::getNinit( const Eref& e ) const
706 {
707  unsigned int vox = getVoxelIndex( e );
708  if ( vox != OFFNODE )
709  return pools_[vox].getNinit( getPoolIndex( e ) );
710  return 0.0;
711 }
712 
713 void Ksolve::setDiffConst( const Eref& e, double v )
714 {
715  ; // Do nothing.
716 }
717 
718 double Ksolve::getDiffConst( const Eref& e ) const
719 {
720  return 0;
721 }
722 
723 void Ksolve::setNumPools( unsigned int numPoolSpecies )
724 {
725  unsigned int numVoxels = pools_.size();
726  for ( unsigned int i = 0 ; i < numVoxels; ++i )
727  {
728  pools_[i].resizeArrays( numPoolSpecies );
729  }
730 }
731 
732 unsigned int Ksolve::getNumPools() const
733 {
734  if ( pools_.size() > 0 )
735  return pools_[0].size();
736  return 0;
737 }
738 
739 VoxelPoolsBase* Ksolve::pools( unsigned int i )
740 {
741  if ( pools_.size() > i )
742  return &pools_[i];
743  return 0;
744 }
745 
746 double Ksolve::volume( unsigned int i ) const
747 {
748  if ( pools_.size() > i )
749  return pools_[i].getVolume();
750  return 0.0;
751 }
752 
753 void Ksolve::getBlock( vector< double >& values ) const
754 {
755  unsigned int startVoxel = values[0];
756  unsigned int numVoxels = values[1];
757  unsigned int startPool = values[2];
758  unsigned int numPools = values[3];
759 
760  assert( startVoxel >= startVoxel_ );
761  assert( numVoxels <= pools_.size() );
762  assert( pools_.size() > 0 );
763  assert( numPools + startPool <= pools_[0].size() );
764  values.resize( 4 + numVoxels * numPools );
765 
766  for ( unsigned int i = 0; i < numVoxels; ++i )
767  {
768  const double* v = pools_[ startVoxel + i ].S();
769  for ( unsigned int j = 0; j < numPools; ++j )
770  {
771  values[ 4 + j * numVoxels + i] = v[ j + startPool ];
772  }
773  }
774 }
775 
776 void Ksolve::setBlock( const vector< double >& values )
777 {
778  unsigned int startVoxel = values[0];
779  unsigned int numVoxels = values[1];
780  unsigned int startPool = values[2];
781  unsigned int numPools = values[3];
782 
783  assert( startVoxel >= startVoxel_ );
784  assert( numVoxels <= pools_.size() );
785  assert( pools_.size() > 0 );
786  assert( numPools + startPool <= pools_[0].size() );
787  assert( values.size() == 4 + numVoxels * numPools );
788 
789  for ( unsigned int i = 0; i < numVoxels; ++i )
790  {
791  double* v = pools_[ startVoxel + i ].varS();
792  for ( unsigned int j = 0; j < numPools; ++j )
793  {
794  v[ j + startPool ] = values[ 4 + j * numVoxels + i ];
795  }
796  }
797 }
798 
800 void Ksolve::updateVoxelVol( vector< double > vols )
801 {
802  // For now we assume identical numbers of voxels. Also assume
803  // identical voxel junctions. But it should not be too hard to
804  // update those too.
805  if ( vols.size() == pools_.size() )
806  {
807  for ( unsigned int i = 0; i < vols.size(); ++i )
808  {
809  pools_[i].setVolumeAndDependencies( vols[i] );
810  }
811  updateRateTerms( ~0U );
812  }
813 }
814 
816 // cross-compartment reaction stuff.
818 
820 // Functions for setup of cross-compartment transfer.
822 
823 void Ksolve::print() const
824 {
825  cout << "path = " << stoichPtr_->getKsolve().path() <<
826  ", numPools = " << pools_.size() << "\n";
827  for ( unsigned int i = 0; i < pools_.size(); ++i )
828  {
829  cout << "pools[" << i << "] contents = ";
830  pools_[i].print();
831  }
832  cout << "method = " << method_ << ", stoich=" << stoich_.path() <<endl;
833  cout << "dsolve = " << dsolve_.path() << endl;
834  cout << "compartment = " << compartment_.path() << endl;
835 }
836 
Id id() const
Definition: Eref.cpp:62
void updateRateTerms(unsigned int index)
Definition: Ksolve.cpp:641
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
Definition: main.cpp:150
vector< VoxelPools > pools_
Definition: Ksolve.h:156
void setDsolve(Id dsolve)
Assigns the diffusion solver. Used by the reac solvers.
Definition: Ksolve.cpp:406
static const Cinfo * initCinfo()
Definition: Ksolve.cpp:40
char * data() const
Definition: Eref.cpp:41
void getBlock(vector< double > &values) const
Definition: Ksolve.cpp:753
void setNinit(const Eref &e, double v)
Set initial # of molecules in given pool and voxel. Bdry cond.
Definition: Ksolve.cpp:698
VoxelPoolsBase * pools(unsigned int i)
Return a pointer to the specified VoxelPool.
Definition: Ksolve.cpp:739
Element * element() const
Synonym for Id::operator()()
Definition: Id.cpp:113
void setNumPools(unsigned int num)
Definition: Ksolve.cpp:723
string getMethod() const
Assigns integration method.
Definition: Ksolve.cpp:245
std::string path(const std::string &separator="/") const
Definition: Id.cpp:76
Definition: Dinfo.h:60
void reinit(const Eref &e, ProcPtr p)
Definition: Ksolve.cpp:600
static DestFinfo dummy("dummy","This Finfo is a dummy. If you are reading this you have used an invalid index", 0)
Id dsolve_
Definition: Ksolve.h:167
Id getKsolve() const
Definition: Stoich.cpp:446
~Ksolve()
Definition: Ksolve.cpp:236
unsigned int dataIndex() const
Definition: Eref.h:50
std::string method
Definition: OdeSystem.h:28
double epsAbs
Definition: OdeSystem.h:36
Stoich * stoichPtr_
Utility ptr used to help Pool Id lookups by the Ksolve.
Definition: Ksolve.h:162
double epsRel
Definition: OdeSystem.h:37
void updateVoxelVol(vector< double > vols)
Definition: Ksolve.cpp:800
double volume(unsigned int i) const
Return volume of voxel i.
Definition: Ksolve.cpp:746
Eref eref() const
Definition: Id.cpp:125
static const Cinfo * ksolveCinfo
Definition: Ksolve.cpp:210
virtual void updateJunctions(double dt)
Used for telling Dsolver to handle all ops across Junctions.
void print() const
Definition: Ksolve.cpp:823
void advance(vector< double > &y, const vector< Triplet< double > > &ops, const vector< double > &diagVal)
unsigned int getPoolIndex(const Eref &e) const
Return pool index, using Stoich ptr to do lookup.
Definition: Ksolve.cpp:666
Definition: Stoich.h:49
virtual void setCompartment(Id compartment)
Assigns compartment.
string method_
Definition: Ksolve.h:138
vector< double > & Svec()
Returns a handle to the mol # vector.
const std::string & name() const
Definition: Cinfo.cpp:260
unsigned int getNumPools() const
gets number of pools (species) handled by system.
Definition: Ksolve.cpp:732
ZombiePoolInterface * dsolvePtr_
Pointer to diffusion solver.
Definition: Ksolve.h:170
double getDiffConst(const Eref &e) const
Diffusion constant: Only one per pool, voxel number is ignored.
Definition: Ksolve.cpp:718
void setEpsRel(double val)
Definition: Ksolve.cpp:293
void setStoich(Id stoich)
Definition: Ksolve.cpp:353
unsigned int convertIdToPoolIndex(Id id) const
Definition: Stoich.cpp:1464
vector< double > getNvec(unsigned int voxel) const
Returns the vector of pool Num at the specified voxel.
Definition: Ksolve.cpp:447
double initStepSize
Definition: OdeSystem.h:35
unsigned int startVoxel_
First voxel indexed on the current node.
Definition: Ksolve.h:159
double getEpsAbs() const
Assigns Absolute tolerance for integration.
Definition: Ksolve.cpp:274
double dt
Definition: ProcInfo.h:18
Definition: OpFunc.h:27
Definition: Eref.h:26
bool isBuilt_
Flag: True when solver setup has been completed.
bool isA(const string &ancestor) const
Definition: Cinfo.cpp:280
void setNumAllVoxels(unsigned int num)
Definition: Ksolve.cpp:438
virtual void setPrev()
Used to tell Dsolver to assign 'prev' values.
const Cinfo * cinfo() const
Definition: Element.cpp:66
const unsigned int OFFNODE
Definition: Ksolve.cpp:38
void process(const Eref &e, ProcPtr p)
Definition: Ksolve.cpp:497
void setMethod(string method)
Definition: Ksolve.cpp:250
unsigned int getNumRates() const
Definition: Stoich.cpp:568
unsigned int getNumVarPools() const
Returns number of local pools that are updated by solver.
Definition: Stoich.cpp:510
unsigned int getNumLocalVoxels() const
Inherited from ZombiePoolInterface.
Definition: Ksolve.cpp:427
virtual void setBlock(const vector< double > &values)=0
Id getStoich() const
Assigns Stoich object to Ksolve.
Definition: Ksolve.cpp:317
Id compartment_
Id of Chem compartment used to figure out volumes of voxels.
void setN(const Eref &e, double v)
Set # of molecules in given pool and voxel. Varies with time.
Definition: Ksolve.cpp:683
void setNvec(unsigned int voxel, vector< double > vec)
Definition: Ksolve.cpp:457
Definition: Id.h:17
void initReinit(const Eref &e, ProcPtr p)
Definition: Ksolve.cpp:630
unsigned int getNumCoreRates() const
Number of rate terms for reactions purely on this compartment.
Definition: Stoich.cpp:574
unsigned int getNumAllPools() const
Definition: Stoich.cpp:520
const vector< RateTerm * > & getRateTerms() const
Returns a reference to the entire rates_ vector.
Definition: Stoich.cpp:589
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
double getNinit(const Eref &e) const
get initial # of molecules in given pool and voxel. Bdry cond.
Definition: Ksolve.cpp:705
double epsRel_
Definition: Ksolve.h:140
#define EPSILON
Definition: MatrixOps.h:28
void setDiffConst(const Eref &e, double v)
Diffusion constant: Only one per pool, voxel number is ignored.
Definition: Ksolve.cpp:713
Id getDsolve() const
Inherited from ZombiePoolInterface.
Definition: Ksolve.cpp:401
void initProc(const Eref &e, ProcPtr p)
Definition: Ksolve.cpp:626
double getEpsRel() const
Assigns Relative tolerance for integration.
Definition: Ksolve.cpp:288
unsigned int getNumAllVoxels() const
Definition: Ksolve.cpp:432
double epsAbs_
Definition: Ksolve.h:139
double getEstimatedDt() const
Definition: Ksolve.cpp:474
void setEpsAbs(double val)
Definition: Ksolve.cpp:279
void setBlock(const vector< double > &values)
Definition: Ksolve.cpp:776
Definition: Cinfo.h:18
unsigned int getVoxelIndex(const Eref &e) const
Definition: Ksolve.cpp:671
Ksolve()
Definition: Ksolve.cpp:216
virtual void getBlock(vector< double > &values) const =0
Definition: Finfo.h:12
double getN(const Eref &e) const
Get # of molecules in given pool and voxel. Varies with time.
Definition: Ksolve.cpp:690