2.5. Neighbourhood operations with defined topology: the snow melt model¶
2.5.1. The local drain direction map¶
In the previous exercise you created a snowmelt model. Your model calculated for each time step (day) the total amount of runoff that was generated in a cell. Here, you will transport this runoff downstream. One approach is to assume that runoff occurs towards a neighbouring cell with the steepest downhill path. These directions are stored in a so-called local drain direction map.
Open snow.py
and save it as runoff.py
. Add a lddcreate
statement calculating the local drain direction map. Run the model and have a look at the local drain direction map.
Question: Where in the script did you enter the lddcreate
function? Explain.
At the top.
In the
__init__
.In the
initial
.In the
dynamic
Correct answers: c.
Feedback:
You need the following lines in the
initial
. The lddcreate function is added to the initial section, because it needs to be calculated only once, at the start. It needs to be defined as a global variable to be later used in the dynamic section for routing of water, so this is why a variable name starting withself.
is used.self.ldd=lddcreate(dem,1e31,1e31,1e31,1e31) self.report(self.ldd,'ldd')
2.5.2. Drain all runoff within one time step: the accuflux function¶
When the size of a study area is sufficiently small and the time step duration sufficiently long that it can be assumed that all runoff generated in a time step reaches the outflow point in the same time step, runoff can be transported downstream using an accu function.
Add an accuflux
statement to runoff.py
calculating discharge for each grid cell. You need to calculate discharge as a result of the sum of rainfall (m/day) and snowmelt (m/day). Discharge should be calculated as m3/day. You can get the area of a cell (here in m3 as the length of the cells on the map is entered in metres when creating the map) with the function cellarea
. Save the runoff.py
script and run.
Animate the discharge using Aguila. Try a logarithmic scale for better visualisation (right-click on the legend, select ‘Edit draw properties’, set ‘Colour assignment’ to logarithmic and set the ‘minimum cutoff’ to a positive (non zero) value).
Question: What is the maximum discharge in the study area?
0.3·10^6 m3/day
1.3·10^6 m3/day
2.3·10^6 m3/day
1.3·10^7 m3/day
Correct answers: d.
Feedback:
from pcraster import * from pcraster.framework import * class MyFirstModel(DynamicModel): def __init__(self): DynamicModel.__init__(self) setclone('dem.map') def initial(self): dem = self.readmap('dem') elevationMeteoStation = 2058.1 elevationAboveMeteoStation = dem - elevationMeteoStation temperatureLapseRate = 0.005 self.temperatureCorrection = elevationAboveMeteoStation * \ temperatureLapseRate self.report(self.temperatureCorrection,'tempCor') self.snow=0.0 self.ldd=lddcreate(dem,1e31,1e31,1e31,1e31) self.report(self.ldd,'ldd') def dynamic(self): precipitation = timeinputscalar('precip.tss',1) self.report(precipitation,'pFromTss') temperatureObserved = timeinputscalar('temp.tss',1) self.report(temperatureObserved,'tempObs') temperature= temperatureObserved - self.temperatureCorrection self.report(temperature,'temp') freezing=temperature < 0.0 self.report(freezing,'freez') snowFall=ifthenelse(freezing,precipitation,0.0) self.report(snowFall,'snF') rainFall=ifthenelse(pcrnot(freezing),precipitation,0.0) self.report(rainFall,'rF') self.snow = self.snow+snowFall potentialMelt = ifthenelse(pcrnot(freezing),temperature*0.01,0) self.report(potentialMelt,'pmelt') actualMelt = min(self.snow, potentialMelt) self.report(actualMelt,'amelt') self.snow = self.snow - actualMelt runoffGenerated = actualMelt + rainFall self.report(runoffGenerated,'rg') discharge=accuflux(self.ldd,runoffGenerated*cellarea()) self.report(discharge,'q') self.report(self.snow,'snow') nrOfTimeSteps=181 myModel = MyFirstModel() dynamicModel = DynamicFramework(myModel,nrOfTimeSteps) dynamicModel.run()