MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Clock Class Reference

#include <Clock.h>

+ Collaboration diagram for Clock:

Public Member Functions

bool checkTickNum (const string &funcName, unsigned int i) const
 Utility func to range-check when Ticks are being changed. More...
 
 Clock ()
 
unsigned long getCurrentStep () const
 
double getCurrentTime () const
 
unsigned int getDefaultTick (string className) const
 
double getDt () const
 
vector< double > getDts () const
 
unsigned long getNsteps () const
 
unsigned int getNumTicks () const
 
double getRunTime () const
 
unsigned int getStride () const
 
double getTickDt (unsigned int i) const
 
unsigned int getTickStep (unsigned int i) const
 
void handleReinit (const Eref &e)
 dest function for message to trigger reinit. More...
 
void handleStart (const Eref &e, double runtime, bool notify)
 dest function for message to run simulation for specified time More...
 
void handleStep (const Eref &e, unsigned long steps)
 dest function for message to run simulation for specified steps More...
 
void innerReportClock () const
 
bool isDoingReinit () const
 
bool isRunning () const
 
void process ()
 
void setDt (double v)
 
void setTickDt (unsigned int i, double v)
 
void setTickStep (unsigned int i, unsigned int v)
 
void stop ()
 
 ~Clock ()
 

Static Public Member Functions

static void buildDefaultTick ()
 Builds the default scheduling map of classes to ticks. More...
 
static const CinfoinitCinfo ()
 
static unsigned int lookupDefaultTick (const string &className)
 
static void reportClock ()
 Static function. More...
 

Static Public Attributes

static const unsigned int numTicks = 32
 

Private Member Functions

void buildTicks (const Eref &e)
 

Private Attributes

vector< unsigned int > activeTicks_
 
vector< unsigned int > activeTicksMap_
 
unsigned long currentStep_
 
double currentTime_
 
bool doingReinit_
 
double dt_
 
ProcInfo info_
 
bool isRunning_
 The minimum dt. All ticks are a multiple of this. More...
 
bool notify_
 When set to true, notify user about the status of simulation by emitting message whenever 10% of simultion is over. More...
 
unsigned long nSteps_
 
double runTime_
 
unsigned int stride_
 
vector< unsigned int > ticks_
 

Static Private Attributes

static vector< double > defaultDt_
 
static map< string, unsigned int > defaultTick_
 

Friends

void testClock ()
 

Detailed Description

Clock now uses integral scheduling. The Clock has an array of child Ticks, each of which controls the process and reinit calls of its targets. The Clock has a minimum dt. All ticks operate with (positive) integral multiples of this, from 1 to anything. If multiple Ticks are due to go off in a given cycle, the order is from lowest to highest. Within a Tick the order of execution of target objects is undefined.

The Reinit call goes through all Ticks in order.

Definition at line 25 of file Clock.h.

Constructor & Destructor Documentation

Clock::Clock ( )

Definition at line 458 of file Clock.cpp.

References buildDefaultTick(), defaultDt_, dt_, numTicks, and ticks_.

459  : runTime_( 0.0 ),
460  currentTime_( 0.0 ),
461  nSteps_( 0 ),
462  currentStep_( 0 ),
463  stride_( 1 ),
464  dt_( 1.0 ),
465  isRunning_( false ),
466  doingReinit_( false ),
467  info_(),
468  ticks_( Clock::numTicks, 0 )
469 {
471  dt_ = defaultDt_[0];
472  for ( unsigned int i = 0; i < Clock::numTicks; ++i )
473  {
474  ticks_[i] = round( defaultDt_[i] / dt_ );
475  }
476 }
bool isRunning_
The minimum dt. All ticks are a multiple of this.
Definition: Clock.h:135
static const unsigned int numTicks
Definition: Clock.h:121
double dt_
Definition: Clock.h:130
unsigned long currentStep_
Definition: Clock.h:128
double currentTime_
Definition: Clock.h:126
ProcInfo info_
Definition: Clock.h:145
static vector< double > defaultDt_
Definition: Clock.h:171
double runTime_
Definition: Clock.h:125
vector< unsigned int > ticks_
Definition: Clock.h:152
bool doingReinit_
Definition: Clock.h:140
static void buildDefaultTick()
Builds the default scheduling map of classes to ticks.
Definition: Clock.cpp:870
unsigned long nSteps_
Definition: Clock.h:127
unsigned int stride_
Definition: Clock.h:129

+ Here is the call graph for this function:

Clock::~Clock ( )

Definition at line 478 of file Clock.cpp.

References Msg::isLastTrump(), numTicks, processVec(), reinitVec(), and sharedProcVec().

479 {
480  if ( Msg::isLastTrump() ) // Clean up, end of the simulation.
481  {
482  for ( unsigned int i = 0; i < Clock::numTicks; ++i )
483  {
484  delete processVec()[i];
485  delete reinitVec()[i];
486  delete sharedProcVec()[i];
487  }
488  }
489 }
static vector< SrcFinfo1< ProcPtr > * > & processVec()
Definition: Clock.cpp:98
static vector< SrcFinfo1< ProcPtr > * > & reinitVec()
Definition: Clock.cpp:105
static const unsigned int numTicks
Definition: Clock.h:121
static bool isLastTrump()
True when MOOSE has been terminated and is being cleaned up.
Definition: Msg.cpp:320
static vector< SharedFinfo * > & sharedProcVec()
Definition: Clock.cpp:112

+ Here is the call graph for this function:

Member Function Documentation

void Clock::buildDefaultTick ( )
static

Builds the default scheduling map of classes to ticks.

This is the authoritative database of default tick assignments for each class. This is here because one needs to see relative locations of all assignments in order to do this. This assumes that in cases where there are two ticks (such as init and process) for a single class, then they are sequential. Base classes are also represented here. They are checked as a fallback if the more specific class lookup fails. Certain classes, such as Zombies, explicitly do not get scheduled even though they may inherit process messages. These are given the tick ~0U.

Definition at line 870 of file Clock.cpp.

References defaultDt_, defaultTick_, and numTicks.

Referenced by Clock().

