def set_parameters(
        self,
        tr_soil_out,
        V0_soil,
        beta_soil_out,
        ETV1,
        fETV0,
        meltrate,
        snow_melt_temp,
    ):
        """
        Creates all connections with the parameter values produced by the
        sampling algorithm.
        """
        # Get all definition from the init method
        p = self.project
        c = p[0]
        outlet = self.outlet
        soil = c.layers[0]

        # Adjustment of the ET
        c.set_uptakestress(cmf.VolumeStress(ETV1, ETV1 * fETV0))

        # Flux from soil to outlet
        cmf.kinematic_wave(soil,
                           outlet,
                           tr_soil_out / V0_soil,
                           V0=V0_soil,
                           exponent=beta_soil_out)

        # # Set parameters of the snow calculations
        cmf.Weather.set_snow_threshold(snow_melt_temp)
        cmf.SimpleTindexSnowMelt(c.snow, soil, c, rate=meltrate)
 def __call__(self, days=7):
     self.c.vegetation.LAI = 7
     self.c.vegetation.height = 10
     self.c.vegetation.CanopyClosure = 0.1
     l = self.c.layers[0]
     self.c.surfacewater.depth = 0.05
     l.soil.Ksat = 0.02
     l.volume = 100
     self.c.canopy.volume = self.c.vegetation.LAI * self.c.vegetation.CanopyCapacityPerLAI
     self.c.set_uptakestress(cmf.VolumeStress(10, 0))
     Vc0 = self.c.canopy.volume
     Vl0 = self.c.layers[0].volume
     Vs0 = self.c.surfacewater.volume
     solver = cmf.CVodeIntegrator(self.p, 1e-9)
     vol = []
     flux = []
     resistance = []
     mpot = []
     self.et.refresh(cmf.Time())
     for t in solver.run(cmf.Time(), cmf.day * days, cmf.min * 6):
         #print(f'{t}: {self.c.surfacewater.depth:0.3f}m')
         vol.append(
             (self.c.canopy.volume / Vc0, self.c.surfacewater.volume / Vs0,
              self.c.layers[0].volume / Vl0))
         flux.append((
             self.c.canopy.flux_to(self.c.evaporation, t),
             self.c.surfacewater.flux_to(self.c.evaporation, t),
             self.c.layers[0].flux_to(self.c.evaporation, t),
             self.c.layers[0].flux_to(self.c.transpiration, t),
             self.c.surfacewater.flux_to(self.c.layers[0], t),
         ))
         resistance.append((self.et.RAA, self.et.RAC, self.et.RAS,
                            self.et.RSC, self.et.RSS))
         mpot.append(self.c.surface_water_coverage())
     return vol, flux, resistance, mpot
    def create_connections(self):
        # Route snow melt to surface
        cmf.SimpleTindexSnowMelt(self.cell.snow,
                                 self.cell.surfacewater,
                                 rate=7)
        # Infiltration
        cmf.SimpleInfiltration(self.soil, self.cell.surfacewater, W0=0.8)
        # Route infiltration / saturation excess to outlet
        cmf.WaterBalanceFlux(self.cell.surfacewater, self.outlet)
        # Parameterize soil water capacity
        self.soil.soil.porosity = 0.2
        C = self.soil.get_capacity()
        # Parameterize water stress function
        self.cell.set_uptakestress(cmf.VolumeStress(0.2 * C, 0 * C))
        cmf.TurcET(self.soil, self.cell.transpiration)

        # Route water from soil to gw
        cmf.PowerLawConnection(self.soil,
                               self.gw,
                               Q0=self.mm_to_m3(50),
                               V0=0.5 * C,
                               beta=4)
        # Route water from gw to outlet
        cmf.LinearStorageConnection(self.gw,
                                    self.outlet,
                                    residencetime=20,
                                    residual=0 * C)
    def setparameters(self,
                      tr,
                      Vr=0.0,
                      V0=1000.,
                      beta=1.0,
                      ETV1=500.,
                      fETV0=0.0,
                      initVol=100.):
        """
        Setzt die Parameter, dabei werden parametrisierte Verbindungen neu erstellt
        
        MP111 - Änderungsbedarf: Sehr groß, hier werden alle Parameter des Modells gesetzt
        Verständlichkeit: mittel

        """
        # Ein paar Abkürzungen um Tipparbeit zu sparen
        c = self.project[0]
        outlet = self.outlet

        # Setze den Water-Uptakestress
        c.set_uptakestress(cmf.VolumeStress(ETV1, ETV1 * fETV0))
        cmf.kinematic_wave(c.layers[0],
                           outlet,
                           tr / V0,
                           exponent=beta,
                           residual=Vr,
                           V0=V0)
        c.layers[0].volume = initVol
