Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
        
        # defining catchment areas
        self.catchment_class = 1.0
        
        # number of upperSoilLayers:
        self.numberOfSoilLayers = int(configuration.landSurfaceOptions['numberOfUpperSoilLayers'])

        self.createSubmodels(initialState)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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]])
Exemplo n.º 5
0
    def readTopo(self, iniItems, optionDict):

        # a dictionary/section of options that will be used
        if optionDict == None: optionDict = iniItems._sections["landSurfaceOptions"]

        # maps of elevation attributes: 
        topoParams = ['tanslope','slopeLength','orographyBeta']
        if optionDict['topographyNC'] == str(None):
            for var in topoParams:
                input = configget(iniItems,"landSurfaceOptions",str(var),"None")
                vars(self)[var] = vos.readPCRmapClone(input,self.cloneMap,
                                                self.tmpDir,self.inputDir)
                if var != "slopeLength": vars(self)[var] = pcr.cover(vars(self)[var], 0.0)
        else:
            topoPropertiesNC = vos.getFullPath(\
                               optionDict['topographyNC'],
                                                self.inputDir)

            for var in topoParams:
                vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(\
                                    topoPropertiesNC,var, \
                                    cloneMapFileName = self.cloneMap)
                if var != "slopeLength": vars(self)[var] = pcr.cover(vars(self)[var], 0.0)

        #~ self.tanslope = pcr.max(self.tanslope, 0.00001)              # In principle, tanslope can be zero. Zero tanslope will provide zero TCL (no interflow)

        # covering slopeLength with its maximum value 
        self.slopeLength = pcr.cover(self.slopeLength, pcr.mapmaximum(self.slopeLength))
        
        # maps of relative elevation above flood plains 
        dzRel = ['dzRel0001','dzRel0005',
                 'dzRel0010','dzRel0020','dzRel0030','dzRel0040','dzRel0050',
                 'dzRel0060','dzRel0070','dzRel0080','dzRel0090','dzRel0100']
        if optionDict['topographyNC'] == str(None):
            for i in range(0, len(dzRel)):
                var = dzRel[i]
                input = optionDict[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]])
Exemplo n.º 6
0
    def get_initial_heads(self):
		
        if self.iniItems.modflowTransientInputOptions['groundwaterHeadIni'] != "None": 
        
            # using a pre-defined groundwater head described in the ini/configuration file
            self.groundwaterHead = vos.readPCRmapClone(self.modflowTransientInputOptions['groundwaterHeadIni'],\
                                                       self.cloneMap, self.tmpDir, self.inputDir)
        else:    

            # using the digital elevation model as the initial head
            self.groundwaterHead = self.dem_average

            # calculate/simulate a steady state condition (until the modflow converge)
            self.modflow_converged = False
            while self.modflow_converged == False:
                self.modflow_simulation("steady-state", self.groundwaterHead, None,1,1,self.criteria_HCLOSE[self.iteration_HCLOSE],\
                                                                                       self.criteria_RCLOSE[self.iteration_RCLOSE])
            
            # extrapolating the calculated heads for areas/cells outside the landmask (to remove isolated cells) # TODO: Using Deltares's trick to remove isolated cells. 
            # 
            # - the calculate groundwater head within the landmask region
            self.groundwaterHead = pcr.ifthen(self.landmask, self.groundwaterHead)
            # - keep the ocean values (dem <= 0.0) - this is in order to maintain the 'behaviors' of sub marine groundwater discharge
            self.groundwaterHead = pcr.cover(self.groundwaterHead, pcr.ifthen(self.dem_average <= 0.0, self.dem_average))
            # - extrapolation # 
            self.groundwaterHead = pcr.cover(self.groundwaterHead, pcr.windowaverage(self.groundwaterHead, 3.*pcr.clone().cellSize()))
            self.groundwaterHead = pcr.cover(self.groundwaterHead, pcr.windowaverage(self.groundwaterHead, 5.*pcr.clone().cellSize()))
            self.groundwaterHead = pcr.cover(self.groundwaterHead, self.dem_average)
            # TODO: Define the window sizes as part of the configuration file.
        
        # after having the initial head, set the following variable to True to indicate the first month of the model simulation
        self.firstMonthOfSimulation = True      
Exemplo n.º 7
0
    def __init__(self, iniItems, landmask, Dir, cloneMap, tmpDir):
        object.__init__(self)

        # clone map file names, temporary directory and global/absolute path of input directory
        self.cloneMap = cloneMap  #iniItems.cloneMap
        self.tmpDir = tmpDir  #iniItems.tmpDir
        self.inputDir = Dir  #iniItems.globalOptions['inputDir']
        self.landmask = landmask

        # local drainage direction:
        self.lddMap = vos.readPCRmapClone(
            iniItems.get("routingOptions", "lddMap"), self.cloneMap,
            self.tmpDir, self.inputDir, True)
        self.lddMap = pcr.lddrepair(pcr.ldd(self.lddMap))
        self.lddMap = pcr.lddrepair(self.lddMap)

        # option to activate water balance check
        self.debugWaterBalance = True
        if configget(iniItems, "routingOptions", "debugWaterBalance",
                     "True") == "False":
            self.debugWaterBalance = False

        # option to perform a run with only natural lakes (without reservoirs)
        self.onlyNaturalWaterBodies = False
        if "onlyNaturalWaterBodies" in iniItems._sections[
                'routingOptions'] and configget(iniItems, "routingOptions",
                                                "onlyNaturalWaterBodies",
                                                "False") == "True":
            logger.info(
                "Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes."
            )
            self.onlyNaturalWaterBodies = True
            self.dateForNaturalCondition = "1900-01-01"  # The run for a natural condition should access only this date.

        # names of files containing water bodies parameters
        if configget(iniItems, "routingOptions", "waterBodyInputNC",
                     "None") == str(None):
            self.useNetCDF = False
            self.fracWaterInp = iniItems.get("routingOptions", "fracWaterInp")
            self.waterBodyIdsInp = iniItems.get("routingOptions",
                                                "waterBodyIds")
            self.waterBodyTypInp = iniItems.get("routingOptions",
                                                "waterBodyTyp")
            self.resMaxCapInp = iniItems.get("routingOptions", "resMaxCapInp")
            self.resSfAreaInp = iniItems.get("routingOptions", "resSfAreaInp")
        else:
            self.useNetCDF = True
            self.ncFileInp       = vos.getFullPath(\
                                   iniItems.get("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
Exemplo n.º 8
0
    def dynamic(self):

        # re-calculate current model time using current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # perform the operation only at the last day of the month (as the input netcdf file has a monthly resolution with the last date of the month as its time stamp)
        if self.modelTime.isLastDayOfMonth():

            self.i_month = self.i_month + 1

            # reading a netcdf file (global extent, 5 arcmin resolution):
            pcr.setclone(self.globeCloneMapFileName)
            global_pcraster_map = vos.netcdf2PCRobjClone(ncFile    = self.netcdf_input['file_name'], \
                                                         varName   = self.netcdf_input['variable_name'], \
                                                         dateInput = self.modelTime.fulldate)
            # save it to pcraster maps (still at a global extent and 5 arcmin resolution);
            # there will be two files as follows:
            # - Format 1: example file names: htop0000.001 (for the 1st time step), htop0000.002, htop0000.003, etc. ...
            pcraster_file_name = self.pcraster_output[
                'output_folder'] + "/global/" + self.pcraster_output[
                    'file_name']
            pcraster_file_name = pcr.framework.frameworkBase.generateNameT(
                pcraster_file_name, self.i_month)
            pcr.report(global_pcraster_map, pcraster_file_name)
            # - Format 2: example file names: htop_2000_01.map, htop_2000_02.map, etc.
            pcraster_file_name = self.pcraster_output[
                'output_folder'] + "/global/" + self.pcraster_output[
                    'file_name'] + "_" + self.modelTime.fulldate[0:7].replace(
                        "-", "_") + ".map"
            pcr.report(global_pcraster_map, pcraster_file_name)

            # reproject and resample it to a local coordinate system
            pcr.setclone(self.localCloneMapFileName)
            local_pcraster_map = vos.readPCRmapClone(v = pcraster_file_name, \
                                                     cloneMapFileName = self.localCloneMapFileName, \
                                                     tmpDir = self.pcraster_output['output_folder'] + "/tmp/", \
                                                     absolutePath = None,\
                                                     isLddMap = False, \
                                                     cover = None, \
                                                     isNomMap = False, \
                                                     inputEPSG  = self.inputEPSG,
                                                     outputEPSG = self.outputEPSG,
                                                     method = "near")
            # save it to pcraster maps (now already at the extent, the resolution and the coordinate system of the local model)
            # there will be two files as follows:
            # - Format 1: example file names: htop0000.001 (for the 1st time step), htop0000.002, htop0000.003, etc. ...
            pcraster_file_name = self.pcraster_output[
                'output_folder'] + "/regional/" + self.pcraster_output[
                    'file_name']
            pcraster_file_name = pcr.framework.frameworkBase.generateNameT(
                pcraster_file_name, self.i_month)
            pcr.report(local_pcraster_map, pcraster_file_name)
            # - Format 2: example file names: htop_2000_01.map, htop_2000_02.map, etc.
            pcraster_file_name = self.pcraster_output[
                'output_folder'] + "/regional/" + self.pcraster_output[
                    'file_name'] + "_" + self.modelTime.fulldate[0:7].replace(
                        "-", "_") + ".map"
            pcr.report(local_pcraster_map, pcraster_file_name)
Exemplo n.º 9
0
    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)

        # defining catchment areas
        self.catchment_class = 1.0

        # number of upperSoilLayers:
        self.numberOfSoilLayers = int(
            configuration.landSurfaceOptions['numberOfUpperSoilLayers'])

        # preparing sub-modules
        self.createSubmodels(initialState)

        # option for debugging to PCR-GLOBWB version 1.0
        self.debug_to_version_one = False
        if configuration.debug_to_version_one: self.debug_to_version_one = True
        if self.debug_to_version_one:

            # preparing initial folder directory
            self.directory_for_initial_maps = vos.getFullPath(
                "initials/", self.configuration.mapsDir)
            if os.path.exists(self.directory_for_initial_maps):
                shutil.rmtree(self.directory_for_initial_maps)
            os.makedirs(self.directory_for_initial_maps)

            # dump the initial state
            self.dumpState(self.directory_for_initial_maps, "initial")
Exemplo n.º 10
0
    def __init__(self, input_files,\
                      output_files,\
                       modelTime,\
                       tmpDir = "/dev/shm/"):
        DynamicModel.__init__(self)           # 

        self.input_files  = input_files
        self.output_files = output_files 
        self.tmpDir = tmpDir

        self.modelTime = modelTime

        pcr.setclone(self.input_files["model_cell_area"])
        clone_map = pcr.boolean(1)
        
        # cell area (m2)
        self.cell_area = vos.readPCRmapClone(\
                        self.input_files["model_cell_area"],\
                        self.input_files["model_cell_area"],\
                        self.tmpDir)
        
        # resampling factor: ratio between target (coarse) and original (fine) resolution
        self.resample_factor = round(
                               vos.getMapAttributes(self.input_files["one_degree_id"],'cellsize')/\
                               vos.getMapAttributes(self.input_files["model_cell_area"],'cellsize'))
        
        # unique ids for upscaling to one degree resolution (grace resolution)
        self.one_degree_id = pcr.nominal(\
                             vos.readPCRmapClone(\
                            self.input_files["one_degree_id"],\
                            self.input_files["model_cell_area"],\
                            self.tmpDir))
        
        # object for reporting at coarse resolution (i.e. one arc degree - grace resolution)
        self.output = OutputNetcdf(self.input_files["one_degree_id"], self.input_files["model_cell_area"])       
        # preparing the netcdf file at coarse resolution:
        self.output.createNetCDF(self.output_files['one_degree_tws']['model'], "pcrglobwb_tws","m")
        #
        # edit some attributes:
        attributeDictionary = {}
        attributeDictionary['description']      = "One degree resolution total water storage (tws), upscaled from PCR-GLOBWB result. "
        self.output.changeAtrribute(self.output_files['one_degree_tws']['model'],\
                                    attributeDictionary)                       
    def get_initial_heads(self):
		
        if self.iniItems.modflowTransientInputOptions['groundwaterHeadIni'] != "None": 
        
            # using a pre-defined groundwater head described in the ini/configuration file
            self.groundwaterHead = vos.readPCRmapClone(self.modflowTransientInputOptions['groundwaterHeadIni'],\
                                                       self.cloneMap, self.tmpDir, self.inputDir)
        else:    

            # calculate/simulate a steady state condition and obtain its calculated head values
            self.modflow_simulation("steady-state", self.dem_average, None)
Exemplo n.º 12
0
    def read_meteo_conversion_factors(self, meteoOptions):

        if 'precipitationConstant' in meteoOptions:
            self.preConst = pcr.cover(
                vos.readPCRmapClone(meteoOptions['precipitationConstant'],
                                    self.cloneMap, self.tmpDir, self.inputDir),
                0.0)
        if 'precipitationFactor' in meteoOptions:
            self.preFactor = pcr.cover(
                vos.readPCRmapClone(meteoOptions['precipitationFactor'],
                                    self.cloneMap, self.tmpDir, self.inputDir),
                1.0)
        if 'temperatureConstant' in meteoOptions:
            self.tmpConst = pcr.cover(
                vos.readPCRmapClone(meteoOptions['temperatureConstant'],
                                    self.cloneMap, self.tmpDir, self.inputDir),
                0.0)
        if 'temperatureFactor' in meteoOptions:
            self.tmpFactor = pcr.cover(
                vos.readPCRmapClone(meteoOptions['temperatureFactor'],
                                    self.cloneMap, self.tmpDir, self.inputDir),
                1.0)
        if 'referenceEPotConstant' in meteoOptions:
            self.refETPotConst = pcr.cover(
                vos.readPCRmapClone(meteoOptions['referenceEPotConstant'],
                                    self.cloneMap, self.tmpDir, self.inputDir),
                0.0)
        if 'referenceEPotFactor' in meteoOptions:
            self.refETPotFactor = pcr.cover(
                vos.readPCRmapClone(meteoOptions['referenceEPotFactor'],
                                    self.cloneMap, self.tmpDir, self.inputDir),
                1.0)
Exemplo n.º 13
0
    def __init__(self, configuration, currTimeStep):
        self._configuration = configuration
        self._modelTime = currTimeStep

        pcr.setclone(configuration.cloneMap)

        # read the ldd map
        self.lddMap = vos.netcdf2PCRobjCloneWithoutTime(configuration.modflowParameterOptions['channelNC'],'lddMap',\
                                                        configuration.cloneMap)
        # ensure ldd map is correct, and actually of type "ldd"
        self.lddMap = pcr.lddrepair(pcr.ldd(self.lddMap))

        # defining the landmask map
        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)

        # preparing the sub-model(s)         - Currently, there is only one sub-model.
        self.createSubmodels()