871 {
872  defaultTick_["DiffAmp"] = 0;
873  defaultTick_["Interpol"] = 0;
874  defaultTick_["PIDController"] = 0;
875  defaultTick_["PulseGen"] = 0;
876  defaultTick_["StimulusTable"] = 0;
877  defaultTick_["testSched"] = 0;
878  defaultTick_["VClamp"] = 0;
879  defaultTick_["SynHandlerBase"] = 1;
880  defaultTick_["SimpleSynHandler"] = 1;
881  defaultTick_["STDPSynHandler"] = 1;
882  defaultTick_["GraupnerBrunel2012CaPlasticitySynHandler"] = 1;
883  defaultTick_["SeqSynHandler"] = 1;
884  defaultTick_["CaConc"] = 1;
885  defaultTick_["CaConcBase"] = 1;
886  defaultTick_["DifShell"] = 1;
887  defaultTick_["DifShellBase"] = 1;
888  defaultTick_["MMPump"] = 1;
889  defaultTick_["DifBuffer"] = 1;
890  defaultTick_["DifBufferBase"] = 1;
891  defaultTick_["MgBlock"] = 1;
892  defaultTick_["Nernst"] = 1;
893  defaultTick_["RandSpike"] = 1;
894  defaultTick_["ChanBase"] = 2;
895  defaultTick_["IntFire"] = 2;
896  defaultTick_["IntFireBase"] = 2;
897  defaultTick_["LIF"] = 2;
898  defaultTick_["QIF"] = 2;
899  defaultTick_["ExIF"] = 2;
900  defaultTick_["AdExIF"] = 2;
901  defaultTick_["AdThreshIF"] = 2;
902  defaultTick_["IzhIF"] = 2;
903  defaultTick_["IzhikevichNrn"] = 2;
904  defaultTick_["SynChan"] = 2;
905  defaultTick_["NMDAChan"] = 2;
906  defaultTick_["GapJunction"] = 2;
907  defaultTick_["HHChannel"] = 2;
908  defaultTick_["HHChannel2D"] = 2;
909  defaultTick_["Leakage"] = 2;
910  defaultTick_["MarkovChannel"] = 2;
911  defaultTick_["MarkovGslSolver"] = 2;
912  defaultTick_["MarkovRateTable"] = 2;
913  defaultTick_["MarkovSolver"] = 2;
914  defaultTick_["MarkovSolverBase"] = 2;
915  defaultTick_["RC"] = 2;
916  defaultTick_["Compartment"] = 4; // Note these use an 'init', at t-1.
917  defaultTick_["CompartmentBase"] = 4; // Uses 'init'
918  defaultTick_["SymCompartment"] = 4; // Uses 'init'
919  defaultTick_["SpikeGen"] = 5;
920  defaultTick_["HSolve"] = 6;
921  defaultTick_["SpikeStats"] = 7;
922  defaultTick_["Table"] = 8;
923  defaultTick_["TimeTable"] = 8;
924  defaultTick_["Dsolve"] = 10;
925  defaultTick_["Adaptor"] = 11;
926  defaultTick_["Func"] = 12;
927  defaultTick_["Function"] = 12;
928  defaultTick_["Arith"] = 12;
929  /*
930  defaultTick_["FuncBase"] = 12;
931  defaultTick_["FuncPool"] = 12;
932  defaultTick_["MathFunc"] = 12;
933  defaultTick_["SumFunc"] = 12;
934  */
935  defaultTick_["BufPool"] = 13;
936  defaultTick_["Pool"] = 13;
937  defaultTick_["PoolBase"] = 13;
938  defaultTick_["CplxEnzBase"] = 14;
939  defaultTick_["Enz"] = 14;
940  defaultTick_["EnzBase"] = 14;
941  defaultTick_["MMenz"] = 14;
942  defaultTick_["Reac"] = 14;
943  defaultTick_["ReacBase"] = 14;
944  defaultTick_["Gsolve"] = 16; // Note this uses an 'init' at t-1
945  defaultTick_["Ksolve"] = 16; // Note this uses an 'init' at t-1
946  defaultTick_["Stats"] = 17;
947 
948  defaultTick_["Table2"] = 18;
949  defaultTick_["Streamer"] = 19;
950  defaultTick_["HDF5DataWriter"] = 30;
951  defaultTick_["HDF5WriterBase"] = 30;
952  defaultTick_["NSDFWriter"] = 30;
953  defaultTick_["PyRun"] = 30;
954 
955  defaultTick_["PostMaster"] = 31;
956 
957  defaultTick_["Annotator"] = ~0U;
958  defaultTick_["ChemCompt"] = ~0U;
959  defaultTick_["Cinfo"] = ~0U;
960  defaultTick_["Clock"] = ~0U;
961  defaultTick_["ConcChan"] = ~0U;
962  defaultTick_["CubeMesh"] = ~0U;
963  defaultTick_["CylMesh"] = ~0U;
964  defaultTick_["DiagonalMsg"] = ~0U;
965  defaultTick_["Double"] = ~0U;
966  defaultTick_["EndoMesh"] = ~0U;
967  defaultTick_["Finfo"] = ~0U;
968  defaultTick_["Group"] = ~0U;
969  defaultTick_["HHGate"] = ~0U;
970  defaultTick_["HHGate2D"] = ~0U;
971  defaultTick_["Interpol2D"] = ~0U;
972  defaultTick_["Long"] = ~0U;
973  defaultTick_["MeshEntry"] = ~0U;
974  defaultTick_["Msg"] = ~0U;
975  defaultTick_["Mstring"] = ~0U;
976  defaultTick_["Neuron"] = ~0U;
977  defaultTick_["NeuroMesh"] = ~0U;
978  defaultTick_["Neutral"] = ~0U;
979  defaultTick_["OneToAllMsg"] = ~0U;
980  defaultTick_["OneToOneDataIndexMsg"] = ~0U;
981  defaultTick_["OneToOneMsg"] = ~0U;
982  defaultTick_["PsdMesh"] = ~0U;
983  defaultTick_["Shell"] = ~0U;
984  defaultTick_["SingleMsg"] = ~0U;
985  defaultTick_["SparseMsg"] = ~0U;
986  defaultTick_["Species"] = ~0U;
987  defaultTick_["Spine"] = ~0U;
988  defaultTick_["SpineMesh"] = ~0U;
989  defaultTick_["SteadyState"] = ~0U;
990  defaultTick_["Stoich"] = ~0U;
991  defaultTick_["Synapse"] = ~0U;
992  defaultTick_["TableBase"] = ~0U;
993  defaultTick_["Unsigned"] = ~0U;
994  defaultTick_["Variable"] = ~0U;
995  defaultTick_["VectorTable"] = ~0U;
996  defaultTick_["ZombieBufPool"] = ~0U;
997  defaultTick_["ZombieCaConc"] = ~0U;
998  defaultTick_["ZombieCompartment"] = ~0U;
999  defaultTick_["ZombieEnz"] = ~0U;
1000  // defaultTick_["ZombieFuncPool"] = ~0U;
1001  defaultTick_["ZombieFunction"] = ~0U;
1002  defaultTick_["ZombieHHChannel"] = ~0U;
1003  defaultTick_["ZombieMMenz"] = ~0U;
1004  defaultTick_["ZombiePool"] = ~0U;
1005  defaultTick_["ZombieReac"] = ~0U;
1006 
1007  defaultDt_.assign( Clock::numTicks, 0.0 );
1008  defaultDt_[0] = 50.0e-6;
1009  defaultDt_[1] = 50.0e-6;
1010  defaultDt_[2] = 50.0e-6;
1011  defaultDt_[3] = 50.0e-6;
1012  defaultDt_[4] = 50.0e-6;
1013  defaultDt_[5] = 50.0e-6;
1014  defaultDt_[6] = 50.0e-6;
1015  defaultDt_[7] = 50.0e-6;
1016  defaultDt_[8] = 1.0e-4; // For the tables for electrical calculations
1017  defaultDt_[9] = 0.0; // Not assigned
1018  defaultDt_[10] = 0.01; // For diffusion.
1019  defaultDt_[11] = 0.1;
1020  defaultDt_[12] = 0.1;
1021  defaultDt_[13] = 0.1;
1022  defaultDt_[14] = 0.1;
1023  defaultDt_[15] = 0.1;
1024  defaultDt_[16] = 0.1;
1025  defaultDt_[17] = 0.1;
1026  defaultDt_[18] = 1; // For tables for chemical calculations.
1027  defaultDt_[19] = 10; // For Streamer
1028 
1029  // 20-29 are not assigned.
1030  defaultDt_[30] = 1; // For the HDF writer
1031  defaultDt_[31] = 0.01; // For the postmaster.
1032 }
static const unsigned int numTicks
Definition: Clock.h:121
static vector< double > defaultDt_
Definition: Clock.h:171
static map< string, unsigned int > defaultTick_
Definition: Clock.h:169

+ Here is the caller graph for this function:

void Clock::buildTicks ( const Eref e)
private

Definition at line 675 of file Clock.cpp.