示例#5
0
    def set_parameters(self):
        """
        Sets the parameters for a cell instance
        :param par: Object with all parameters
        :return: None
        """
        c = self.cell
        out = self.outlet

        # Fill in some water
        c.layers[0].volume = 296.726 / 1000 * self.area * 1e6
        c.layers[1].volume = 77.053 / 1000 * self.area * 1e6

        # Scale to the cellsize
        V0_L1 = (185.524 / 1000) * self.area * 1e6
        V0_L2 = (150.623 / 1000) * self.area * 1e6

        # Set uptake stress
        ETV1 = 0.145 * V0_L1
        ETV0 = 0.434 * ETV1
        c.set_uptakestress(cmf.VolumeStress(ETV1, ETV0))

        # Connect layer and outlet
        cmf.PowerLawConnection(c.layers[0],
                               out,
                               Q0=V0_L1 / 48.823,
                               V0=V0_L1,
                               beta=2.949)

        cmf.PowerLawConnection(c.layers[0],
                               c.layers[1],
                               Q0=(V0_L1 / 3.198),
                               V0=V0_L1,
                               beta=3.743)
        cmf.PowerLawConnection(c.layers[1],
                               out,
                               Q0=V0_L2 / 162.507,
                               V0=V0_L2,
                               beta=1.081)

        # Snow
        cmf.SimpleTindexSnowMelt(c.snow, c.layers[0], c, rate=3.957)
        cmf.Weather.set_snow_threshold(3.209)

        # Split the rainfall in interception and throughfall
        cmf.Rainfall(c.canopy, c, False, True)
        cmf.Rainfall(c.surfacewater, c, True, False)

        # Make an overflow for the interception storage
        cmf.RutterInterception(c.canopy, c.surfacewater, c)

        # Transpiration from the plants is added
        cmf.CanopyStorageEvaporation(c.canopy, c.evaporation, c)

        # Sets the paramaters for interception
        c.vegetation.LAI = 9.852

        # Defines how much throughfall there is (in %)
        c.vegetation.CanopyClosure = 0.603
示例#6
0
 def __call__(self, test):
     for stress in [cmf.VolumeStress(15, 5), cmf.ContentStress(), cmf.SuctionStress()]:
         self.layer.wetness = 0.31  # roughly pF=2.5
         self.cell.set_uptakestress(stress)
         solver = cmf.HeunIntegrator(self.project)
         solver.t = cmf.Time(1, 6, 2019)
         for _ in solver.run(solver.t, solver.t + cmf.day * 10, cmf.day):
             test.assertGreater(self.layer.wetness, 0.1)
示例#7
0
    def set_parameters(self, par):
        """
        Sets the parameters for a cell instance
        :param par: Object with all parameters
        :return: None
        """
        c = self.cell
        out = self.outlet

        # Scale to the cellsize
        V0_L1 = (par.V0_L1 / 1000) * self.area * 1e6
        V0_L2 = (par.V0_L2 / 1000) * self.area * 1e6

        # Set uptake stress
        ETV1 = par.fETV1 * V0_L1
        ETV0 = par.fETV0 * ETV1
        c.set_uptakestress(cmf.VolumeStress(ETV1, ETV0))

        # Connect layer and outlet
        cmf.PowerLawConnection(c.layers[0],
                               out,
                               Q0=V0_L1 / par.tr_L1_out,
                               V0=V0_L1,
                               beta=par.beta_L1_out)

        cmf.PowerLawConnection(c.layers[0],
                               c.layers[1],
                               Q0=(V0_L1 / par.tr_L1_L2),
                               V0=V0_L1,
                               beta=par.beta_L1_L2)
        cmf.PowerLawConnection(c.layers[1],
                               out,
                               Q0=V0_L2 / par.tr_L2_out,
                               V0=V0_L2,
                               beta=par.beta_L2_out)

        # Snow
        cmf.SimpleTindexSnowMelt(c.snow,
                                 c.layers[0],
                                 c,
                                 rate=par.snow_meltrate)
        cmf.Weather.set_snow_threshold(par.snow_melt_temp)

        # Split the rainfall in interception and throughfall
        cmf.Rainfall(c.canopy, c, False, True)
        cmf.Rainfall(c.surfacewater, c, True, False)

        # Make an overflow for the interception storage
        cmf.RutterInterception(c.canopy, c.surfacewater, c)

        # Transpiration from the plants is added
        cmf.CanopyStorageEvaporation(c.canopy, c.evaporation, c)

        # Sets the paramaters for interception
        c.vegetation.LAI = par.LAI

        # Defines how much throughfall there is (in %)
        c.vegetation.CanopyClosure = par.CanopyClosure
