def upscale_riverlength(ldd, order, factor): """ Upscales the riverlength using 'factor' The resulting maps can be resampled (e.g. using resample.exe) by factor and should include the accurate length as determined with the original higher resolution maps. This function is **depricated**, use are_riverlength instead as this version is very slow for large maps Input: - ldd - minimum streamorder to include Output: - distance per factor cells """ strorder = pcr.streamorder(ldd) strorder = pcr.ifthen(strorder >= order, strorder) dist = pcr.cover( pcr.max(pcr.celllength(), pcr.ifthen(pcr.boolean(strorder), pcr.downstreamdist(ldd))), 0, ) totdist = pcr.max( pcr.ifthen( pcr.boolean(strorder), pcr.windowtotal(pcr.ifthen(pcr.boolean(strorder), dist), pcr.celllength() * factor), ), dist, ) return totdist
def upscale_riverlength(ldd, order, factor): """ Upscales the riverlength using 'factor' The resulting maps can be resampled (e.g. using resample.exe) by factor and should include the accurate length as determined with the original higher resolution maps. This function is **depricated**, use are_riverlength instead as this version is very slow for large maps Input: - ldd - minimum streamorder to include Output: - distance per factor cells """ strorder = pcr.streamorder(ldd) strorder = pcr.ifthen(strorder >= order, strorder) dist = pcr.cover( pcr.max( pcr.celllength(), pcr.ifthen(pcr.boolean(strorder), pcr.downstreamdist(ldd)) ), 0, ) totdist = pcr.max( pcr.ifthen( pcr.boolean(strorder), pcr.windowtotal( pcr.ifthen(pcr.boolean(strorder), dist), pcr.celllength() * factor ), ), dist, ) return totdist
def dynamic(self): """ dynamic part of the water use module init water use before sub step routing """ settings = LisSettings.instance() option = settings.options binding = settings.binding maskinfo = MaskInfo.instance() if option['wateruse']: # ************************************************************ # ***** READ WATER DEMAND DATA ***************************** # ************************************************************ if option['TransientWaterDemandChange']: if option['readNetcdfStack']: if option['useWaterDemandAveYear']: # using average year in NetCDF file format self.var.DomesticDemandMM = readnetcdf( binding['DomesticDemandMaps'], self.var.currentTimeStep(), timestampflag='closest', averageyearflag=True) * self.var.DtDay self.var.IndustrialDemandMM = readnetcdf( binding['IndustrialDemandMaps'], self.var.currentTimeStep(), timestampflag='closest', averageyearflag=True) * self.var.DtDay self.var.LivestockDemandMM = readnetcdf( binding['LivestockDemandMaps'], self.var.currentTimeStep(), timestampflag='closest', averageyearflag=True) * self.var.DtDay self.var.EnergyDemandMM = readnetcdf( binding['EnergyDemandMaps'], self.var.currentTimeStep(), timestampflag='closest', averageyearflag=True) * self.var.DtDay else: # Read from stack of maps in NetCDF format. Get time step corresponding to model step. # added management for sub-daily model time steps self.var.DomesticDemandMM = readnetcdf( binding['DomesticDemandMaps'], self.var.currentTimeStep(), timestampflag='closest') * self.var.DtDay self.var.IndustrialDemandMM = readnetcdf( binding['IndustrialDemandMaps'], self.var.currentTimeStep(), timestampflag='closest') * self.var.DtDay self.var.LivestockDemandMM = readnetcdf( binding['LivestockDemandMaps'], self.var.currentTimeStep(), timestampflag='closest') * self.var.DtDay self.var.EnergyDemandMM = readnetcdf( binding['EnergyDemandMaps'], self.var.currentTimeStep(), timestampflag='closest') * self.var.DtDay else: # Read from stack of maps in Pcraster format self.var.DomesticDemandMM = readmapsparse( binding['DomesticDemandMaps'], self.var.currentTimeStep(), self.var.DomesticDemandMM) * self.var.DtDay self.var.IndustrialDemandMM = readmapsparse( binding['IndustrialDemandMaps'], self.var.currentTimeStep(), self.var.IndustrialDemandMM) * self.var.DtDay self.var.LivestockDemandMM = readmapsparse( binding['LivestockDemandMaps'], self.var.currentTimeStep(), self.var.LivestockDemandMM) * self.var.DtDay self.var.EnergyDemandMM = readmapsparse( binding['EnergyDemandMaps'], self.var.currentTimeStep(), self.var.EnergyDemandMM) * self.var.DtDay # ************************************************************ # ***** LIVESTOCK ******************************************** # ************************************************************ self.var.LivestockAbstractionMM = self.var.LivestockDemandMM self.var.LivestockConsumptiveUseMM = self.var.LivestockAbstractionMM * self.var.LivestockConsumptiveUseFraction # the amount that is not returned to the hydrological cycle LivestockAbstractionFromGroundwaterM3 = np.where( self.var.GroundwaterBodies > 0, self.var.FractionGroundwaterUsed * self.var.LivestockConsumptiveUseMM * self.var.MMtoM3, maskinfo.in_zero()) LivestockAbstractionFromNonConventionalWaterM3 = self.var.FractionNonConventionalWaterUsed * self.var.LivestockConsumptiveUseMM * self.var.MMtoM3 LivestockAbstractionFromSurfaceWaterM3 = self.var.LivestockConsumptiveUseMM * self.var.MMtoM3 - LivestockAbstractionFromGroundwaterM3 - LivestockAbstractionFromNonConventionalWaterM3 self.var.TotalLivestockAbstractionM3 += LivestockAbstractionFromGroundwaterM3 + LivestockAbstractionFromSurfaceWaterM3 + LivestockAbstractionFromNonConventionalWaterM3 # ************************************************************ # ***** DOMESTIC ********************************************* # ************************************************************ self.var.DomesticAbstractionMM = self.var.DomesticDemandMM * self.var.DomesticWaterSavingConstant * self.var.DomesticLeakageConstant # Domestic Water Abstraction (mm per day), already taking into account water saving in households and leakage of the supply network # Domestic water abstraction is larger if there is leakage, but is smaller if there is water savings self.var.LeakageMM = ( self.var.DomesticLeakageConstant - 1 ) * self.var.DomesticDemandMM * self.var.DomesticWaterSavingConstant # Leakage in mm per day self.var.LeakageLossMM = self.var.LeakageMM * self.var.LeakageWaterLossFraction # The leakage amount that is lost (evaporated) self.var.LeakageSoilMM = self.var.LeakageMM - self.var.LeakageLossMM self.var.DomesticConsumptiveUseMM = self.var.DomesticDemandMM * self.var.DomesticWaterSavingConstant * self.var.DomesticConsumptiveUseFraction + self.var.LeakageLossMM # DomesticConsumptiveUseMM is the amount that disappears from the waterbalance # Assumption here is that leakage is partially lost/evaporated (LeakageWaterLoss fraction) DomAbstractionFromGroundwaterM3 = np.where( self.var.GroundwaterBodies > 0, self.var.FractionGroundwaterUsed * self.var.DomesticConsumptiveUseMM * self.var.MMtoM3, maskinfo.in_zero()) DomAbstractionFromNonConventionalWaterM3 = self.var.FractionNonConventionalWaterUsed * self.var.DomesticConsumptiveUseMM * self.var.MMtoM3 DomAbstractionFromSurfaceWaterM3 = self.var.DomesticConsumptiveUseMM * self.var.MMtoM3 - DomAbstractionFromGroundwaterM3 - DomAbstractionFromNonConventionalWaterM3 # ************************************************************ # ***** INDUSTRY ********************************************* # ************************************************************ self.var.IndustrialAbstractionMM = self.var.IndustrialDemandMM * ( 1 - self.var.WaterReUseFraction) self.var.IndustrialConsumptiveUseMM = self.var.IndustrialAbstractionMM * self.var.IndustryConsumptiveUseFraction # IndustrialAbstractionMM = scalar(timeinputsparse(IndustrialAbstractionMaps)) * (1-WaterReUseFraction); # Industrial Water Demand (mm per day) # WaterReUseFraction: Fraction of water re-used in industry (e.g. 50% = 0.5 = half of the water is re-used, used twice (baseline=0, maximum=1) # IndustrialConsumptiveUseMM is the amount that evaporates etc # only 1 map so this one is loaded in initial! IndustrialWaterAbstractionM3 = self.var.IndustrialConsumptiveUseMM * self.var.MMtoM3 IndustrialAbstractionFromGroundwaterM3 = np.where( self.var.GroundwaterBodies > 0, self.var.FractionGroundwaterUsed * IndustrialWaterAbstractionM3, maskinfo.in_zero()) IndustrialAbstractionFromNonConventionalWaterM3 = self.var.FractionNonConventionalWaterUsed * IndustrialWaterAbstractionM3 IndustrialAbstractionFromSurfaceWaterM3 = IndustrialWaterAbstractionM3 - IndustrialAbstractionFromGroundwaterM3 - IndustrialAbstractionFromNonConventionalWaterM3 # ************************************************************ # ***** ENERGY *********************************************** # ************************************************************ self.var.EnergyAbstractionMM = self.var.EnergyDemandMM self.var.EnergyConsumptiveUseMM = self.var.EnergyAbstractionMM * self.var.EnergyConsumptiveUseFraction # EnergyConsumptiveUseMM is the amount that evaporates etc EnergyAbstractionFromSurfaceWaterM3 = self.var.EnergyConsumptiveUseMM * self.var.MMtoM3 # all taken from surface water # ************************************************************ # ***** IRRIGATION ******************************************* # ************************************************************ # water demand from loop3 = irrigated zone self.var.Ta[2] = np.maximum( np.minimum(self.var.RWS[2] * self.var.TranspirMaxCorrected, self.var.W1[2] - self.var.WWP1[2]), maskinfo.in_zero()) IrrigationWaterDemandMM = ( self.var.TranspirMaxCorrected - self.var.Ta[2]) * self.var.IrrigationMult # a factor (IrrigationMult) add some water (to prevent salinisation) # irrigationWaterNeed assumed to be equal to potential transpiration minus actual transpiration # in mm here, assumed for the entire pixel, thus later to be corrected with IrrigationFraction # IrrigationType (value between 0 and 1) is used here to distinguish between additional adding water until fieldcapacity (value set to 1) or not (value set to 0) IrrigationWaterDemandMM = np.where( self.var.FrostIndex > self.var.FrostIndexThreshold, maskinfo.in_zero(), IrrigationWaterDemandMM) # IrrigationWaterDemand is 0 when soil is frozen IrrigationWaterAbstractionMM = np.where( (self.var.IrrigationEfficiency * self.var.ConveyanceEfficiency) > 0, IrrigationWaterDemandMM * self.var.IrrigationFraction / (self.var.IrrigationEfficiency * self.var.ConveyanceEfficiency), maskinfo.in_zero()) self.var.IrrigationWaterAbstractionM3 = np.maximum( IrrigationWaterAbstractionMM * self.var.MMtoM3, maskinfo.in_zero()) # irrigation efficiency max 1, ~0.90 drip irrigation, ~0.75 sprinkling # conveyance efficiency, around 0.80 for average channel # multiplied by actual irrigated area (fraction) and cellsize(MMtoM3) in M3 per pixel IrrigationAbstractionFromGroundwaterM3 = np.where( self.var.GroundwaterBodies > 0, self.var.FractionGroundwaterUsed * self.var.IrrigationWaterAbstractionM3, maskinfo.in_zero()) IrrigationAbstractionFromSurfaceWaterM3 = np.maximum( self.var.IrrigationWaterAbstractionM3 - IrrigationAbstractionFromGroundwaterM3, maskinfo.in_zero()) # ************************************************************ # ***** TOTAL ABSTRACTIONS (DEMANDED) ************************ # ************************************************************ self.var.TotalAbstractionFromGroundwaterM3 = IrrigationAbstractionFromGroundwaterM3 + DomAbstractionFromGroundwaterM3 + LivestockAbstractionFromGroundwaterM3 + IndustrialAbstractionFromGroundwaterM3 self.var.TotalAbstractionFromSurfaceWaterM3 = IrrigationAbstractionFromSurfaceWaterM3 + self.var.PaddyRiceWaterAbstractionFromSurfaceWaterM3 + DomAbstractionFromSurfaceWaterM3 + LivestockAbstractionFromSurfaceWaterM3 + IndustrialAbstractionFromSurfaceWaterM3 + EnergyAbstractionFromSurfaceWaterM3 PaddyRiceWaterAbstractionFromSurfaceWaterMM = self.var.PaddyRiceWaterAbstractionFromSurfaceWaterM3 * self.var.M3toMM # taken from paddy rice routine self.var.TotalDemandM3 = ( self.var.LivestockAbstractionMM + self.var.DomesticAbstractionMM + IrrigationWaterAbstractionMM + PaddyRiceWaterAbstractionFromSurfaceWaterMM + self.var.IndustrialAbstractionMM + self.var.EnergyAbstractionMM) * self.var.MMtoM3 self.var.TotalIrrigationAbstractionM3 += IrrigationAbstractionFromGroundwaterM3 + IrrigationAbstractionFromSurfaceWaterM3 self.var.TotalPaddyRiceIrrigationAbstractionM3 += self.var.PaddyRiceWaterAbstractionFromSurfaceWaterM3 # totals calculated for reporting, for comparing with national reported values and possible calibration # ************************************************************ # ***** ABSTRACTION FROM GROUNDWATER ************************* # ************************************************************ self.var.LZ = self.var.LZ - self.var.TotalAbstractionFromGroundwaterM3 * self.var.M3toMM self.var.IrriLossCUM = self.var.IrriLossCUM + self.var.TotalAbstractionFromGroundwaterM3 # Abstraction is taken from lower groundwater zone # for mass balance calculation also summed up in IrrilossCUM (in M3) # *********************************************************************** # ***** ABSTRACTION SUPPLIED BY NONCONVENTIONAL SOURCES (DESALINATION) ** # *********************************************************************** self.var.NonConventionalWaterM3 = DomAbstractionFromNonConventionalWaterM3 + LivestockAbstractionFromNonConventionalWaterM3 + IndustrialAbstractionFromNonConventionalWaterM3 # Non conventional water producted is not abstracted from surface water # ************************************************************ # ***** ABSTRACTION FROM LAKES AND RESERVOIRS **************** # ************************************************************ if option['simulateReservoirs']: # PotentialAbstractionFromReservoirsM3 = np.minimum(0.02 * self.var.ReservoirStorageM3, 0.01*self.var.TotalReservoirStorageM3C) #original PotentialAbstractionFromReservoirsM3 = np.minimum( 0.02 * self.var.ReservoirStorageM3, 0.01 * self.var.TotalReservoirStorageM3C) * self.var.DtDay PotentialAbstractionFromReservoirsM3 = np.where( np.isnan(PotentialAbstractionFromReservoirsM3), 0, PotentialAbstractionFromReservoirsM3) else: PotentialAbstractionFromReservoirsM3 = maskinfo.in_zero() if option['simulateLakes']: # CM # PotentialAbstractionFromLakesM3 = 0.10 * self.var.LakeStorageM3 #original PotentialAbstractionFromLakesM3 = 0.10 * self.var.LakeStorageM3 * self.var.DtDay PotentialAbstractionFromLakesM3 = np.where( np.isnan(PotentialAbstractionFromLakesM3), 0, PotentialAbstractionFromLakesM3) else: PotentialAbstractionFromLakesM3 = maskinfo.in_zero() if option['simulateReservoirs'] or option['simulateLakes']: PotentialAbstractionFromLakesAndReservoirsM3 = PotentialAbstractionFromLakesM3 + PotentialAbstractionFromReservoirsM3 # potential total m3 that can be extracted from all lakes and reservoirs in a pixel else: PotentialAbstractionFromLakesAndReservoirsM3 = maskinfo.in_zero( ) AreatotalPotentialAbstractionFromLakesAndReservoirsM3 = np.take( np.bincount( self.var.WUseRegionC, weights=PotentialAbstractionFromLakesAndReservoirsM3), self.var.WUseRegionC) # potential total m3 that can be extracted from all lakes and reservoirs in the water region AreatotalWaterAbstractionFromAllSurfaceSourcesM3 = np.take( np.bincount( self.var.WUseRegionC, weights=self.var.TotalAbstractionFromSurfaceWaterM3), self.var.WUseRegionC) # the total amount that needs to be extracted from surface water, lakes and reservoirs in the water region # self.var.FractionAllSurfaceWaterUsed = np.maximum(1 - self.var.FractionGroundwaterUsed - self.var.FractionNonConventionalWaterUsed,maskinfo.in_zero()) # self.var.FractionSurfaceWaterUsed = np.maximum(1 - self.var.FractionGroundwaterUsed - self.var.FractionNonConventionalWaterUsed-self.var.FractionLakeReservoirWaterUsed,maskinfo.in_zero()) # AreatotalWaterToBeAbstractedfromLakesReservoirsM3 = np.where( (self.var.FractionSurfaceWaterUsed+self.var.FractionLakeReservoirWaterUsed)> 0, (self.var.FractionLakeReservoirWaterUsed / (self.var.FractionSurfaceWaterUsed+self.var.FractionLakeReservoirWaterUsed)) * AreatotalWaterAbstractionFromAllSurfaceSourcesM3,maskinfo.in_zero()) AreatotalWaterToBeAbstractedfromLakesReservoirsM3 = self.var.FractionLakeReservoirWaterUsed * AreatotalWaterAbstractionFromAllSurfaceSourcesM3 self.var.AreatotalWaterAbstractedfromLakesReservoirsM3 = np.minimum( AreatotalWaterToBeAbstractedfromLakesReservoirsM3, AreatotalPotentialAbstractionFromLakesAndReservoirsM3) # total amount of m3 abstracted from all lakes and reservoirs in the water regions FractionAbstractedByLakesReservoirs = np.where( AreatotalWaterAbstractionFromAllSurfaceSourcesM3 > 0, self.var.AreatotalWaterAbstractedfromLakesReservoirsM3 / AreatotalWaterAbstractionFromAllSurfaceSourcesM3, maskinfo.in_zero()) self.var.TotalAbstractionFromSurfaceWaterM3 = self.var.TotalAbstractionFromSurfaceWaterM3 * ( 1 - FractionAbstractedByLakesReservoirs) # the original surface water abstraction amount is corrected for what is now already abstracted by lakes and reservoirs FractionLakesReservoirsEmptying = np.where( AreatotalPotentialAbstractionFromLakesAndReservoirsM3 > 0, self.var.AreatotalWaterAbstractedfromLakesReservoirsM3 / AreatotalPotentialAbstractionFromLakesAndReservoirsM3, maskinfo.in_zero()) self.var.LakeAbstractionM3 = PotentialAbstractionFromLakesM3 * FractionLakesReservoirsEmptying if option['simulateLakes']: self.var.LakeStorageM3 = self.var.LakeStorageM3 - self.var.LakeAbstractionM3 self.var.ReservoirAbstractionM3 = PotentialAbstractionFromReservoirsM3 * FractionLakesReservoirsEmptying if option['simulateReservoirs']: self.var.ReservoirStorageM3 = self.var.ReservoirStorageM3 - self.var.ReservoirAbstractionM3 # subtract abstracted water from lakes and reservoir storage # ************************************************************ # ***** Abstraction from channels **************************** # ***** average abstraction taken from entire waterregion **** # ***** limited by available channel water and e-flow minimum* # ************************************************************ AreaTotalDemandedAbstractionFromSurfaceWaterM3 = np.maximum( np.take( np.bincount( self.var.WUseRegionC, weights=self.var.TotalAbstractionFromSurfaceWaterM3), self.var.WUseRegionC), 0) PixelAvailableWaterFromChannelsM3 = np.maximum( self.var.ChanM3Kin - self.var.EFlowThreshold * self.var.DtSec, 0) * (1 - self.var.WUsePercRemain) # respecting e-flow AreaTotalAvailableWaterFromChannelsM3 = np.maximum( np.take( np.bincount(self.var.WUseRegionC, weights=PixelAvailableWaterFromChannelsM3), self.var.WUseRegionC), 0) AreaTotalDemandedWaterFromChannelsM3 = np.minimum( AreaTotalAvailableWaterFromChannelsM3, AreaTotalDemandedAbstractionFromSurfaceWaterM3) self.var.FractionAbstractedFromChannels = np.where( AreaTotalAvailableWaterFromChannelsM3 > 0, np.minimum( AreaTotalDemandedWaterFromChannelsM3 / AreaTotalAvailableWaterFromChannelsM3, 1), 0) # IS THE DEFINITION OF AreaTotalDemandedWaterFromChannelsM3 REDUNDANT WITH np.minimum(...) ABOVE? # fraction that is abstracted from channels (should be 0-1) self.var.WUseAddM3 = self.var.FractionAbstractedFromChannels * PixelAvailableWaterFromChannelsM3 # pixel abstracted water in m3 self.var.WUseAddM3Dt = self.var.WUseAddM3 * self.var.InvNoRoutSteps # splitting water use per timestep into water use per sub time step self.var.wateruseCum += self.var.WUseAddM3 # summing up for water balance calculation # If report wateruse if (option['repwateruseGauges']) or (option['repwateruseSites']): self.var.WUseSumM3 = accuflux( self.var.Ldd, decompress(self.var.WUseAddM3) * self.var.InvDtSec) # totalAdd = areatotal(decompress(WUseAddM3),self.var.WUseRegion); self.var.totalAddM3 = np.take( np.bincount(self.var.WUseRegionC, weights=self.var.WUseAddM3), self.var.WUseRegionC) self.var.WaterUseShortageM3 = self.var.TotalAbstractionFromSurfaceWaterM3 - self.var.WUseAddM3 # amount of M3 that cannot be extracted from any source, including the channels self.var.PotentialSurfaceWaterAvailabilityForIrrigationM3 = np.maximum( PixelAvailableWaterFromChannelsM3 - self.var.TotalAbstractionFromSurfaceWaterM3 + IrrigationAbstractionFromSurfaceWaterM3 + self.var.PaddyRiceWaterAbstractionFromSurfaceWaterM3, 0.0) # available water excluding the surface water irrigation needs # ************************************************************ # ***** Water Allocation ************************************* # ***** average abstraction taken from entire waterregion **** # ***** limited by available channel water and e-flow minimum* # ************************************************************ # totalAbstr = areatotal(decompress(TotalAbstractionFromSurfaceWaterM3),self.var.WUseRegion) self.var.AreaTotalAbstractionFromSurfaceWaterM3 = np.take( np.bincount( self.var.WUseRegionC, weights=self.var.TotalAbstractionFromSurfaceWaterM3 - self.var.WUseAddM3), self.var.WUseRegionC) self.var.AreaTotalAbstractionFromGroundwaterM3 = np.take( np.bincount( self.var.WUseRegionC, weights=self.var.TotalAbstractionFromGroundwaterM3), self.var.WUseRegionC) # demand self.var.AreaTotalDemandM3 = np.take( np.bincount(self.var.WUseRegionC, weights=self.var.TotalDemandM3), self.var.WUseRegionC) # totalEne = areatotal(decompress(self.var.EnergyConsumptiveUseMM*self.var.MMtoM3),self.var.WUseRegion) AreatotalIrriM3 = np.take( np.bincount( self.var.WUseRegionC, weights=IrrigationAbstractionFromSurfaceWaterM3 + self.var.PaddyRiceWaterAbstractionFromSurfaceWaterM3), self.var.WUseRegionC) # AreatotalDomM3 = np.take(np.bincount(self.var.WUseRegionC, weights=DomAbstractionFromSurfaceWaterM3), # self.var.WUseRegionC) # AreatotalLiveM3 = np.take(np.bincount(self.var.WUseRegionC, weights=LivestockAbstractionFromSurfaceWaterM3), # self.var.WUseRegionC) # AreatotalIndM3 = np.take(np.bincount(self.var.WUseRegionC, weights=IndustrialAbstractionFromSurfaceWaterM3), # self.var.WUseRegionC) # AreatotalEneM3 = np.take(np.bincount(self.var.WUseRegionC, weights=EnergyAbstractionFromSurfaceWaterM3), # self.var.WUseRegionC) # Allocation rule: Domestic -> Energy -> Livestock -> Industry -> Irrigation self.var.AreatotalIrrigationShortageM3 = np.take( np.bincount(self.var.WUseRegionC, weights=self.var.WaterUseShortageM3), self.var.WUseRegionC) self.var.AreatotalIrrigationUseM3 = np.maximum( AreatotalIrriM3 - self.var.AreatotalIrrigationShortageM3, 0.0) with np.errstate(all='ignore'): fractionIrrigationAvailability = np.where( AreatotalIrriM3 > 0, self.var.AreatotalIrrigationUseM3 / AreatotalIrriM3, 1.0) self.var.IrrigationWaterAbstractionM3 = fractionIrrigationAvailability * IrrigationAbstractionFromSurfaceWaterM3 + IrrigationAbstractionFromGroundwaterM3 # real irrigation is percentage of avail/demand for waterregion * old surface + old groundwater abstraction IrrigationWaterDemand = self.var.IrrigationWaterAbstractionM3 * self.var.M3toMM IrrigationWaterDemand = np.where( self.var.IrrigationFraction > 0, IrrigationWaterDemand / self.var.IrrigationFraction, 0.0) # for mass balance calculate the loss of irrigation water # --------------------------------------------------------- # updating soil in loop3=irrigation # --------------------------------------------------------- Wold = self.var.W1[2] IrrigationDemandW1b = np.maximum( IrrigationWaterDemand - (self.var.WFilla - self.var.W1a[2]), 0) self.var.W1a[2] = np.where( self.var.W1a[2] >= self.var.WFilla, self.var.W1a[2], np.minimum(self.var.WFilla, self.var.W1a[2] + IrrigationWaterDemand)) self.var.W1b[2] = np.where( self.var.W1b[2] >= self.var.WFillb, self.var.W1b[2], np.minimum(self.var.WFillb, self.var.W1b[2] + IrrigationDemandW1b)) self.var.W1[2] = np.add(self.var.W1a[2], self.var.W1b[2]) # if irrigated soil is less than Pf3 then fill up to Pf3 (if there is water demand) # if more than Pf3 the additional water is transpirated # there is already no water demand if the soil is frozen Wdiff = self.var.W1[2] - Wold self.var.Ta[2] = self.var.Ta[2] + IrrigationWaterDemand - Wdiff self.var.IrriLossCUM = self.var.IrriLossCUM - self.var.IrrigationWaterAbstractionM3 * self.var.IrrigationEfficiency * self.var.ConveyanceEfficiency - Wdiff * self.var.MMtoM3 * self.var.IrrigationFraction # Added to TA but also # for mass balance calculate the loss of irrigation water # AdR: irrigation demand added to W1 and Ta; so assumption here that soil moisture stays the same # we could also abstract more water equivalent to satisfy Ta and bring soil moisture to pF2 or so, for later consideration# # self.var.Ta[2] = np.where(self.var.FrostIndex > self.var.FrostIndexThreshold, maskinfo.in_zero(), self.var.Ta[2]) # transpiration is 0 when soil is frozen # --------------------------------------------------------- # E-flow # --------------------------------------------------------- self.var.EFlowIndicator = np.where( self.var.ChanQ <= self.var.EFlowThreshold, maskinfo.in_zero() + 1.0, maskinfo.in_zero()) # if ChanQ is less than EflowThreshold, EFlowIndicator becomes 1 # ************************************************************ # ***** update state variables *** # ************************************************************ # CM Update state variables for changes to W1a[2] and W1b[2] self.var.Theta1a[2] = self.var.W1a[2] / self.var.SoilDepth1a[2] self.var.Theta1b[2] = self.var.W1b[2] / self.var.SoilDepth1b[2] # ************************************************************ # ***** smooth lower zone with correction *** # ************************************************************ if option['groundwaterSmooth']: LZPcr = decompress(self.var.LZ) Range = self.var.LZSmoothRange * celllength() LZTemp1 = ifthen(self.var.GroundwaterBodiesPcr == 1, LZPcr) LZTemp2 = ifthen(self.var.GroundwaterBodiesPcr == 1, windowtotal(LZTemp1, Range)) LZTemp3 = windowtotal(LZTemp1 * 0 + 1, Range) LZSmooth = ifthenelse(LZTemp3 == 0, 0.0, pcrDiv(LZTemp2, LZTemp3)) LZPcr = ifthenelse(self.var.GroundwaterBodiesPcr == 0, LZPcr, 0.9 * LZPcr + 0.1 * LZSmooth) diffCorr = 0.1 * areaaverage(LZSmooth - LZTemp1, self.var.groundwaterCatch) # error of 0.1 LZSmooth operation (same factor of 0.1 as above) LZPcr -= cover(diffCorr, 0) # correction of LZ by the average error from smoothing operation self.var.LZ = compressArray(LZPcr)