References activeTicks_, activeTicksMap_, Eref::element(), Element::hasMsgs(), processVec(), stride_, and ticks_.

Referenced by handleReinit(), handleStep(), and testClock().

676 {
677  activeTicks_.resize(0);
678  activeTicksMap_.resize(0);
679  stride_ = ~0U;
680  for ( unsigned int i = 0; i < ticks_.size(); ++i )
681  {
682  if ( ticks_[i] > 0 &&
683  e.element()->hasMsgs( processVec()[i]->getBindIndex() ) )
684  {
685  activeTicks_.push_back( ticks_[i] );
686  activeTicksMap_.push_back( i );
687  if ( ticks_[i] > 0 && stride_ > ticks_[i] )
688  stride_ = ticks_[i];
689  }
690  }
691  // Should really do the HCF of N numbers here to get the stride.
692 }
static vector< SrcFinfo1< ProcPtr > * > & processVec()
Definition: Clock.cpp:98
Element * element() const
Definition: Eref.h:42
vector< unsigned int > activeTicksMap_
Definition: Clock.h:163
vector< unsigned int > activeTicks_
Definition: Clock.h:158
bool hasMsgs(BindIndex b) const
Definition: Element.cpp:307
vector< unsigned int > ticks_
Definition: Clock.h:152
unsigned int stride_
Definition: Clock.h:129

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool Clock::checkTickNum ( const string &  funcName,
unsigned int  i 
) const

Utility func to range-check when Ticks are being changed.

Definition at line 557 of file Clock.cpp.

References doingReinit_, isRunning_, and numTicks.

Referenced by setTickDt(), and setTickStep().

558 {
559  if ( isRunning_ || doingReinit_)
560  {
561  cout << "Warning: Clock::" << funcName <<
562  ": Cannot change dt while simulation is running\n";
563  return false;
564  }
565  if ( i >= Clock::numTicks )
566  {
567  cout << "Warning: Clock::" << funcName <<
568  "( " << i << " ): Clock has only " <<
569  Clock::numTicks << " ticks \n";
570  return false;
571  }
572  return true;
573 }
bool isRunning_
The minimum dt. All ticks are a multiple of this.
Definition: Clock.h:135
static const unsigned int numTicks
Definition: Clock.h:121
bool doingReinit_
Definition: Clock.h:140

+ Here is the caller graph for this function:

unsigned long Clock::getCurrentStep ( ) const

Definition at line 522 of file Clock.cpp.

References currentStep_.

Referenced by initCinfo().

523 {
524  return currentStep_;
525 }
unsigned long currentStep_
Definition: Clock.h:128

+ Here is the caller graph for this function:

double Clock::getCurrentTime ( ) const

Definition at line 512 of file Clock.cpp.

References currentTime_.

Referenced by initCinfo(), and testClock().

513 {
514  return currentTime_;
515 }
double currentTime_
Definition: Clock.h:126

+ Here is the caller graph for this function:

unsigned int Clock::getDefaultTick ( string  className) const

Definition at line 628 of file Clock.cpp.

References lookupDefaultTick().

Referenced by initCinfo().

629 {
630  return Clock::lookupDefaultTick( s );
631 }
static unsigned int lookupDefaultTick(const string &className)
Definition: Clock.cpp:1035

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

double Clock::getDt ( void  ) const

Definition at line 503 of file Clock.cpp.

References dt_.

Referenced by initCinfo().

504 {
505  return dt_;
506 }
double dt_
Definition: Clock.h:130

+ Here is the caller graph for this function:

vector< double > Clock::getDts ( ) const

Definition at line 537 of file Clock.cpp.

References dt_, and ticks_.

Referenced by initCinfo().

538 {
539  vector< double > ret;
540  for ( unsigned int i = 0; i < ticks_.size(); ++i )
541  {
542  ret.push_back( ticks_[ i ] * dt_ );
543  }
544  return ret;
545 }
double dt_
Definition: Clock.h:130
vector< unsigned int > ticks_
Definition: Clock.h:152

+ Here is the caller graph for this function:

unsigned long Clock::getNsteps ( ) const

Definition at line 517 of file Clock.cpp.

References nSteps_.

Referenced by initCinfo().

518 {
519  return nSteps_;
520 }
unsigned long nSteps_
Definition: Clock.h:127

+ Here is the caller graph for this function:

unsigned int Clock::getNumTicks ( ) const

Definition at line 527 of file Clock.cpp.

References numTicks.

Referenced by initCinfo().

528 {
529  return numTicks;
530 }
static const unsigned int numTicks
Definition: Clock.h:121

+ Here is the caller graph for this function:

double Clock::getRunTime ( ) const

Definition at line 507 of file Clock.cpp.

References runTime_.

Referenced by initCinfo().

508 {
509  return runTime_;
510 }
double runTime_
Definition: Clock.h:125

+ Here is the caller graph for this function:

unsigned int Clock::getStride ( ) const

Definition at line 532 of file Clock.cpp.

References stride_.

Referenced by initCinfo().

533 {
534  return stride_;
535 }
unsigned int stride_
Definition: Clock.h:129

+ Here is the caller graph for this function:

double Clock::getTickDt ( unsigned int  i) const

Definition at line 621 of file Clock.cpp.

References dt_, numTicks, and ticks_.

Referenced by initCinfo(), Table::reinit(), and Streamer::reinit().

622 {
623  if ( i < Clock::numTicks )
624  return ticks_[i] * dt_;
625  return 0.0;
626 }
static const unsigned int numTicks
Definition: Clock.h:121
double dt_
Definition: Clock.h:130
vector< unsigned int > ticks_
Definition: Clock.h:152

+ Here is the caller graph for this function:

unsigned int Clock::getTickStep ( unsigned int  i) const

Definition at line 580 of file Clock.cpp.

References numTicks, and ticks_.

Referenced by initCinfo().

581 {
582  if ( i < Clock::numTicks )
583  return ticks_[i];
584  return 0;
585 }
static const unsigned int numTicks
Definition: Clock.h:121
vector< unsigned int > ticks_
Definition: Clock.h:152

+ Here is the caller graph for this function:

void Clock::handleReinit ( const Eref e)

dest function for message to trigger reinit.

This is the dest function that sets off the reinit.

Definition at line 808 of file Clock.cpp.

References activeTicks_, activeTicksMap_, buildTicks(), currentStep_, currentTime_, ProcInfo::currTime, doingReinit_, ProcInfo::dt, dt_, info_, isRunning_, nSteps_, and reinitVec().

Referenced by initCinfo(), and testClock().

809 {
810  if ( isRunning_ || doingReinit_ )
811  {
812  cout << "Clock::handleReinit: Warning: simulation already in progress.\n Command ignored\n";
813  return;
814  }
815  currentTime_ = 0.0;
816  currentStep_ = 0;
817  nSteps_ = 0;
818  buildTicks( e );
819  doingReinit_ = true;
820  // Curr time is end of current step.
821  info_.currTime = 0.0;
822  vector< unsigned int >::const_iterator k = activeTicksMap_.begin();
823  for ( vector< unsigned int>::iterator j =
824  activeTicks_.begin(); j != activeTicks_.end(); ++j )
825  {
826  info_.dt = *j * dt_;
827  reinitVec()[*k++]->send( e, &info_ );
828  }
829  info_.dt = dt_;
830  doingReinit_ = false;
831 }
bool isRunning_
The minimum dt. All ticks are a multiple of this.
Definition: Clock.h:135
static vector< SrcFinfo1< ProcPtr > * > & reinitVec()
Definition: Clock.cpp:105
double dt_
Definition: Clock.h:130
double currTime
Definition: ProcInfo.h:19
vector< unsigned int > activeTicksMap_
Definition: Clock.h:163
vector< unsigned int > activeTicks_
Definition: Clock.h:158
unsigned long currentStep_
Definition: Clock.h:128
double currentTime_
Definition: Clock.h:126
ProcInfo info_
Definition: Clock.h:145
void buildTicks(const Eref &e)
Definition: Clock.cpp:675
double dt
Definition: ProcInfo.h:18
bool doingReinit_
Definition: Clock.h:140
unsigned long nSteps_
Definition: Clock.h:127

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Clock::handleStart ( const Eref e,
double  runtime,
bool  notify 
)