示例#8
0
    def setparameters(self, par=None):
        """
        Sets the parameters of the model by creating the connections
        """
        par = par or spotpy.parameter.create_set(self, valuetype='optguess')

        # Some shortcuts to gain visibility
        c = self.project[0]
        o = self.outlet

        # Set uptake stress
        ETV1 = par.fETV1 * par.V0
        ETV0 = par.fETV0 * ETV1
        c.set_uptakestress(cmf.VolumeStress(ETV1, ETV0))

        # Connect layer with outlet
        cmf.PowerLawConnection(c.layers[0], o,
                               Q0=par.V0 / par.tr, beta=par.beta,
                               residual=par.Vr * par.V0, V0=par.V0)
示例#9
0
    def create_connections(self, p: Parameters):
        """
        Creates the connections and parameterizes the storages of the model
        """
        # Infiltration
        cmf.SimpleInfiltration(self.soil, self.cell.surfacewater, W0=p.infiltration_w0)
        # Route infiltration / saturation excess to outlet
        cmf.waterbalance_connection(self.cell.surfacewater, self.outlet)

        capacity = self.set_soil_capacity(p)

        cmf.timeseriesETpot(self.soil, self.cell.transpiration, self.data.ETpot)

        # Parameterize infiltration capacity
        self.soil.soil.Ksat = p.infiltration_capacity / 1000

        # Parameterize water stress function
        self.cell.set_uptakestress(cmf.VolumeStress(
            p.ETV1 * capacity, 0)
        )
    def setparameters(self,
                      tr_soil_GW = 12.36870481, 
                      tr_soil_fulda = 12.,
                      tr_surf = 3.560855356,
                      tr_GW_l = 829.7188064, 
                      tr_GW_u_fulda = 270.05035, 
                      tr_GW_u_GW_l = 270., 
                      tr_fulda = 2.264612944,                     

                      V0_soil = 280.0850875,  
                      
                      beta_soil_GW=1.158865311, 
                      beta_fulda = 1.1,
                      
                      ETV1=2.575261852,
                      fETV0=0.014808919,
                      
                      meltrate = 4.464735097,
                      snow_melt_temp = 4.51938545,
                      
#                      Qd_max = 0.250552812,
#                      TW_threshold = 10.,
                      
                      LAI = 2.992013336,
                      CanopyClosure = 5.,
                      
                      Ksat = 0.02
                      ):  # this list has to be identical with the one above
        """
        sets the parameters, all parameterized connections will be created anew    
        """
        # Get all definitions from init method
        p = self.project
        c = p[0]
        outlet = self.outlet
        fulda = self.fulda
     #  trinkwasser = self.trinkwasser

        # Adjustment of the evapotranspiration
        c.set_uptakestress(cmf.VolumeStress(ETV1,ETV1 * fETV0))
        
        # Flux from the surfaces to the river
        cmf.kinematic_wave(c.surfacewater,fulda,tr_surf)
        # flux from surfaces to the soil (infiltration)
        cmf.SimpleInfiltration(c.layers[0], c.surfacewater) 

        # change the saturated conductivity of the soil
        c.layers[0].soil.Ksat = Ksat
         
        # Flux from soil to river (interflow)
        cmf.kinematic_wave(c.layers[0],fulda,tr_soil_fulda/V0_soil, V0 = V0_soil)        
        # flux from the soil to the upper groundwater (percolation)
        cmf.kinematic_wave(c.layers[0], c.layers[1],tr_soil_GW, exponent=beta_soil_GW) 

        # flux from the upper groundwater to the river (baseflow)
        cmf.kinematic_wave(c.layers[1], fulda, tr_GW_u_fulda)               
        # flux from upper to lower groundwater (percolation)
        cmf.kinematic_wave(c.layers[1], c.layers[2],tr_GW_u_GW_l)#, exponent=beta_GW_u_GW_l) 
        
        # flux from the lower groundwater to river (baseflow)
        cmf.kinematic_wave(c.layers[2], fulda, tr_GW_l)        
        # Flux from the lower groundwater to the drinking water outlet
        # the fourths argument is the amount that is now allowed to be slurped 
