def checkWaterBalance(self, storesAtBeginning, storesAtEnd): # for the entire modules: snow + interception + soil + groundwater + waterDemand # except: river/routing precipitation = pcr.ifthen(self.landmask,\ self.meteo.precipitation) # unit: m runoff = pcr.ifthen(self.landmask,self.routing.runoff) vos.waterBalanceCheck([precipitation],\ [runoff],\ [storesAtBeginning],\ [storesAtEnd],\ 'all modules (including water demand), but except river/routing',\ True,\ self._modelTime.fulldate,threshold=1e-3)
def update( self, newStorageAtLakeAndReservoirs, timestepsToAvgDischarge, maxTimestepsToAvgDischargeShort, maxTimestepsToAvgDischargeLong, currTimeStep, avgChannelDischarge, length_of_time_step=vos.secondsPerDay(), downstreamDemand=None, ): if self.debugWaterBalance: preStorage = self.waterBodyStorage # unit: m self.timestepsToAvgDischarge = ( timestepsToAvgDischarge ) # TODO: include this one in "currTimeStep" # obtain inflow (and update storage) self.moveFromChannelToWaterBody( newStorageAtLakeAndReservoirs, timestepsToAvgDischarge, maxTimestepsToAvgDischargeShort, length_of_time_step, ) # calculate outflow (and update storage) self.getWaterBodyOutflow( maxTimestepsToAvgDischargeLong, avgChannelDischarge, length_of_time_step, downstreamDemand, ) if self.debugWaterBalance: vos.waterBalanceCheck( [pcr.cover(self.inflow / self.waterBodyArea, 0.0)], [pcr.cover(self.waterBodyOutflow / self.waterBodyArea, 0.0)], [pcr.cover(preStorage / self.waterBodyArea, 0.0)], [pcr.cover(self.waterBodyStorage / self.waterBodyArea, 0.0)], "WaterBodyStorage (unit: m)", True, currTimeStep.fulldate, threshold=5e-3, )
def checkLandSurfaceWaterBalance(self, storesAtBeginning, storesAtEnd): # for the entire stores from snow + interception + soil + groundwater, but excluding river/routing # # - incoming fluxes (unit: m) precipitation = pcr.ifthen(self.landmask, self.meteo.precipitation) irrGrossDemand = pcr.ifthen(self.landmask, self.landSurface.irrGrossDemand) surfaceWaterInf = pcr.ifthen(self.landmask, self.groundwater.surfaceWaterInf) # # - outgoing fluxes (unit: m) actualET = pcr.ifthen(self.landmask, self.landSurface.actualET) runoff = pcr.ifthen(self.landmask, self.routing.runoff) nonFossilGroundwaterAbs = pcr.ifthen(self.landmask, self.groundwater.nonFossilGroundwaterAbs) # vos.waterBalanceCheck([precipitation,surfaceWaterInf,irrGrossDemand],\ [actualET,runoff,nonFossilGroundwaterAbs],\ [storesAtBeginning],\ [storesAtEnd],\ 'all stores (snow + interception + soil + groundwater), but except river/routing',\ True,\ self._modelTime.fulldate,threshold=1e-3)
def update(self,newStorageAtLakeAndReservoirs,\ timestepsToAvgDischarge,\ maxTimestepsToAvgDischargeShort,\ maxTimestepsToAvgDischargeLong,\ currTimeStep,\ avgChannelDischarge,\ length_of_time_step = vos.secondsPerDay(),\ downstreamDemand = None): if self.debugWaterBalance: \ preStorage = self.waterBodyStorage # unit: m self.timestepsToAvgDischarge = timestepsToAvgDischarge # TODO: include this one in "currTimeStep" # obtain inflow (and update storage) self.moveFromChannelToWaterBody(\ newStorageAtLakeAndReservoirs,\ timestepsToAvgDischarge,\ maxTimestepsToAvgDischargeShort,\ length_of_time_step) # calculate outflow (and update storage) self.getWaterBodyOutflow(\ maxTimestepsToAvgDischargeLong,\ avgChannelDischarge,\ length_of_time_step,\ downstreamDemand) if self.debugWaterBalance: \ vos.waterBalanceCheck([ pcr.cover(self.inflow/self.waterBodyArea,0.0)],\ [pcr.cover(self.waterBodyOutflow/self.waterBodyArea,0.0)],\ [ pcr.cover(preStorage/self.waterBodyArea,0.0)],\ [pcr.cover(self.waterBodyStorage/self.waterBodyArea,0.0)],\ 'WaterBodyStorage (unit: m)',\ True,\ currTimeStep.fulldate,threshold=5e-3) self.waterBodyBalance = (pcr.cover(self.inflow/self.waterBodyArea, 0.0) - pcr.cover(self.waterBodyOutflow/self.waterBodyArea,0.0)) -\ (pcr.cover(self.waterBodyStorage/self.waterBodyArea,0.0) - pcr.cover(preStorage/self.waterBodyArea,0.0))
def update(self,landSurface,routing,currTimeStep): if self.debugWaterBalance: preStorGroundwater = self.storGroundwater preStorGroundwaterFossil = self.storGroundwaterFossil # get riverbed infiltration from the previous time step (from routing) self.surfaceWaterInf = routing.riverbedExchange/routing.cellArea # m self.storGroundwater += self.surfaceWaterInf # get net recharge (percolation-capRise) and update storage: self.storGroundwater = pcr.max(0.,\ self.storGroundwater + landSurface.gwRecharge) # potential groundwater abstraction (unit: m) potGroundwaterAbstract = landSurface.totalPotentialGrossDemand -\ landSurface.allocSurfaceWaterAbstract if self.usingAllocSegments == False or self.limitAbstraction: # Note: For simplicity, no network for a run with limitAbstraction. logger.info("Groundwater abstraction is only to satisfy local demand. No network for distributing groundwater.") # nonFossil groundwater abstraction (unit: m) to fulfill water demand # - assumption: Groundwater is only abstracted to satisfy local demand. self.nonFossilGroundwaterAbs = \ pcr.max(0.0, pcr.min(self.storGroundwater,\ potGroundwaterAbstract)) # self.allocNonFossilGroundwater = self.nonFossilGroundwaterAbs if self.usingAllocSegments and self.limitAbstraction == False: # Note: Incorporating distribution network of groundwater source is possible only if limitAbstraction = False. logger.info("Using groundwater source allocation.") # gross/potential demand volume in each cell (unit: m3) cellVolGrossDemand = potGroundwaterAbstract*routing.cellArea # total gross demand volume in each segment/zone (unit: m3) segTtlGrossDemand = pcr.areatotal(cellVolGrossDemand, self.allocSegments) # total available groundwater water volume in each cell - ignore small values (less than 1 m3) cellAvlGroundwater = pcr.max(0.00, self.storGroundwater* routing.cellArea) cellAvlGroundwater = pcr.rounddown( cellAvlGroundwater/1.)*1. # total available surface water volume in each segment/zone (unit: m3) segAvlGroundwater = pcr.areatotal(cellAvlGroundwater, self.allocSegments) segAvlGroundwater = pcr.max(0.00, segAvlGroundwater) # total actual surface water abstraction volume in each segment/zone (unit: m3) # # - not limited to available water - ignore small values (less than 1 m3) segActGroundwaterAbs = pcr.max(0.0,\ pcr.rounddown(segTtlGrossDemand)) # # - limited to available water segActGroundwaterAbs = pcr.min(segAvlGroundwater, segActGroundwaterAbs) # actual surface water abstraction volume in each cell (unit: m3) volActGroundwaterAbstract = vos.getValDivZero(\ cellAvlGroundwater, segAvlGroundwater, vos.smallNumber) * \ segActGroundwaterAbs volActGroundwaterAbstract = pcr.min(cellAvlGroundwater , volActGroundwaterAbstract) # unit: m3 # actual non fossil groundwater abstraction volume in meter (unit: m) self.nonFossilGroundwaterAbs = pcr.ifthen(self.landmask, volActGroundwaterAbstract) /\ routing.cellArea # unit: m # allocation non fossil groundwater abstraction volume to each cell (unit: m3) self.volAllocGroundwaterAbstract = vos.getValDivZero(\ cellVolGrossDemand, segTtlGrossDemand, vos.smallNumber) *\ segActGroundwaterAbs # unit: m3 # allocation surface water abstraction in meter (unit: m) self.allocNonFossilGroundwater = pcr.ifthen(self.landmask, self.volAllocGroundwaterAbstract)/\ routing.cellArea # unit: m if self.debugWaterBalance == str('True'): abstraction = pcr.cover(pcr.areatotal(self.nonFossilGroundwaterAbs *routing.cellArea, self.allocSegments)/self.segmentArea, 0.0) allocation = pcr.cover(pcr.areatotal(self.allocNonFossilGroundwater*routing.cellArea, self.allocSegments)/self.segmentArea, 0.0) vos.waterBalanceCheck([abstraction],\ [allocation],\ [pcr.scalar(0.0)],\ [pcr.scalar(0.0)],\ 'non fossil groundwater abstraction - allocation per zone/segment (PS: Error here may be caused by rounding error.)' ,\ True,\ "",threshold=5e-4) # update storGoundwater after self.nonFossilGroundwaterAbs self.storGroundwater = pcr.max(0.,self.storGroundwater - self.nonFossilGroundwaterAbs) # unmetDemand (m), satisfied by fossil gwAbstractions # TODO: Include desalinization self.unmetDemand = pcr.max(0.0, potGroundwaterAbstract - \ self.allocNonFossilGroundwater) # m (equal to zero if limitAbstraction = True) if self.limitAbstraction: logger.info("No fossil groundwater abstraction is allowed") # TODO: check that self.unmetDemand = 0.0 # correcting unmetDemand with available fossil groundwater # Note: For simplicity, limitFossilGroundwaterAbstraction can only be combined with local source assumption if self.usingAllocSegments == False and self.limitFossilGroundwaterAbstraction: self.unmetDemand = pcr.min(pcr.max(0.0, self.storGroundwaterFossil), self.unmetDemand) # calculate the average groundwater abstraction (m/day) from the last 365 days: totalAbstraction = self.unmetDemand + self.nonFossilGroundwaterAbs deltaAbstraction = totalAbstraction - self.avgAbstraction self.avgAbstraction = self.avgAbstraction +\ deltaAbstraction/\ pcr.min(365., pcr.max(1.0, routing.timestepsToAvgDischarge)) self.avgAbstraction = pcr.max(0.0, self.avgAbstraction) # update storGroundwaterFossil after unmetDemand self.storGroundwaterFossil -= self.unmetDemand # calculate baseflow and update storage: self.baseflow = pcr.max(0.,\ pcr.min(self.storGroundwater,\ self.recessionCoeff* \ self.storGroundwater)) self.storGroundwater = pcr.max(0.,\ self.storGroundwater - self.baseflow) # PS: baseflow must be calculated at the end (to ensure the availability of storGroundwater to support nonFossilGroundwaterAbs) if self.debugWaterBalance: vos.waterBalanceCheck([self.surfaceWaterInf,\ landSurface.gwRecharge],\ [self.baseflow,\ self.nonFossilGroundwaterAbs],\ [ preStorGroundwater],\ [self.storGroundwater],\ 'storGroundwater',\ True,\ currTimeStep.fulldate,threshold=1e-4) if self.debugWaterBalance: vos.waterBalanceCheck([pcr.scalar(0.0)],\ [self.unmetDemand],\ [ preStorGroundwaterFossil],\ [self.storGroundwaterFossil],\ 'storGroundwaterFossil',\ True,\ currTimeStep.fulldate,threshold=1e-3) if self.debugWaterBalance and self.limitFossilGroundwaterAbstraction: vos.waterBalanceCheck([pcr.scalar(0.0)],\ [self.unmetDemand],\ [pcr.max(0.0, preStorGroundwaterFossil)],\ [pcr.max(0.0,self.storGroundwaterFossil)],\ 'storGroundwaterFossil (with limitFossilGroundwaterAbstraction)',\ True,\ currTimeStep.fulldate,threshold=1e-3) if self.debugWaterBalance and landSurface.limitAbstraction: vos.waterBalanceCheck([potGroundwaterAbstract],\ [self.nonFossilGroundwaterAbs],\ [pcr.scalar(0.)],\ [pcr.scalar(0.)],\ 'non fossil groundwater abstraction',\ True,\ currTimeStep.fulldate,threshold=1e-4) if self.debugWaterBalance: vos.waterBalanceCheck([self.unmetDemand, self.allocNonFossilGroundwater, landSurface.allocSurfaceWaterAbstract],\ [landSurface.totalPotentialGrossDemand],\ [pcr.scalar(0.)],\ [pcr.scalar(0.)],\ 'water demand allocation (from surface water, groundwater and unmetDemand)',\ True,\ currTimeStep.fulldate,threshold=1e-4) if self.report == True: timeStamp = datetime.datetime(currTimeStep.year,\ currTimeStep.month,\ currTimeStep.day,\ 0) # writing daily output to netcdf files timestepPCR = currTimeStep.timeStepPCR if self.outDailyTotNC[0] != "None": for var in self.outDailyTotNC: self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_dailyTot.nc",\ var,\ pcr2numpy(self.__getattribute__(var),vos.MV),\ timeStamp,timestepPCR-1) # writing monthly output to netcdf files # -cummulative if self.outMonthTotNC[0] != "None": for var in self.outMonthTotNC: # introduce variables at the beginning of simulation or # reset variables at the beginning of the month if currTimeStep.timeStepPCR == 1 or \ currTimeStep.day == 1:\ vars(self)[var+'MonthTot'] = pcr.scalar(0.0) # accumulating vars(self)[var+'MonthTot'] += vars(self)[var] # reporting at the end of the month: if currTimeStep.endMonth == True: self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_monthTot.nc",\ var,\ pcr2numpy(self.__getattribute__(var+'MonthTot'),\ vos.MV),timeStamp,currTimeStep.monthIdx-1) # -average if self.outMonthAvgNC[0] != "None": for var in self.outMonthAvgNC: # only if a accumulator variable has not been defined: if var not in self.outMonthTotNC: # introduce accumulator at the beginning of simulation or # reset accumulator at the beginning of the month if currTimeStep.timeStepPCR == 1 or \ currTimeStep.day == 1:\ vars(self)[var+'MonthTot'] = pcr.scalar(0.0) # accumulating vars(self)[var+'MonthTot'] += vars(self)[var] # calculating average & reporting at the end of the month: if currTimeStep.endMonth == True: vars(self)[var+'MonthAvg'] = vars(self)[var+'MonthTot']/\ currTimeStep.day self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_monthAvg.nc",\ var,\ pcr2numpy(self.__getattribute__(var+'MonthAvg'),\ vos.MV),timeStamp,currTimeStep.monthIdx-1) # # -last day of the month if self.outMonthEndNC[0] != "None": for var in self.outMonthEndNC: # reporting at the end of the month: if currTimeStep.endMonth == True: self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_monthEnd.nc",\ var,\ pcr2numpy(self.__getattribute__(var),vos.MV),\ timeStamp,currTimeStep.monthIdx-1) # writing yearly output to netcdf files # -cummulative if self.outAnnuaTotNC[0] != "None": for var in self.outAnnuaTotNC: # introduce variables at the beginning of simulation or # reset variables at the beginning of the month if currTimeStep.timeStepPCR == 1 or \ currTimeStep.doy == 1:\ vars(self)[var+'AnnuaTot'] = pcr.scalar(0.0) # accumulating vars(self)[var+'AnnuaTot'] += vars(self)[var] # reporting at the end of the year: if currTimeStep.endYear == True: self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_annuaTot.nc",\ var,\ pcr2numpy(self.__getattribute__(var+'AnnuaTot'),\ vos.MV),timeStamp,currTimeStep.annuaIdx-1) # -average if self.outAnnuaAvgNC[0] != "None": for var in self.outAnnuaAvgNC: # only if a accumulator variable has not been defined: if var not in self.outAnnuaTotNC: # introduce accumulator at the beginning of simulation or # reset accumulator at the beginning of the year if currTimeStep.timeStepPCR == 1 or \ currTimeStep.doy == 1:\ vars(self)[var+'AnnuaTot'] = pcr.scalar(0.0) # accumulating vars(self)[var+'AnnuaTot'] += vars(self)[var] # # calculating average & reporting at the end of the year: if currTimeStep.endYear == True: vars(self)[var+'AnnuaAvg'] = vars(self)[var+'AnnuaTot']/\ currTimeStep.doy self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_annuaAvg.nc",\ var,\ pcr2numpy(self.__getattribute__(var+'AnnuaAvg'),\ vos.MV),timeStamp,currTimeStep.annuaIdx-1) # # -last day of the year if self.outAnnuaEndNC[0] != "None": for var in self.outAnnuaEndNC: # reporting at the end of the year: if currTimeStep.endYear == True: self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_annuaEnd.nc",\ var,\ pcr2numpy(self.__getattribute__(var),vos.MV),\ timeStamp,currTimeStep.annuaIdx-1)
def checkWaterBalance(self, storesAtBeginning, storesAtEnd): # for the entire modules: snow + interception + soil + groundwater + waterDemand # except: river/routing irrGrossDemand = pcr.ifthen(self.landmask,\ self.landSurface.irrGrossDemand) # unit: m nonIrrGrossDemand = \ pcr.ifthen(self.landmask,\ self.landSurface.nonIrrGrossDemand) # unit: m precipitation = pcr.ifthen(self.landmask,\ self.meteo.precipitation) # unit: m surfaceWaterInf = pcr.ifthen(self.landmask,\ self.groundwater.surfaceWaterInf) surfaceWaterAbstraction = \ pcr.ifthen(self.landmask,\ self.landSurface.actSurfaceWaterAbstract) nonFossilGroundwaterAbs = pcr.ifthen(self.landmask,self.groundwater.nonFossilGroundwaterAbs) unmetDemand = pcr.ifthen(self.landmask,\ self.groundwater.unmetDemand) # PS: We assume that unmetDemand is extracted (only) to satisfy local demand. runoff = pcr.ifthen(self.landmask,self.routing.runoff) actualET = pcr.ifthen(self.landmask,\ self.landSurface.actualET) vos.waterBalanceCheck([precipitation,surfaceWaterInf,irrGrossDemand],\ [actualET,runoff,nonFossilGroundwaterAbs],\ [storesAtBeginning],\ [storesAtEnd],\ 'all modules (including water demand), but except river/routing',\ True,\ self._modelTime.fulldate,threshold=1e-3) if self.landSurface.usingAllocSegments: allocSurfaceWaterAbstract = \ pcr.ifthen(self.landmask,\ self.landSurface.allocSurfaceWaterAbstract) allocNonFossilGroundwaterAbs = \ pcr.ifthen(self.landmask,\ self.groundwater.allocNonFossilGroundwater) allocUnmetDemand = unmetDemand # PS: We assume that unmetDemand is extracted (only) to satisfy local demand. segTotalDemand = pcr.areatotal( pcr.cover((irrGrossDemand+nonIrrGrossDemand) * self.routing.cellArea, 0.0), self.landSurface.allocSegments) / self.landSurface.segmentArea segAllocSurfaceWaterAbstract = pcr.areatotal( pcr.cover(allocSurfaceWaterAbstract * self.routing.cellArea, 0.0), self.landSurface.allocSegments) / self.landSurface.segmentArea segAllocNonFossilGroundwaterAbs = pcr.areatotal( pcr.cover(allocNonFossilGroundwaterAbs * self.routing.cellArea, 0.0), self.landSurface.allocSegments) / self.landSurface.segmentArea segAllocUnmetDemand = pcr.areatotal( pcr.cover(allocUnmetDemand * self.routing.cellArea, 0.0), self.landSurface.allocSegments) / self.landSurface.segmentArea vos.waterBalanceCheck([segTotalDemand],\ [segAllocSurfaceWaterAbstract,segAllocNonFossilGroundwaterAbs,segAllocUnmetDemand],\ [pcr.scalar(0.0)],\ [pcr.scalar(0.0)],\ 'Water balance error in water allocation (per zone). Note that error here is most likely due to rounding error (32 bit implementation of pcraster)',\ True,\ self._modelTime.fulldate,threshold=5e-3) else: vos.waterBalanceCheck([irrGrossDemand,nonIrrGrossDemand],\ [surfaceWaterAbstraction,nonFossilGroundwaterAbs,unmetDemand],\ [pcr.scalar(0.0)],\ [pcr.scalar(0.0)],\ 'Water balance error in water allocation.',\ True,\ self._modelTime.fulldate,threshold=1e-3)
def update(self,landSurface,routing,currTimeStep): logger.info("Updating groundwater") if self.debugWaterBalance: preStorGroundwater = self.storGroundwater preStorGroundwaterFossil = self.storGroundwaterFossil # get riverbed infiltration from the previous time step (from routing) self.surfaceWaterInf = routing.riverbedExchange/\ routing.cellArea # unit: m self.storGroundwater += self.surfaceWaterInf # get net recharge (percolation-capRise) and update storage: self.storGroundwater = pcr.max(0.,\ self.storGroundwater + landSurface.gwRecharge) # non fossil groundwater abstraction self.nonFossilGroundwaterAbs = landSurface.nonFossilGroundwaterAbs self.storGroundwater = pcr.max(0.,\ self.storGroundwater - self.nonFossilGroundwaterAbs) # baseflow self.baseflow = pcr.max(0.,\ pcr.min(self.storGroundwater,\ self.recessionCoeff* \ self.storGroundwater)) self.storGroundwater = pcr.max(0.,\ self.storGroundwater - self.baseflow) # PS: baseflow must be calculated at the end (to ensure the availability of storGroundwater to support nonFossilGroundwaterAbs) # fossil groundwater abstraction: self.fossilGroundwaterAbstr = landSurface.fossilGroundwaterAbstr self.storGroundwaterFossil -= self.fossilGroundwaterAbstr # fossil groundwater cannot be negative if limitFossilGroundwaterAbstraction is used if self.limitFossilGroundwaterAbstraction: self.storGroundwaterFossil = pcr.max(0.0, self.storGroundwaterFossil) # groundwater allocation (Note: This is done in the landSurface module) self.allocNonFossilGroundwater = landSurface.allocNonFossilGroundwater self.fossilGroundwaterAlloc = landSurface.fossilGroundwaterAlloc # Note: The following variable (unmetDemand) is a bad name and used in the past. # Its definition is actually as follows: (the amount of demand that is satisfied/allocated from fossil groundwater) self.unmetDemand = self.fossilGroundwaterAlloc # calculate the average total groundwater abstraction (m/day) from the last 365 days: totalAbstraction = self.fossilGroundwaterAbstr + self.nonFossilGroundwaterAbs deltaAbstraction = totalAbstraction - self.avgAbstraction self.avgAbstraction = self.avgAbstraction +\ deltaAbstraction/\ pcr.min(365., pcr.max(1.0, routing.timestepsToAvgDischarge)) self.avgAbstraction = pcr.max(0.0, self.avgAbstraction) # calculate the average non fossil groundwater allocation (m/day) # - from the last 365 days: deltaAllocation = self.allocNonFossilGroundwater - self.avgNonFossilAllocation self.avgNonFossilAllocation = self.avgNonFossilAllocation +\ deltaAllocation/\ pcr.min(365., pcr.max(1.0, routing.timestepsToAvgDischarge)) self.avgNonFossilAllocation = pcr.max(0.0, self.avgNonFossilAllocation) # - from the last 7 days: deltaAllocationShort = self.allocNonFossilGroundwater - self.avgNonFossilAllocationShort self.avgNonFossilAllocationShort = self.avgNonFossilAllocationShort +\ deltaAllocationShort/\ pcr.min(7., pcr.max(1.0, routing.timestepsToAvgDischarge)) self.avgNonFossilAllocationShort = pcr.max(0.0, self.avgNonFossilAllocationShort) # calculate the average total (fossil + non fossil) groundwater allocation (m/day) totalGroundwaterAllocation = self.allocNonFossilGroundwater + self.fossilGroundwaterAlloc # - from the last 365 days: deltaAllocation = totalGroundwaterAllocation - self.avgAllocation self.avgAllocation = self.avgAllocation +\ deltaAllocation/\ pcr.min(365., pcr.max(1.0, routing.timestepsToAvgDischarge)) self.avgAllocation = pcr.max(0.0, self.avgAllocation) # - from the last 7 days: deltaAllocationShort = totalGroundwaterAllocation - self.avgAllocationShort self.avgAllocationShort = self.avgAllocationShort +\ deltaAllocationShort/\ pcr.min(7., pcr.max(1.0, routing.timestepsToAvgDischarge)) self.avgAllocationShort = pcr.max(0.0, self.avgAllocationShort) if self.debugWaterBalance: vos.waterBalanceCheck([self.surfaceWaterInf,\ landSurface.gwRecharge],\ [self.baseflow,\ self.nonFossilGroundwaterAbs],\ [ preStorGroundwater],\ [self.storGroundwater],\ 'storGroundwater',\ True,\ currTimeStep.fulldate,threshold=1e-4) if self.debugWaterBalance: vos.waterBalanceCheck([pcr.scalar(0.0)],\ [self.fossilGroundwaterAbstr],\ [ preStorGroundwaterFossil],\ [self.storGroundwaterFossil],\ 'storGroundwaterFossil',\ True,\ currTimeStep.fulldate,threshold=1e-3) if self.debugWaterBalance: vos.waterBalanceCheck([landSurface.desalinationAllocation,\ self.unmetDemand, \ self.allocNonFossilGroundwater, \ landSurface.allocSurfaceWaterAbstract],\ [landSurface.totalPotentialGrossDemand],\ [pcr.scalar(0.)],\ [pcr.scalar(0.)],\ 'demand allocation (desalination, surface water, groundwater & unmetDemand. Error here may be due to rounding error.',\ True,\ currTimeStep.fulldate,threshold=1e-3) # old-style reporting self.old_style_groundwater_reporting(currTimeStep) # TODO: remove this one