dest function for message to run simulation for specified time

Start has to happen gracefully: If the simulation was stopped for any reason, it has to pick up where it left off. The "runtime" argument is the additional time to run the simulation.

Definition at line 699 of file Clock.cpp.

References dt_, handleStep(), notify_, and stride_.

Referenced by initCinfo(), and testClock().

700 {
701  notify_ = notify;
702 
703  if ( stride_ == 0 || stride_ == ~0U )
704  stride_ = 1;
705  unsigned long n = round( runtime / ( stride_ * dt_ ) );
706 
707  handleStep( e, n );
708 
709 }
double dt_
Definition: Clock.h:130
bool notify_
When set to true, notify user about the status of simulation by emitting message whenever 10% of simu...
Definition: Clock.h:178
void handleStep(const Eref &e, unsigned long steps)
dest function for message to run simulation for specified steps
Definition: Clock.cpp:711
unsigned int stride_
Definition: Clock.h:129

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Clock::handleStep ( const Eref e,
unsigned long  steps 
)

dest function for message to run simulation for specified steps

Definition at line 711 of file Clock.cpp.

References activeTicks_, activeTicksMap_, buildTicks(), currentStep_, currentTime_, ProcInfo::currTime, doingReinit_, ProcInfo::dt, dt_, finished(), info_, isRunning_, notify_, nSteps_, processVec(), runTime_, SrcFinfo0::send(), and stride_.

Referenced by handleStart(), and initCinfo().