#        # out of the lower groundwater
#        cmf.TechnicalFlux(c.layers[2],trinkwasser,Qd_max,TW_threshold,cmf.day)
#        
#        # Flux from drinking water to the river
#        cmf.waterbalance_connection(trinkwasser, fulda)     
        
        # flux from the river to the outlet
        cmf.kinematic_wave(fulda, outlet, tr_fulda, exponent = beta_fulda) 
        
        # set snowmelt temperature
        cmf.Weather.set_snow_threshold(snow_melt_temp)        
        # Snowmelt at the surfaces
        snowmelt_surf = cmf.SimpleTindexSnowMelt(c.snow,c.surfacewater,c,rate=meltrate)

        # Splits the rainfall in interzeption and throughfall
        cmf.Rainfall(c.canopy,c, False, True)
        cmf.Rainfall(c.surfacewater,c, True, False)
        # Makes a overflow for the interception storage
        cmf.RutterInterception(c.canopy,c.surfacewater,c)
        # Transpiration on the plants is added
        cmf.CanopyStorageEvaporation(c.canopy,c.evaporation,c)
        # Sets the parameters for the interception       
        c.vegetation.LAI= LAI    
        # Defines how much throughfall there is (in %)
        c.vegetation.CanopyClosure = CanopyClosure
示例#11
0
    def set_parameters(self, params):
        """
        Sets the parameters for the current cell.

        :param: params: dictionary of parameters.
        :return:
        """
        # Get all definition from the init method
        cell = self.cell
        outlet = self.outlet
        soil = cell.layers[0]
        gw = cell.layers[1]
        
        # EVT1 must be adjusted to cell size
        ETV1 = params["ETV1"]
        ETV1 = (ETV1 / 1000) * cell.area
        
        # V0 must be adjusted to cell size as well
        V0_soil = params["V0_soil"]
        V0_soil = (V0_soil / 1000) * cell.area
        
        # Adjustment of the ET
        cell.set_uptakestress(cmf.VolumeStress(
                                ETV1,
                                ETV1 * params["fETV0"]))

        # Flux from soil to outlet
        cmf.kinematic_wave(soil,
                           outlet,
                           params["tr_soil_out"] / V0_soil,
                           V0=V0_soil,
                           exponent=params["beta_soil_out"])

        # Flux from soil to groundwater
        cmf.kinematic_wave(soil, gw,
                           params["tr_soil_gw"] / V0_soil,
                           V0=V0_soil,
                           exponent=params["beta_soil_gw"])

        # Flux from the  groundwater to the outlet (baseflow)
        cmf.kinematic_wave(gw, outlet, params["tr_gw_out"])

        # Split the rainfall in interception and throughfall
        cmf.Rainfall(cell.canopy, cell, False, True)
        cmf.Rainfall(cell.surfacewater, cell, True, False)

        # Make an overflow for the interception storage
        cmf.RutterInterception(cell.canopy, cell.surfacewater, cell)

        # Transpiration from the plants is added
        cmf.CanopyStorageEvaporation(cell.canopy, cell.evaporation, cell)

        # Sets the paramaters for interception
        cell.vegetation.LAI = params["LAI"]

        # Defines how much throughfall there is (in %)
        cell.vegetation.CanopyClosure = params["CanopyClosure"]

        # # Set parameters of the snow calculations
        cmf.Weather.set_snow_threshold(params["snow_melt_temp"])
        cmf.SimpleTindexSnowMelt(cell.snow, soil, cell,
                                 rate=params["meltrate"])