Exemplo n.º 14
0
def main():

    # output folder
    clean_out_folder = True
    if os.path.exists(out_folder):
        if clean_out_folder:
            shutil.rmtree(out_folder)
            os.makedirs(out_folder)
    else:
        os.makedirs(out_folder)
    os.chdir(out_folder)
    os.system("pwd")

    # tmp folder
    tmp_folder = out_folder + "/tmp/"
    if os.path.exists(tmp_folder): shutil.rmtree(tmp_folder)
    os.makedirs(tmp_folder)

    # set the clone map
    print("set the clone map")
    pcr.setclone(global_clone_map_file)

    # read ldd map
    print("define the ldd")
    # ~ ldd_map = pcr.readmap(global_ldd_inp_file)
    ldd_map     = pcr.lddrepair(pcr.lddrepair(pcr.ldd(vos.readPCRmapClone(v                = global_ldd_inp_file, \
                                                                          cloneMapFileName = global_clone_map_file, \
                                                                          tmpDir           = tmp_folder, \
                                                                          absolutePath     = None, \
                                                                          isLddMap         = True, \
                                                                          cover            = None, \
                                                                          isNomMap         = False))))

    # define the landmask
    if landmask_map_file == None:
        print("define the landmask based on the ldd input")
        # ~ landmask = pcr.defined(pcr.readmap(global_ldd_inp_file))
        landmask = pcr.defined(ldd_map)
        landmask = pcr.ifthen(landmask, landmask)
    else:
        print("define the landmask based on the input landmask_map_file")
        landmask = pcr.readmap(landmask_map_file)
        ldd_map = pcr.ifthen(landmask, pcr.cover(ldd_map, pcr.ldd(5)))
        ldd_map = pcr.lddrepair(pcr.lddrepair(pcr.ldd(ldd_map)))
        landmask = pcr.defined(ldd_map)
    landmask = pcr.ifthen(landmask, landmask)

    # save ldd files used
    # - global ldd
    cmd = "cp " + str(global_ldd_inp_file) + " ."
    print(cmd)
    os.system(cmd)
    # - ldd map that is used
    pcr.report(ldd_map, "lddmap_used.map")

    # make catchment map
    print("make catchment map")
    catchment_map = pcr.catchment(ldd_map, pcr.pit(ldd_map))

    # read global subdomain file
    print("read global subdomain file")
    global_subdomain_map = vos.readPCRmapClone(
        v=global_subdomain_file,
        cloneMapFileName=global_clone_map_file,
        tmpDir=tmp_folder,
        absolutePath=None,
        isLddMap=False,
        cover=None,
        isNomMap=True)

    # set initial subdomain
    print("assign subdomains to all catchments")
    subdomains_initial = pcr.areamajority(global_subdomain_map, catchment_map)
    subdomains_initial = pcr.ifthen(landmask, subdomains_initial)

    pcr.aguila(subdomains_initial)

    pcr.report(subdomains_initial, "global_subdomains_initial.map")

    print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial))[0])))
    print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial))[1])))

    print("Checking all subdomains, avoid too large subdomains")

    num_of_masks = int(vos.getMinMaxMean(pcr.scalar(subdomains_initial))[1])

    # clone code that will be assigned
    assigned_number = 0

    subdomains_final = pcr.ifthen(
        pcr.scalar(subdomains_initial) < -7777, pcr.nominal(0))

    for nr in range(1, num_of_masks + 1, 1):

        msg = "Processing the landmask %s" % (str(nr))
        print(msg)

        mask_selected_boolean = pcr.ifthen(subdomains_initial == nr,
                                           pcr.boolean(1.0))

        process_this_clone = False
        if pcr.cellvalue(pcr.mapmaximum(pcr.scalar(mask_selected_boolean)), 1,
                         1)[0] > 0:
            process_this_clone = True

        # ~ if nr == 1: pcr.aguila(mask_selected_boolean)

        # - initial check value
        check_ok = True

        if process_this_clone:
            xmin, ymin, xmax, ymax = boundingBox(mask_selected_boolean)
            area_in_degree2 = (xmax - xmin) * (ymax - ymin)

            # ~ print(str(area_in_degree2))

            # check whether the size of bounding box is ok
            reference_area_in_degree2 = 2500.
            if area_in_degree2 > 1.50 * reference_area_in_degree2:
                check_ok = False
            if (xmax - xmin) > 10 * (ymax - ymin): check_ok = False

        # ~ # ignore checking
        # ~ check_ok = True

        if check_ok == True and process_this_clone == True:

            msg = "Clump is not needed."
            msg = "\n\n" + str(msg) + "\n\n"
            print(msg)

            # assign the clone code
            assigned_number = assigned_number + 1

            # update global landmask for river and land
            mask_selected_nominal = pcr.ifthen(mask_selected_boolean,
                                               pcr.nominal(assigned_number))
            subdomains_final = pcr.cover(subdomains_final,
                                         mask_selected_nominal)

        if check_ok == False and process_this_clone == True:

            msg = "Clump is needed."
            msg = "\n\n" + str(msg) + "\n\n"
            print(msg)

            # make clump
            clump_ids = pcr.nominal(pcr.clump(mask_selected_boolean))

            # merge clumps that are close together
            clump_ids_window_majority = pcr.windowmajority(clump_ids, 10.0)
            clump_ids = pcr.areamajority(clump_ids_window_majority, clump_ids)
            # ~ pcr.aguila(clump_ids)

            # minimimum and maximum values
            min_clump_id = int(
                pcr.cellvalue(pcr.mapminimum(pcr.scalar(clump_ids)), 1)[0])
            max_clump_id = int(
                pcr.cellvalue(pcr.mapmaximum(pcr.scalar(clump_ids)), 1)[0])

            for clump_id in range(min_clump_id, max_clump_id + 1, 1):

                msg = "Processing the clump %s of %s from the landmask %s" % (
                    str(clump_id), str(max_clump_id), str(nr))
                msg = "\n\n" + str(msg) + "\n\n"
                print(msg)

                # identify mask based on the clump
                mask_selected_boolean_from_clump = pcr.ifthen(
                    clump_ids == pcr.nominal(clump_id), mask_selected_boolean)
                mask_selected_boolean_from_clump = pcr.ifthen(
                    mask_selected_boolean_from_clump,
                    mask_selected_boolean_from_clump)

                # check whether the clump is empty
                check_mask_selected_boolean_from_clump = pcr.ifthen(
                    mask_selected_boolean, mask_selected_boolean_from_clump)
                check_if_empty = float(
                    pcr.cellvalue(
                        pcr.mapmaximum(
                            pcr.scalar(
                                pcr.defined(
                                    check_mask_selected_boolean_from_clump))),
                        1)[0])

                if check_if_empty == 0.0:

                    msg = "Map is empty !"
                    msg = "\n\n" + str(msg) + "\n\n"
                    print(msg)

                else:

                    msg = "Map is NOT empty !"
                    msg = "\n\n" + str(msg) + "\n\n"
                    print(msg)

                    # assign the clone code
                    assigned_number = assigned_number + 1

                    # update global landmask for river and land
                    mask_selected_nominal = pcr.ifthen(
                        mask_selected_boolean_from_clump,
                        pcr.nominal(assigned_number))
                    subdomains_final = pcr.cover(subdomains_final,
                                                 mask_selected_nominal)

    # ~ # kill all aguila processes if exist
    # ~ os.system('killall aguila')

    pcr.aguila(subdomains_final)

    print("")
    print("")
    print("")

    print("The subdomain map is READY.")

    pcr.report(subdomains_final, "global_subdomains_final.map")

    num_of_masks = int(vos.getMinMaxMean(pcr.scalar(subdomains_final))[1])
    print(num_of_masks)

    print("")
    print("")
    print("")

    print("Making the clone and landmask maps for all subdomains")

    num_of_masks = int(vos.getMinMaxMean(pcr.scalar(subdomains_final))[1])

    # clone and mask folders
    clone_folder = out_folder + "/clone/"
    if os.path.exists(clone_folder): shutil.rmtree(clone_folder)
    os.makedirs(clone_folder)
    mask_folder = out_folder + "/mask/"
    if os.path.exists(mask_folder): shutil.rmtree(mask_folder)
    os.makedirs(mask_folder)

    print("")
    print("")

    for nr in range(1, num_of_masks + 1, 1):

        msg = "Processing the subdomain %s" % (str(nr))
        print(msg)

        # set the global clone
        pcr.setclone(global_clone_map_file)

        mask_selected_boolean = pcr.ifthen(subdomains_final == nr,
                                           pcr.boolean(1.0))

        mask_selected_nominal = pcr.ifthen(subdomains_final == nr,
                                           pcr.nominal(nr))
        mask_file = "mask/mask_%s.map" % (str(nr))
        pcr.report(mask_selected_nominal, mask_file)

        xmin, ymin, xmax, ymax = boundingBox(mask_selected_boolean)
        area_in_degree2 = (xmax - xmin) * (ymax - ymin)

        print(
            str(nr) + " ; " + str(area_in_degree2) + " ; " +
            str((xmax - xmin)) + " ; " + str((ymax - ymin)))

        # cellsize in arcdegree
        cellsize = cellsize_in_arcmin / 60.

        # number of rows and cols
        num_rows = int(round(ymax - ymin) / cellsize)
        num_cols = int(round(xmax - xmin) / cellsize)

        # make the clone map using mapattr
        clonemap_mask_file = "clone/clonemap_mask_%s.map" % (str(nr))
        cmd = "mapattr -s -R %s -C %s -B -P yb2t -x %s -y %s -l %s %s" % (
            str(num_rows), str(num_cols), str(xmin), str(ymax), str(cellsize),
            clonemap_mask_file)
        print(cmd)
        os.system(cmd)

        # set the local landmask for the clump
        pcr.setclone(clonemap_mask_file)
        local_mask = vos.readPCRmapClone(v = mask_file, \
                                         cloneMapFileName = clonemap_mask_file,
                                         tmpDir = tmp_folder, \
                                         absolutePath = None, isLddMap = False, cover = None, isNomMap = True)
        local_mask_boolean = pcr.defined(local_mask)
        local_mask_boolean = pcr.ifthen(local_mask_boolean, local_mask_boolean)
        pcr.report(local_mask_boolean, mask_file)

    print("")
    print("")
    print("")

    print(num_of_masks)
    except:
        pass
            
    # initiate the netcd file and object: 
    tssNetCDF = ConvertMapsToNetCDF4(cloneMapFile = cloneMapFileName, attribute = attributeDictionary)
    tssNetCDF.createNetCDF(ncFileName,varNames,varUnits)

    index = 0 # for posCnt
    
    # set clone and define land mask region
    pcr.setclone(landmaskFile)
    landmask = pcr.defined(pcr.readmap(landmaskFile))
    landmask = pcr.ifthen(landmask, landmask)
    
    # cell area (m2)
    cellArea = vos.readPCRmapClone(cellAreaFile,
                                   cloneMapFileName,tmp_directory)
    cellArea = pcr.ifthen(landmask,cellArea)
    
    for iYear in range(staYear,endYear+1):

        # time stamp
        timeStamp = datetime.datetime(int(iYear),int(1),int(1),int(0))
        fulldate = '%4i-%02i-%02i' %(int(iYear),int(1),int(1))
        print fulldate

        # index for time object in the netcdf file:
        index = index + 1

        # reading values from the input netcdf files (30min)
        abstraction_volume_30min = pcr.roundup(
                                   vos.netcdf2PCRobjClone(inputDirectory+inputFiles,\
# class map file name:
#~ class_map_file_name = "/home/sutan101/data/aqueduct_gis_layers/aqueduct_shp_from_marta/Aqueduct_States.map"
#~ class_map_file_name = "/home/sutan101/data/aqueduct_gis_layers/aqueduct_shp_from_marta/Aqueduct_GDBD.map"
#~ class_map_file_name = "/home/sutan101/data/processing_whymap/version_19september2014/major_aquifer_30min.extended.map"
#~ class_map_file_name = "/home/sutan101/data/processing_whymap/version_19september2014/major_aquifer_30min.map"
class_map_file_name = str(sys.argv[2])
class_map_default_folder = "/home/sutan101/data/aqueduct_gis_layers/aqueduct_shp_from_marta/" 
if class_map_file_name == "state": class_map_file_name = class_map_default_folder + "/Aqueduct_States.map"
if class_map_file_name == "drainage_unit": class_map_file_name = class_map_default_folder + "/Aqueduct_GDBD.map"
if class_map_file_name == "aquifer": class_map_file_name = class_map_default_folder + "/why_wgs1984_BUENO.map"
if class_map_file_name == "country": class_map_file_name = "/home/sutan101/data/country_shp_from_tianyi/World_Polys_High.map"

# reading the class map
class_map    = pcr.nominal(pcr.uniqueid(landmask))
if class_map_file_name != "pixel":
	class_map = vos.readPCRmapClone(class_map_file_name, clone_map, tmp_directory, None, False, None, True, False)
	class_map = pcr.ifthen(pcr.scalar(class_map) > 0.0, pcr.nominal(class_map)) 

# time selection
start_year = int(sys.argv[3])
end_year   = int(sys.argv[4])
 
# cell_area (unit: m2)
cell_area = pcr.readmap("/data/hydroworld/PCRGLOBWB20/input5min/routing/cellsize05min.correct.map") 
segment_cell_area = pcr.areatotal(cell_area, class_map)

# extent of aquifer/sedimentary basins:
sedimentary_basin = pcr.cover(pcr.scalar(pcr.readmap("/home/sutan101/data/sed_extent/sed_extent.map")), 0.0)
cell_area = sedimentary_basin * cell_area
#~ cell_area = pcr.ifthenelse(pcr.areatotal(cell_area, class_map) > 0.25 * segment_cell_area, cell_area, 0.0)
Exemplo n.º 17
0
out_file = inp_file + "_climatology_average.nc"
cmd = "cdo -L -f nc4 -z zip -timavg " + inp_file + " " + out_file
print("")
print(cmd)
os.system(cmd)
print("")
input_files['averageClimatologyDischargeMonthAvg'] = out_file

# set the pcraster clone, ldd, landmask, and cell area map
msg = "Setting the clone, ldd, landmask, and cell area maps" + ":"
logger.info(msg)
# - clone
clone_map_file = input_files['clone_map_05min']
pcr.setclone(clone_map_file)
# - ldd
ldd = vos.readPCRmapClone(input_files['ldd_map_05min'], clone_map_file,
                          output_files['tmp_folder'], None, True)
ldd = pcr.lddrepair(pcr.ldd(ldd))
ldd = pcr.lddrepair(ldd)
# - landmask
landmask = pcr.ifthen(pcr.defined(ldd), pcr.boolean(1.0))
# - cell area
cell_area = vos.readPCRmapClone(input_files['cell_area_05min'], clone_map_file,
                                output_files['tmp_folder'])

# set the basin map
msg = "Setting the basin map" + ":"
logger.info(msg)
basin_map = pcr.nominal(\
            vos.readPCRmapClone(input_files['basin_map_05min'],
                                input_files['clone_map_05min'],
                                output_files['tmp_folder'],
Exemplo n.º 18
0
    def __init__(self, iniItems, landmask, spinUp):
        object.__init__(self)

        self.cloneMap = iniItems.cloneMap
        self.tmpDir = iniItems.tmpDir
        self.inputDir = iniItems.globalOptions['inputDir']

        # landmask/area of interest
        self.landmask = landmask
        if iniItems.globalOptions['landmask'] != "None":
            self.landmask = vos.readPCRmapClone(\
            iniItems.globalOptions['landmask'],
            self.cloneMap,self.tmpDir,self.inputDir)

        # option to ignore snow (temperature will be set to 25 deg C if this option is activated)
        self.ignore_snow = False
        if 'ignoreSnow' in list(iniItems.meteoOptions.keys(
        )) and iniItems.meteoOptions['ignoreSnow'] == "True":
            self.ignore_snow = True

        self.preFileNC = iniItems.meteoOptions[
            'precipitationNC']  # starting from 19 Feb 2014, we only support netcdf input files
        self.tmpFileNC = iniItems.meteoOptions['temperatureNC']

        self.refETPotMethod = iniItems.meteoOptions['referenceETPotMethod']
        if self.refETPotMethod == 'Hamon':            self.latitudes = \
            pcr.ycoordinate(self.cloneMap) # needed to calculate 'referenceETPot'
        if self.refETPotMethod == 'Input':            self.etpFileNC = \
iniItems.meteoOptions['refETPotFileNC']

        #-----------------------------------------------------------------------
        # NOTE: RvB 13/07/2016 Added correction constant and factor and variable name
        # to allow for easier use of netCDF climate inpute files
        # EHS 20/08/2016 modified for more flexibilities.
        # - meteo conversion factors
        self.preConst = 0.0
        self.preFactor = 1.0
        self.tmpConst = 0.0
        self.tmpFactor = 1.0
        self.refETPotConst = 0.0
        self.refETPotFactor = 1.0
        self.read_meteo_conversion_factors(iniItems.meteoOptions)
        # - variable names
        self.preVarName = 'precipitation'
        self.tmpVarName = 'temperature'
        self.refETPotVarName = 'evapotranspiration'
        self.read_meteo_variable_names(iniItems.meteoOptions)

        # daily time step
        self.usingDailyTimeStepForcingData = False
        if iniItems.timeStep == 1.0 and iniItems.timeStepUnit == "day":
            self.usingDailyTimeStepForcingData = True

        # forcing downscaling options:
        self.forcingDownscalingOptions(iniItems)

        # option to use netcdf files that are defined per year (one file for each year)
        self.precipitation_set_per_year = iniItems.meteoOptions[
            'precipitation_set_per_year'] == "True"
        self.temperature_set_per_year = iniItems.meteoOptions[
            'temperature_set_per_year'] == "True"
        self.refETPotFileNC_set_per_year = iniItems.meteoOptions[
            'refETPotFileNC_set_per_year'] == "True"

        # make the iniItems available for the other modules:
        self.iniItems = iniItems

        self.report = True
        try:
            self.outDailyTotNC = iniItems.meteoOptions['outDailyTotNC'].split(
                ",")
            self.outMonthTotNC = iniItems.meteoOptions['outMonthTotNC'].split(
                ",")
            self.outMonthAvgNC = iniItems.meteoOptions['outMonthAvgNC'].split(
                ",")
            self.outMonthEndNC = iniItems.meteoOptions['outMonthEndNC'].split(
                ",")
            self.outAnnuaTotNC = iniItems.meteoOptions['outAnnuaTotNC'].split(
                ",")
            self.outAnnuaAvgNC = iniItems.meteoOptions['outAnnuaAvgNC'].split(
                ",")
            self.outAnnuaEndNC = iniItems.meteoOptions['outAnnuaEndNC'].split(
                ",")
        except:
            self.report = False
        if self.report == True:
            # daily output in netCDF files:
            self.outNCDir = iniItems.outNCDir
            self.netcdfObj = PCR2netCDF(iniItems)
            #
            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")
    def dynamic(self):
        
        # re-calculate current model time using current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # for variables other than temperature and maximum temperature, just read them directly
        if self.output['variable_name'] != "temperature" and self.output['variable_name'] != "maximum_temperature":
            
            pcraster_map_file_name = pcr.framework.frameworkBase.generateNameT(self.pcraster_file_name,\
                                                                               self.modelTime.timeStepPCR) 
            pcr_map_values = vos.readPCRmapClone(v = pcraster_map_file_name,\
                                                 cloneMapFileName = self.cloneMapFileName,\
                                                 tmpDir = self.tmpDir,\
                                                 absolutePath = None, isLddMap = False,\
                                                 cover = None,\
                                                 isNomMap = False,\
                                                 inputEPSG = self.inputEPSG,\
                                                 outputEPSG = self.outputEPSG,\
                                                 method = self.resample_method)

        # for temperature and maximum temperature, we have to make sure that maximum temperature is higher than minimum temperature
        if self.output['variable_name'] == "temperature" or self.output['variable_name'] == "maximum_temperature":
            
            min_map_file_name = pcr.framework.frameworkBase.generateNameT(self.pcraster_files['directory']+"/tn", self.modelTime.timeStepPCR)
            max_map_file_name = pcr.framework.frameworkBase.generateNameT(self.pcraster_files['directory']+"/tx", self.modelTime.timeStepPCR)
            min_map_values = vos.readPCRmapClone(v = min_map_file_name,\
                                                 cloneMapFileName = self.cloneMapFileName,\
                                                 tmpDir = self.tmpDir,\
                                                 absolutePath = None, isLddMap = False,\
                                                 cover = None,\
                                                 isNomMap = False,\
                                                 inputEPSG = self.inputEPSG,\
                                                 outputEPSG = self.outputEPSG,\
                                                 method = self.resample_method)
            max_map_values = vos.readPCRmapClone(v = max_map_file_name,\
                                                 cloneMapFileName = self.cloneMapFileName,\
                                                 tmpDir = self.tmpDir,\
                                                 absolutePath = None, isLddMap = False,\
                                                 cover = None,\
                                                 isNomMap = False,\
                                                 inputEPSG = self.inputEPSG,\
                                                 outputEPSG = self.outputEPSG,\
                                                 method = self.resample_method)
            
            # make sure that maximum values are higher than minimum values
            max_map_values = pcr.max(min_map_values, max_map_values)
            
            if self.output['variable_name'] == "temperature": pcr_map_values = 0.50*(min_map_values + \
                                                                                     max_map_values)
            if self.output['variable_name'] == "maximum_temperature": pcr_map_values = pcr.max(min_map_values, max_map_values)
        
        # for precipitation, converting the unit from mm.day-1 to m.day-1
        if self.output['variable_name'] == "precipitation": pcr_map_values *= 0.001
        
        # reporting
        timeStamp = datetime.datetime(self.modelTime.year,\
                                      self.modelTime.month,\
                                      self.modelTime.day,0)
        self.netcdf_report.data2NetCDF(self.output['file_name'],\
                                       self.output['variable_name'],\
                                       pcr.pcr2numpy(pcr_map_values,vos.MV),\
                                       timeStamp)
    except:
        pass
            
    # initiate the netcd file and object: 
    tssNetCDF = ConvertMapsToNetCDF4(cloneMapFile = cloneMapFileName, attribute = attributeDictionary, cellSizeInArcMinutes = cellSizeInArcMinutes)
    tssNetCDF.createNetCDF(ncFileName,varNames,varUnits)

    index = 0 # for posCnt
    
    # set clone and define land mask region
    pcr.setclone(landmask05minFile)
    landmask = pcr.defined(pcr.readmap(landmask05minFile))
    landmask = pcr.ifthen(landmask, landmask)
    
    # cell area at 5 arc min resolution
    cellArea = vos.readPCRmapClone(cellArea05minFile,
                                   cloneMapFileName,tmp_directory)
    cellArea = pcr.ifthen(landmask,cellArea)
    
    # ids for every 30 arc min grid:
    uniqueIDs30min = vos.readPCRmapClone(uniqueIDs30minFile,
                                         cloneMapFileName,tmp_directory) 
    uniqueIDs30min = pcr.nominal(pcr.ifthen(landmask, uniqueIDs30min))
    
    for iYear in range(staYear,endYear+1):
        for iMonth in range(1,12+1):
            timeStamp = datetime.datetime(int(iYear),int(iMonth),int(1),int(0))

            fulldate = '%4i-%02i-%02i' %(int(iYear),int(iMonth),int(1))
            print fulldate

            monthRange = float(calendar.monthrange(int(iYear), int(iMonth))[1])
Exemplo n.º 21
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:
            minRecessionCoeff = 1.0e-4                                       # This is the minimum value used in Van Beek et al. (2011). 
        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)       
        self.specificYield  = pcr.max(0.010,self.specificYield)         # TODO: TO BE CHECKED: The resample process of 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)
            cellArea = pcr.ifthen(self.landmask, cellArea)              # TODO: integrate this one with the one coming from the routing module

            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)
Exemplo n.º 22
0
    attributeDictionary['comment'    ]  = "None"
    # additional attribute defined in PCR-GLOBWB 
    attributeDictionary['description'] = "prepared by Edwin H. Sutanudjaja"

    # initiate the netcd object: 
    tssNetCDF = MakingNetCDF(cloneMapFile = cloneMapFileName, \
                             attribute = attributeDictionary, \
                             cellSizeInArcMinutes = cellSizeInArcMinutes)
    # making netcdf files:
    for var in variable_names:
        tssNetCDF.createNetCDF(output[var]['file_name'], var, output[var]['unit'])

    # class (country) ids
    uniqueIDsFile = "/projects/0/dfguu/users/edwin/data/country_shp_from_tianyi/World_Polys_High.map"
    uniqueIDs = pcr.nominal(\
                vos.readPCRmapClone(uniqueIDsFile, cloneMapFileName, tmp_directory, 
                                    None, False, None, True))
    uniqueIDs = pcr.readmap(uniqueIDsFile)
    uniqueIDs = pcr.ifthen(pcr.scalar(uniqueIDs) >= 0.0, uniqueIDs)
    
    # landmask                               
    landmask = pcr.defined(pcr.readmap(landmask05minFile))
    landmask = pcr.ifthen(landmask, landmask)
    # - extending landmask with uniqueIDs
    landmask = pcr.cover(landmask, pcr.defined(uniqueIDs))
    
    # extending class (country) ids
    max_step = 5
    for i in range(1, max_step+1, 1):
        cmd = "Extending class: step "+str(i)+" from " + str(max_step)
        print(cmd)
        uniqueIDs = pcr.cover(uniqueIDs, pcr.windowmajority(uniqueIDs, 0.5))
Exemplo n.º 23
0
    def readSoilMapOfFAO(self, iniItems, optionDict = None):

        # a dictionary/section of options that will be used
        if optionDict == None: optionDict = iniItems._sections["landSurfaceOptions"] #iniItems.landSurfaceOptions
        
        # soil variable names given either in the ini or netCDF file:
        soilParameters = ['airEntryValue1','airEntryValue2',       
                          'poreSizeBeta1','poreSizeBeta2',        
                          'resVolWC1','resVolWC2',            
                          'satVolWC1','satVolWC2',
                          'KSat1','KSat2',
                          'percolationImp']
        if optionDict['soilPropertiesNC'] == str(None):
            for var in soilParameters:
                input = optionDict[str(var)]
                vars(self)[var] = \
                               vos.readPCRmapClone(input,self.cloneMap,\
                                             self.tmpDir,self.inputDir)
                vars(self)[var] = pcr.scalar(vars(self)[var])

                if input == "percolationImp": vars(self)[var] = pcr.cover(vars(self)[var], 0.0)
                
                # extrapolation 
                # - TODO: Make a general extrapolation option as a function in the virtualOS.py 
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 0.75))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))
                vars(self)[var] = pcr.cover(vars(self)[var], 0.0)

        else:
            soilPropertiesNC = vos.getFullPath(\
                               optionDict['soilPropertiesNC'],
                                                self.inputDir)
            for var in soilParameters:
                vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(\
                                    soilPropertiesNC,var, \
                                    cloneMapFileName = self.cloneMap)

                if var == "percolationImp": vars(self)[var] = pcr.cover(vars(self)[var], 0.0)

                # extrapolation 
                # - TODO: Make a general extrapolation option as a function in the virtualOS.py 
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 0.75))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))
                vars(self)[var] = pcr.cover(vars(self)[var],
                                  pcr.windowaverage(vars(self)[var], 1.00))

                vars(self)[var] = pcr.cover(vars(self)[var], 0.01)
            
        # make sure that resVolWC1 <= satVolWC1
        self.resVolWC1 = pcr.min(self.resVolWC1, self.satVolWC1)
        self.resVolWC2 = pcr.min(self.resVolWC2, self.satVolWC2)
        
        if self.numberOfLayers == 2:
            self.satVolMoistContUpp = self.satVolWC1                         # saturated volumetric moisture content (m3.m-3)
            self.satVolMoistContLow = self.satVolWC2
            self.resVolMoistContUpp = self.resVolWC1                         # residual volumetric moisture content (m3.m-3)
            self.resVolMoistContLow = self.resVolWC2
            self.airEntryValueUpp   = self.airEntryValue1                    # air entry value (m) according to soil water retention curve of Clapp & Hornberger (1978)
            self.airEntryValueLow   = self.airEntryValue2
            self.poreSizeBetaUpp    = self.poreSizeBeta1                     # pore size distribution parameter according to Clapp & Hornberger (1978) 
            self.poreSizeBetaLow    = self.poreSizeBeta2
            self.kSatUpp            = self.KSat1                             # saturated hydraulic conductivity (m.day-1) 
            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

        self.percolationImp = pcr.cover(self.percolationImp, 0.0)            # fractional area where percolation to groundwater store is impeded (dimensionless)

        # soil thickness and storage variable names 
        # as given either in the ini or netCDF file:
        soilStorages = ['firstStorDepth',      'secondStorDepth',      
                        'soilWaterStorageCap1','soilWaterStorageCap2'] 
        if optionDict['soilPropertiesNC'] == str(None):
            for var in soilStorages:
                input = optionDict[str(var)]
                temp = str(var)+'Inp'
                vars(self)[temp] = vos.readPCRmapClone(input,\
                                            self.cloneMap,
                                            self.tmpDir,self.inputDir)

                # extrapolation 
                # - TODO: Make a general extrapolation option as a function in the virtualOS.py 
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 0.75))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                vars(self)[temp] = pcr.cover(vars(self)[temp], 0.0)

        else:
            soilPropertiesNC = vos.getFullPath(\
                               optionDict['soilPropertiesNC'],
                                                self.inputDir)
            for var in soilStorages:
                temp = str(var)+'Inp'
                vars(self)[temp] = vos.netcdf2PCRobjCloneWithoutTime(\
                                     soilPropertiesNC,var, \
                                     cloneMapFileName = self.cloneMap)
                # extrapolation 
                # - TODO: Make a general extrapolation option as a function in the virtualOS.py 
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 0.75))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                vars(self)[temp] = pcr.cover(vars(self)[temp],
                                   pcr.windowaverage(vars(self)[temp], 1.05))
                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                                    # This is called as WMAX in the original pcrcalc script. 
        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