712 {
713  numSteps *= stride_;
714  if ( isRunning_ || doingReinit_ )
715  {
716  cout << "Clock::handleStart: Warning: simulation already in progress.\n Command ignored\n";
717  return;
718  }
719 
720  time_t rawtime;
721  struct tm * timeinfo;
722  char now[80];
723 
724  buildTicks( e );
725  assert( currentStep_ == nSteps_ );
726  assert( activeTicks_.size() == activeTicksMap_.size() );
727  nSteps_ += numSteps;
728  runTime_ = nSteps_ * dt_;
729  for ( isRunning_ = (activeTicks_.size() > 0 );
731  {
732  // Curr time is end of current step.
733  unsigned long endStep = currentStep_ + stride_;
734  currentTime_ = info_.currTime = dt_ * endStep;
735 
736 #if PARALLELIZE_CLOCK_USING_CPP11_ASYNC
737 
738  // NOTE: It does not produce very promising results. The challenge here
739  // is doing load-balancing.
740  // TODO: To start with, we can put one solver on one thread and everything
741  // else onto 1 thread. Each Hsove, Ksolve, and Gsolve can take its own
742  // thread and rest are on different threads.
743 
744  unsigned int nTasks = activeTicks_.size( );
745  unsigned int numThreads_ = 3;
746  unsigned int blockSize = 1 + (nTasks / numThreads_);
747 
748  for( unsigned int i = 0; i < numThreads_; ++i )
749  {
750  std::async( std::launch::async
751  , [this,blockSize,i,nTasks,endStep,e]
752  {
753  unsigned int mapI = i * blockSize;
754  // Get the block we want to run in paralle.
755  for( unsigned int ii = i * blockSize; ii < min((i+1) * blockSize, nTasks); ii++ )
756  {
757  unsigned int j = activeTicks_[ ii ];
758  if( endStep % j == 0 )
759  {
760  info_.dt = j * dt_;
761  processVec( )[ activeTicksMap_[mapI] ]->send( e, &info_ );
762  }
763  mapI++;
764  }
765  }
766  );
767  }
768 #else
769  vector< unsigned int >::const_iterator k = activeTicksMap_.begin();
770  for ( vector< unsigned int>::iterator j =
771  activeTicks_.begin(); j != activeTicks_.end(); ++j )
772  {
773  if ( endStep % *j == 0 )
774  {
775  info_.dt = *j * dt_;
776  processVec()[*k]->send( e, &info_ );
777  }
778  ++k;
779  }
780 #endif
781 
782  // When 10% of simulation is over, notify user when notify_ is set to
783  // true.
784  if( notify_ )
785  {
786  if( fmod(100 * currentTime_ / runTime_ , 10.0) == 0.0 )
787  {
788  time( &rawtime );
789  timeinfo = localtime( &rawtime );
790  strftime(now, 80, "%c", timeinfo);
791  cout << "@ " << now << ": " << 100 * currentTime_ / runTime_
792  << "% of total " << runTime_ << " seconds is over." << endl;
793  }
794  }
795 
796  if ( activeTicks_.size() == 0 )
798  }
799 
800  info_.dt = dt_;
801  isRunning_ = false;
802  finished()->send( e );
803 }
static vector< SrcFinfo1< ProcPtr > * > & processVec()
Definition: Clock.cpp:98
bool isRunning_
The minimum dt. All ticks are a multiple of this.
Definition: Clock.h:135
double dt_
Definition: Clock.h:130
double currTime
Definition: ProcInfo.h:19
bool notify_
When set to true, notify user about the status of simulation by emitting message whenever 10% of simu...
Definition: Clock.h:178
vector< unsigned int > activeTicksMap_
Definition: Clock.h:163
vector< unsigned int > activeTicks_
Definition: Clock.h:158
unsigned long currentStep_
Definition: Clock.h:128
double currentTime_
Definition: Clock.h:126
ProcInfo info_
Definition: Clock.h:145
double runTime_
Definition: Clock.h:125
void buildTicks(const Eref &e)
Definition: Clock.cpp:675
double dt
Definition: ProcInfo.h:18
bool doingReinit_
Definition: Clock.h:140
static SrcFinfo0 * finished()
Definition: Clock.cpp:71
unsigned long nSteps_
Definition: Clock.h:127
void send(const Eref &e) const
Definition: SrcFinfo.cpp:70
unsigned int stride_
Definition: Clock.h:129

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const Cinfo * Clock::initCinfo ( )
static

Definition at line 133 of file Clock.cpp.

References clockCinfo, finished(), getCurrentStep(), getCurrentTime(), getDefaultTick(), getDt(), getDts(), getNsteps(), getNumTicks(), getRunTime(), getStride(), getTickDt(), getTickStep(), handleReinit(), handleStart(), handleStep(), Neutral::initCinfo(), isRunning(), numTicks, setDt(), setTickDt(), setTickStep(), sharedProcVec(), and stop().

Referenced by init(), testFibonacci(), and testShellAddMsg().

134 {
136  // Field definitions
138  static ValueFinfo< Clock, double > dt(
139  "baseDt",
140  "Base timestep for simulation. This is the smallest dt out "
141  "of all the clock ticks. By definition all other timesteps "
142  "are integral multiples of this, and are rounded to "
143  "ensure that this is the case . ",
144  &Clock::setDt,
145  &Clock::getDt
146  );
148  "runTime",
149  "Duration to run the simulation",
151  );
152  static ReadOnlyValueFinfo< Clock, double > currentTime(
153  "currentTime",
154  "Current simulation time",
156  );
158  "nsteps",
159  "Number of steps to advance the simulation, in units of the smallest timestep on the clock ticks",
161  );
163  "numTicks",
164  "Number of clock ticks",
166  );
168  "stride",
169  "Number by which the simulation advances the current step on each cycle. stride = smallest active timestep/smallest defined timestep.",
171  );
173  "currentStep",
174  "Current simulation step",
176  );
177 
179  "dts",
180  "Utility function returning the dt (timestep) of all ticks.",
182  );
183 
185  "isRunning",
186  "Utility function to report if simulation is in progress.",
188  );
189 
191  tickStep(
192  "tickStep",
193  "Step size of specified Tick, as integral multiple of dt_"
194  " A zero step size means that the Tick is inactive",
197  );
198 
200  "tickDt",
201  "Timestep dt of specified Tick. Always integral multiple of "
202  "dt_. If you assign a non-integer multiple it will round off. "
203  " A zero timestep means that the Tick is inactive",
206  );
207 
209  "defaultTick",
210  "Looks up the default Tick to use for the specified class. "
211  "If no tick is assigned, as for classes without a process "
212  "operation or zombie classes, the tick is ~0U. "
213  "If nothing can be found returns 0 and emits a warning.",
215  );
217  // Shared definitions
219  static vector< SharedFinfo *> procs = sharedProcVec();
220 
222  // MsgDest definitions
224  static DestFinfo start( "start",
225  "Sets off the simulation for the specified duration",
227  );
228 
229  static DestFinfo step( "step",
230  "Sets off the simulation for the specified # of steps. "
231  "Here each step advances the simulation by the timestep of the "
232  "smallest tick that is actually in use. ",
234  );
235 
236  static DestFinfo stop( "stop",
237  "Halts the simulation, with option to restart seamlessly",
239  );
240 
241  static DestFinfo reinit( "reinit",
242  "Zeroes out all ticks, starts at t = 0",
244  );
245 
246  static Finfo* clockControlFinfos[] =
247  {
248  &start, &step, &stop, &reinit,
249  };
251  // SharedFinfo for Shell to control Clock
253  static SharedFinfo clockControl( "clockControl",
254  "Controls all scheduling aspects of Clock, usually from Shell",
255  clockControlFinfos,
256  sizeof( clockControlFinfos ) / sizeof( Finfo* )
257  );
258 
259  static Finfo* clockFinfos[] =
260  {
261  // Fields
262  &dt, // Value
263  &runTime, // ReadOnlyValue
264  &currentTime, // ReadOnlyValue
265  &nsteps, // ReadOnlyValue
266  &numTicks, // ReadOnlyValue
267  &stride, // ReadOnlyValue
268  &currentStep, // ReadOnlyValue
269  &dts, // ReadOnlyValue
270  &isRunning, // ReadOnlyValue
271  &tickStep, // LookupValue
272  &tickDt, // LookupValue
273  &defaultTick, // ReadOnlyLookupValue
274  &clockControl, // Shared
275  finished(), // Src
276  procs[0], // Src
277  procs[1], // Src
278  procs[2], // Src
279  procs[3], // Src
280  procs[4], // Src
281  procs[5], // Src
282  procs[6], // Src
283  procs[7], // Src
284  procs[8], // Src
285  procs[9], // Src
286  procs[10], // Src
287  procs[11], // Src
288  procs[12], // Src
289  procs[13], // Src
290  procs[14], // Src
291  procs[15], // Src
292  procs[16], // Src
293  procs[17], // Src
294  procs[18], // Src
295  procs[19], // Src
296  procs[20], // Src
297  procs[21], // Src
298  procs[22], // Src
299  procs[23], // Src
300  procs[24], // Src
301  procs[25], // Src
302  procs[26], // Src
303  procs[27], // Src
304  procs[28], // Src
305  procs[29], // Src
306  procs[30], // Src
307  procs[31], // Src
308  };
309 
310  static string doc[] =
311  {
312  "Name", "Clock",
313  "Author", "Upinder S. Bhalla, Nov 2013, NCBS",
314  "Description",
315 
316  "Every object scheduled for operations in MOOSE is connected to one"
317  "of the 'Tick' entries on the Clock.\n"
318  "The Clock manages 32 'Ticks', each of which has its own dt,"
319  "which is an integral multiple of the clock baseDt_. "
320  "On every clock step the ticks are examined to see which of them"
321  "is due for updating. When a tick is updated, the 'process' call "
322  "of all the objects scheduled on that tick is called. "
323  "Order of execution: If a subset of ticks are scheduled for "
324  "execution at a given timestep, then they will be executed in "
325  "numerical order, lowest tick first and highest last. "
326  "There is no guarantee of execution order for objects within "
327  "a clock tick.\n"
328  "The clock provides default scheduling for all objects which "
329  "can be accessed using Clock::lookupDefaultTick( className ). "
330  "Specific items of note are that the output/file dump objects are "
331  "second-last, and the postmaster is last on the order of Ticks. "
332  "The clock also starts up with some default timesteps for each "
333  "of these ticks, and this can be overridden using the shell "
334  "command setClock, or by directly assigning tickStep values on the "
335  "clock object."
336  "Which objects use which tick? As a rule of thumb, try this: \n"
337  "Electrical/compartmental model calculations: Ticks 0-7 \n"
338  "Tables and output objects for electrical output: Tick 8 \n"
339  "Diffusion solver: Tick 10 \n"
340  "Chemical/compartmental model calculations: Ticks 11-17\n"
341  "Tables and output objects for chemical output: Tick 18 \n"
342  "Unassigned: Ticks 20-29 \n"
343  "Special: 30-31 \n"
344  "Data output is a bit special, since you may want to store data "
345  "at different rates for electrical and chemical processes in the "
346  "same model. Here you will have to specifically assign distinct "
347  "clock ticks for the tables/fileIO objects handling output at "
348  "different time-resolutions. Typically one uses tick 8 and 18.\n"
349  "Here are the detailed mappings of class to tick.\n"
350  " Class Tick dt \n"
351  " DiffAmp 0 50e-6\n"
352  " Interpol 0 50e-6\n"
353  " PIDController 0 50e-6\n"
354  " PulseGen 0 50e-6\n"
355  " StimulusTable 0 50e-6\n"
356  " testSched 0 50e-6\n"
357  " VClamp 0 50e-6\n"
358  " SynHandlerBase 1 50e-6\n"
359  " SimpleSynHandler 1 50e-6\n"
360  " STDPSynHandler 1 50e-6\n"
361  " GraupnerBrunel2012CaPlasticitySynHandler 1 50e-6\n"
362  " SeqSynHandler 1 50e-6\n"
363  " CaConc 1 50e-6\n"
364  " CaConcBase 1 50e-6\n"
365  " DifShell 1 50e-6\n"
366  " DifShellBase 1 50e-6\n"
367  " MMPump 1 50e-6\n"
368  " DifBuffer 1 50e-6\n"
369  " DifBufferBase 1 50e-6\n"
370  " MgBlock 1 50e-6\n"
371  " Nernst 1 50e-6\n"
372  " RandSpike 1 50e-6\n"
373  " ChanBase 2 50e-6\n"
374  " IntFire 2 50e-6\n"
375  " IntFireBase 2 50e-6\n"
376  " LIF 2 50e-6\n"
377  " QIF 2 50e-6\n"
378  " ExIF 2 50e-6\n"
379  " AdExIF 2 50e-6\n"
380  " AdThreshIF 2 50e-6\n"
381  " IzhIF 2 50e-6\n"
382  " IzhikevichNrn 2 50e-6\n"
383  " SynChan 2 50e-6\n"
384  " NMDAChan 2 50e-6\n"
385  " GapJunction 2 50e-6\n"
386  " HHChannel 2 50e-6\n"
387  " HHChannel2D 2 50e-6\n"
388  " Leakage 2 50e-6\n"
389  " MarkovChannel 2 50e-6\n"
390  " MarkovGslSolver 2 50e-6\n"
391  " MarkovRateTable 2 50e-6\n"
392  " MarkovSolver 2 50e-6\n"
393  " MarkovSolverBase 2 50e-6\n"
394  " RC 2 50e-6\n"
395  " Compartment (init) 3 50e-6\n"
396  " CompartmentBase (init ) 3 50e-6\n"
397  " SymCompartment (init) 3 50e-6\n"
398  " Compartment 4 50e-6\n"
399  " CompartmentBase 4 50e-6\n"
400  " SymCompartment 4 50e-6\n"
401  " SpikeGen 5 50e-6\n"
402  " HSolve 6 50e-6\n"
403  " SpikeStats 7 50e-6\n"
404  " Table 8 0.1e-3\n"
405  " TimeTable 8 0.1e-3\n"
406 
407  " Dsolve 10 0.01\n"
408  " Adaptor 11 0.1\n"
409  " Func 12 0.1\n"
410  " Function 12 0.1\n"
411  " Arith 12 0.1\n"
412  " BufPool 13 0.1\n"
413  " Pool 13 0.1\n"
414  " PoolBase 13 0.1\n"
415  " CplxEnzBase 14 0.1\n"
416  " Enz 14 0.1\n"
417  " EnzBase 14 0.1\n"
418  " MMenz 14 0.1\n"
419  " Reac 14 0.1\n"
420  " ReacBase 14 0.1\n"
421  " Gsolve (init) 15 0.1\n"
422  " Ksolve (init) 15 0.1\n"
423  " Gsolve 16 0.1\n"
424  " Ksolve 16 0.1\n"
425  " Stats 17 0.1\n"
426  " Table2 18 1\n"
427  " Streamer 19 10\n"
428 
429  " HDF5DataWriter 30 1\n"
430  " HDF5WriterBase 30 1\n"
431  " NSDFWriter 30 1\n"
432  " PyRun 30 1\n"
433  " PostMaster 31 0.01\n"
434  " \n"
435  " Note that the other classes are not scheduled at all.",
436  };
437 
438  static Dinfo< Clock > dinfo;
439  static Cinfo clockCinfo(
440  "Clock",
441  // "Clock class handles sequencing of operations in simulations",
443  clockFinfos,
444  sizeof(clockFinfos)/sizeof(Finfo *),
445  &dinfo,
446  doc,
447  sizeof(doc)/sizeof(string)
448  );
449 
450  return &clockCinfo;
451 }
void setDt(double v)
Definition: Clock.cpp:493
static const unsigned int numTicks
Definition: Clock.h:121
void stop()
Definition: Clock.cpp:641
void handleReinit(const Eref &e)
dest function for message to trigger reinit.
Definition: Clock.cpp:808
double getCurrentTime() const
Definition: Clock.cpp:512
Definition: Dinfo.h:60
unsigned int getStride() const
Definition: Clock.cpp:532
unsigned int getTickStep(unsigned int i) const
Definition: Clock.cpp:580
Definition: EpFunc.h:64
unsigned int getNumTicks() const
Definition: Clock.cpp:527
vector< double > getDts() const
Definition: Clock.cpp:537
double getTickDt(unsigned int i) const
Definition: Clock.cpp:621
void handleStart(const Eref &e, double runtime, bool notify)
dest function for message to run simulation for specified time
Definition: Clock.cpp:699
double getDt() const
Definition: Clock.cpp:503
unsigned long getCurrentStep() const
Definition: Clock.cpp:522
void handleStep(const Eref &e, unsigned long steps)
dest function for message to run simulation for specified steps
Definition: Clock.cpp:711
bool isRunning() const
Definition: Clock.cpp:547
Definition: EpFunc.h:49
double getRunTime() const
Definition: Clock.cpp:507
void setTickStep(unsigned int i, unsigned int v)
Definition: Clock.cpp:575
void setTickDt(unsigned int i, double v)
Definition: Clock.cpp:591
static SrcFinfo0 * finished()
Definition: Clock.cpp:71
static const Cinfo * clockCinfo
Definition: Clock.cpp:453
Definition: OpFunc.h:13
unsigned int getDefaultTick(string className) const
Definition: Clock.cpp:628
static vector< SharedFinfo * > & sharedProcVec()
Definition: Clock.cpp:112
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
Definition: Cinfo.h:18
Definition: EpFunc.h:79
unsigned long getNsteps() const
Definition: Clock.cpp:517
Definition: Finfo.h:12

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Clock::innerReportClock ( ) const