示例#12
0
    def set_parameters(
        self,
        tr_soil_gw,
        tr_soil_out,
        tr_gw_out,
        V0_soil,
        beta_soil_gw,
        beta_soil_out,
        ETV1,
        fETV0,
        #
        # meltrate,
        # snow_melt_temp,
        LAI,
        CanopyClosure,
    ):
        """
        Creates all connections with the parameter values produced by the
        sampling algorithm.
        """
        print("tr_soil_gw: {}; tr_soil_out: {}; tr_gw_out: {}; V0_soil: {}; "
              "beta_soil_gw: {}; beta_soil_out: {}; ETV1: {}; fETV0: {}; "
              "LAI: {}; CanopyClosure:"
              " {}\n".format(tr_soil_gw, tr_soil_out, tr_gw_out, V0_soil,
                             beta_soil_gw, beta_soil_out, ETV1, fETV0, LAI,
                             CanopyClosure))
        # Get all definition from the init method
        p = self.project
        c = p[0]
        outlet = self.outlet
        soil = c.layers[0]
        gw = c.layers[1]

        # Adjustment of the ET
        c.set_uptakestress(cmf.VolumeStress(ETV1, ETV1 * fETV0))

        # Flux from soil to outlet
        cmf.kinematic_wave(soil,
                           outlet,
                           tr_soil_out / V0_soil,
                           V0=V0_soil,
                           exponent=beta_soil_out)

        # Flux from soil to groundwater
        cmf.kinematic_wave(soil,
                           gw,
                           tr_soil_gw / V0_soil,
                           V0=V0_soil,
                           exponent=beta_soil_gw)

        # Flux from the  groundwater to the outlet (baseflow)
        cmf.kinematic_wave(gw, outlet, tr_gw_out)

        # Split the rainfall in interception and throughfall
        cmf.Rainfall(c.canopy, c, False, True)
        cmf.Rainfall(c.surfacewater, c, True, False)

        # Make an overflow for the interception storage
        cmf.RutterInterception(c.canopy, c.surfacewater, c)

        # Transpiration from the plants is added
        cmf.CanopyStorageEvaporation(c.canopy, c.evaporation, c)

        # Sets the paramaters for interception
        c.vegetation.LAI = LAI

        # Defines how much throughfall there is (in %)
        c.vegetation.CanopyClosure = CanopyClosure
