def set_input_files(self): # fullPath of CLONE: self.cloneMap = vos.getFullPath(self.globalOptions['cloneMap'], self.globalOptions['inputDir']) # Get the fullPaths of the INPUT directories/files mentioned in # a list/dictionary: dirsAndFiles = ['precipitationNC', 'temperatureNC', 'refETPotFileNC'] for item in dirsAndFiles: if self.meteoOptions[item] != "None": self.meteoOptions[item] = vos.getFullPath( self.meteoOptions[item], self.globalOptions['inputDir'])
def __init__(self, iniItems, landmask): object.__init__(self) # clone map file names, temporary directory and global/absolute path of input directory self.cloneMap = iniItems.cloneMap self.tmpDir = iniItems.tmpDir self.inputDir = iniItems.globalOptions['inputDir'] self.landmask = landmask # ADDED: variables necessary for 2-way coupling functions # ---------------------------------------------------------------------------------------------------------------- # variable to control activation of 2-way coupling functions (can be changed through BMI) self.ActivateCoupling = iniItems.globalOptions['ActivateCoupling'] # introduce relevant variables for 2-way coupling so they can be changed through BMI when needed # to control the presence of water bodies self.waterBodyIdsAdjust = pcr.ifthen(self.landmask, pcr.scalar(1.0)) # ---------------------------------------------------------------------------------------------------------------- # option to activate water balance check self.debugWaterBalance = True if iniItems.routingOptions['debugWaterBalance'] == "False": self.debugWaterBalance = False # option to perform a run with only natural lakes (without reservoirs) self.onlyNaturalWaterBodies = False if "onlyNaturalWaterBodies" in iniItems.routingOptions.keys( ) and iniItems.routingOptions['onlyNaturalWaterBodies'] == "True": logger.info( "WARNING!! Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes." ) self.onlyNaturalWaterBodies = True # The run for a natural condition should access only this date. self.dateForNaturalCondition = "1900-01-01" # names of files containing water bodies parameters if iniItems.routingOptions['waterBodyInputNC'] == str(None): self.useNetCDF = False self.fracWaterInp = iniItems.routingOptions['fracWaterInp'] self.waterBodyIdsInp = iniItems.routingOptions['waterBodyIds'] self.waterBodyTypInp = iniItems.routingOptions['waterBodyTyp'] self.resMaxCapInp = iniItems.routingOptions['resMaxCapInp'] self.resSfAreaInp = iniItems.routingOptions['resSfAreaInp'] else: self.useNetCDF = True self.ncFileInp = vos.getFullPath( iniItems.routingOptions['waterBodyInputNC'], self.inputDir) # minimum width (m) used in the weir formula # TODO: define minWeirWidth based on the GLWD, GRanD database and/or bankfull discharge formula self.minWeirWidth = 10. # lower and upper limits at which reservoir release is terminated and # at which reservoir release is equal to long-term average outflow self.minResvrFrac = 0.10 self.maxResvrFrac = 0.75
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 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 create_output_directories(self): # making the root/parent of OUTPUT directory: cleanOutputDir = False if cleanOutputDir: try: shutil.rmtree(self.globalOptions['outputDir']) except: pass # for new outputDir (not exist yet) try: os.makedirs(self.globalOptions['outputDir']) except: pass # for new outputDir (not exist yet) # making temporary directory: self.tmpDir = vos.getFullPath("tmp/", self.globalOptions['outputDir']) if os.path.exists(self.tmpDir): shutil.rmtree(self.tmpDir) os.makedirs(self.tmpDir) self.outNCDir = vos.getFullPath("netcdf/", self.globalOptions['outputDir']) if os.path.exists(self.outNCDir): shutil.rmtree(self.outNCDir) os.makedirs(self.outNCDir) # making backup for the python scripts used: self.scriptDir = vos.getFullPath("scripts/", self.globalOptions['outputDir']) if os.path.exists(self.scriptDir): shutil.rmtree(self.scriptDir) os.makedirs(self.scriptDir) path_of_this_module = os.path.dirname(__file__) for filename in glob.glob(os.path.join(path_of_this_module, '*.py')): shutil.copy(filename, self.scriptDir) # making log directory: self.logFileDir = vos.getFullPath("log/", self.globalOptions['outputDir']) cleanLogDir = True if os.path.exists(self.logFileDir) and cleanLogDir: shutil.rmtree(self.logFileDir) os.makedirs(self.logFileDir) # making endStateDir directory: self.endStateDir = vos.getFullPath("states/", self.globalOptions['outputDir']) if os.path.exists(self.endStateDir): shutil.rmtree(self.endStateDir) os.makedirs(self.endStateDir) # making pcraster maps directory: self.mapsDir = vos.getFullPath("maps/", self.globalOptions['outputDir']) cleanMapDir = True if os.path.exists(self.mapsDir) and cleanMapDir: shutil.rmtree(self.mapsDir) os.makedirs(self.mapsDir) # go to pcraster maps directory (so all pcr.report files will be saved in this directory) os.chdir(self.mapsDir)
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)