Definition at line 657 of file Clock.cpp.

References currentTime_, dt_, isRunning_, runTime_, and ticks_.

Referenced by reportClock().

658 {
659  cout << "reporting Clock: runTime= " << runTime_ <<
660  ", currentTime= " << currentTime_ <<
661  ", dt= " << dt_ << ", isRunning = " << isRunning_ << endl;
662  cout << "Dts= ";
663  for ( unsigned int i = 0; i < ticks_.size(); ++i )
664  {
665  cout << "tick[" << i << "] = " << ticks_[i] << " " <<
666  ticks_[i] * dt_ << endl;
667  }
668  cout << endl;
669 }
bool isRunning_
The minimum dt. All ticks are a multiple of this.
Definition: Clock.h:135
double dt_
Definition: Clock.h:130
double currentTime_
Definition: Clock.h:126
double runTime_
Definition: Clock.h:125
vector< unsigned int > ticks_
Definition: Clock.h:152

+ Here is the caller graph for this function:

bool Clock::isDoingReinit ( ) const

Flag: True when the simulation is busy with reinit

Definition at line 552 of file Clock.cpp.

References doingReinit_.

553 {
554  return doingReinit_;
555 }
bool doingReinit_
Definition: Clock.h:140
bool Clock::isRunning ( ) const

Flag: True when the simulation is still running.

Definition at line 547 of file Clock.cpp.

References isRunning_.

Referenced by initCinfo().

548 {
549  return isRunning_;
550 }
bool isRunning_
The minimum dt. All ticks are a multiple of this.
Definition: Clock.h:135

+ Here is the caller graph for this function:

unsigned int Clock::lookupDefaultTick ( const string &  className)
static

Look up the default Tick number for the specified class. Note that for objects having an 'init' action as well as process, the assigned tick is for 'init' and the next number will be used for 'process'.

Definition at line 1035 of file Clock.cpp.

References defaultTick_.

Referenced by getDefaultTick(), innerCopyElements(), Shell::innerCreate(), Stoich::unZombifyModel(), and Element::zombieSwap().

1036 {
1037  map< string, unsigned int >::const_iterator i =
1038  defaultTick_.find( className );
1039  if ( i == defaultTick_.end() )
1040  {
1041  cout << "Warning: unknown className: '" << className << "'.\n" <<
1042  "Advisable to update the defaultTick table in the Clock class.\n";
1043  return 0;
1044  }
1045  return i->second;
1046 }
static map< string, unsigned int > defaultTick_
Definition: Clock.h:169

+ Here is the caller graph for this function:

void Clock::process ( )
void Clock::reportClock ( )
static

Static function.

Utility function to tell us about the scheduling

Definition at line 651 of file Clock.cpp.