#~ end_year = 2099
# - based on the system arguments:
str_year = int(sys.argv[3])
end_year = int(sys.argv[4])


# set the pcraster clone, ldd and landmask maps 
msg = "Setting the clone, ldd and landmask maps" + ":"
logger.info(msg)
# - clone 
clone_map_file = input_files['clone_map_05min']
pcr.setclone(clone_map_file)
# - ldd
ldd = vos.readPCRmapClone(input_files['ldd_map_05min'],
                          clone_map_file,
                          output_files['tmp_folder'],
                          None,
                          True)
ldd = pcr.lddrepair(pcr.ldd(ldd))
ldd = pcr.lddrepair(ldd)
# - landmask
landmask  = pcr.ifthen(pcr.defined(ldd), pcr.boolean(1.0))

# set the cell areas for 5 arc-min and half arc-degree cells 
msg = "Setting the cell areas for 5 arc-min and half arc-degree cells" + ":"
logger.info(msg)
# - 5 arc-min
cell_area = vos.readPCRmapClone(input_files['cell_area_05min'],
                          clone_map_file,
                          output_files['tmp_folder'])
cell_area = pcr.ifthen(landmask, cell_area)
Exemplo n.º 25
0
    def modflow_simulation(self,\
                           simulation_type,\
                           initial_head,\
                           currTimeStep = None,\
                           PERLEN = 1.0, 
                           NSTP   = 1, \
                           HCLOSE = 1.0,\
                           RCLOSE = 10.* 400.*400.,\
                           MXITER = 50,\
                           ITERI = 30,\
                           NPCOND = 1,\
                           RELAX = 1.00,\
                           NBPOL = 2,\
                           DAMP = 1,\
                           ITMUNI = 4, LENUNI = 2, TSMULT = 1.0):
        
        # initiate pcraster modflow object if modflow is not called yet:
        if self.modflow_has_been_called == False or self.modflow_converged == False:
            self.initiate_modflow()
            self.modflow_has_been_called = True

        if simulation_type == "transient":
            logger.info("Preparing MODFLOW input for a transient simulation.")
            SSTR = 0
        if simulation_type == "steady-state":
            logger.info("Preparing MODFLOW input for a steady-state simulation.")
            SSTR = 1

        # waterBody class to define the extent of lakes and reservoirs
        #
        if simulation_type == "steady-state":
            self.WaterBodies = waterBodies.WaterBodies(self.iniItems,\
                                                       self.landmask,\
                                                       self.onlyNaturalWaterBodies)
            self.WaterBodies.getParameterFiles(date_given = self.iniItems.globalOptions['startTime'],\
                                               cellArea = self.cellAreaMap, \
                                               ldd = self.lddMap)        
        #
        if simulation_type == "transient":
            if currTimeStep.timeStepPCR == 1:
               self.WaterBodies = waterBodies.WaterBodies(self.iniItems,\
                                                          self.landmask,\
                                                          self.onlyNaturalWaterBodies)
            if currTimeStep.timeStepPCR == 1 or currTimeStep.doy == 1:
               self.WaterBodies.getParameterFiles(date_given = str(currTimeStep.fulldate),\
                                                  cellArea = self.cellAreaMap, \
                                                  ldd = self.lddMap)        

        print "here"

        # using dem_average as the initial groundwater head value 
        self.pcr_modflow.setInitialHead(initial_head, 1)
        
        # set parameter values for the DIS package and PCG solver
        self.pcr_modflow.setDISParameter(ITMUNI, LENUNI, PERLEN, NSTP, TSMULT, SSTR)
        self.pcr_modflow.setPCG(MXITER, ITERI, NPCOND, HCLOSE, RCLOSE, RELAX, NBPOL, DAMP)
        #
        # Some notes about the values  
        #
        # ITMUNI = 4     # indicates the time unit (0: undefined, 1: seconds, 2: minutes, 3: hours, 4: days, 5: years)
        # LENUNI = 2     # indicates the length unit (0: undefined, 1: feet, 2: meters, 3: centimeters)
        # PERLEN = 1.0   # duration of a stress period
        # NSTP   = 1     # number of time steps in a stress period
        # TSMULT = 1.0   # multiplier for the length of the successive iterations
        # SSTR   = 1     # 0 - transient, 1 - steady state
        #
        # MXITER = 50                 # maximum number of outer iterations           # Deltares use 50
        # ITERI  = 30                 # number of inner iterations                   # Deltares use 30
        # NPCOND = 1                  # 1 - Modified Incomplete Cholesky, 2 - Polynomial matrix conditioning method;
        # HCLOSE = 0.01               # HCLOSE (unit: m) 
        # RCLOSE = 10.* 400.*400.     # RCLOSE (unit: m3)
        # RELAX  = 1.00               # relaxation parameter used with NPCOND = 1
        # NBPOL  = 2                  # indicates whether the estimate of the upper bound on the maximum eigenvalue is 2.0 (but we don ot use it, since NPCOND = 1) 
        # DAMP   = 1                  # no damping (DAMP introduced in MODFLOW 2000)
        
        # read input files (for the steady-state condition, we use pcraster maps):
        if simulation_type == "steady-state":
            # - discharge (m3/s) from PCR-GLOBWB
            discharge = vos.readPCRmapClone(self.iniItems.modflowSteadyStateInputOptions['avgDischargeInputMap'],\
                                                self.cloneMap, self.tmpDir, self.inputDir)
            # - recharge/capillary rise (unit: m/day) from PCR-GLOBWB 
            gwRecharge = vos.readPCRmapClone(self.iniItems.modflowSteadyStateInputOptions['avgGroundwaterRechargeInputMap'],\
                                                self.cloneMap, self.tmpDir, self.inputDir)
            if self.ignoreCapRise: gwRecharge = pcr.max(0.0, gwRecharge) 
            gwAbstraction = pcr.spatial(pcr.scalar(0.0))

        # read input files (for the transient, input files are given in netcdf files):
        if simulation_type == "transient":
            # - discharge (m3/s) from PCR-GLOBWB
            discharge = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['dischargeInputNC'],
                                               "discharge",str(currTimeStep.fulldate),None,self.cloneMap)
            # - recharge/capillary rise (unit: m/day) from PCR-GLOBWB 
            gwRecharge = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['groundwaterRechargeInputNC'],\
                                               "groundwater_recharge",str(currTimeStep.fulldate),None,self.cloneMap)
            if self.ignoreCapRise: gwRecharge = pcr.max(0.0, gwRecharge) 
            # - groundwater abstraction (unit: m/day) from PCR-GLOBWB 
            gwAbstraction = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['groundwaterAbstractionInputNC'],\
                                               "total_groundwater_abstraction",str(currTimeStep.fulldate),None,self.cloneMap)

        # set recharge, river, well and drain packages
        self.set_river_package(discharge, currTimeStep)
        self.set_recharge_package(gwRecharge)
        self.set_well_package(gwAbstraction)
        self.set_drain_package()
        
        # execute MODFLOW 
        logger.info("Executing MODFLOW.")
        self.pcr_modflow.run()
        
        logger.info("Check if the model whether a run has converged or not")
        self.modflow_converged = self.check_modflow_convergence()
        if self.modflow_converged == False:

            msg = "MODFLOW FAILED TO CONVERGE with HCLOSE = "+str(HCLOSE)+" and RCLOSE = "+str(RCLOSE)
            logger.info(msg)
            
            # iteration index for the RCLOSE
            self.iteration_RCLOSE += 1 
            # reset if the index has reached the length of available criteria
            if self.iteration_RCLOSE > (len(self.criteria_RCLOSE)-1): self.iteration_RCLOSE = 0     

            # iteration index for the HCLOSE
            if self.iteration_RCLOSE == 0: self.iteration_HCLOSE += 1 
            
            # we have to reset modflow as we want to change the PCG setup
            self.modflow_has_been_called = False
            
            # for the steady state simulation, we still save the calculated head as the initial estimate for the next iteration
            if simulation_type == "steady-state": self.groundwaterHead = self.pcr_modflow.getHeads(1)
            # NOTE: We cannot implement this principle for transient simulation 
            
        else:

            msg = "HURRAY!!! MODFLOW CONVERGED with HCLOSE = "+str(HCLOSE)+" and RCLOSE = "+str(RCLOSE)
            logger.info(msg)

            # reset the iteration because modflow has converged
            self.iteration_HCLOSE = 0
            self.iteration_RCLOSE = 0
            
            self.modflow_has_been_called = True
            
            # obtaining the results from modflow simulation
            self.groundwaterHead = None
            self.groundwaterHead = self.pcr_modflow.getHeads(1)  
            
            # calculate groundwater depth only in the landmask region
            self.groundwaterDepth = pcr.ifthen(self.landmask, self.dem_average - self.groundwaterHead)
