The run parameters of a Simulation are conveyed to theModel by means of a Runner. Rather than simply being a list of time-parameters, runners can be extended to add quite interesting model behaviour without changing a line of code to the model itself.
|note: this concept is under development and subject to changes|
starting the model
To start a model run, call
runModel() in the unit model.py. he unit runCSR.py is the prefered place to set up and activate the runner.
without a runner
The Model is always started with a runner which is passed to
runModel(). If this function is called without arguments, a default runner is created that will run the model for 365 days.
with a runner
The Runner-class is co-developed with Model and therefore it resides in model.py, too. An instance of Runner can be created and passed to
runModel() to run the model for an other period than 365 days.
The class's constructor is
def __init__(self, days = 365, years = 0, startTime = 1):
- days: # days to run, in addition to years
- years: # years to run, in addition to days
- startTime: day number of the starting day
|example, to run for approx. 1.5 years|
runModel(Runner(days = 180, years = 1)) # alternative way: runner = Runner(days = 180, years = 1) runner.run()
creating a custom runner
Runner can be subclassed to implement custom behaviour. Examples are bypassing the standard initialisation, and defining output events. The methods available are:
def identification(self): """ Shown at the beginning of a simulation run, each subclassed Runner ought to define its own identification line. @return: string """ return <identification statement> def doAfterModelConstruction(self, system): def doSetUpComplete(self, system): def doInitialized(self, system): def doStartTimeStep(self, system, time): def doEndTimeStep(self, system, time): def doEndRun(self, system):
Each subclass must override
identification() to feed back to the user which Runner is in charge. The other methods are called at specific moments during the simulation and optional to override.
|simple output example|
@override def doInitialized(self, system): self._system = system for state in getGlobalStateList(): state.onIntegration = self.printIntegrands def printIntegrands(self, state, effective_rate, value): print "%s of %s (t=%f):" % (state.name, state.owner, self._system.time) print " ", value, "+", effective_rate, "=", value + effective_rate, print "[%s]" % (state.units if len(state.units) > 0 else '?')
example: inteurupt execution
|simple output example|
@override def doInitialized(self, system): sys.exit("%s will only run upto initialization" % (self.__class__.__name__))
example: bypass initialization
|change initialization of patches|
@override def doAfterModelConstruction(self, modelSystem): modelSystem.modelArea.builder = BareSoilInitializer()