示例#13
0
    def setparameters(self, tr_first_out, tr_first_river, tr_first_second,
                      tr_second_third, tr_second_river, tr_third_river,
                      tr_river_out, beta_first_out, beta_first_river,
                      beta_first_second, beta_second_river, beta_second_third,
                      beta_third_river, beta_river_out, canopy_lai,
                      canopy_closure, snow_meltrate, snow_melt_temp,
                      V0_first_out, V0_first_river, V0_first_second, ETV0,
                      fETV0):
        """
        sets the Parameters, all Parametrized connections will be created anew
        """
        # Get all definitions from init method
        p = self.project
        cell = p[0]
        first = cell.layers[0]
        second = cell.layers[1]
        third = cell.layers[2]

        river = self.river

        out = self.outlet

        # Adjustment of the evapotranspiration
        cell.set_uptakestress(cmf.VolumeStress(ETV0, ETV0 * fETV0))

        # Kinematic waves
        cmf.kinematic_wave(first,
                           second,
                           tr_first_second,
                           exponent=beta_first_second,
                           V0=V0_first_second)
        cmf.kinematic_wave(first,
                           out,
                           tr_first_out,
                           exponent=beta_first_out,
                           V0=V0_first_out)
        cmf.kinematic_wave(first,
                           river,
                           tr_first_river,
                           exponent=beta_first_river,
                           V0=V0_first_river)

        cmf.kinematic_wave(second,
                           river,
                           tr_second_river,
                           exponent=beta_second_river)

        cmf.kinematic_wave(second,
                           third,
                           tr_second_third,
                           exponent=beta_second_third)

        cmf.kinematic_wave(third,
                           river,
                           tr_third_river,
                           exponent=beta_third_river)

        cmf.kinematic_wave(river, out, tr_river_out, exponent=beta_river_out)

        # set snowmelt temperature
        cmf.Weather.set_snow_threshold(snow_melt_temp)
        # Snowmelt at the surfaces
        cmf.SimpleTindexSnowMelt(cell.snow,
                                 cell.surfacewater,
                                 cell,
                                 rate=snow_meltrate)

        # Splits the rainfall in interception and throughfall
        cmf.Rainfall(cell.canopy, cell, False, True)
        cmf.Rainfall(cell.surfacewater, cell, True, False)
        # Makes a overflow for the interception storage
        cmf.RutterInterception(cell.canopy, cell.surfacewater, cell)
        # Transpiration on the plants is added
        cmf.CanopyStorageEvaporation(cell.canopy, cell.evaporation, cell)
        # Sets the Parameters for the interception
        cell.vegetation.LAI = canopy_lai
        # Defines how much throughfall there is (in %)
        cell.vegetation.CanopyClosure = canopy_closure
    def setparameters(self,
                      tr_soil_GW = 12.36870481, 
                      tr_soil_fulda = 12.,
                   #   tr_surf = 3.560855356,
                      tr_GW_l = 829.7188064, 
                      tr_GW_u_fulda = 270.05035, 
                      tr_GW_u_GW_l = 270., 
                      tr_fulda = 2.264612944,                     

                      V0_soil = 280.0850875,  
                      
                      beta_soil_GW=1.158865311, 
                      beta_fulda = 1.1,
                      
                      ETV1=2.575261852,
                      fETV0=0.014808919,
                      
                  #    meltrate = 4.464735097,
                #      snow_melt_temp = 4.51938545,
                      
                      Qd_max = 0.250552812,
                      TW_threshold = 10.,
                      
                 #     LAI = 2.992013336,
                #      CanopyClosure = 5.,
                      
                #      Ksat = 0.02
                      ):  # this list has to be identical with the one above
        """
        sets the parameters, all parameterized connections will be created anew    
        """
        # Get all definitions from init method
        p = self.project
        c = p[0]
        outlet = self.outlet
        fulda = self.fulda
        trinkwasser = self.trinkwasser

        # Adjustment of the evapotranspiration
        c.set_uptakestress(cmf.VolumeStress(ETV1,ETV1 * fETV0))
        
        # Flux from the surfaces to the river
   #     cmf.kinematic_wave(c.surfacewater,fulda,tr_surf)
        # flux from surfaces to the soil (infiltration)
     #   cmf.SimpleInfiltration(c.layers[0], c.surfacewater) 

        # change the saturated conductivity of the soil
    #    c.layers[0].soil.Ksat = Ksat
         
        # Flux from soil to river (interflow)
        cmf.kinematic_wave(c.layers[0],fulda,tr_soil_fulda/V0_soil, V0 = V0_soil)        
        # flux from the soil to the upper groundwater (percolation)
        cmf.kinematic_wave(c.layers[0], c.layers[1],tr_soil_GW, exponent=beta_soil_GW) 

        # flux from the upper groundwater to the river (baseflow)
        cmf.kinematic_wave(c.layers[1], fulda, tr_GW_u_fulda)               
        # flux from upper to lower groundwater (percolation)
        cmf.kinematic_wave(c.layers[1], c.layers[2],tr_GW_u_GW_l)#, exponent=beta_GW_u_GW_l) 
        
        # flux from the lower groundwater to river (baseflow)
        cmf.kinematic_wave(c.layers[2], fulda, tr_GW_l)        
        # Flux from the lower groundwater to the drinking water outlet
        # the fourths argument is the amount that is now allowed to be slurped 
        # out of the lower groundwater
        cmf.TechnicalFlux(c.layers[2],trinkwasser,Qd_max,TW_threshold,cmf.day)
        
        # Flux from drinking water to the river
        cmf.waterbalance_connection(trinkwasser, fulda)     
        
        # flux from the river to the outlet
        cmf.kinematic_wave(fulda, outlet, tr_fulda, exponent = beta_fulda) 
示例#15
0
cell = p.NewCell(0, 0, 0, 1000)
layer = cell.add_layer(1.0)

# Set summertime, when the living is easy... (1)
summer = cmf.Weather(Tmin=19, Tmax=28, rH=50, wind=4.0,
                     sunshine=0.9, daylength=14, Rs=26)
cell.set_weather(summer)

# Initial condition (4)
layer.volume = 400.0

# ET-Method (3)
et_pot_turc = cmf.TurcET(layer, cell.transpiration)

# Stress conditions (5, 6)
stress = cmf.VolumeStress(300, 100)
cell.set_uptakestress(stress)

# A solver
solver = cmf.HeunIntegrator(p)
solver.t = datetime(2018, 5, 1)
et_act = cmf.timeseries(solver.t, cmf.day)
volume = cmf.timeseries(solver.t, cmf.day)
while solver.t < datetime(2018, 10, 1):
    et_act.add(cell.transpiration(solver.t))
    volume.add(layer.volume)
    solver(cmf.day)

# And a plot
plot(et_act, c='g')
ylabel(r'$ET_{act} \left[\frac{mm}{day}\right]$')