Exemplo n.º 26
0
    def __init__(self, iniItems, landmask):
        object.__init__(self)
        
        # cloneMap, temporary directory for the resample process, temporary directory for the modflow process, absolute path for input directory, landmask
        self.cloneMap        = iniItems.cloneMap
        self.tmpDir          = iniItems.tmpDir
        self.tmp_modflow_dir = iniItems.tmp_modflow_dir
        self.inputDir        = iniItems.globalOptions['inputDir']
        self.landmask        = landmask
        
        # configuration from the ini file
        self.iniItems = iniItems
                
        # topography properties: read several variables from the netcdf file
        for var in ['dem_minimum','dem_maximum','dem_average','dem_standard_deviation',\
                    'slopeLength','orographyBeta','tanslope',\
                    'dzRel0000','dzRel0001','dzRel0005',\
                    'dzRel0010','dzRel0020','dzRel0030','dzRel0040','dzRel0050',\
                    'dzRel0060','dzRel0070','dzRel0080','dzRel0090','dzRel0100']:
            vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['topographyNC'], \
                                                                var, self.cloneMap)
            vars(self)[var] = pcr.cover(vars(self)[var], 0.0)

        # channel properties: read several variables from the netcdf file
        for var in ['lddMap','cellAreaMap','gradient','bankfull_width',
                    'bankfull_depth','dem_floodplain','dem_riverbed']:
            vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['channelNC'], \
                                                                var, self.cloneMap)
            vars(self)[var] = pcr.cover(vars(self)[var], 0.0)
        
        # minimum channel width
        minimum_channel_width = 0.5                                               # TODO: Define this one in the configuration file
        self.bankfull_width = pcr.max(minimum_channel_width, self.bankfull_width)
        
        #~ # cell fraction if channel water reaching the flood plan               # NOT USED YET 
        #~ self.flood_plain_fraction = self.return_innundation_fraction(pcr.max(0.0, self.dem_floodplain - self.dem_minimum))
        
        # coefficient of Manning
        self.manningsN = vos.readPCRmapClone(self.iniItems.modflowParameterOptions['manningsN'],\
                                             self.cloneMap,self.tmpDir,self.inputDir)
        
        # minimum channel gradient
        minGradient   = 0.00005                                                   # TODO: Define this one in the configuration file
        self.gradient = pcr.max(minGradient, pcr.cover(self.gradient, minGradient))

        # correcting lddMap
        self.lddMap = pcr.ifthen(pcr.scalar(self.lddMap) > 0.0, self.lddMap)
        self.lddMap = pcr.lddrepair(pcr.ldd(self.lddMap))
        
        # channelLength = approximation of channel length (unit: m)  # This is approximated by cell diagonal. 
        cellSizeInArcMin      = np.round(pcr.clone().cellSize()*60.)               # FIXME: This one will not work if you use the resolution: 0.5, 1.5, 2.5 arc-min
        verticalSizeInMeter   = cellSizeInArcMin*1852.                            
        horizontalSizeInMeter = self.cellAreaMap/verticalSizeInMeter
        self.channelLength    = ((horizontalSizeInMeter)**(2)+\
                                 (verticalSizeInMeter)**(2))**(0.5)
        
        # option for lakes and reservoir
        self.onlyNaturalWaterBodies = False
        if self.iniItems.modflowParameterOptions['onlyNaturalWaterBodies'] == "True": self.onlyNaturalWaterBodies = True

        # groundwater linear recession coefficient (day-1) ; the linear reservoir concept is still being used to represent fast response flow  
        #                                                                                                                  particularly from karstic aquifer in mountainous regions                    
        self.recessionCoeff = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['groundwaterPropertiesNC'],\
                                                                 'recessionCoeff', self.cloneMap)
        self.recessionCoeff = pcr.cover(self.recessionCoeff,0.00)       
        self.recessionCoeff = pcr.min(1.0000,self.recessionCoeff)       
        #
        if 'minRecessionCoeff' in iniItems.modflowParameterOptions.keys():
            minRecessionCoeff = float(iniItems.modflowParameterOptions['minRecessionCoeff'])
        else:
            minRecessionCoeff = 1.0e-4                                       # This is the minimum value used in Van Beek et al. (2011). 
        self.recessionCoeff = pcr.max(minRecessionCoeff,self.recessionCoeff)      
        
        # aquifer saturated conductivity (m/day)
        self.kSatAquifer = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['groundwaterPropertiesNC'],\
                                                             'kSatAquifer', self.cloneMap)
        self.kSatAquifer = pcr.cover(self.kSatAquifer,pcr.mapmaximum(self.kSatAquifer))       
        self.kSatAquifer = pcr.max(0.001,self.kSatAquifer)
        # TODO: Define the minimum value as part of the configuration file
        
        # aquifer specific yield (dimensionless)
        self.specificYield = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['groundwaterPropertiesNC'],\
                                                               'specificYield', self.cloneMap)
        self.specificYield = pcr.cover(self.specificYield,pcr.mapmaximum(self.specificYield))       
        self.specificYield = pcr.max(0.010,self.specificYield)         # TODO: TO BE CHECKED: The resample process of specificYield     
        self.specificYield = pcr.min(1.000,self.specificYield)       
        # TODO: Define the minimum value as part of the configuration file

        # estimate of thickness (unit: m) of accesible groundwater 
        totalGroundwaterThickness = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['estimateOfTotalGroundwaterThicknessNC'],\
                                    'thickness', self.cloneMap)
        # extrapolation 
        totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,\
                                    pcr.windowaverage(totalGroundwaterThickness, 1.0))
        totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,\
                                    pcr.windowaverage(totalGroundwaterThickness, 1.5))
        totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, 0.0)
        #
        # set minimum thickness
        minimumThickness = pcr.scalar(float(\
                           self.iniItems.modflowParameterOptions['minimumTotalGroundwaterThickness']))
        totalGroundwaterThickness = pcr.max(minimumThickness, totalGroundwaterThickness)
        #
        # set maximum thickness: 250 m.   # TODO: Define this one as part of the ini file
        maximumThickness = 250.
        self.totalGroundwaterThickness = pcr.min(maximumThickness, totalGroundwaterThickness)
        # TODO: Define the maximum value as part of the configuration file

        # surface water bed thickness  (unit: m)
        bed_thickness  = 0.1              # TODO: Define this as part of the configuration file
        # surface water bed resistance (unit: day)
        bed_resistance = bed_thickness / (self.kSatAquifer) 
        minimum_bed_resistance = 1.0      # TODO: Define this as part of the configuration file
        self.bed_resistance = pcr.max(minimum_bed_resistance,\
                                              bed_resistance,)
        
        # option to ignore capillary rise
        self.ignoreCapRise = True
        if self.iniItems.modflowParameterOptions['ignoreCapRise'] == "False": self.ignoreCapRise = False
        
        # a variable to indicate if the modflow has been called or not
        self.modflow_has_been_called = False
        
        # list of the convergence criteria for HCLOSE (unit: m)
        # - Deltares default's value is 0.001 m                         # check this value with Jarno
        self.criteria_HCLOSE = [0.001, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]  
        self.criteria_HCLOSE = sorted(self.criteria_HCLOSE)
        
        # list of the convergence criteria for RCLOSE (unit: m3)
        # - Deltares default's value for their 25 and 250 m resolution models is 10 m3  # check this value with Jarno
        cell_area_assumption = verticalSizeInMeter * float(pcr.cellvalue(pcr.mapmaximum(horizontalSizeInMeter),1)[0])
        self.criteria_RCLOSE = [10., 10.* cell_area_assumption/(250.*250.), 10.* cell_area_assumption/(25.*25.)]
        self.criteria_RCLOSE = sorted(self.criteria_RCLOSE)

        # initiate the index for HCLOSE and RCLOSE
        self.iteration_HCLOSE = 0
        self.iteration_RCLOSE = 0
        
        # initiate old style reporting                                  # TODO: remove this!
        self.initiate_old_style_groundwater_reporting(iniItems)