References Eref::data(), Id::eref(), and innerReportClock().

652 {
653  const Clock* c = reinterpret_cast< const Clock* >( Id( 1 ).eref().data() );
654  c->innerReportClock();
655 }
char * data() const
Definition: Eref.cpp:41
Definition: Clock.h:25
Eref eref() const
Definition: Id.cpp:125
void innerReportClock() const
Definition: Clock.cpp:657
Definition: Id.h:17

+ Here is the call graph for this function:

void Clock::setDt ( double  v)

Definition at line 493 of file Clock.cpp.

References dt_, and isRunning_.

Referenced by initCinfo().

494 {
495  if ( isRunning_ )
496  {
497  cout << "Warning: Clock::setDt: Cannot change dt while simulation is running\n";
498  return;
499  }
500  dt_ = v;
501 }
bool isRunning_
The minimum dt. All ticks are a multiple of this.
Definition: Clock.h:135
double dt_
Definition: Clock.h:130

+ Here is the caller graph for this function:

void Clock::setTickDt ( unsigned int  i,
double  v 
)

A little nasty because we want to ensure that the main clock dt is set intelligently from the assignment here.

Definition at line 591 of file Clock.cpp.

References checkTickNum(), dt_, minimumDt, numTicks, and ticks_.

Referenced by initCinfo().

592 {
593  unsigned int numUsed = 0;
594  if ( v < minimumDt )
595  {
596  cout << "Warning: Clock::setTickDt: " << v <<
597  " is smaller than minimum allowed timestep " <<
598  minimumDt << endl;
599  cout << "dt not set\n";
600  return;
601  }
602  for ( unsigned int j = 0; j < numTicks; ++j )
603  numUsed += ( ticks_[j] != 0 );
604 
605  if ( numUsed == 0 )
606  {
607  dt_ = v;
608  }
609  else if ( dt_ > v )
610  {
611  for ( unsigned int j = 0; j < numTicks; ++j )
612  if ( ticks_[j] != 0 )
613  ticks_[j] = round( ( ticks_[j] * dt_ ) / v );
614  dt_ = v;
615  }
616 
617  if ( checkTickNum( "setTickDt", i ) )
618  ticks_[i] = round( v / dt_ );
619 }
static const unsigned int numTicks
Definition: Clock.h:121
double dt_
Definition: Clock.h:130
const double minimumDt
minimumDt is smaller than any known event on the scales MOOSE handles.
Definition: Clock.cpp:63
bool checkTickNum(const string &funcName, unsigned int i) const
Utility func to range-check when Ticks are being changed.
Definition: Clock.cpp:557
vector< unsigned int > ticks_
Definition: Clock.h:152

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Clock::setTickStep ( unsigned int  i,
unsigned int  v 
)

Definition at line 575 of file Clock.cpp.

References checkTickNum(), and ticks_.

Referenced by initCinfo().

576 {
577  if ( checkTickNum( "setTickStep", i ) )
578  ticks_[i] = v;
579 }
bool checkTickNum(const string &funcName, unsigned int i) const
Utility func to range-check when Ticks are being changed.
Definition: Clock.cpp:557
vector< unsigned int > ticks_
Definition: Clock.h:152

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Clock::stop ( )

Halts running simulation gracefully, letting it restart wherever it left off from.

Does a graceful stop of the simulation, leaving so it can continue cleanly with another step or start command.

Definition at line 641 of file Clock.cpp.

References isRunning_.

Referenced by initCinfo().

642 {
643  isRunning_ = 0;
644 }
bool isRunning_
The minimum dt. All ticks are a multiple of this.
Definition: Clock.h:135

+ Here is the caller graph for this function:

Friends And Related Function Documentation

void testClock ( )
friend

Check that clock scheduling works.

Definition at line 80 of file testScheduling.cpp.

81 {
82  const double runtime = 20.0;
83  Id clock(1);
84 
85  bool ret = Field< double >::set( clock, "baseDt", 1.0);
86  assert( ret );
87  ret = LookupField< unsigned int, double >::set( clock, "tickDt", 0, 2.0);
88  assert( ret );
89  ret = LookupField< unsigned int, double >::set( clock, "tickDt", 3, 1.0);
90  assert( ret );
91  ret = LookupField< unsigned int, double >::set( clock, "tickDt", 1, 2.0);
92  assert( ret );
93  ret = LookupField< unsigned int, double >::set( clock, "tickDt", 2, 5.0);
94  assert( ret );
95  ret = LookupField< unsigned int, double >::set( clock, "tickDt", 4, 3.0);
96  assert( ret );
97  ret = LookupField< unsigned int, double >::set( clock, "tickDt", 7, 5.0);
98  assert( ret );
99 
100  /*
101  Id tabid = Id::nextId();
102  Element* tse = new Element( tsid, testSchedCinfo, "tse", 1 );
103 
104  Eref ts( tse, 0 );
105 
106  FuncId f( processFinfo.getFid() );
107  const Finfo* proc0 = clock.element()->cinfo()->findFinfo( "process0" );
108  assert( proc0 );
109  const SrcFinfo* sproc0 = dynamic_cast< const SrcFinfo* >( proc0 );
110  assert( sproc0 );
111  unsigned int b0 = sproc0->getBindIndex();
112  SingleMsg *m0 = new SingleMsg( er0.eref(), ts );
113  er0.element()->addMsgAndFunc( m0->mid(), f, er0.dataId.value()*2 + b0);
114  SingleMsg *m1 = new SingleMsg( er1.eref(), ts );
115  er1.element()->addMsgAndFunc( m1->mid(), f, er1.dataId.value()*2 + b0);
116  SingleMsg *m2 = new SingleMsg( er2.eref(), ts );
117  er2.element()->addMsgAndFunc( m2->mid(), f, er2.dataId.value()*2 + b0);
118  SingleMsg *m3 = new SingleMsg( er3.eref(), ts );
119  er3.element()->addMsgAndFunc( m3->mid(), f, er3.dataId.value()*2 + b0);
120  SingleMsg *m4 = new SingleMsg( er4.eref(), ts );
121  er4.element()->addMsgAndFunc( m4->mid(), f, er4.dataId.value()*2 + b0);
122  SingleMsg *m5 = new SingleMsg( er5.eref(), ts );
123  er5.element()->addMsgAndFunc( m5->mid(), f, er5.dataId.value()*2 + b0);
124 
125 
126 
127  assert( cdata->tickPtr_[0].mgr()->ticks_[0] == reinterpret_cast< const Tick* >( er3.data() ) );
128  assert( cdata->tickPtr_[1].mgr()->ticks_[0] == reinterpret_cast< const Tick* >( er2.data() ) );
129  assert( cdata->tickPtr_[1].mgr()->ticks_[1] == reinterpret_cast< const Tick* >( er1.data() ) );
130  assert( cdata->tickPtr_[2].mgr()->ticks_[0] == reinterpret_cast< const Tick* >( er4.data() ) );
131  assert( cdata->tickPtr_[3].mgr()->ticks_[0] == reinterpret_cast< const Tick* >( er0.data() ) );
132  assert( cdata->tickPtr_[3].mgr()->ticks_[1] == reinterpret_cast< const Tick* >( er5.data() ) );
133  */
134 
135  Eref clocker = clock.eref();
136  Clock* cdata = reinterpret_cast< Clock* >( clocker.data() );
137  assert ( cdata->ticks_.size() == Clock::numTicks );
138  cdata->buildTicks( clocker );
139  assert( cdata->activeTicks_.size() == 0 ); // No messages
140 
141  // Now put in the scheduling tester and messages.
142  Id test = Id::nextId();
143  Element* teste = new GlobalDataElement( test, testSchedCinfo, "test", 1 );
144  assert( teste );
145  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
146 
147  shell->doAddMsg( "oneToAll", clock, "process0", test, "process" );
148  shell->doAddMsg( "oneToAll", clock, "process1", test, "process" );
149  shell->doAddMsg( "oneToAll", clock, "process2", test, "process" );
150  shell->doAddMsg( "oneToAll", clock, "process3", test, "process" );
151  shell->doAddMsg( "oneToAll", clock, "process4", test, "process" );
152  shell->doAddMsg( "oneToAll", clock, "process7", test, "process" );
153  // clock.element()->digestMessages();
154  cdata->handleReinit( clocker );
155  assert( cdata->activeTicks_.size() == 6 ); // No messages
156  assert( cdata->activeTicks_[0] == 2 );
157  assert( cdata->activeTicks_[1] == 2 );
158  assert( cdata->activeTicks_[2] == 5 );
159  assert( cdata->activeTicks_[3] == 1 );
160  assert( cdata->activeTicks_[4] == 3 );
161  assert( cdata->activeTicks_[5] == 5 );
162  cdata->handleStart( clocker, runtime, false );
163  assert( doubleEq( cdata->getCurrentTime(), runtime ) );
164  test.destroy();
165  for ( unsigned int i = 0; i < Clock::numTicks; ++i )
166  cdata->ticks_[i] = 0;
167  cdata->buildTicks( clocker );
168  cout << "." << flush;
169 }
char * data() const
Definition: Eref.cpp:41
static bool set(const ObjId &dest, const string &field, L index, A arg)
Definition: SetGet.h:467
static const unsigned int numTicks
Definition: Clock.h:121
void handleReinit(const Eref &e)
dest function for message to trigger reinit.
Definition: Clock.cpp:808
Definition: Clock.h:25
double getCurrentTime() const
Definition: Clock.cpp:512
Eref eref() const
Definition: Id.cpp:125
static bool set(const ObjId &dest, const string &field, A arg)
Definition: SetGet.h:245
void handleStart(const Eref &e, double runtime, bool notify)
dest function for message to run simulation for specified time
Definition: Clock.cpp:699
vector< unsigned int > activeTicks_
Definition: Clock.h:158
bool doubleEq(double x, double y)
Definition: doubleEq.cpp:16
static Id nextId()
Definition: Id.cpp:132
static const Cinfo * testSchedCinfo
void buildTicks(const Eref &e)
Definition: Clock.cpp:675
vector< unsigned int > ticks_
Definition: Clock.h:152
Definition: Eref.h:26
ObjId doAddMsg(const string &msgType, ObjId src, const string &srcField, ObjId dest, const string &destField)
Definition: Shell.cpp:269
Definition: Id.h:17
Definition: Shell.h:43

