def getICs(self, iniItems, iniConditions=None): # print iniItems.groundwaterOptions['storGroundwaterFossilIni'] # initial condition for storGroundwater (unit: m) if iniConditions == None: # when the model just start self.storGroundwater = vos.readPCRmapClone( iniItems.groundwaterOptions['storGroundwaterIni'], self.cloneMap, self.tmpDir, self.inputDir) self.avgAbstraction = vos.readPCRmapClone( iniItems.groundwaterOptions['avgTotalGroundwaterAbstractionIni'], self.cloneMap, self.tmpDir, self.inputDir) else: # during/after spinUp self.storGroundwater = iniConditions['groundwater']['storGroundwater'] self.avgAbstraction = iniConditions['groundwater']['avgTotalGroundwaterAbstractionIni'] # initial condition for storGroundwaterFossil (unit: m) # # Note that storGroundwaterFossil should not be depleted during the spin-up. # if iniItems.groundwaterOptions['storGroundwaterFossilIni'] != "Maximum": #logger.info("Using a pre-defined initial condition for fossil groundwater storage.") self.storGroundwaterFossil = vos.readPCRmapClone( iniItems.groundwaterOptions['storGroundwaterFossilIni'], self.cloneMap, self.tmpDir, self.inputDir) # if self.limitFossilGroundwaterAbstraction and iniItems.groundwaterOptions['storGroundwaterFossilIni'] != "Maximum": #logger.info("The pre-defined initial condition for fossil groundwater is limited by fossilWaterCap (full capacity).") self.storGroundwaterFossil = pcr.min( self.storGroundwaterFossil, self.fossilWaterCap) # if self.limitFossilGroundwaterAbstraction and iniItems.groundwaterOptions['storGroundwaterFossilIni'] == "Maximum": #logger.info("Assuming 'full' fossilWaterCap as the initial condition for fossil groundwater storage.") self.storGroundwaterFossil = self.fossilWaterCap # make sure that active storGroundwater and avgAbstraction cannot be negative # self.storGroundwater = pcr.cover(self.storGroundwater, 0.0) self.storGroundwater = pcr.max(0., self.storGroundwater) self.storGroundwater = pcr.ifthen(self.landmask, self.storGroundwater) # self.avgAbstraction = pcr.cover(self.avgAbstraction, 0.0) self.avgAbstraction = pcr.max(0., self.avgAbstraction) self.avgAbstraction = pcr.ifthen(self.landmask, self.avgAbstraction) # storGroundwaterFossil can be negative (particularly if limitFossilGroundwaterAbstraction == False) self.storGroundwaterFossil = pcr.ifthen(self.landmask, self.storGroundwaterFossil)
def readTopo(self, iniItems): # maps of elevation attributes: topoParams = ['tanslope', 'slopeLength', 'orographyBeta'] if iniItems.landSurfaceOptions['topographyNC'] == str(None): for var in topoParams: input = iniItems.landSurfaceOptions[str(var)] vars(self)[var] = pcr.scalar(0.0) vars(self)[var] = vos.readPCRmapClone(input, self.cloneMap, self.tmpDir, self.inputDir) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) else: topoPropertiesNC = vos.getFullPath( iniItems.landSurfaceOptions['topographyNC'], self.inputDir) for var in topoParams: vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime( topoPropertiesNC, var, cloneMapFileName=self.cloneMap) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) self.tanslope = pcr.max(self.tanslope, 0.00001) # maps of relative elevation above flood plains dzRel = [ 'dzRel0001', 'dzRel0005', 'dzRel0010', 'dzRel0020', 'dzRel0030', 'dzRel0040', 'dzRel0050', 'dzRel0060', 'dzRel0070', 'dzRel0080', 'dzRel0090', 'dzRel0100' ] if iniItems.landSurfaceOptions['topographyNC'] == str(None): for i in range(0, len(dzRel)): var = dzRel[i] input = iniItems.landSurfaceOptions[str(var)] vars(self)[var] = vos.readPCRmapClone(input, self.cloneMap, self.tmpDir, self.inputDir) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) if i > 0: vars(self)[var] = pcr.max( vars(self)[var], vars(self)[dzRel[i - 1]]) else: for i in range(0, len(dzRel)): var = dzRel[i] vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime( topoPropertiesNC, var, cloneMapFileName=self.cloneMap) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) if i > 0: vars(self)[var] = pcr.max( vars(self)[var], vars(self)[dzRel[i - 1]])
def __init__(self, configuration, currTimeStep, initialState=None): self._configuration = configuration self._modelTime = currTimeStep pcr.setclone(configuration.cloneMap) # Read the ldd map. self.lddMap = vos.readPCRmapClone( configuration.routingOptions['lddMap'], configuration.cloneMap, configuration.tmpDir, configuration.globalOptions['inputDir'], True) # ensure ldd map is correct, and actually of type "ldd" self.lddMap = pcr.lddrepair(pcr.ldd(self.lddMap)) if configuration.globalOptions['landmask'] != "None": self.landmask = vos.readPCRmapClone( configuration.globalOptions['landmask'], configuration.cloneMap, configuration.tmpDir, configuration.globalOptions['inputDir']) else: self.landmask = pcr.defined(self.lddMap) # ADDED: variables necessary for 2-way coupling functions # ---------------------------------------------------------------------------------------------------------------- # variable to control activation of 2-way coupling functions (can be changed through BMI) self.ActivateCoupling = self._configuration.globalOptions[ 'ActivateCoupling'] # ---------------------------------------------------------------------------------------------------------------- # defining catchment areas self.catchment_class = 1.0 # number of upperSoilLayers: self.numberOfSoilLayers = int( configuration.landSurfaceOptions['numberOfUpperSoilLayers']) self.createSubmodels(initialState)
def readSoilMapOfFAO(self, iniItems): # soil variable names given either in the ini or netCDF file: soilParameters = [ 'airEntryValue1', 'airEntryValue2', 'poreSizeBeta1', 'poreSizeBeta2', 'resVolWC1', 'resVolWC2', 'satVolWC1', 'satVolWC2', 'KSat1', 'KSat2', 'percolationImp' ] if iniItems.landSurfaceOptions['soilPropertiesNC'] == str(None): for var in soilParameters: input = iniItems.landSurfaceOptions[str(var)] vars(self)[var] = \ vos.readPCRmapClone(input, self.cloneMap, self.tmpDir, self.inputDir) vars(self)[var] = pcr.scalar(vars(self)[var]) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) else: soilPropertiesNC = vos.getFullPath( iniItems.landSurfaceOptions['soilPropertiesNC'], self.inputDir) for var in soilParameters: vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime( soilPropertiesNC, var, cloneMapFileName=self.cloneMap) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) if self.numberOfLayers == 2: # saturated volumetric moisture content (m3.m-3) self.satVolMoistContUpp = self.satVolWC1 self.satVolMoistContLow = self.satVolWC2 # residual volumetric moisture content (m3.m-3) self.resVolMoistContUpp = self.resVolWC1 self.resVolMoistContLow = self.resVolWC2 # air entry value (m) according to soil water retention curve of Clapp & Hornberger (1978) self.airEntryValueUpp = self.airEntryValue1 self.airEntryValueLow = self.airEntryValue2 # pore size distribution parameter according to Clapp & Hornberger (1978) self.poreSizeBetaUpp = self.poreSizeBeta1 self.poreSizeBetaLow = self.poreSizeBeta2 # saturated hydraulic conductivity (m.day-1) self.kSatUpp = self.KSat1 self.kSatLow = self.KSat2 if self.numberOfLayers == 3: self.satVolMoistContUpp000005 = self.satVolWC1 self.satVolMoistContUpp005030 = self.satVolWC1 self.satVolMoistContLow030150 = self.satVolWC2 self.resVolMoistContUpp000005 = self.resVolWC1 self.resVolMoistContUpp005030 = self.resVolWC1 self.resVolMoistContLow030150 = self.resVolWC2 self.airEntryValueUpp000005 = self.airEntryValue1 self.airEntryValueUpp005030 = self.airEntryValue1 self.airEntryValueLow030150 = self.airEntryValue2 self.poreSizeBetaUpp000005 = self.poreSizeBeta1 self.poreSizeBetaUpp005030 = self.poreSizeBeta1 self.poreSizeBetaLow030150 = self.poreSizeBeta2 self.kSatUpp000005 = self.KSat1 self.kSatUpp005030 = self.KSat1 self.kSatLow030150 = self.KSat2 # fractional area where percolation to groundwater store is impeded (dimensionless) self.percolationImp = self.percolationImp # soil thickness and storage variable names # as given either in the ini or netCDF file: soilStorages = [ 'firstStorDepth', 'secondStorDepth', 'soilWaterStorageCap1', 'soilWaterStorageCap2' ] if iniItems.landSurfaceOptions['soilPropertiesNC'] == str(None): for var in soilStorages: input = iniItems.landSurfaceOptions[str(var)] temp = str(var) + 'Inp' vars(self)[temp] = vos.readPCRmapClone(input, self.cloneMap, self.tmpDir, self.inputDir) vars(self)[temp] = pcr.cover(vars(self)[temp], 0.0) else: soilPropertiesNC = vos.getFullPath( iniItems.landSurfaceOptions['soilPropertiesNC'], self.inputDir) for var in soilStorages: temp = str(var) + 'Inp' vars(self)[temp] = vos.netcdf2PCRobjCloneWithoutTime( soilPropertiesNC, var, cloneMapFileName=self.cloneMap) vars(self)[temp] = pcr.cover(vars(self)[temp], 0.0) # layer thickness if self.numberOfLayers == 2: self.thickUpp = (0.30 / 0.30) * self.firstStorDepthInp self.thickLow = (1.20 / 1.20) * self.secondStorDepthInp if self.numberOfLayers == 3: self.thickUpp000005 = (0.05 / 0.30) * self.firstStorDepthInp self.thickUpp005030 = (0.25 / 0.30) * self.firstStorDepthInp self.thickLow030150 = (1.20 / 1.20) * self.secondStorDepthInp # soil storage if self.numberOfLayers == 2: # ~ self.storCapUpp = (0.30/0.30)*self.soilWaterStorageCap1Inp # ~ self.storCapLow = (1.20/1.20)*self.soilWaterStorageCap2Inp # 22 Feb 2014: We can calculate this based on thickness and porosity. self.storCapUpp = self.thickUpp * \ (self.satVolMoistContUpp - self.resVolMoistContUpp) self.storCapLow = self.thickLow * \ (self.satVolMoistContLow - self.resVolMoistContLow) self.rootZoneWaterStorageCap = self.storCapUpp + \ self.storCapLow if self.numberOfLayers == 3: self.storCapUpp000005 = self.thickUpp000005 * \ (self.satVolMoistContUpp000005 - self.resVolMoistContUpp000005) self.storCapUpp005030 = self.thickUpp005030 * \ (self.satVolMoistContUpp005030 - self.resVolMoistContUpp005030) self.storCapLow030150 = self.thickLow030150 * \ (self.satVolMoistContLow030150 - self.resVolMoistContLow030150) self.rootZoneWaterStorageCap = self.storCapUpp000005 + \ self.storCapUpp005030 + \ self.storCapLow030150
def readSoil(self, iniItems): # default values of soil parameters that are constant/uniform for the entire domain: self.clappAddCoeff = pcr.scalar(3.0) # dimensionless self.matricSuctionFC = pcr.scalar(1.0) # unit: m self.matricSuction50 = pcr.scalar(10. / 3.) # unit: m self.matricSuctionWP = pcr.scalar(156.0) # unit: m self.maxGWCapRise = pcr.scalar(5.0) # unit: m # # values defined in the ini/configuration file: soilParameterConstants = [ 'clappAddCoeff', 'matricSuctionFC', 'matricSuction50', 'matricSuctionWP', 'maxGWCapRise' ] for var in soilParameterConstants: if var in iniItems.landSurfaceOptions.keys(): input = iniItems.landSurfaceOptions[str(var)] vars(self)[var] = vos.readPCRmapClone(input, self.cloneMap, self.tmpDir, self.inputDir) # read soil parameter based on the FAO soil map: self.readSoilMapOfFAO(iniItems) # assign Campbell's (1974) beta coefficient, as well as degree # of saturation at field capacity and corresponding unsaturated hydraulic conductivity # if self.numberOfLayers == 2: self.campbellBetaUpp = 2.*self.poreSizeBetaUpp + \ self.clappAddCoeff # Campbell's (1974) coefficient ; Rens's line: BCB = 2*BCH + BCH_ADD self.campbellBetaLow = 2.*self.poreSizeBetaLow + \ self.clappAddCoeff self.effSatAtFieldCapUpp = \ (self.matricSuctionFC / self.airEntryValueUpp) **\ (-1 / self.poreSizeBetaUpp) # saturation degree at field capacity ; THEFF_FC = (PSI_FC/PSI_A)**(-1/BCH) self.effSatAtFieldCapLow = \ (self.matricSuctionFC / self.airEntryValueLow) **\ (-1 / self.poreSizeBetaLow) self.kUnsatAtFieldCapUpp = pcr.max( 0., self.effSatAtFieldCapUpp**self.poreSizeBetaUpp * self.kSatUpp) self.kUnsatAtFieldCapLow = pcr.max( 0., self.effSatAtFieldCapLow**self.poreSizeBetaLow * self.kSatLow) # if self.numberOfLayers == 3: self.campbellBetaUpp000005 = 2.*self.poreSizeBetaUpp000005 + \ self.clappAddCoeff self.campbellBetaUpp005030 = 2.*self.poreSizeBetaUpp005030 + \ self.clappAddCoeff self.campbellBetaLow030150 = 2.*self.poreSizeBetaLow030150 + \ self.clappAddCoeff self.effSatAtFieldCapUpp000005 = \ (self.matricSuctionFC / self.airEntryValueUpp000005) **\ (-1 / self.poreSizeBetaUpp000005) self.effSatAtFieldCapUpp005030 = \ (self.matricSuctionFC / self.airEntryValueUpp005030) **\ (-1 / self.poreSizeBetaUpp005030) self.effSatAtFieldCapLow030150 = \ (self.matricSuctionFC / self.airEntryValueLow030150) **\ (-1 / self.poreSizeBetaLow030150) self.kUnsatAtFieldCapUpp000005 = pcr.max( 0., self.effSatAtFieldCapUpp000005**self.poreSizeBetaUpp000005 * self.kSatUpp000005) self.kUnsatAtFieldCapUpp005030 = pcr.max( 0., self.effSatAtFieldCapUpp005030**self.poreSizeBetaUpp005030 * self.kSatUpp005030) self.kUnsatAtFieldCapLow030150 = pcr.max( 0., self.effSatAtFieldCapLow030150**self.poreSizeBetaLow030150 * self.kSatLow030150) # calculate degree of saturation at which transpiration is halved (50) # and at wilting point # if self.numberOfLayers == 2: self.effSatAt50Upp = (self.matricSuction50/self.airEntryValueUpp) **\ (-1/self.poreSizeBetaUpp) self.effSatAt50Low = (self.matricSuction50/self.airEntryValueLow) **\ (-1/self.poreSizeBetaLow) self.effSatAtWiltPointUpp = \ (self.matricSuctionWP/self.airEntryValueUpp) **\ (-1/self.poreSizeBetaUpp) self.effSatAtWiltPointLow = \ (self.matricSuctionWP/self.airEntryValueLow) **\ (-1/self.poreSizeBetaLow) if self.numberOfLayers == 3: self.effSatAt50Upp000005 = (self.matricSuction50/self.airEntryValueUpp000005) **\ (-1/self.poreSizeBetaUpp000005) self.effSatAt50Upp005030 = (self.matricSuction50/self.airEntryValueUpp005030) **\ (-1/self.poreSizeBetaUpp005030) self.effSatAt50Low030150 = (self.matricSuction50/self.airEntryValueLow030150) **\ (-1/self.poreSizeBetaLow030150) self.effSatAtWiltPointUpp000005 = \ (self.matricSuctionWP/self.airEntryValueUpp000005) **\ (-1/self.poreSizeBetaUpp000005) self.effSatAtWiltPointUpp005030 = \ (self.matricSuctionWP/self.airEntryValueUpp005030) **\ (-1/self.poreSizeBetaUpp005030) self.effSatAtWiltPointLow030150 = \ (self.matricSuctionWP/self.airEntryValueLow030150) **\ (-1/self.poreSizeBetaLow030150) # calculate interflow parameter (TCL): # if self.numberOfLayers == 2: self.interflowConcTime = (2. * self.kSatLow * self.tanslope) / \ (self.slopeLength * (1. - self.effSatAtFieldCapLow) * (self.satVolMoistContLow - self.resVolMoistContLow)) # TCL = Duration*(2*KS2*TANSLOPE)/(LSLOPE*(1-THEFF2_FC)*(THETASAT2-THETARES2)) # if self.numberOfLayers == 3: self.interflowConcTime = (2. * self.kSatLow030150 * self.tanslope) / \ (self.slopeLength * (1.-self.effSatAtFieldCapLow030150) * (self.satVolMoistContLow030150 - self.resVolMoistContLow030150)) self.interflowConcTime = pcr.cover(self.interflowConcTime, 0.0)
def __init__(self, iniItems, landmask, spinUp): object.__init__(self) self.cloneMap = iniItems.cloneMap self.tmpDir = iniItems.tmpDir self.inputDir = iniItems.globalOptions['inputDir'] self.landmask = landmask # option to activate water balance check self.debugWaterBalance = True if iniItems.routingOptions['debugWaterBalance'] == "False": self.debugWaterBalance = False if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None): # assign the recession coefficient parameter(s) self.recessionCoeff = vos.readPCRmapClone( iniItems.groundwaterOptions['recessionCoeff'], self.cloneMap, self.tmpDir, self.inputDir) else: groundwaterPropertiesNC = vos.getFullPath( iniItems.groundwaterOptions[ 'groundwaterPropertiesNC'], self.inputDir) self.recessionCoeff = vos.netcdf2PCRobjCloneWithoutTime( groundwaterPropertiesNC, 'recessionCoeff', cloneMapFileName=self.cloneMap) # groundwater recession coefficient (day-1_ self.recessionCoeff = pcr.cover(self.recessionCoeff, 0.00) self.recessionCoeff = pcr.min(1.0000, self.recessionCoeff) # if 'minRecessionCoeff' in iniItems.groundwaterOptions.keys(): minRecessionCoeff = float( iniItems.groundwaterOptions['minRecessionCoeff']) else: # This is the minimum value used in Van Beek et al. (2011). minRecessionCoeff = 1.0e-4 self.recessionCoeff = pcr.max(minRecessionCoeff, self.recessionCoeff) if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None): # assign aquifer specific yield self.specificYield = vos.readPCRmapClone( iniItems.groundwaterOptions['specificYield'], self.cloneMap, self.tmpDir, self.inputDir) else: self.specificYield = vos.netcdf2PCRobjCloneWithoutTime( groundwaterPropertiesNC, 'specificYield', cloneMapFileName=self.cloneMap) self.specificYield = pcr.cover(self.specificYield, 0.0) # TODO: TO BE CHECKED: The resample process of specificYield self.specificYield = pcr.max(0.010, self.specificYield) self.specificYield = pcr.min(1.000, self.specificYield) if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None): # assign aquifer saturated conductivity self.kSatAquifer = vos.readPCRmapClone( iniItems.groundwaterOptions['kSatAquifer'], self.cloneMap, self.tmpDir, self.inputDir) else: self.kSatAquifer = vos.netcdf2PCRobjCloneWithoutTime( groundwaterPropertiesNC, 'kSatAquifer', cloneMapFileName=self.cloneMap) self.kSatAquifer = pcr.cover(self.kSatAquifer, 0.0) self.kSatAquifer = pcr.max(0.010, self.kSatAquifer) # limitAbstraction options self.limitAbstraction = False if iniItems.landSurfaceOptions['limitAbstraction'] == "True": self.limitAbstraction = True # option for limitting fossil groundwater abstractions - This option is only defined for IWMI project self.limitFossilGroundwaterAbstraction = False if self.limitAbstraction == False and\ "extraOptionsforProjectWithIWMI" in iniItems.allSections and\ iniItems.extraOptionsforProjectWithIWMI['limitFossilGroundWaterAbstraction'] == "True": #logger.info('Fossil groundwater abstraction limit is used (IWMI project).') self.limitFossilGroundwaterAbstraction = True # estimate of thickness (unit: mm) of aceesible groundwater: shallow and deep totalGroundwaterThickness = vos.readPCRmapClone( iniItems.extraOptionsforProjectWithIWMI['estimateOfTotalGroundwaterThickness'], self.cloneMap, self.tmpDir, self.inputDir) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 1.0)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 1.5)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 2.5)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 5.0)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 7.5)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.mapmaximum(totalGroundwaterThickness)) # set minimum thickness to 50 m: totalGroundwaterThickness = pcr.max( 50.0, totalGroundwaterThickness) # estimate of capacity (unit: m) of renewable groundwater (shallow) storGroundwaterCap = pcr.cover( vos.readPCRmapClone( iniItems.extraOptionsforProjectWithIWMI['estimateOfRenewableGroundwaterCapacity'], self.cloneMap, self.tmpDir, self.inputDir), 0.0) # fossil groundwater capacity (unit: m) self.fossilWaterCap = pcr.max(0.0, totalGroundwaterThickness*self.specificYield - storGroundwaterCap) # option for limitting regional groundwater abstractions - This option is only defined self.limitRegionalAnnualGroundwaterAbstraction = False if "extraOptionsforProjectWithIWMI" in iniItems.allSections and\ iniItems.extraOptionsforProjectWithIWMI['limitRegionalAnnualGroundwaterAbstraction'] == "True": #logger.info('Limit for regional groundwater abstraction is used (IWMI project).') self.limitRegionalAnnualGroundwaterAbstraction = True region_ids = vos.readPCRmapClone( iniItems.extraOptionsforProjectWithIWMI['regionIds'], self.cloneMap, self.tmpDir, self.inputDir) self.region_ids = pcr.nominal(region_ids) self.region_ids = pcr.ifthen(self.landmask, self.region_ids) self.regionalAnnualGroundwaterAbstractionLimit = vos.readPCRmapClone( iniItems.extraOptionsforProjectWithIWMI['pumpingCapacity'], self.cloneMap, self.tmpDir, self.inputDir) self.regionalAnnualGroundwaterAbstractionLimit = pcr.roundup( self.regionalAnnualGroundwaterAbstractionLimit*1000.)/1000. self.regionalAnnualGroundwaterAbstractionLimit = pcr.cover( self.regionalAnnualGroundwaterAbstractionLimit, 0.0) self.regionalAnnualGroundwaterAbstractionLimit *= 1000. * \ 1000. * 1000. # unit: m3/year self.regionalAnnualGroundwaterAbstractionLimit = pcr.ifthen(self.landmask, self.regionalAnnualGroundwaterAbstractionLimit) # zones at which water allocation (surface and groundwater allocation) is determined self.usingAllocSegments = False if iniItems.landSurfaceOptions['allocationSegmentsForGroundSurfaceWater'] != "None": self.usingAllocSegments = True # incorporating groundwater distribution network: if self.usingAllocSegments and self.limitAbstraction == False: self.allocSegments = vos.readPCRmapClone( iniItems.landSurfaceOptions['allocationSegmentsForGroundSurfaceWater'], self.cloneMap, self.tmpDir, self.inputDir, isLddMap=False, cover=None, isNomMap=True) self.allocSegments = pcr.ifthen(self.landmask, self.allocSegments) cellArea = vos.readPCRmapClone( iniItems.routingOptions['cellAreaMap'], self.cloneMap, self.tmpDir, self.inputDir) # TODO: integrate this one with the one coming from the routing module cellArea = pcr.ifthen(self.landmask, cellArea) self.segmentArea = pcr.areatotal( pcr.cover(cellArea, 0.0), self.allocSegments) self.segmentArea = pcr.ifthen(self.landmask, self.segmentArea) self.report = True try: self.outDailyTotNC = iniItems.groundwaterOptions['outDailyTotNC'].split( ",") self.outMonthTotNC = iniItems.groundwaterOptions['outMonthTotNC'].split( ",") self.outMonthAvgNC = iniItems.groundwaterOptions['outMonthAvgNC'].split( ",") self.outMonthEndNC = iniItems.groundwaterOptions['outMonthEndNC'].split( ",") self.outAnnuaTotNC = iniItems.groundwaterOptions['outAnnuaTotNC'].split( ",") self.outAnnuaAvgNC = iniItems.groundwaterOptions['outAnnuaAvgNC'].split( ",") self.outAnnuaEndNC = iniItems.groundwaterOptions['outAnnuaEndNC'].split( ",") except: self.report = False if self.report == True: self.outNCDir = iniItems.outNCDir self.netcdfObj = PCR2netCDF(iniItems) # # daily output in netCDF files: if self.outDailyTotNC[0] != "None": for var in self.outDailyTotNC: # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" + str(var)+"_dailyTot.nc", var, "undefined") # MONTHly output in netCDF files: # - cummulative if self.outMonthTotNC[0] != "None": for var in self.outMonthTotNC: # initiating monthlyVarTot (accumulator variable): vars(self)[var+'MonthTot'] = None # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" + str(var)+"_monthTot.nc", var, "undefined") # - average if self.outMonthAvgNC[0] != "None": for var in self.outMonthAvgNC: # initiating monthlyTotAvg (accumulator variable) vars(self)[var+'MonthTot'] = None # initiating monthlyVarAvg: vars(self)[var+'MonthAvg'] = None # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" + str(var)+"_monthAvg.nc", var, "undefined") # - last day of the month if self.outMonthEndNC[0] != "None": for var in self.outMonthEndNC: # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" + str(var)+"_monthEnd.nc", var, "undefined") # YEARly output in netCDF files: # - cummulative if self.outAnnuaTotNC[0] != "None": for var in self.outAnnuaTotNC: # initiating yearly accumulator variable: vars(self)[var+'AnnuaTot'] = None # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" + str(var)+"_annuaTot.nc", var, "undefined") # - average if self.outAnnuaAvgNC[0] != "None": for var in self.outAnnuaAvgNC: # initiating annualyVarAvg: vars(self)[var+'AnnuaAvg'] = None # initiating annualyTotAvg (accumulator variable) vars(self)[var+'AnnuaTot'] = None # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" + str(var)+"_annuaAvg.nc", var, "undefined") # - last day of the year if self.outAnnuaEndNC[0] != "None": for var in self.outAnnuaEndNC: # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" + str(var)+"_annuaEnd.nc", var, "undefined") # get initial conditions self.getICs(iniItems, spinUp)
def getParameterFiles(self, currTimeStep, cellArea, ldd, cellLengthFD, cellSizeInArcDeg, initial_condition_dictionary=None): # parameters for Water Bodies: fracWat # waterBodyIds # waterBodyOut # waterBodyArea # waterBodyTyp # waterBodyCap # cell surface area (m2) and ldd self.cellArea = cellArea ldd = pcr.ifthen(self.landmask, ldd) # date used for accessing/extracting water body information date_used = currTimeStep.fulldate year_used = currTimeStep.year if self.onlyNaturalWaterBodies == True: date_used = self.dateForNaturalCondition year_used = self.dateForNaturalCondition[0:4] # fracWat = fraction of surface water bodies (dimensionless) self.fracWat = pcr.scalar(0.0) if self.useNetCDF: self.fracWat = vos.netcdf2PCRobjClone( self.ncFileInp, 'fracWaterInp', date_used, useDoy='yearly', cloneMapFileName=self.cloneMap) else: self.fracWat = vos.readPCRmapClone( self.fracWaterInp + str(year_used) + ".map", self.cloneMap, self.tmpDir, self.inputDir) self.fracWat = pcr.cover(self.fracWat, 0.0) self.fracWat = pcr.max(0.0, self.fracWat) self.fracWat = pcr.min(1.0, self.fracWat) self.waterBodyIds = pcr.nominal(0) # waterBody ids self.waterBodyOut = pcr.boolean(0) # waterBody outlets self.waterBodyArea = pcr.scalar(0.) # waterBody surface areas # water body ids if self.useNetCDF: self.waterBodyIds = vos.netcdf2PCRobjClone( self.ncFileInp, 'waterBodyIds', date_used, useDoy='yearly', cloneMapFileName=self.cloneMap) else: self.waterBodyIds = vos.readPCRmapClone( self.waterBodyIdsInp + str(year_used) + ".map", self.cloneMap, self.tmpDir, self.inputDir, False, None, True) # self.waterBodyIds = pcr.ifthen( pcr.scalar(self.waterBodyIds) > 0., pcr.nominal(self.waterBodyIds)) # ADDED: adjust waterBodyIds if ActivateCoupling is set to True # ---------------------------------------------------------------------------------------------------------------- if self.ActivateCoupling == 'True': self.waterBodyIds = pcr.scalar( self.waterBodyIds) * self.waterBodyIdsAdjust self.waterBodyIds = pcr.nominal(self.waterBodyIds) # ---------------------------------------------------------------------------------------------------------------- # water body outlets (correcting outlet positions) wbCatchment = pcr.catchmenttotal(pcr.scalar(1), ldd) self.waterBodyOut = pcr.ifthen(wbCatchment == pcr.areamaximum( wbCatchment, self.waterBodyIds), self.waterBodyIds) # = outlet ids self.waterBodyOut = pcr.ifthen( pcr.scalar(self.waterBodyIds) > 0., self.waterBodyOut) # TODO: Please also consider endorheic lakes! # correcting water body ids self.waterBodyIds = pcr.ifthen( pcr.scalar(self.waterBodyIds) > 0., pcr.subcatchment(ldd, self.waterBodyOut)) # boolean map for water body outlets: self.waterBodyOut = pcr.ifthen( pcr.scalar(self.waterBodyOut) > 0., pcr.boolean(1)) # reservoir surface area (m2): if self.useNetCDF: resSfArea = 1000. * 1000. * \ vos.netcdf2PCRobjClone(self.ncFileInp, 'resSfAreaInp', date_used, useDoy='yearly', cloneMapFileName=self.cloneMap) else: resSfArea = 1000. * 1000. * vos.readPCRmapClone( self.resSfAreaInp + str(year_used) + ".map", self.cloneMap, self.tmpDir, self.inputDir) resSfArea = pcr.areaaverage(resSfArea, self.waterBodyIds) resSfArea = pcr.cover(resSfArea, 0.) # water body surface area (m2): (lakes and reservoirs) self.waterBodyArea = pcr.max( pcr.areatotal(pcr.cover(self.fracWat * self.cellArea, 0.0), self.waterBodyIds), pcr.areaaverage(pcr.cover(resSfArea, 0.0), self.waterBodyIds)) self.waterBodyArea = pcr.ifthen(self.waterBodyArea > 0., self.waterBodyArea) # correcting water body ids and outlets (exclude all water bodies with surfaceArea = 0) self.waterBodyIds = pcr.ifthen(self.waterBodyArea > 0., self.waterBodyIds) self.waterBodyOut = pcr.ifthen(pcr.boolean(self.waterBodyIds), self.waterBodyOut) # water body types: # - 2 = reservoirs (regulated discharge) # - 1 = lakes (weirFormula) # - 0 = non lakes or reservoirs (e.g. wetland) self.waterBodyTyp = pcr.nominal(0) if self.useNetCDF: self.waterBodyTyp = vos.netcdf2PCRobjClone( self.ncFileInp, 'waterBodyTyp', date_used, useDoy='yearly', cloneMapFileName=self.cloneMap) else: self.waterBodyTyp = vos.readPCRmapClone( self.waterBodyTypInp + str(year_used) + ".map", self.cloneMap, self.tmpDir, self.inputDir, False, None, True) # excluding wetlands (waterBodyTyp = 0) in all functions related to lakes/reservoirs # self.waterBodyTyp = pcr.ifthen( pcr.scalar(self.waterBodyTyp) > 0, pcr.nominal(self.waterBodyTyp)) self.waterBodyTyp = pcr.ifthen( pcr.scalar(self.waterBodyIds) > 0, pcr.nominal(self.waterBodyTyp)) self.waterBodyTyp = pcr.areamajority( self.waterBodyTyp, self.waterBodyIds ) # choose only one type: either lake or reservoir self.waterBodyTyp = pcr.ifthen( pcr.scalar(self.waterBodyTyp) > 0, pcr.nominal(self.waterBodyTyp)) self.waterBodyTyp = pcr.ifthen(pcr.boolean(self.waterBodyIds), self.waterBodyTyp) # correcting lakes and reservoirs ids and outlets self.waterBodyIds = pcr.ifthen( pcr.scalar(self.waterBodyTyp) > 0, self.waterBodyIds) self.waterBodyOut = pcr.ifthen( pcr.scalar(self.waterBodyIds) > 0, self.waterBodyOut) # reservoir maximum capacity (m3): self.resMaxCap = pcr.scalar(0.0) self.waterBodyCap = pcr.scalar(0.0) if self.useNetCDF: self.resMaxCap = 1000. * 1000. * \ vos.netcdf2PCRobjClone(self.ncFileInp, 'resMaxCapInp', date_used, useDoy='yearly', cloneMapFileName=self.cloneMap) else: self.resMaxCap = 1000. * 1000. * vos.readPCRmapClone( self.resMaxCapInp + str(year_used) + ".map", self.cloneMap, self.tmpDir, self.inputDir) self.resMaxCap = pcr.ifthen(self.resMaxCap > 0, self.resMaxCap) self.resMaxCap = pcr.areaaverage(self.resMaxCap, self.waterBodyIds) # water body capacity (m3): (lakes and reservoirs) # Note: Most of lakes have capacities > 0. self.waterBodyCap = pcr.cover(self.resMaxCap, 0.0) self.waterBodyCap = pcr.ifthen(pcr.boolean(self.waterBodyIds), self.waterBodyCap) # correcting water body types: # Reservoirs that have zero capacities will be assumed as lakes. self.waterBodyTyp = \ pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0., self.waterBodyTyp) self.waterBodyTyp = pcr.ifthenelse( self.waterBodyCap > 0., self.waterBodyTyp, pcr.ifthenelse( pcr.scalar(self.waterBodyTyp) == 2, pcr.nominal(1), self.waterBodyTyp)) # final corrections: self.waterBodyTyp = pcr.ifthen( self.waterBodyArea > 0., self.waterBodyTyp ) # make sure that all lakes and/or reservoirs have surface areas self.waterBodyTyp = \ pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0., self.waterBodyTyp) # make sure that only types 1 and 2 will be considered in lake/reservoir functions self.waterBodyIds = pcr.ifthen( pcr.scalar(self.waterBodyTyp) > 0., self.waterBodyIds ) # make sure that all lakes and/or reservoirs have ids self.waterBodyOut = pcr.ifthen( pcr.scalar(self.waterBodyIds) > 0., self.waterBodyOut ) # make sure that all lakes and/or reservoirs have outlets # for a natural run (self.onlyNaturalWaterBodies == True) # which uses only the year 1900, assume all reservoirs are lakes if self.onlyNaturalWaterBodies == True and date_used == self.dateForNaturalCondition: logger.info( "WARNING!! Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes." ) self.waterBodyTyp = \ pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0., pcr.nominal(1)) # check that all lakes and/or reservoirs have types, ids, surface areas and outlets: test = pcr.defined(self.waterBodyTyp) & pcr.defined(self.waterBodyArea) &\ pcr.defined(self.waterBodyIds) & pcr.boolean( pcr.areamaximum(pcr.scalar(self.waterBodyOut), self.waterBodyIds)) a, b, c = vos.getMinMaxMean(pcr.scalar(test) - pcr.scalar(1.0)) threshold = 1e-3 if abs(a) > threshold or abs(b) > threshold: logger.info( "WARNING !!!!! Missing information in some lakes and/or reservoirs." ) # at the beginning of simulation period (timeStepPCR = 1) # - we have to define/get the initial conditions # if currTimeStep.timeStepPCR == 1: self.getICs(initial_condition_dictionary) # For each new reservoir (introduced at the beginning of the year) # initiating storage, average inflow and outflow # self.waterBodyStorage = pcr.cover(self.waterBodyStorage, 0.0) self.avgInflow = pcr.cover(self.avgInflow, 0.0) self.avgOutflow = pcr.cover(self.avgOutflow, 0.0) # cropping only in the landmask region: self.fracWat = pcr.ifthen(self.landmask, self.fracWat) self.waterBodyIds = pcr.ifthen(self.landmask, self.waterBodyIds) self.waterBodyOut = pcr.ifthen(self.landmask, self.waterBodyOut) self.waterBodyArea = pcr.ifthen(self.landmask, self.waterBodyArea) self.waterBodyTyp = pcr.ifthen(self.landmask, self.waterBodyTyp) self.waterBodyCap = pcr.ifthen(self.landmask, self.waterBodyCap) self.waterBodyStorage = pcr.ifthen(self.landmask, self.waterBodyStorage) self.avgInflow = pcr.ifthen(self.landmask, self.avgInflow) self.avgOutflow = pcr.ifthen(self.landmask, self.avgOutflow)