Exemplo n.º 27
0
    def __init__(self,
                 iniItems,
                 landmask,
                 onlyNaturalWaterBodies=False,
                 lddMap=None):
        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

        self.iniItems = iniItems

        # local drainage direction:
        if lddMap is None:
            self.lddMap = vos.readPCRmapClone(
                iniItems.routingOptions['lddMap'], self.cloneMap, self.tmpDir,
                self.inputDir, True)
            self.lddMap = pcr.lddrepair(pcr.ldd(self.lddMap))
            self.lddMap = pcr.lddrepair(self.lddMap)
        else:
            self.lddMap = lddMap

        # the following is needed for a modflowOfflineCoupling run
        if 'modflowOfflineCoupling' in list(iniItems.globalOptions.keys(
        )) and iniItems.globalOptions[
                'modflowOfflineCoupling'] == "True" and 'routingOptions' not in iniItems.allSections:
            logger.info(
                "The 'routingOptions' are not defined in the configuration ini file. We will adopt them from the 'modflowParameterOptions'."
            )
            iniItems.routingOptions = iniItems.modflowParameterOptions

        # option to activate water balance check
        self.debugWaterBalance = True
        if 'debugWaterBalance' in list(iniItems.routingOptions.keys(
        )) and iniItems.routingOptions['debugWaterBalance'] == "False":
            self.debugWaterBalance = False

        # option to perform a run with only natural lakes (without reservoirs)
        self.onlyNaturalWaterBodies = onlyNaturalWaterBodies
        if "onlyNaturalWaterBodies" in list(iniItems.routingOptions.keys(
        )) and iniItems.routingOptions['onlyNaturalWaterBodies'] == "True":
            logger.info(
                "Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes."
            )
            self.onlyNaturalWaterBodies = True
            self.dateForNaturalCondition = "1900-01-01"  # The run for a natural condition should access only this date.

        # 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
        # - default values
        self.minResvrFrac = 0.10
        self.maxResvrFrac = 0.75
        # - from the ini file
        if "minResvrFrac" in list(iniItems.routingOptions.keys()):
            minResvrFrac = iniItems.routingOptions['minResvrFrac']
            self.minResvrFrac = vos.readPCRmapClone(minResvrFrac,
                                                    self.cloneMap, self.tmpDir,
                                                    self.inputDir)
        if "maxResvrFrac" in list(iniItems.routingOptions.keys()):
            maxResvrFrac = iniItems.routingOptions['maxResvrFrac']
            self.maxResvrFrac = vos.readPCRmapClone(maxResvrFrac,
                                                    self.cloneMap, self.tmpDir,
                                                    self.inputDir)
Exemplo n.º 28
0
    def getParameterFiles(self,currTimeStep,cellArea,ldd,\
                               initial_condition_dictionary = None,\
                               currTimeStepInDateTimeFormat = False):

        # 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
        if currTimeStepInDateTimeFormat:
            date_used = currTimeStep
            year_used = currTimeStep.year
        else:
            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))

        # 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           # This may give more than two outlets, particularly if there are more than one cells that have largest upstream areas
        # - make sure that there is only one outlet for each water body
        self.waterBodyOut = pcr.ifthen(\
                            pcr.areaorder(pcr.scalar(self.waterBodyOut), \
                            self.waterBodyOut) == 1., self.waterBodyOut)
        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)
        self.waterBodyCap = pcr.cover(
            self.resMaxCap, 0.0)  # Note: Most of lakes have capacities > 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(
                "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.cover(pcr.scalar(test), 1.0) - pcr.scalar(1.0))
        threshold = 1e-3
        if abs(a) > threshold or abs(b) > threshold:
            logger.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 initial_condition_dictionary != None and 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
        # PS: THIS IS NOT NEEDED FOR OFFLINE MODFLOW RUN!
        #
        try:
            self.waterBodyStorage = pcr.cover(self.waterBodyStorage, 0.0)
            self.avgInflow = pcr.cover(self.avgInflow, 0.0)
            self.avgOutflow = pcr.cover(self.avgOutflow, 0.0)
            self.waterBodyStorage = pcr.ifthen(self.landmask,
                                               self.waterBodyStorage)
            self.avgInflow = pcr.ifthen(self.landmask, self.avgInflow)
            self.avgOutflow = pcr.ifthen(self.landmask, self.avgOutflow)
        except:
            # PS: FOR OFFLINE MODFLOW RUN!
            pass
        # TODO: Remove try and except

        # 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)