Member Data Documentation

vector< unsigned int > Clock::activeTicks_
private

Array of active ticks. Drops out ticks lacking targets or with a zero step. Sorted in increasing order of tick index.

Definition at line 158 of file Clock.h.

Referenced by buildTicks(), handleReinit(), handleStep(), and testClock().

vector< unsigned int > Clock::activeTicksMap_
private

Maps the activeTicks_ array to the ticks index so we can trigger the appropriate message.

Definition at line 163 of file Clock.h.

Referenced by buildTicks(), handleReinit(), and handleStep().

unsigned long Clock::currentStep_
private

Definition at line 128 of file Clock.h.

Referenced by getCurrentStep(), handleReinit(), and handleStep().

double Clock::currentTime_
private

Definition at line 126 of file Clock.h.

Referenced by getCurrentTime(), handleReinit(), handleStep(), and innerReportClock().

vector< double > Clock::defaultDt_
staticprivate

Definition at line 171 of file Clock.h.

Referenced by buildDefaultTick(), and Clock().

map< string, unsigned int > Clock::defaultTick_
staticprivate

This is the database of default scheduling. Assigns classes to ticks. Filled in at Clock creation time.

Definition at line 169 of file Clock.h.

Referenced by buildDefaultTick(), and lookupDefaultTick().

bool Clock::doingReinit_
private

True while the system is doing a reinit

Definition at line 140 of file Clock.h.

Referenced by checkTickNum(), handleReinit(), handleStep(), and isDoingReinit().

double Clock::dt_
private
ProcInfo Clock::info_
private

Maintains Process info

Definition at line 145 of file Clock.h.

Referenced by handleReinit(), and handleStep().

bool Clock::isRunning_
private

The minimum dt. All ticks are a multiple of this.

True while a process job is running

Definition at line 135 of file Clock.h.

Referenced by checkTickNum(), handleReinit(), handleStep(), innerReportClock(), isRunning(), setDt(), and stop().

bool Clock::notify_
private

When set to true, notify user about the status of simulation by emitting message whenever 10% of simultion is over.

Definition at line 178 of file Clock.h.

Referenced by handleStart(), and handleStep().

unsigned long Clock::nSteps_
private

Definition at line 127 of file Clock.h.

Referenced by getNsteps(), handleReinit(), and handleStep().

const unsigned int Clock::numTicks = 32
static

number of Ticks.

The Clock manages simulation scheduling, in a close collaboration with the Tick. This version does this using an array of child Ticks, which it manages directly.

Simulation scheduling requires that certain functions of groups of objects be called in a strict sequence according to a range of timesteps, dt. For example, the numerical integration function of a compartment may be called every 10 microseconds. Furthermore, there may be ion channels in the simulation which also have to be called every 10 microseconds, but always after all the compartments have been called. Finally, the graphical update function to plot the compartment voltage may be called every 1 millisecond of simulation time. The whole sequence has to be repeated till the runtime of the simulation is complete.

This scheduler uses integral multiples of the base timestep dt_.

The system works like this:

  1. Assign times to each Tick. This is divided by dt_ and the rounded value is used for the integral multiple. Zero means the tick is not scheduled.
  2. The process call goes through all active ticks in order every timestep. Each Tick increments its counter and decides if it is time to fire.
  3. The Reinit call goes through all active ticks in order, just once.
  4. We connect up the Ticks to their target objects.
  5. We begin the simulation by calling 'start' or 'step' on the Clock. 'step' executes exactly one timestep (of the minimum dt_), visiting all ticks as above.. 'start' executes an integral number of such timesteps.
  6. To interrupt the simulation at some intermediate time, call 'stop'. This lets the system complete its current step.
  7. To restart the simulation from where it left off, use the same 'start' or 'step' function on the Clock. As all the ticks retain their state, the simulation can resume smoothly.

Definition at line 121 of file Clock.h.

Referenced by buildDefaultTick(), buildProcessVec(), checkTickNum(), Clock(), getNumTicks(), getTickDt(), getTickStep(), initCinfo(), setTickDt(), sharedProcVec(), testClock(), and ~Clock().

double Clock::runTime_
private

Definition at line 125 of file Clock.h.

Referenced by getRunTime(), handleStep(), and innerReportClock().

unsigned int Clock::stride_
private

Definition at line 129 of file Clock.h.

Referenced by buildTicks(), getStride(), handleStart(), and handleStep().

vector< unsigned int > Clock::ticks_
private

Ticks are sub-elements and send messages to sets of target Elements that handle calculations in which update order does not matter.

Definition at line 152 of file Clock.h.

Referenced by buildTicks(), Clock(), getDts(), getTickDt(), getTickStep(), innerReportClock(), setTickDt(), setTickStep(), and testClock().


The documentation for this class was generated from the following files: