MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Clock.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment,
4 ** also known as GENESIS 3 base code.
5 ** copyright (C) 2003-2013 Upinder S. Bhalla. and NCBS
6 ** It is made available under the terms of the
7 ** GNU Lesser General Public License version 2.1
8 ** See the file COPYING.LIB for the full notice.
9 **********************************************************************/
10 
51 #include "../basecode/header.h"
52 #include "Clock.h"
53 #include "../utility/numutil.h"
54 #include "../utility/print_function.hpp"
55 
56 #if PARALLELIZE_CLOCK_USING_CPP11_ASYNC
57 #include <future>
58 #endif
59 
60 // Declaration of some static variables.
61 const unsigned int Clock::numTicks = 32;
63 const double minimumDt = 1e-7;
64 map< string, unsigned int > Clock::defaultTick_;
65 vector< double > Clock::defaultDt_;
66 
68 // MsgSrc definitions
70 
72 {
73  static SrcFinfo0 finished(
74  "finished",
75  "Signal for completion of run"
76  );
77  return &finished;
78 }
79 
80 // Static func for building the process vectors.
81 static vector< SrcFinfo1< ProcPtr >* > buildProcessVec( const string& name )
82 {
83  vector< SrcFinfo1< ProcPtr >* > vec;
84  vec.resize( Clock::numTicks );
85  for ( unsigned int i = 0; i < Clock::numTicks; ++i )
86  {
87  stringstream ss;
88  ss << name << i;
89  stringstream ss2;
90  ss2 << name << " for Tick " << i;
91  vec[i] = new SrcFinfo1< ProcPtr >( ss.str(), ss2.str() );
92  }
93  return vec;
94 }
95 
96 // This vector contains the SrcFinfos used for Process calls for each
97 // of the Ticks.
98 static vector< SrcFinfo1< ProcPtr >* >& processVec()
99 {
100  static vector< SrcFinfo1< ProcPtr >* > processVec =
101  buildProcessVec( "process" );
102  return processVec;
103 }
104 
105 static vector< SrcFinfo1< ProcPtr >* >& reinitVec()
106 {
107  static vector< SrcFinfo1< ProcPtr >* > reinitVec =
108  buildProcessVec( "reinit" );
109  return reinitVec;
110 }
111 
112 static vector< SharedFinfo *>& sharedProcVec()
113 {
114  static vector< SharedFinfo* > vec;
115  if ( vec.size() == 0 )
116  {
117  vec.resize( Clock::numTicks );
118  for ( unsigned int i = 0; i < Clock::numTicks; ++i )
119  {
120  stringstream ss;
121  Finfo* temp[2];
122  temp[0] = processVec()[i];
123  temp[1] = reinitVec()[i];
124  ss << "proc" << i;
125  vec[i] = new SharedFinfo( ss.str(),
126  "Shared process/reinit message",
127  temp, 2 );
128  }
129  }
130  return vec;
131 }
132 
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 }
452 
454 
456 // Constructor
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 }
477 
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 }
491 // Field function definitions
493 void Clock::setDt( double v)
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 }
502 
503 double Clock::getDt() const
504 {
505  return dt_;
506 }
507 double Clock::getRunTime() const
508 {
509  return runTime_;
510 }
511 
512 double Clock::getCurrentTime() const
513 {
514  return currentTime_;
515 }
516 
517 unsigned long Clock::getNsteps() const
518 {
519  return nSteps_;
520 }
521 
522 unsigned long Clock::getCurrentStep() const
523 {
524  return currentStep_;
525 }
526 
527 unsigned int Clock::getNumTicks() const
528 {
529  return numTicks;
530 }
531 
532 unsigned int Clock::getStride() const
533 {
534  return stride_;
535 }
536 
537 vector< double > Clock::getDts() const
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 }
546 
547 bool Clock::isRunning() const
548 {
549  return isRunning_;
550 }
551 
553 {
554  return doingReinit_;
555 }
556 
557 bool Clock::checkTickNum( const string& funcName, unsigned int i ) const
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 }
574 
575 void Clock::setTickStep( unsigned int i, unsigned int v )
576 {
577  if ( checkTickNum( "setTickStep", i ) )
578  ticks_[i] = v;
579 }
580 unsigned int Clock::getTickStep( unsigned int i ) const
581 {
582  if ( i < Clock::numTicks )
583  return ticks_[i];
584  return 0;
585 }
586 
591 void Clock::setTickDt( unsigned int i, double v )
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 }
620 
621 double Clock::getTickDt( unsigned int i ) const
622 {
623  if ( i < Clock::numTicks )
624  return ticks_[i] * dt_;
625  return 0.0;
626 }
627 
628 unsigned int Clock::getDefaultTick( string s ) const
629 {
630  return Clock::lookupDefaultTick( s );
631 }
632 
634 // Dest function definitions
636 
642 {
643  isRunning_ = 0;
644 }
645 
647 // Info functions
649 
652 {
653  const Clock* c = reinterpret_cast< const Clock* >( Id( 1 ).eref().data() );
654  c->innerReportClock();
655 }
656 
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 }
670 
672 // Core scheduling functions.
674 
675 void Clock::buildTicks( const Eref& e )
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 }
693 
699 void Clock::handleStart( const Eref& e, double runtime, bool notify )
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 }
710 
711 void Clock::handleStep( const Eref& e, unsigned long numSteps )
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 }
804 
808 void Clock::handleReinit( const Eref& e )
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 }
832 
833 /*
834  * Useful function, only I don't need it yet. Was implemented for Dsolve
835 double Dsolve::findDt( const Eref& e )
836 {
837  // Here is the horrible stuff to traverse the message to get the dt.
838  const Finfo* f = Dsolve::initCinfo()->findFinfo( "reinit" );
839  const DestFinfo* df = dynamic_cast< const DestFinfo* >( f );
840  assert( df );
841  unsigned int fid = df->getFid();
842  ObjId caller = e.element()->findCaller( fid );
843  const Msg* m = Msg::getMsg( caller );
844  assert( m );
845  vector< string > src = m->getSrcFieldsOnE1();
846  assert( src.size() > 0 );
847  string temp = src[0].substr( src[0].length() - 1 ); // reinitxx
848  unsigned int tick = atoi( temp.c_str() );
849  assert( tick < 10 );
850  Id clock( 1 );
851  assert( clock.element() == m->e1() );
852  double dt = LookupField< unsigned int, double >::
853  get( clock, "tickDt", tick );
854  return dt;
855 }
856 */
857 
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 }
1033 
1034 // Static function
1035 unsigned int Clock::lookupDefaultTick( const string& className )
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 vector< SrcFinfo1< ProcPtr > * > & processVec()
Definition: Clock.cpp:98
bool isRunning_
The minimum dt. All ticks are a multiple of this.
Definition: Clock.h:135
void setDt(double v)
Definition: Clock.cpp:493
Clock()
Definition: Clock.cpp:458
char * data() const
Definition: Eref.cpp:41
static vector< SrcFinfo1< ProcPtr > * > & reinitVec()
Definition: Clock.cpp:105
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
Definition: Clock.h:25
double dt_
Definition: Clock.h:130
double getCurrentTime() const
Definition: Clock.cpp:512
double currTime
Definition: ProcInfo.h:19
Definition: Dinfo.h:60
bool notify_
When set to true, notify user about the status of simulation by emitting message whenever 10% of simu...
Definition: Clock.h:178
static const Cinfo * initCinfo()
Definition: Clock.cpp:133
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
bool isDoingReinit() const
Definition: Clock.cpp:552
vector< double > getDts() const
Definition: Clock.cpp:537
static vector< SrcFinfo1< ProcPtr > * > buildProcessVec(const string &name)
Definition: Clock.cpp:81
double getTickDt(unsigned int i) const
Definition: Clock.cpp:621
Eref eref() const
Definition: Id.cpp:125
~Clock()
Definition: Clock.cpp:478
Element * element() const
Definition: Eref.h:42
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 > activeTicksMap_
Definition: Clock.h:163
const double minimumDt
minimumDt is smaller than any known event on the scales MOOSE handles.
Definition: Clock.cpp:63
vector< unsigned int > activeTicks_
Definition: Clock.h:158
unsigned long currentStep_
Definition: Clock.h:128
bool checkTickNum(const string &funcName, unsigned int i) const
Utility func to range-check when Ticks are being changed.
Definition: Clock.cpp:557
double currentTime_
Definition: Clock.h:126
double getDt() const
Definition: Clock.cpp:503
ProcInfo info_
Definition: Clock.h:145
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
bool hasMsgs(BindIndex b) const
Definition: Element.cpp:307
static vector< double > defaultDt_
Definition: Clock.h:171
double runTime_
Definition: Clock.h:125
static bool isLastTrump()
True when MOOSE has been terminated and is being cleaned up.
Definition: Msg.cpp:320
Definition: EpFunc.h:49
void buildTicks(const Eref &e)
Definition: Clock.cpp:675
double dt
Definition: ProcInfo.h:18
vector< unsigned int > ticks_
Definition: Clock.h:152
Definition: Eref.h:26
bool doingReinit_
Definition: Clock.h:140
static unsigned int lookupDefaultTick(const string &className)
Definition: Clock.cpp:1035
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 void buildDefaultTick()
Builds the default scheduling map of classes to ticks.
Definition: Clock.cpp:870
static SrcFinfo0 * finished()
Definition: Clock.cpp:71
static const Cinfo * clockCinfo
Definition: Clock.cpp:453
unsigned long nSteps_
Definition: Clock.h:127
static char name[]
Definition: mfield.cpp:401
static void reportClock()
Static function.
Definition: Clock.cpp:651
void innerReportClock() const
Definition: Clock.cpp:657
void send(const Eref &e) const
Definition: SrcFinfo.cpp:70
Definition: Id.h:17
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
static map< string, unsigned int > defaultTick_
Definition: Clock.h:169
unsigned int stride_
Definition: Clock.h:129
Definition: Cinfo.h:18
Definition: EpFunc.h:79
unsigned long getNsteps() const
Definition: Clock.cpp:517
Definition: Finfo.h:12