Exemplo n.º 29
0
    def readSoil(self, iniItems, optionDict = None):

        # a dictionary/section of options that will be used
        if optionDict == None: optionDict = iniItems._sections["landSurfaceOptions"] #iniItems.landSurfaceOptions

        # 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.matricSuction50 = pcr.scalar(3.33)       # 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 configsection(iniItems,"landSurfaceOptions"):
                input = configget(iniItems,"landSurfaceOptions",str(var),"None")
                vars(self)[var] = vos.readPCRmapClone(input,self.cloneMap,\
                                                            self.tmpDir,self.inputDir)
        
        # read soil parameter based on the FAO soil map:
        self.readSoilMapOfFAO(iniItems, optionDict)                                 
       
        # 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 = self.poreSizeBetaUpp*2.0 + \
                                      self.clappAddCoeff                       # Campbell's (1974) coefficient ; Rens's line: BCB = 2*BCH + BCH_ADD
            self.campbellBetaLow = self.poreSizeBetaLow*2.0 + \
                                      self.clappAddCoeff                

            self.effSatAtFieldCapUpp = \
                     (self.matricSuctionFC / self.airEntryValueUpp)**\
                                        (-1.0/ self.poreSizeBetaUpp )          # saturation degree at field capacity       : THEFF_FC = (PSI_FC/PSI_A)**(-1/BCH)
            self.effSatAtFieldCapUpp = pcr.cover(self.effSatAtFieldCapUpp, 1.0)
            
            self.effSatAtFieldCapLow = \
                     (self.matricSuctionFC / self.airEntryValueLow)**\
                                        (-1.0/ self.poreSizeBetaLow )
            self.effSatAtFieldCapLow = pcr.cover(self.effSatAtFieldCapLow, 1.0)

            self.kUnsatAtFieldCapUpp = pcr.max(0., \
             (self.effSatAtFieldCapUpp ** self.campbellBetaUpp) * self.kSatUpp)  # unsaturated conductivity at field capacity: KTHEFF_FC = max(0,THEFF_FC[TYPE]**BCB*KS1)
            self.kUnsatAtFieldCapLow = pcr.max(0., \
             (self.effSatAtFieldCapLow ** self.campbellBetaLow) * self.kSatLow)
        #
        if self.numberOfLayers == 3:

            self.campbellBetaUpp000005 = self.poreSizeBetaUpp000005*2.0 + \
                                            self.clappAddCoeff
            self.campbellBetaUpp005030 = self.poreSizeBetaUpp005030*2.0 + \
                                            self.clappAddCoeff                
            self.campbellBetaLow030150 = self.poreSizeBetaLow030150*2.0 + \
                                            self.clappAddCoeff                

            self.effSatAtFieldCapUpp000005 = \
                     (self.matricSuctionFC / self.airEntryValueUpp000005)**\
                                        (-1.0/ self.poreSizeBetaUpp000005)
            self.effSatAtFieldCapUpp005030 = \
                     (self.matricSuctionFC / self.airEntryValueUpp005030)**\
                                        (-1.0/ self.poreSizeBetaUpp005030)
            self.effSatAtFieldCapLow030150 = \
                     (self.matricSuctionFC / self.airEntryValueLow030150)**\
                                        (-1.0/ self.poreSizeBetaLow030150)

            self.kUnsatAtFieldCapUpp000005 = pcr.max(0., \
             (self.effSatAtFieldCapUpp000005 ** self.campbellBetaUpp000005) * self.kSatUpp000005)
            self.kUnsatAtFieldCapUpp005030 = pcr.max(0., \
             (self.effSatAtFieldCapUpp005030 ** self.campbellBetaUpp005030) * self.kSatUpp005030)
            self.kUnsatAtFieldCapLow030150 = pcr.max(0., \
             (self.effSatAtFieldCapLow030150 ** self.campbellBetaLow030150) * 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.0/self.poreSizeBetaUpp)
            self.effSatAt50Upp = pcr.cover(self.effSatAt50Upp, 1.0)                                        
            self.effSatAt50Low = (self.matricSuction50/self.airEntryValueLow)**\
                                                    (-1.0/self.poreSizeBetaLow)
            self.effSatAt50Low = pcr.cover(self.effSatAt50Low, 1.0)                                        
            self.effSatAtWiltPointUpp = pcr.cover(\
                                 (self.matricSuctionWP/self.airEntryValueUpp)**\
                                                    (-1.0/self.poreSizeBetaUpp), 1.0)
            self.effSatAtWiltPointLow = pcr.cover(\
                                 (self.matricSuctionWP/self.airEntryValueLow)**\
                                                    (-1.0/self.poreSizeBetaLow), 1.0)
        if self.numberOfLayers == 3:
            self.effSatAt50Upp000005 = (self.matricSuction50/self.airEntryValueUpp000005)**\
                                                          (-1.0/self.poreSizeBetaUpp000005)
            self.effSatAt50Upp005030 = (self.matricSuction50/self.airEntryValueUpp005030)**\
                                                          (-1.0/self.poreSizeBetaUpp005030)
            self.effSatAt50Low030150 = (self.matricSuction50/self.airEntryValueLow030150)**\
                                                          (-1.0/self.poreSizeBetaLow030150)
            self.effSatAtWiltPointUpp000005 = \
                                       (self.matricSuctionWP/self.airEntryValueUpp000005)**\
                                                          (-1.0/self.poreSizeBetaUpp000005)
            self.effSatAtWiltPointUpp005030 = \
                                       (self.matricSuctionWP/self.airEntryValueUpp005030)**\
                                                          (-1.0/self.poreSizeBetaUpp005030)
            self.effSatAtWiltPointLow030150 = \
                                       (self.matricSuctionWP/self.airEntryValueLow030150)**\
                                                          (-1.0/self.poreSizeBetaLow030150)

        # calculate interflow parameter (TCL): 
        #
        if self.numberOfLayers == 2:
            self.interflowConcTime = (self.kSatLow * self.tanslope*2.0) / \
                     (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 = (self.kSatLow030150 * self.tanslope*2.0) / \
                     (self.slopeLength * (1.-self.effSatAtFieldCapLow030150) * \
             (self.satVolMoistContLow030150 - self.resVolMoistContLow030150))
        
        self.interflowConcTime = pcr.max(0.0, pcr.cover(self.interflowConcTime, 0.0))     
Exemplo n.º 30
0
    def modflow_simulation(self,\
                           simulation_type,\
                           initial_head_layer_1, initial_head_layer_2,\
                           currTimeStep = None,\
                           NSTP   = 1, \
                           HCLOSE = 0.5,\
                           RCLOSE = 100.* 400.*400.,\
                           MXITER = 300,\
                           ITERI = 100,\
                           NPCOND = 1,\
                           RELAX = 1.00,\
                           NBPOL = 2,\
                           DAMP = 1,\
                           ITMUNI = 4, LENUNI = 2, PERLEN = 1.0, TSMULT = 1.0):
        # initiate pcraster modflow object
        self.initiate_modflow()

        if simulation_type == "transient":
            logger.info("Preparing MODFLOW input for a transient simulation.")
            SSTR = 0
        if simulation_type == "steady-state":
            logger.info(
                "Preparing MODFLOW input for a steady-state simulation.")
            SSTR = 1

        # waterBody class to define the extent of lakes and reservoirs
        #
        if simulation_type == "steady-state":
            self.WaterBodies = waterBodies.WaterBodies(self.iniItems,\
                                                       self.landmask,\
                                                       self.onlyNaturalWaterBodies)
            self.WaterBodies.getParameterFiles(date_given = self.iniItems.globalOptions['startTime'],\
                                               cellArea = self.cellAreaMap, \
                                               ldd = self.lddMap)
        #
        if simulation_type == "transient":
            if currTimeStep.timeStepPCR == 1:
                self.WaterBodies = waterBodies.WaterBodies(self.iniItems,\
                                                           self.landmask,\
                                                           self.onlyNaturalWaterBodies)
            if currTimeStep.timeStepPCR == 1 or currTimeStep.doy == 1:
                self.WaterBodies.getParameterFiles(date_given = str(currTimeStep.fulldate),\
                                                   cellArea = self.cellAreaMap, \
                                                   ldd = self.lddMap)

        # using dem_average as the initial groundwater head value
        self.pcr_modflow.setInitialHead(initial_head_layer_1, 1)
        self.pcr_modflow.setInitialHead(initial_head_layer_2, 2)

        # set parameter values for the DIS package and PCG solver
        self.pcr_modflow.setDISParameter(ITMUNI, LENUNI, PERLEN, NSTP, TSMULT,
                                         SSTR)
        self.pcr_modflow.setPCG(MXITER, ITERI, NPCOND, HCLOSE, RCLOSE, RELAX,
                                NBPOL, DAMP)
        #
        # Some notes about the values
        #
        # ITMUNI = 4     # indicates the time unit (0: undefined, 1: seconds, 2: minutes, 3: hours, 4: days, 5: years)
        # LENUNI = 2     # indicates the length unit (0: undefined, 1: feet, 2: meters, 3: centimeters)
        # PERLEN = 1.0   # duration of a stress period
        # NSTP   = 1     # number of time steps in a stress period
        # TSMULT = 1.0   # multiplier for the length of the successive iterations
        # SSTR   = 1     # 0 - transient, 1 - steady state
        #
        # MXITER = 100                # maximum number of outer iterations
        # ITERI  = 30                 # number of inner iterations
        # NPCOND = 1                  # 1 - Modified Incomplete Cholesky, 2 - Polynomial matrix conditioning method;
        # HCLOSE = 0.01               # HCLOSE (unit: m) # 0.05 is working
        # RCLOSE = 10.* 400.*400.     # RCLOSE (unit: m3) ; Deltares people uses 100 m3 for their 25 m resolution modflow model
        # RELAX  = 1.00               # relaxation parameter used with NPCOND = 1
        # NBPOL  = 2                  # indicates whether the estimate of the upper bound on the maximum eigenvalue is 2.0 (but we don ot use it, since NPCOND = 1)
        # DAMP   = 1                  # no damping (DAMP introduced in MODFLOW 2000)

        # read input files (for the steady-state condition, we use pcraster maps):
        if simulation_type == "steady-state":
            # - discharge (m3/s) from PCR-GLOBWB
            discharge = vos.readPCRmapClone(self.iniItems.modflowSteadyStateInputOptions['avgDischargeInputMap'],\
                                                self.cloneMap, self.tmpDir, self.inputDir)
            # - recharge/capillary rise (unit: m/day) from PCR-GLOBWB
            gwRecharge = vos.readPCRmapClone(self.iniItems.modflowSteadyStateInputOptions['avgGroundwaterRechargeInputMap'],\
                                                self.cloneMap, self.tmpDir, self.inputDir)
            if self.ignoreCapRise: gwRecharge = pcr.max(0.0, gwRecharge)
            gwAbstraction = pcr.spatial(pcr.scalar(0.0))

        # read input files (for the transient, input files are given in netcdf files):
        if simulation_type == "transient":
            # - discharge (m3/s) from PCR-GLOBWB
            discharge = vos.netcdf2PCRobjClone(
                self.iniItems.modflowTransientInputOptions['dischargeInputNC'],
                "discharge", str(currTimeStep.fulldate), None, self.cloneMap)
            # - recharge/capillary rise (unit: m/day) from PCR-GLOBWB
            gwRecharge = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['groundwaterRechargeInputNC'],\
                                               "groundwater_recharge",str(currTimeStep.fulldate),None,self.cloneMap)
            if self.ignoreCapRise: gwRecharge = pcr.max(0.0, gwRecharge)
            # - groundwater abstraction (unit: m/day) from PCR-GLOBWB
            gwAbstraction = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['groundwaterAbstractionInputNC'],\
                                               "total_groundwater_abstraction",str(currTimeStep.fulldate),None,self.cloneMap)

        # set recharge and river packages
        self.set_river_package(discharge)
        self.set_recharge_package(gwRecharge)
        self.set_well_package(gwAbstraction)

        # execute MODFLOW
        logger.info("Executing MODFLOW.")
        self.pcr_modflow.run()

        # TODO: Add the mechanism to check whether a run has converged or not.

        # obtaining the results from modflow simulation
        self.groundwaterHeadLayer2 = None
        self.groundwaterHeadLayer2 = self.pcr_modflow.getHeads(2)
        self.groundwaterHeadLayer1 = None
        self.groundwaterHeadLayer1 = self.pcr_modflow.getHeads(1)

        # calculate groundwater depth only in the landmask region
        self.groundwaterDepth = pcr.ifthen(
            self.landmask, self.dem_average - self.groundwaterHeadLayer2)
def main():

    # global map of subdomain masks
    global_clone_map = "/scratch/mo/nest/ulysses/data/edwin/clone_maps/version_2020-08-04/clone_all_maps/clone_ulysses_06min_global.map"

    # number of subdomain masks
    num_of_masks = 54

    # list of subdomain mask files for land (all in nc files)
    subdomain_land_nc = "/scratch/mo/nest/ulysses/data/subdomain_masks/subdomain_land_%s.nc"

    # lisk of subdomain maks files for touring (all in nc files)
    subdomain_river_nc = "/scratch/mo/nest/ulysses/data/subdomain_river_masks/subdomain_river_%s.nc"

    # output folder (and tmp folder)
    out_folder = "/scratch/mo/nest/ulysses/data/edwin/clone_maps/version_2020-08-04/pcraster_maps/"
    clean_out_folder = True
    if os.path.exists(out_folder):
        if clean_out_folder:
            shutil.rmtree(out_folder)
            os.makedirs(out_folder)
    else:
        os.makedirs(out_folder)
    os.chdir(out_folder)
    os.system("pwd")

    # make tmp folder
    tmp_folder = os.path.join(out_folder, "tmp_clone_uly") + "/"
    if os.path.exists(tmp_folder): shutil.rmtree(tmp_folder)
    os.makedirs(tmp_folder)

    # make initial landmask maps at the global extent
    # - set to the global clone map
    pcr.setclone(global_clone_map)
    # - for land
    landmask_land_all = pcr.ifthen(
        pcr.scalar(global_clone_map) > 10, pcr.nominal(0))
    # - for river
    landmask_river_and_land_all = pcr.ifthen(
        pcr.scalar(global_clone_map) > 10, pcr.nominal(0))

    for nr in range(1, num_of_masks + 1, 1):

        msg = "Processing the landmask %s" % (str(nr))
        msg = "\n\n" + str(msg) + "\n\n"
        print(msg)

        # set to the global clone map
        pcr.setclone(global_clone_map)

        # read land nc file (and convert it to pcraster)
        subdomain_land_nc_file = subdomain_land_nc % (str(nr))
        mask_land_selected = vos.netcdf2PCRobjCloneWithoutTime(ncFile  = subdomain_land_nc_file, \
                                                               varName = "mask",\
                                                               cloneMapFileName  = global_clone_map,\
                                                               LatitudeLongitude = True,\
                                                               specificFillValue = "NaN",\
                                                               absolutePath = None)
        mask_land_selected_boolean = pcr.ifthen(
            pcr.scalar(mask_land_selected) > 0.0, pcr.boolean(1.0))
        mask_land_selected_boolean = pcr.ifthen(mask_land_selected_boolean,
                                                mask_land_selected_boolean)

        # update global landmask for land
        mask_land_selected_nominal = pcr.ifthen(mask_land_selected_boolean,
                                                pcr.nominal(nr))
        landmask_land_all = pcr.cover(landmask_land_all,
                                      mask_land_selected_nominal)
        # ~ pcr.aguila(landmask_land_all)

        # read river nc file (and convert it to pcraster)
        subdomain_river_nc_file = subdomain_river_nc % (str(nr))
        mask_river_selected = vos.netcdf2PCRobjCloneWithoutTime(ncFile  = subdomain_river_nc_file, \
                                                                varName = "mask",\
                                                                cloneMapFileName  = global_clone_map,\
                                                                LatitudeLongitude = True,\
                                                                specificFillValue = "NaN",\
                                                                absolutePath = None)
        mask_river_selected_boolean = pcr.ifthen(
            pcr.scalar(mask_river_selected) > 0.0, pcr.boolean(1.0))
        mask_river_selected_boolean = pcr.ifthen(mask_river_selected_boolean,
                                                 mask_river_selected_boolean)

        # merge land and river landmask
        mask_selected_boolean = pcr.cover(mask_land_selected_boolean,
                                          mask_river_selected_boolean)
        mask_selected_nominal = pcr.ifthen(mask_selected_boolean,
                                           pcr.nominal(nr))
        # ~ pcr.aguila(mask_selected_nominal)
        filename_for_land_river_mask_at_global_extent = "global_landmask_river_and_land_mask_%s.map" % (
            str(nr))
        filename_for_land_river_mask_at_global_extent = os.path.join(
            out_folder, filename_for_land_river_mask_at_global_extent)
        pcr.report(mask_selected_nominal,
                   filename_for_land_river_mask_at_global_extent)

        # update global landmask for land and river
        landmask_river_and_land_all = pcr.cover(landmask_river_and_land_all,
                                                mask_selected_nominal)
        # ~ pcr.aguila(landmask_river_and_land_all)

        # get the bounding box based on the landmask file
        xmin, ymin, xmax, ymax = boundingBox(mask_selected_boolean)

        # cellsize
        cellsize = vos.getMapAttributes(global_clone_map, "cellsize")
        num_rows = int(round(ymax - ymin) / cellsize)
        num_cols = int(round(xmax - xmin) / cellsize)

        # make the clone map using mapattr
        clonemap_mask_file = "clonemap_mask_%s.map" % (str(nr))
        # - example: mapattr -s -R 19 -C 68 -B -P yb2t -x 12 -y -14.02 -l 0.8 mask2.map
        cmd = "mapattr -s -R %s -C %s -B -P yb2t -x %s -y %s -l %s %s" % (
            str(num_rows), str(num_cols), str(xmin), str(ymax), str(cellsize),
            clonemap_mask_file)
        print(cmd)
        os.system(cmd)

        # set the landmask for land
        pcr.setclone(clonemap_mask_file)
        landmask_land = vos.netcdf2PCRobjCloneWithoutTime(ncFile  = subdomain_land_nc_file, \
                                                          varName = "mask",\
                                                          cloneMapFileName  = clonemap_mask_file,\
                                                          LatitudeLongitude = True,\
                                                          specificFillValue = "NaN",\
                                                          absolutePath = None)
        landmask_land_boolean = pcr.ifthen(
            pcr.scalar(landmask_land) > 0.0, pcr.boolean(1.0))
        landmask_land_boolean = pcr.ifthen(landmask_land_boolean,
                                           landmask_land_boolean)
        # - save the landmask for land (used for PCR-GLOBWB reporting)
        landmask_land_file = "landmask_land_mask_%s.map" % (str(nr))
        pcr.report(landmask_land_boolean, landmask_land_file)

        # set the landmask for river and land
        landmask_river_and_land = vos.readPCRmapClone(v = filename_for_land_river_mask_at_global_extent, \
                                                      cloneMapFileName = clonemap_mask_file,
                                                      tmpDir = tmp_folder, \
                                                      absolutePath = None, isLddMap = False, cover = None, isNomMap = True)
        landmask_river_and_land_boolean = pcr.ifthen(
            pcr.scalar(landmask_river_and_land) > 0.0, pcr.boolean(1.0))
        landmask_river_and_land_boolean = pcr.ifthen(
            landmask_river_and_land_boolean, landmask_river_and_land_boolean)
        landmask_river_and_land_file = "landmask_river_and_land_mask_%s.map" % (
            str(nr))
        pcr.report(landmask_river_and_land_boolean,
                   landmask_river_and_land_file)

    # kill all aguila processes if exist
    os.system('killall aguila')

    # report a global nominal map for land
    pcr.setclone(global_clone_map)
    filename_for_nominal_land_mask_at_global_extent = "global_landmask_land_mask_all.map"
    pcr.report(landmask_land_all,
               filename_for_nominal_land_mask_at_global_extent)
    pcr.aguila(landmask_land_all)

    # report a global nominal map for river and and land
    pcr.setclone(global_clone_map)
    filename_for_nominal_land_river_mask_at_global_extent = "global_landmask_river_and_land_mask_all.map"
    pcr.report(landmask_river_and_land_all,
               filename_for_nominal_land_river_mask_at_global_extent)
    pcr.aguila(landmask_river_and_land_all)

    print("\n\n Done \n\n")
