Clock::~Clock() { if ( Msg::isLastTrump() ) { // Clean up, end of the simulation. for ( unsigned int i = 0; i < Clock::numTicks; ++i ) { delete processVec()[i]; delete reinitVec()[i]; delete sharedProcVec()[i]; } } }
const Cinfo* Clock::initCinfo() { /////////////////////////////////////////////////////// // Field definitions /////////////////////////////////////////////////////// static ValueFinfo< Clock, double > dt( "baseDt", "Base timestep for simulation. This is the smallest dt out " "of all the clock ticks. By definition all other timesteps " "are integral multiples of this, and are rounded to " "ensure that this is the case . ", &Clock::setDt, &Clock::getDt ); static ReadOnlyValueFinfo< Clock, double > runTime( "runTime", "Duration to run the simulation", &Clock::getRunTime ); static ReadOnlyValueFinfo< Clock, double > currentTime( "currentTime", "Current simulation time", &Clock::getCurrentTime ); static ReadOnlyValueFinfo< Clock, unsigned long > nsteps( "nsteps", "Number of steps to advance the simulation, in units of the smallest timestep on the clock ticks", &Clock::getNsteps ); static ReadOnlyValueFinfo< Clock, unsigned int > numTicks( "numTicks", "Number of clock ticks", &Clock::getNumTicks ); static ReadOnlyValueFinfo< Clock, unsigned int > stride( "stride", "Number by which the simulation advances the current step on each cycle. " "stride = smallest active timestep/smallest defined timestep.", &Clock::getStride ); static ReadOnlyValueFinfo< Clock, unsigned long > currentStep( "currentStep", "Current simulation step", &Clock::getCurrentStep ); static ReadOnlyValueFinfo< Clock, vector< double > > dts( "dts", "Utility function returning the dt (timestep) of all ticks.", &Clock::getDts ); static ReadOnlyValueFinfo< Clock, bool > isRunning( "isRunning", "Utility function to report if simulation is in progress.", &Clock::isRunning ); static LookupValueFinfo< Clock, unsigned int, unsigned int > tickStep( "tickStep", "Step size of specified Tick, as integral multiple of dt_" " A zero step size means that the Tick is inactive", &Clock::setTickStep, &Clock::getTickStep ); static LookupValueFinfo< Clock, unsigned int, double > tickDt( "tickDt", "Timestep dt of specified Tick. Always integral multiple of " "dt_. If you assign a non-integer multiple it will round off. " " A zero timestep means that the Tick is inactive", &Clock::setTickDt, &Clock::getTickDt ); static ReadOnlyLookupValueFinfo< Clock, string, unsigned int > defaultTick( "defaultTick", "Looks up the default Tick to use for the specified class. " "If no tick is assigned, as for classes without a process " "operation or zombie classes, the tick is ~0U. " "If nothing can be found returns 0 and emits a warning.", &Clock::getDefaultTick ); /////////////////////////////////////////////////////// // Shared definitions /////////////////////////////////////////////////////// static vector< SharedFinfo *> procs = sharedProcVec(); /////////////////////////////////////////////////////// // MsgDest definitions /////////////////////////////////////////////////////// static DestFinfo start( "start" , "Sets off the simulation for the specified duration", new EpFunc2< Clock, double, bool >(&Clock::handleStart ) ); static DestFinfo step( "step" , "Sets off the simulation for the specified # of steps. " "Here each step advances the simulation by the timestep of the " "smallest tick that is actually in use. " , new EpFunc1< Clock, unsigned long >(&Clock::handleStep ) ); static DestFinfo stop( "stop" , "Halts the simulation, with option to restart seamlessly" , new OpFunc0< Clock >(&Clock::stop ) ); static DestFinfo reinit( "reinit" , "Zeroes out all ticks, starts at t = 0" , new EpFunc0< Clock >(&Clock::handleReinit ) ); static Finfo* clockControlFinfos[] = { &start, &step, &stop, &reinit, }; /////////////////////////////////////////////////////// // SharedFinfo for Shell to control Clock static SharedFinfo clockControl( "clockControl" , "Controls all scheduling aspects of Clock, usually from Shell" , clockControlFinfos , sizeof( clockControlFinfos ) / sizeof( Finfo* ) ); static Finfo* clockFinfos[] = { // Fields &dt, // Value &runTime, // ReadOnlyValue ¤tTime, // ReadOnlyValue &nsteps, // ReadOnlyValue &numTicks, // ReadOnlyValue &stride, // ReadOnlyValue ¤tStep, // ReadOnlyValue &dts, // ReadOnlyValue &isRunning, // ReadOnlyValue &tickStep, // LookupValue &tickDt, // LookupValue &defaultTick, // ReadOnlyLookupValue &clockControl, // Shared finished(), // Src procs[0], // Src procs[1], // Src procs[2], // Src procs[3], // Src procs[4], // Src procs[5], // Src procs[6], // Src procs[7], // Src procs[8], // Src procs[9], // Src procs[10], // Src procs[11], // Src procs[12], // Src procs[13], // Src procs[14], // Src procs[15], // Src procs[16], // Src procs[17], // Src procs[18], // Src procs[19], // Src procs[20], // Src procs[21], // Src procs[22], // Src procs[23], // Src procs[24], // Src procs[25], // Src procs[26], // Src procs[27], // Src procs[28], // Src procs[29], // Src procs[30], // Src procs[31], // Src }; static string doc[] = { "Name", "Clock", "Author", "Upinder S. Bhalla, Nov 2013, NCBS", "Description", "Every object scheduled for operations in MOOSE is connected to one" "of the 'Tick' entries on the Clock.\n" "The Clock manages 32 'Ticks', each of which has its own dt," "which is an integral multiple of the clock baseDt_. " "On every clock step the ticks are examined to see which of them" "is due for updating. When a tick is updated, the 'process' call " "of all the objects scheduled on that tick is called. " "Order of execution: If a subset of ticks are scheduled for " "execution at a given timestep, then they will be executed in " "numerical order, lowest tick first and highest last. " "There is no guarantee of execution order for objects within " "a clock tick.\n" "The clock provides default scheduling for all objects which " "can be accessed using Clock::lookupDefaultTick( className ). " "Specific items of note are that the output/file dump objects are " "second-last, and the postmaster is last on the order of Ticks. " "The clock also starts up with some default timesteps for each " "of these ticks, and this can be overridden using the shell " "command setClock, or by directly assigning tickStep values on the " "clock object." "Which objects use which tick? As a rule of thumb, try this: \n" "Electrical/compartmental model calculations: Ticks 0-7 \n" "Tables and output objects for electrical output: Tick 8 \n" "Diffusion solver: Tick 10 \n" "Chemical/compartmental model calculations: Ticks 11-17\n" "Tables and output objects for chemical output: Tick 18 \n" "Unassigned: Ticks 20-29 \n" "Special: 30-31 \n" "Data output is a bit special, since you may want to store data " "at different rates for electrical and chemical processes in the " "same model. Here you will have to specifically assign distinct " "clock ticks for the tables/fileIO objects handling output at " "different time-resolutions. Typically one uses tick 8 and 18.\n" "Here are the detailed mappings of class to tick.\n" " Class Tick dt \n" " DiffAmp 0 50e-6\n" " Interpol 0 50e-6\n" " PIDController 0 50e-6\n" " PulseGen 0 50e-6\n" " StimulusTable 0 50e-6\n" " testSched 0 50e-6\n" " VClamp 0 50e-6\n" " SynHandlerBase 1 50e-6\n" " SimpleSynHandler 1 50e-6\n" " STDPSynHandler 1 50e-6\n" " GraupnerBrunel2012CaPlasticitySynHandler 1 50e-6\n" " SeqSynHandler 1 50e-6\n" " CaConc 1 50e-6\n" " CaConcBase 1 50e-6\n" " DifShell 1 50e-6\n" " DifShellBase 1 50e-6\n" " MMPump 1 50e-6\n" " DifBuffer 1 50e-6\n" " DifBufferBase 1 50e-6\n" " MgBlock 1 50e-6\n" " Nernst 1 50e-6\n" " RandSpike 1 50e-6\n" " ChanBase 2 50e-6\n" " IntFire 2 50e-6\n" " IntFireBase 2 50e-6\n" " LIF 2 50e-6\n" " QIF 2 50e-6\n" " ExIF 2 50e-6\n" " AdExIF 2 50e-6\n" " AdThreshIF 2 50e-6\n" " IzhIF 2 50e-6\n" " IzhikevichNrn 2 50e-6\n" " SynChan 2 50e-6\n" " NMDAChan 2 50e-6\n" " GapJunction 2 50e-6\n" " HHChannel 2 50e-6\n" " HHChannel2D 2 50e-6\n" " Leakage 2 50e-6\n" " MarkovChannel 2 50e-6\n" " MarkovGslSolver 2 50e-6\n" " MarkovRateTable 2 50e-6\n" " MarkovSolver 2 50e-6\n" " MarkovSolverBase 2 50e-6\n" " RC 2 50e-6\n" " Compartment (init) 3 50e-6\n" " CompartmentBase (init ) 3 50e-6\n" " SymCompartment (init) 3 50e-6\n" " Compartment 4 50e-6\n" " CompartmentBase 4 50e-6\n" " SymCompartment 4 50e-6\n" " SpikeGen 5 50e-6\n" " HSolve 6 50e-6\n" " SpikeStats 7 50e-6\n" " Table 8 0.1e-3\n" " TimeTable 8 0.1e-3\n" " Dsolve 10 0.01\n" " Adaptor 11 0.1\n" " Func 12 0.1\n" " Function 12 0.1\n" " Arith 12 0.1\n" " BufPool 13 0.1\n" " Pool 13 0.1\n" " PoolBase 13 0.1\n" " CplxEnzBase 14 0.1\n" " Enz 14 0.1\n" " EnzBase 14 0.1\n" " MMenz 14 0.1\n" " Reac 14 0.1\n" " ReacBase 14 0.1\n" " Gsolve (init) 15 0.1\n" " Ksolve (init) 15 0.1\n" " Gsolve 16 0.1\n" " Ksolve 16 0.1\n" " Stats 17 0.1\n" " Table2 18 1\n" " SocketStreamer 19 1\n" " Streamer 20 5\n" " HDF5DataWriter 30 1\n" " HDF5WriterBase 30 1\n" " NSDFWriter 30 1\n" " PyRun 30 1\n" " PostMaster 31 0.01\n" " \n" " Note that the other classes are not scheduled at all.", }; static Dinfo< Clock > dinfo; static Cinfo clockCinfo( "Clock", // "Clock class handles sequencing of operations in simulations", Neutral::initCinfo(), clockFinfos, sizeof(clockFinfos)/sizeof(Finfo *), &dinfo, doc, sizeof(doc)/sizeof(string) ); return &clockCinfo; }