2.2. The dynamic modelling framework¶
2.2.1. The dynamic modelling class¶
For dynamic (temporal) modelling, PCRaster comes with a predefined class. It will make it relatively simple to do time iterations, and to define inputs and outputs of a model. Open the file dynMod.py
in your editor, on Microsoft Windows we recommend for instance the standard Python editor (IDLE) that comes with Python (available at Start, Programs, Python, IDLE). The script is the most basic script for dynamic modelling, it does only contain the statements that are needed for the control flow of the program. When you start a project, you can take this template and add statements to construct a model. But first run this ‘empty’ model.
Question: What does it print?
It prints dots; each dot represents a second run time.
Idem, each dot represents a time step.
Correct answers: b.
Feedback: None
When constructing the model, you will only add statements to the initial and dynamic methods. For more advanced models you may want to add also calculations outside these methods, but for now, you will see that the initial and dynamic methods provide most of what you need.
Now let’s see how it executes things that you add to the initial and dynamic. Replace the pass
statement in the initial with
print('running the initial')
Replace the pass
statement in the dynamic with
timeStep = self.currentTimeStep()
print('running the dynamic for time step: ', timeStep)
Save and run the modified model.
Question: What is the order in which the initial and dynamic are executed?
The initial and dynamic are executed at the same time.
First the initial is executed once. Next, the dynamic is executed 10 times.
The initial is not executed, it only runs the dynamic.
Correct answers: b.
Feedback: None
2.2.2. Modelling with feedback¶
Now, let’s do forward modelling with feedback. We have a reservoir that is defined by the differential equation:
dx/dt = -cx
In hydrology, this is known as a linear reservoir. The variable x is the amount of water in the reservoir, and c is a rate constant. The script feedback.py
solves the linear reservoir equation using an explicit solution. Open the script and run it.
The initial sets the initial content of the reservoir. Here it merely uses an initial value that is converted to another unit, using conversionValue
. For the variable x in the differential equation, the script uses the variable name reservoir
. The dynamic solves the differential equation by subtracting each timestep the outflow
from the reservoir
. Note that the variable reservoir
is preceded by self.
. This is needed because all other variables, e.g. conversionValue
are local variables, i.e. they exist only in the method (initial or dynamic) were they have been defined. Preceding a variable with self.
makes it a member variable of the class. This means it exists (can be used) in all other methods.
Add to the dynamic the line
print(conversionValue)
and run the model.
Question: What is printed? How can you solve this error if you really want to print it in the dynamic?
An error message is printed, indicating there is a typo in the script.
An error message is printed, which indicates that
conversionValue
is defined as a local variable. The solution is to useself.conversionValue
throughout the script.An error message is printed, which indicates that
conversionValue
is defined as a global variable. The solution is to useself.conversionValue
throughout the script.
Correct answers: b.
Feedback: None
An extension to the reservoir equation would be to add constant inflow of 0.5:
dx/dt = -cx + 0.5
Modify the script to simulate this inflow.
Question: What did you add to the script? Where did you type it?
I added
+ 0.5
toself.reservoir
in theinitial
.I added
inflow = 0.5
to theinitial
and changed the line in the dynamic to:self.reservoir = self.reservoir - outflow + inflow
I added
self.inflow = 0.5
to theinitial
and changed the line in the dynamic to:self.reservoir = self.reservoir - outflow + self.inflow
Correct answers: c.
Feedback:
from pcraster import * from pcraster.framework import * class MyFirstModel(DynamicModel): def __init__(self): DynamicModel.__init__(self) setclone('dem.map') def initial(self): conversionValue = 3.0 self.reservoir = 30.0 / conversionValue print('initial reservoir is: ', self.reservoir) self.inflow = 0.5 def dynamic(self): outflow = 0.1 * self.reservoir self.reservoir = self.reservoir - outflow + self.inflow print(self.reservoir) nrOfTimeSteps=100 myModel = MyFirstModel() dynamicModel = DynamicFramework(myModel,nrOfTimeSteps) dynamicModel.run()
Question: If you run the model for a long time, what happens to the reservoir?
The reservoir decreases until it reaches 5.
The reservoir increases until it reaches 5.
The reservoir decreases until it reaches 3.
The reservoir increases until it reaches 3.
Correct answers: a.
Feedback: None