# - number of rows and clones
nrRows = int((latMax-latMin)/deltaLat)
nrCols = int((lonMax-lonMin)/deltaLon)
# - make and set the clone map
tempCloneMap = outputDir+'/temp_clone.map'
command = 'mapattr -s -R %d -C %d -P "yb2t"	-B -x %f -y %f -l %f %s' %\
	(nrRows,nrCols,lonMin,latMax,deltaLat,tempCloneMap)
vos.cmd_line(command, using_subprocess = False)
# - set the clone map
pcr.setclone(tempCloneMap)
clone_map_file = tempCloneMap

# set the landmask
landmask_05_min = pcr.defined(
                  vos.readPCRmapClone("extended_landmask_5min.map", \
                                      clone_map_file, \
                                      tmp_folder, \
                                      None, True, None, False))
landmask_used = pcr.ifthen(landmask_05_min, landmask_05_min)
landmask_30_sec_file = "/projects/0/dfguu/users/edwinhs/data/HydroSHEDS/hydro_basin_without_lakes/integrating_ldd/version_9_december_2016/merged_ldd.map"
landmask_30_sec = pcr.defined(pcr.readmap(landmask_30_sec_file))
landmask_used = pcr.ifthen(landmask_05_min, landmask_30_sec)
#~ pcr.aguila(landmask_used)

#~ print areas
#~ print areas[0]

# get a list of input files that will be merged
msg = "Get the list of input files that will be merged."
logger.info(msg)
inputDir = inputDirRoot + "/" + areas[0] + "/output_folder/"
files = getFileList(inputDir, '/*/*-year*.map')
Exemplo n.º 33
0
    def __init__(self, modelTime, input_file, output_file, variable_name,
                 variable_unit):
        DynamicModel.__init__(self)

        self.modelTime = modelTime

        # netcdf input file - based on PCR-GLOBWB output
        self.input_file = "/projects/0/dfguu/users/edwin/pcr-globwb-aqueduct/historical/1951-2005/gfdl-esm2m/temperature_annuaAvg_output_%s-12-31_to_%s-12-31.nc"
        self.input_file = input_file

        # output file - in netcdf format
        self.output_file = output_folder + "/mekong/basin_temperature_annuaAvg_output.nc"
        self.output_file = output_file

        # output variable name and unit
        self.variable_name = variable_name
        self.variable_unit = variable_unit

        # preparing temporary directory
        self.temporary_directory = output_folder + "/tmp/"
        os.makedirs(self.temporary_directory)

        # clone and landmask maps
        logger.info("Set the clone and landmask maps.")
        self.clonemap_file_name = "/projects/0/dfguu/users/edwinhs/data/mekong_etc_clone/version_2018-10-22/final/clone_mekong.map"
        pcr.setclone(self.clonemap_file_name)
        landmask_file_name = "/projects/0/dfguu/users/edwinhs/data/mekong_etc_clone/version_2018-10-22/final/mask_mekong.map"
        self.landmask = vos.readPCRmapClone(landmask_file_name, \
                                            self.clonemap_file_name, \
                                            self.temporary_directory, \
                                            None, False, None, True)

        # pcraster input files
        # - river network map and sub-catchment map
        ldd_file_name = "/projects/0/dfguu/data/hydroworld/PCRGLOBWB20/input5min/routing/lddsound_05min.map"
        # - cell area (unit: m2)
        cell_area_file_name = "/projects/0/dfguu/data/hydroworld/PCRGLOBWB20/input5min/routing/cellsize05min.correct.map"

        # loading pcraster input maps
        self.ldd_network   = vos.readPCRmapClone(ldd_file_name, \
                                                 self.clonemap_file_name, \
                                                 self.temporary_directory, \
                                                 None, \
                                                 True)
        self.ldd_network = pcr.lddrepair(pcr.ldd(self.ldd_network))
        self.ldd_network = pcr.lddrepair(self.ldd_network)
        self.cell_area     = vos.readPCRmapClone(cell_area_file_name, \
                                                 self.clonemap_file_name, \
                                                 self.temporary_directory, \
                                                 None)

        # set/limit all input maps to the defined landmask
        self.ldd_network = pcr.ifthen(self.landmask, self.ldd_network)
        self.cell_area = pcr.ifthen(self.landmask, self.cell_area)

        # calculate basin/catchment area
        self.basin_area = pcr.catchmenttotal(self.cell_area, self.ldd_network)
        self.basin_area = pcr.ifthen(self.landmask, self.basin_area)

        # preparing an object for reporting netcdf files:
        self.netcdf_report = netcdf_writer.PCR2netCDF(self.clonemap_file_name)

        # preparing netcdf output files:
        self.netcdf_report.createNetCDF(self.output_file, \
                                        self.variable_name, \
                                        self.variable_unit)
Exemplo n.º 34
0
    def forcingDownscalingOptions(self, iniItems):

        self.downscalePrecipitationOption = False
        self.downscaleTemperatureOption = False
        self.downscaleReferenceETPotOption = False

        if 'meteoDownscalingOptions' in iniItems.allSections:

            # downscaling options
            if iniItems.meteoDownscalingOptions[
                    'downscalePrecipitation'] == "True":
                self.downscalePrecipitationOption = True
                logger.info(
                    "Precipitation forcing will be downscaled to the cloneMap resolution."
                )

            if iniItems.meteoDownscalingOptions[
                    'downscaleTemperature'] == "True":
                self.downscaleTemperatureOption = True
                logger.info(
                    "Temperature forcing will be downscaled to the cloneMap resolution."
                )

            if iniItems.meteoDownscalingOptions[
                    'downscaleReferenceETPot'] == "True" and self.refETPotMethod != 'Hamon':
                self.downscaleReferenceETPotOption = True
                logger.info(
                    "Reference potential evaporation will be downscaled to the cloneMap resolution."
                )

            # Note that for the Hamon method: referencePotET will be calculated based on temperature,
            # therefore, we do not have to downscale it (particularly if temperature is already provided at high resolution).

        if self.downscalePrecipitationOption or\
           self.downscaleTemperatureOption   or\
           self.downscaleReferenceETPotOption:

            # creating anomaly DEM
            highResolutionDEM = vos.readPCRmapClone(\
               iniItems.meteoDownscalingOptions['highResolutionDEM'],
               self.cloneMap,self.tmpDir,self.inputDir)
            highResolutionDEM = pcr.cover(highResolutionDEM, 0.0)
            highResolutionDEM = pcr.max(highResolutionDEM, 0.0)
            self.meteoDownscaleIds = vos.readPCRmapClone(\
               iniItems.meteoDownscalingOptions['meteoDownscaleIds'],
               self.cloneMap,self.tmpDir,self.inputDir,isLddMap=False,cover=None,isNomMap=True)
            self.cellArea = vos.readPCRmapClone(\
               iniItems.routingOptions['cellAreaMap'],
               self.cloneMap,self.tmpDir,self.inputDir)
            loweResolutionDEM = pcr.areatotal(pcr.cover(highResolutionDEM*self.cellArea, 0.0),\
                                              self.meteoDownscaleIds)/\
                                pcr.areatotal(pcr.cover(self.cellArea, 0.0),\
                                              self.meteoDownscaleIds)
            self.anomalyDEM = highResolutionDEM - loweResolutionDEM  # unit: meter

            # temperature lapse rate (netCDF) file
            self.temperLapseRateNC = vos.getFullPath(iniItems.meteoDownscalingOptions[\
                                        'temperLapseRateNC'],self.inputDir)
            self.temperatCorrelNC  = vos.getFullPath(iniItems.meteoDownscalingOptions[\
                                        'temperatCorrelNC'],self.inputDir)                    # TODO: Remove this criteria.

            # precipitation lapse rate (netCDF) file
            self.precipLapseRateNC = vos.getFullPath(iniItems.meteoDownscalingOptions[\
                                        'precipLapseRateNC'],self.inputDir)
            self.precipitCorrelNC  = vos.getFullPath(iniItems.meteoDownscalingOptions[\
                                        'precipitCorrelNC'],self.inputDir)                    # TODO: Remove this criteria.

        else:
            logger.info("No forcing downscaling is implemented.")

        # forcing smoothing options: - THIS is still experimental. PS: MUST BE TESTED.
        self.forcingSmoothing = False
        if 'meteoDownscalingOptions' in iniItems.allSections and \
           'smoothingWindowsLength' in list(iniItems.meteoDownscalingOptions.keys()):

            if float(iniItems.meteoDownscalingOptions['smoothingWindowsLength']
                     ) > 0.0:
                self.forcingSmoothing = True
                self.smoothingWindowsLength = vos.readPCRmapClone(\
                   iniItems.meteoDownscalingOptions['smoothingWindowsLength'],
                   self.cloneMap,self.tmpDir,self.inputDir)
                msg = "Forcing data will be smoothed with 'windowaverage' using the window length:" + str(
                    iniItems.meteoDownscalingOptions['smoothingWindowsLength'])
                logger.info(msg)
    def evaluateAllModelResults(self,\
                                globalCloneMapFileName,\
                                catchmentClassFileName,\
                                lddMapFileName,\
                                cellAreaMapFileName,\
                                pcrglobwb_output,\
                                analysisOutputDir = "",\
                                tmpDir = None):     

        # temporary directory
        if tmpDir == None: tmpDir = self.tmpDir+"/edwin_grdc_"
        
        # output directory for all analyses for all stations
        analysisOutputDir   = str(analysisOutputDir)
        self.chartOutputDir = analysisOutputDir+"/chart/"
        self.tableOutputDir = analysisOutputDir+"/table/"
        #
        if analysisOutputDir == "": self.chartOutputDir = "chart/"
        if analysisOutputDir == "": self.tableOutputDir = "table/"
        #
        # make the chart and table directories:
        os.system('rm -r '+self.chartOutputDir+"*")
        os.system('rm -r '+self.tableOutputDir+"*")
        os.makedirs(self.chartOutputDir)
        os.makedirs(self.tableOutputDir)
        
        # cloneMap for all pcraster operations
        pcr.setclone(globalCloneMapFileName)
        cloneMap = pcr.boolean(1)
        self.cell_size_in_arc_degree = vos.getMapAttributesALL(globalCloneMapFileName)['cellsize']
        
        # ldd map
        lddMap = vos.readPCRmapClone(lddMapFileName, \
                                     globalCloneMapFileName, \
                                     tmpDir, None, \
                                     True, None, False)
        lddMap = pcr.lddrepair(lddMap)
        
        # cell area map
        cellArea = vos.readPCRmapClone(cellAreaMapFileName, \
                                       globalCloneMapFileName, \
                                       tmpDir)
        cellArea = pcr.scalar(cellArea)
        
        # The landMaskClass map contains the nominal classes for all landmask regions. 
        landMaskClass = pcr.nominal(cloneMap)  # default: if catchmentClassFileName is not given
        if catchmentClassFileName != None:
            landMaskClass = vos.readPCRmapClone(catchmentClassFileName, \
                                                globalCloneMapFileName, \
                                                tmpDir, None, \
                                                False, None, True)
            landMaskClass = pcr.nominal(landMaskClass)

        # model catchment areas and cordinates
        catchmentAreaAll = pcr.catchmenttotal(cellArea, lddMap) / (1000*1000)  # unit: km2
        xCoordinate = pcr.xcoordinate(cloneMap)
        yCoordinate = pcr.ycoordinate(cloneMap)
        
        for id in self.list_of_grdc_ids: 

            logger.info("Evaluating simulated discharge to the grdc observation at "+str(self.attributeGRDC["id_from_grdc"][str(id)])+".")
            
            # identify model pixel
            self.identifyModelPixel(tmpDir, catchmentAreaAll, landMaskClass, xCoordinate, yCoordinate,str(id))

            # evaluate model results to GRDC data
            self.evaluateModelResultsToGRDC(str(id),pcrglobwb_output,catchmentClassFileName,tmpDir)
            
        # write the summary to a table 
        summary_file = analysisOutputDir+"summary.txt"
        #
        logger.info("Writing the summary for all stations to the file: "+str(summary_file)+".")
        #
        # prepare the file:
        summary_file_handle = open(summary_file,"w")
        #
        # write the header
        summary_file_handle.write( ";".join(self.grdc_dict_keys)+"\n")
        #
        # write the content
        for id in self.list_of_grdc_ids:
            rowLine  = ""
            for key in self.grdc_dict_keys: rowLine += str(self.attributeGRDC[key][str(id)]) + ";"   
            rowLine = rowLine[0:-1] + "\n"
            summary_file_handle.write(rowLine)
        summary_file_handle.close()           
clone_map_file    = "/projects/0/dfguu/data/hydroworld/others/05ArcMinCloneMaps/new_masks_from_top/clone_" + str(mask_code) + ".map" 
msg = "Set the pcraster clone map to : " + str(clone_map_file)
logger.info(msg)
pcr.setclone(clone_map_file)
# - set the landmask
landmask_map_file = "/projects/0/dfguu/data/hydroworld/others/05ArcMinCloneMaps/new_masks_from_top/mask_"  + str(mask_code) + ".map"
msg = "Set the landmask to : " + str(landmask_map_file)
logger.info(msg)
landmask = pcr.readmap(landmask_map_file)

# resampling low resolution ldd map
msg = "Resample the low resolution ldd map."
logger.info(msg)
ldd_map_low_resolution_file_name = "/projects/0/dfguu/data/hydroworld/PCRGLOBWB20/input5min/routing/lddsound_05min.map"
ldd_map_low_resolution = vos.readPCRmapClone(ldd_map_low_resolution_file_name, \
                                             clone_map_file, \
                                             tmp_folder, \
                                             None, True, None, False)
ldd_map_low_resolution = pcr.ifthen(landmask, ldd_map_low_resolution)    # NOTE THAT YOU MAY NOT HAVE TO MASK-OUT THE LDD.
ldd_map_low_resolution = pcr.lddrepair(pcr.ldd(ldd_map_low_resolution))
ldd_map_low_resolution = pcr.lddrepair(ldd_map_low_resolution)
pcr.report(ldd_map_low_resolution, "resampled_low_resolution_ldd.map")


# permanent water bodies files (at 5 arc-minute resolution)
reservoir_capacity_file = "/projects/0/dfguu/data/hydroworld/PCRGLOBWB20/input5min/routing/reservoirs/waterBodiesFinal_version15Sept2013/maps/reservoircapacity_2010.map"
fracwat_file            = "/projects/0/dfguu/data/hydroworld/PCRGLOBWB20/input5min/routing/reservoirs/waterBodiesFinal_version15Sept2013/maps/fracwat_2010.map"
water_body_id_file      = "/projects/0/dfguu/data/hydroworld/PCRGLOBWB20/input5min/routing/reservoirs/waterBodiesFinal_version15Sept2013/maps/waterbodyid_2010.map"


# cell_area_file
cell_area_file = "/projects/0/dfguu/data/hydroworld/PCRGLOBWB20/input5min/routing/cellsize05min.correct.map"
Exemplo n.º 37
0
    def __init__(self, iniItems, landmask):
        object.__init__(self)

        # cloneMap, temporary directory, absolute path for input directory, landmask
        self.cloneMap = iniItems.cloneMap
        self.tmpDir = iniItems.tmpDir
        self.inputDir = iniItems.globalOptions['inputDir']
        self.landmask = landmask

        # configuration from the ini file
        self.iniItems = iniItems

        # topography properties: read several variables from the netcdf file
        for var in ['dem_minimum','dem_maximum','dem_average','dem_standard_deviation',\
                    'slopeLength','orographyBeta','tanslope',\
                    'dzRel0000','dzRel0001','dzRel0005',\
                    'dzRel0010','dzRel0020','dzRel0030','dzRel0040','dzRel0050',\
                    'dzRel0060','dzRel0070','dzRel0080','dzRel0090','dzRel0100']:
            vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['topographyNC'], \
                                                                var, self.cloneMap)
            vars(self)[var] = pcr.cover(vars(self)[var], 0.0)

        # channel properties: read several variables from the netcdf file
        for var in [
                'lddMap', 'cellAreaMap', 'gradient', 'bankfull_width',
                'bankfull_depth', 'dem_floodplain', 'dem_riverbed'
        ]:
            vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['channelNC'], \
                                                                var, self.cloneMap)
            vars(self)[var] = pcr.cover(vars(self)[var], 0.0)

        # minimum channel width
        minimum_channel_width = 0.1
        self.bankfull_width = pcr.max(minimum_channel_width,
                                      self.bankfull_width)

        #~ # cell fraction if channel water reaching the flood plan # NOT USED
        #~ self.flood_plain_fraction = self.return_innundation_fraction(pcr.max(0.0, self.dem_floodplain - self.dem_minimum))

        # coefficient of Manning
        self.manningsN = vos.readPCRmapClone(self.iniItems.modflowParameterOptions['manningsN'],\
                                             self.cloneMap,self.tmpDir,self.inputDir)

        # minimum channel gradient
        minGradient = 0.00005
        self.gradient = pcr.max(minGradient,
                                pcr.cover(self.gradient, minGradient))

        # correcting lddMap
        self.lddMap = pcr.ifthen(pcr.scalar(self.lddMap) > 0.0, self.lddMap)
        self.lddMap = pcr.lddrepair(pcr.ldd(self.lddMap))

        # channelLength = approximation of channel length (unit: m)  # This is approximated by cell diagonal.
        cellSizeInArcMin = np.round(pcr.clone().cellSize() * 60.)
        verticalSizeInMeter = cellSizeInArcMin * 1852.
        self.channelLength  = ((self.cellAreaMap/verticalSizeInMeter)**(2)+\
                                                (verticalSizeInMeter)**(2))**(0.5)

        # option for lakes and reservoir
        self.onlyNaturalWaterBodies = False
        if self.iniItems.modflowParameterOptions[
                'onlyNaturalWaterBodies'] == "True":
            self.onlyNaturalWaterBodies = True

        # groundwater linear recession coefficient (day-1) ; the linear reservoir concept is still being used to represent fast response flow
        #                                                                                                                  particularly from karstic aquifer in mountainous regions
        self.recessionCoeff = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['groundwaterPropertiesNC'],\
                                                                 'recessionCoeff', self.cloneMap)
        self.recessionCoeff = pcr.cover(self.recessionCoeff, 0.00)
        self.recessionCoeff = pcr.min(1.0000, self.recessionCoeff)
        #
        if 'minRecessionCoeff' in iniItems.modflowParameterOptions.keys():
            minRecessionCoeff = float(
                iniItems.modflowParameterOptions['minRecessionCoeff'])
        else:
            minRecessionCoeff = 1.0e-4  # This is the minimum value used in Van Beek et al. (2011).
        self.recessionCoeff = pcr.max(minRecessionCoeff, self.recessionCoeff)

        # aquifer saturated conductivity (m/day)
        self.kSatAquifer = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['groundwaterPropertiesNC'],\
                                                             'kSatAquifer', self.cloneMap)
        self.kSatAquifer = pcr.cover(self.kSatAquifer,
                                     pcr.mapmaximum(self.kSatAquifer))
        self.kSatAquifer = pcr.max(0.010, self.kSatAquifer)

        self.kSatAquifer *= 0.001

        # aquifer specific yield (dimensionless)
        self.specificYield = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['groundwaterPropertiesNC'],\
                                                               'specificYield', self.cloneMap)
        self.specificYield = pcr.cover(self.specificYield,
                                       pcr.mapmaximum(self.specificYield))
        self.specificYield = pcr.max(
            0.010, self.specificYield
        )  # TODO: TO BE CHECKED: The resample process of specificYield
        self.specificYield = pcr.min(1.000, self.specificYield)

        # estimate of thickness (unit: m) of accesible groundwater
        totalGroundwaterThickness = vos.netcdf2PCRobjCloneWithoutTime(self.iniItems.modflowParameterOptions['estimateOfTotalGroundwaterThicknessNC'],\
                                    'thickness', self.cloneMap)
        # extrapolation
        totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,\
                                    pcr.windowaverage(totalGroundwaterThickness, 1.0))
        totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,\
                                    pcr.windowaverage(totalGroundwaterThickness, 1.5))
        totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, 0.0)
        #
        # set minimum thickness
        minimumThickness = pcr.scalar(float(\
                           self.iniItems.modflowParameterOptions['minimumTotalGroundwaterThickness']))
        totalGroundwaterThickness = pcr.max(minimumThickness,
                                            totalGroundwaterThickness)
        #
        # set maximum thickness: 250 m.
        maximumThickness = 250.
        self.totalGroundwaterThickness = pcr.min(maximumThickness,
                                                 totalGroundwaterThickness)

        # river bed resistance (unit: day)
        self.bed_resistance = 1.0

        # option to ignore capillary rise
        self.ignoreCapRise = True
        if self.iniItems.modflowParameterOptions['ignoreCapRise'] == "False":
            self.ignoreCapRise = False

        # initiate old style reporting                                  # TODO: remove this!
        self.initiate_old_style_groundwater_reporting(iniItems)
Exemplo n.º 38
0
    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:
            self.satVolMoistContUpp = self.satVolWC1  # saturated volumetric moisture content (m3.m-3)
            self.satVolMoistContLow = self.satVolWC2
            self.resVolMoistContUpp = self.resVolWC1  # residual volumetric moisture content (m3.m-3)
            self.resVolMoistContLow = self.resVolWC2
            self.airEntryValueUpp = self.airEntryValue1  # air entry value (m) according to soil water retention curve of Clapp & Hornberger (1978)
            self.airEntryValueLow = self.airEntryValue2
            self.poreSizeBetaUpp = self.poreSizeBeta1  # pore size distribution parameter according to Clapp & Hornberger (1978)
            self.poreSizeBetaLow = self.poreSizeBeta2
            self.kSatUpp = self.KSat1  # saturated hydraulic conductivity (m.day-1)
            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

        self.percolationImp = self.percolationImp  # fractional area where percolation to groundwater store is impeded (dimensionless)

        # 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
    for var in variable_names:
        input_files['file_name'][hydro_year][var] = glob.glob(input_files['folder'] + "/" + str(hydro_year) + "/" + str(var) + "*" + str(str_year) + "_to_" + str(end_year) + "*.nc")[0]
        msg = input_files['file_name'][hydro_year][var]
        logger.info(msg)


# set the pcraster clone, ldd, landmask, and cell area map 
msg = "Setting the clone, ldd, landmask, and cell area maps" + ":"
logger.info(msg)
# - clone 
clone_map_file = input_files['clone_map_05min']
pcr.setclone(clone_map_file)
# - ldd
ldd = vos.readPCRmapClone(input_files['ldd_map_05min'],
                          clone_map_file,
                          output_files['tmp_folder'],
                          None,
                          True)
ldd = pcr.lddrepair(pcr.ldd(ldd))
ldd = pcr.lddrepair(ldd)
# - landmask
landmask  = pcr.ifthen(pcr.defined(ldd), pcr.boolean(1.0))
# - cell area
cell_area = vos.readPCRmapClone(input_files['cell_area_05min'],
                          clone_map_file,
                          output_files['tmp_folder'])


# read the hydrological year 
msg = "Reading the hydrological year types" + ":"
logger.info(msg)
Exemplo n.º 40
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:
            minRecessionCoeff = 1.0e-4                                       # This is the minimum value used in Van Beek et al. (2011). 
        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)       
        self.specificYield  = pcr.max(0.010,self.specificYield)         # TODO: TO BE CHECKED: The resample process of 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 regional groundwater abstractions
        if iniItems.groundwaterOptions['pumpingCapacityNC'] != "None":

            logger.info('Limit for annual regional groundwater abstraction is used.')
            self.limitRegionalAnnualGroundwaterAbstraction = True
            self.pumpingCapacityNC = vos.getFullPath(\
                                     iniItems.groundwaterOptions['pumpingCapacityNC'],self.inputDir,False)
        else:
            logger.warning('NO LIMIT for regional groundwater (annual) pumping. It may result too high groundwater abstraction.')
            self.limitRegionalAnnualGroundwaterAbstraction = False
        
        # option for limitting fossil groundwater abstractions: 
        self.limitFossilGroundwaterAbstraction = False
        #
        # estimate of fossil groundwater capacity:
        if iniItems.groundwaterOptions['limitFossilGroundWaterAbstraction'] == "True": 

            logger.info('Fossil groundwater abstractions are allowed with LIMIT.')
            self.limitFossilGroundwaterAbstraction = True

            # estimate of thickness (unit: m) of accesible groundwater: shallow and deep 
            totalGroundwaterThickness = vos.readPCRmapClone(\
                                        iniItems.groundwaterOptions['estimateOfTotalGroundwaterThickness'],
                                        self.cloneMap,self.tmpDir,self.inputDir)
            # extrapolation 
            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, 0.0)
            #
            # set minimum thickness
            minimumThickness = pcr.scalar(float(\
                               iniItems.groundwaterOptions['minimumTotalGroundwaterThickness']))
            totalGroundwaterThickness = pcr.max(minimumThickness, totalGroundwaterThickness)
            #            
            # estimate of capacity (unit: m) of renewable groundwater (shallow)
            storGroundwaterCap =  pcr.cover(
                                  vos.readPCRmapClone(\
                                  iniItems.groundwaterOptions['estimateOfRenewableGroundwaterCapacity'],
                                  self.cloneMap,self.tmpDir,self.inputDir), 0.0)
            #
            # fossil groundwater capacity (unit: m)
            self.fossilWaterCap = pcr.ifthen(self.landmask,\
                                  pcr.max(0.0,\
                                  totalGroundwaterThickness*self.specificYield - storGroundwaterCap))

        # zones at which groundwater allocations are determined
        self.usingAllocSegments = False
        if iniItems.landSurfaceOptions['allocationSegmentsForGroundSurfaceWater']  != "None": self.usingAllocSegments = True
        
        # incorporating groundwater distribution network:
        if self.usingAllocSegments:

            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)
            cellArea = pcr.ifthen(self.landmask, cellArea)              # TODO: integrate this one with the one coming from the routing module

            self.segmentArea = pcr.areatotal(pcr.cover(cellArea, 0.0), self.allocSegments)
            self.segmentArea = pcr.ifthen(self.landmask, self.segmentArea)
        
        # get initial conditions
        self.getICs(iniItems,spinUp)

        # initiate old style reporting                                  # TODO: remove this!
        self.initiate_old_style_groundwater_reporting(iniItems)