Esempio n. 1
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)
Esempio n. 2
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]])
Esempio n. 3
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)
Esempio n. 4
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:
            # saturated volumetric moisture content (m3.m-3)
            self.satVolMoistContUpp = self.satVolWC1
            self.satVolMoistContLow = self.satVolWC2
            # residual volumetric moisture content (m3.m-3)
            self.resVolMoistContUpp = self.resVolWC1
            self.resVolMoistContLow = self.resVolWC2
            # air entry value (m) according to soil water retention curve of Clapp & Hornberger (1978)
            self.airEntryValueUpp = self.airEntryValue1
            self.airEntryValueLow = self.airEntryValue2
            # pore size distribution parameter according to Clapp & Hornberger (1978)
            self.poreSizeBetaUpp = self.poreSizeBeta1
            self.poreSizeBetaLow = self.poreSizeBeta2
            # saturated hydraulic conductivity (m.day-1)
            self.kSatUpp = self.KSat1
            self.kSatLow = self.KSat2

        if self.numberOfLayers == 3:
            self.satVolMoistContUpp000005 = self.satVolWC1
            self.satVolMoistContUpp005030 = self.satVolWC1
            self.satVolMoistContLow030150 = self.satVolWC2
            self.resVolMoistContUpp000005 = self.resVolWC1
            self.resVolMoistContUpp005030 = self.resVolWC1
            self.resVolMoistContLow030150 = self.resVolWC2
            self.airEntryValueUpp000005 = self.airEntryValue1
            self.airEntryValueUpp005030 = self.airEntryValue1
            self.airEntryValueLow030150 = self.airEntryValue2
            self.poreSizeBetaUpp000005 = self.poreSizeBeta1
            self.poreSizeBetaUpp005030 = self.poreSizeBeta1
            self.poreSizeBetaLow030150 = self.poreSizeBeta2
            self.kSatUpp000005 = self.KSat1
            self.kSatUpp005030 = self.KSat1
            self.kSatLow030150 = self.KSat2

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

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

        # layer thickness
        if self.numberOfLayers == 2:
            self.thickUpp = (0.30 / 0.30) * self.firstStorDepthInp
            self.thickLow = (1.20 / 1.20) * self.secondStorDepthInp
        if self.numberOfLayers == 3:
            self.thickUpp000005 = (0.05 / 0.30) * self.firstStorDepthInp
            self.thickUpp005030 = (0.25 / 0.30) * self.firstStorDepthInp
            self.thickLow030150 = (1.20 / 1.20) * self.secondStorDepthInp

        # soil storage
        if self.numberOfLayers == 2:
            # ~ self.storCapUpp = (0.30/0.30)*self.soilWaterStorageCap1Inp
            # ~ self.storCapLow = (1.20/1.20)*self.soilWaterStorageCap2Inp                     # 22 Feb 2014: We can calculate this based on thickness and porosity.
            self.storCapUpp = self.thickUpp * \
                (self.satVolMoistContUpp - self.resVolMoistContUpp)
            self.storCapLow = self.thickLow * \
                (self.satVolMoistContLow - self.resVolMoistContLow)
            self.rootZoneWaterStorageCap = self.storCapUpp + \
                self.storCapLow
        if self.numberOfLayers == 3:
            self.storCapUpp000005 = self.thickUpp000005 * \
                (self.satVolMoistContUpp000005 - self.resVolMoistContUpp000005)
            self.storCapUpp005030 = self.thickUpp005030 * \
                (self.satVolMoistContUpp005030 - self.resVolMoistContUpp005030)
            self.storCapLow030150 = self.thickLow030150 * \
                (self.satVolMoistContLow030150 - self.resVolMoistContLow030150)
            self.rootZoneWaterStorageCap = self.storCapUpp000005 + \
                self.storCapUpp005030 + \
                self.storCapLow030150
Esempio n. 5
0
    def readSoil(self, iniItems):

        # default values of soil parameters that are constant/uniform for the entire domain:
        self.clappAddCoeff = pcr.scalar(3.0)  # dimensionless
        self.matricSuctionFC = pcr.scalar(1.0)  # unit: m
        self.matricSuction50 = pcr.scalar(10. / 3.)  # unit: m
        self.matricSuctionWP = pcr.scalar(156.0)  # unit: m
        self.maxGWCapRise = pcr.scalar(5.0)  # unit: m
        #
        # values defined in the ini/configuration file:
        soilParameterConstants = [
            'clappAddCoeff', 'matricSuctionFC', 'matricSuction50',
            'matricSuctionWP', 'maxGWCapRise'
        ]
        for var in soilParameterConstants:
            if var in iniItems.landSurfaceOptions.keys():
                input = iniItems.landSurfaceOptions[str(var)]
                vars(self)[var] = vos.readPCRmapClone(input, self.cloneMap,
                                                      self.tmpDir,
                                                      self.inputDir)

        # read soil parameter based on the FAO soil map:
        self.readSoilMapOfFAO(iniItems)

        # assign Campbell's (1974) beta coefficient, as well as degree
        # of saturation at field capacity and corresponding unsaturated hydraulic conductivity
        #
        if self.numberOfLayers == 2:

            self.campbellBetaUpp = 2.*self.poreSizeBetaUpp + \
                self.clappAddCoeff                # Campbell's (1974) coefficient ; Rens's line: BCB = 2*BCH + BCH_ADD
            self.campbellBetaLow = 2.*self.poreSizeBetaLow + \
                self.clappAddCoeff

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

            self.kUnsatAtFieldCapUpp = pcr.max(
                0.,
                self.effSatAtFieldCapUpp**self.poreSizeBetaUpp * self.kSatUpp)
            self.kUnsatAtFieldCapLow = pcr.max(
                0.,
                self.effSatAtFieldCapLow**self.poreSizeBetaLow * self.kSatLow)
        #
        if self.numberOfLayers == 3:

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

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

            self.kUnsatAtFieldCapUpp000005 = pcr.max(
                0.,
                self.effSatAtFieldCapUpp000005**self.poreSizeBetaUpp000005 *
                self.kSatUpp000005)
            self.kUnsatAtFieldCapUpp005030 = pcr.max(
                0.,
                self.effSatAtFieldCapUpp005030**self.poreSizeBetaUpp005030 *
                self.kSatUpp005030)
            self.kUnsatAtFieldCapLow030150 = pcr.max(
                0.,
                self.effSatAtFieldCapLow030150**self.poreSizeBetaLow030150 *
                self.kSatLow030150)

        # calculate degree of saturation at which transpiration is halved (50)
        # and at wilting point
        #
        if self.numberOfLayers == 2:
            self.effSatAt50Upp = (self.matricSuction50/self.airEntryValueUpp) **\
                (-1/self.poreSizeBetaUpp)
            self.effSatAt50Low = (self.matricSuction50/self.airEntryValueLow) **\
                (-1/self.poreSizeBetaLow)
            self.effSatAtWiltPointUpp = \
                (self.matricSuctionWP/self.airEntryValueUpp) **\
                (-1/self.poreSizeBetaUpp)
            self.effSatAtWiltPointLow = \
                (self.matricSuctionWP/self.airEntryValueLow) **\
                (-1/self.poreSizeBetaLow)
        if self.numberOfLayers == 3:
            self.effSatAt50Upp000005 = (self.matricSuction50/self.airEntryValueUpp000005) **\
                (-1/self.poreSizeBetaUpp000005)
            self.effSatAt50Upp005030 = (self.matricSuction50/self.airEntryValueUpp005030) **\
                (-1/self.poreSizeBetaUpp005030)
            self.effSatAt50Low030150 = (self.matricSuction50/self.airEntryValueLow030150) **\
                (-1/self.poreSizeBetaLow030150)
            self.effSatAtWiltPointUpp000005 = \
                (self.matricSuctionWP/self.airEntryValueUpp000005) **\
                (-1/self.poreSizeBetaUpp000005)
            self.effSatAtWiltPointUpp005030 = \
                (self.matricSuctionWP/self.airEntryValueUpp005030) **\
                (-1/self.poreSizeBetaUpp005030)
            self.effSatAtWiltPointLow030150 = \
                (self.matricSuctionWP/self.airEntryValueLow030150) **\
                (-1/self.poreSizeBetaLow030150)

        # calculate interflow parameter (TCL):
        #
        if self.numberOfLayers == 2:
            self.interflowConcTime = (2. * self.kSatLow * self.tanslope) / \
                (self.slopeLength * (1. - self.effSatAtFieldCapLow) *
                 (self.satVolMoistContLow - self.resVolMoistContLow))    # TCL = Duration*(2*KS2*TANSLOPE)/(LSLOPE*(1-THEFF2_FC)*(THETASAT2-THETARES2))
        #
        if self.numberOfLayers == 3:
            self.interflowConcTime = (2. * self.kSatLow030150 * self.tanslope) / \
                (self.slopeLength * (1.-self.effSatAtFieldCapLow030150) *
                 (self.satVolMoistContLow030150 - self.resVolMoistContLow030150))

        self.interflowConcTime = pcr.cover(self.interflowConcTime, 0.0)
Esempio n. 6
0
    def __init__(self, iniItems, landmask, spinUp):
        object.__init__(self)

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

        # option to activate water balance check
        self.debugWaterBalance = True
        if iniItems.routingOptions['debugWaterBalance'] == "False":
            self.debugWaterBalance = False

        if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None):
            # assign the recession coefficient parameter(s)
            self.recessionCoeff = vos.readPCRmapClone(
                iniItems.groundwaterOptions['recessionCoeff'],
                self.cloneMap, self.tmpDir, self.inputDir)
        else:
            groundwaterPropertiesNC = vos.getFullPath(
                iniItems.groundwaterOptions[
                    'groundwaterPropertiesNC'],
                self.inputDir)
            self.recessionCoeff = vos.netcdf2PCRobjCloneWithoutTime(
                groundwaterPropertiesNC, 'recessionCoeff',
                cloneMapFileName=self.cloneMap)

        # groundwater recession coefficient (day-1_
        self.recessionCoeff = pcr.cover(self.recessionCoeff, 0.00)
        self.recessionCoeff = pcr.min(1.0000, self.recessionCoeff)
        #
        if 'minRecessionCoeff' in iniItems.groundwaterOptions.keys():
            minRecessionCoeff = float(
                iniItems.groundwaterOptions['minRecessionCoeff'])
        else:
            # This is the minimum value used in Van Beek et al. (2011).
            minRecessionCoeff = 1.0e-4
        self.recessionCoeff = pcr.max(minRecessionCoeff, self.recessionCoeff)

        if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None):
            # assign aquifer specific yield
            self.specificYield = vos.readPCRmapClone(
                iniItems.groundwaterOptions['specificYield'],
                self.cloneMap, self.tmpDir, self.inputDir)
        else:
            self.specificYield = vos.netcdf2PCRobjCloneWithoutTime(
                groundwaterPropertiesNC, 'specificYield',
                cloneMapFileName=self.cloneMap)

        self.specificYield = pcr.cover(self.specificYield, 0.0)
        # TODO: TO BE CHECKED: The resample process of specificYield
        self.specificYield = pcr.max(0.010, self.specificYield)
        self.specificYield = pcr.min(1.000, self.specificYield)

        if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None):
            # assign aquifer saturated conductivity
            self.kSatAquifer = vos.readPCRmapClone(
                iniItems.groundwaterOptions['kSatAquifer'],
                self.cloneMap, self.tmpDir, self.inputDir)
        else:
            self.kSatAquifer = vos.netcdf2PCRobjCloneWithoutTime(
                groundwaterPropertiesNC, 'kSatAquifer',
                cloneMapFileName=self.cloneMap)

        self.kSatAquifer = pcr.cover(self.kSatAquifer, 0.0)
        self.kSatAquifer = pcr.max(0.010, self.kSatAquifer)

        # limitAbstraction options
        self.limitAbstraction = False
        if iniItems.landSurfaceOptions['limitAbstraction'] == "True":
            self.limitAbstraction = True

        # option for limitting fossil groundwater abstractions - This option is only defined for IWMI project
        self.limitFossilGroundwaterAbstraction = False
        if self.limitAbstraction == False and\
           "extraOptionsforProjectWithIWMI" in iniItems.allSections and\
           iniItems.extraOptionsforProjectWithIWMI['limitFossilGroundWaterAbstraction'] == "True":

            #logger.info('Fossil groundwater abstraction limit is used (IWMI project).')
            self.limitFossilGroundwaterAbstraction = True

            # estimate of thickness (unit: mm) of aceesible groundwater: shallow and deep
            totalGroundwaterThickness = vos.readPCRmapClone(
                iniItems.extraOptionsforProjectWithIWMI['estimateOfTotalGroundwaterThickness'],
                self.cloneMap, self.tmpDir, self.inputDir)
            totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,
                                                  pcr.windowaverage(totalGroundwaterThickness, 1.0))
            totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,
                                                  pcr.windowaverage(totalGroundwaterThickness, 1.5))
            totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,
                                                  pcr.windowaverage(totalGroundwaterThickness, 2.5))
            totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,
                                                  pcr.windowaverage(totalGroundwaterThickness, 5.0))
            totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,
                                                  pcr.windowaverage(totalGroundwaterThickness, 7.5))
            totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness,
                                                  pcr.mapmaximum(totalGroundwaterThickness))

            # set minimum thickness to 50 m:
            totalGroundwaterThickness = pcr.max(
                50.0, totalGroundwaterThickness)

            # estimate of capacity (unit: m) of renewable groundwater (shallow)
            storGroundwaterCap = pcr.cover(
                vos.readPCRmapClone(
                    iniItems.extraOptionsforProjectWithIWMI['estimateOfRenewableGroundwaterCapacity'],
                    self.cloneMap, self.tmpDir, self.inputDir),
                0.0)

            # fossil groundwater capacity (unit: m)
            self.fossilWaterCap = pcr.max(0.0,
                                          totalGroundwaterThickness*self.specificYield - storGroundwaterCap)

        # option for limitting regional groundwater abstractions - This option is only defined
        self.limitRegionalAnnualGroundwaterAbstraction = False
        if "extraOptionsforProjectWithIWMI" in iniItems.allSections and\
           iniItems.extraOptionsforProjectWithIWMI['limitRegionalAnnualGroundwaterAbstraction'] == "True":

            #logger.info('Limit for regional groundwater abstraction is used (IWMI project).')
            self.limitRegionalAnnualGroundwaterAbstraction = True

            region_ids = vos.readPCRmapClone(
                iniItems.extraOptionsforProjectWithIWMI['regionIds'],
                self.cloneMap, self.tmpDir, self.inputDir)
            self.region_ids = pcr.nominal(region_ids)
            self.region_ids = pcr.ifthen(self.landmask, self.region_ids)

            self.regionalAnnualGroundwaterAbstractionLimit = vos.readPCRmapClone(
                iniItems.extraOptionsforProjectWithIWMI['pumpingCapacity'],
                self.cloneMap, self.tmpDir, self.inputDir)
            self.regionalAnnualGroundwaterAbstractionLimit = pcr.roundup(
                self.regionalAnnualGroundwaterAbstractionLimit*1000.)/1000.
            self.regionalAnnualGroundwaterAbstractionLimit = pcr.cover(
                self.regionalAnnualGroundwaterAbstractionLimit, 0.0)

            self.regionalAnnualGroundwaterAbstractionLimit *= 1000. * \
                1000. * 1000.  # unit: m3/year
            self.regionalAnnualGroundwaterAbstractionLimit = pcr.ifthen(self.landmask,
                                                                        self.regionalAnnualGroundwaterAbstractionLimit)

        # zones at which water allocation (surface and groundwater allocation) is determined
        self.usingAllocSegments = False
        if iniItems.landSurfaceOptions['allocationSegmentsForGroundSurfaceWater'] != "None":
            self.usingAllocSegments = True

        # incorporating groundwater distribution network:
        if self.usingAllocSegments and self.limitAbstraction == False:

            self.allocSegments = vos.readPCRmapClone(
                iniItems.landSurfaceOptions['allocationSegmentsForGroundSurfaceWater'],
                self.cloneMap, self.tmpDir, self.inputDir, isLddMap=False, cover=None, isNomMap=True)
            self.allocSegments = pcr.ifthen(self.landmask, self.allocSegments)

            cellArea = vos.readPCRmapClone(
                iniItems.routingOptions['cellAreaMap'],
                self.cloneMap, self.tmpDir, self.inputDir)
            # TODO: integrate this one with the one coming from the routing module
            cellArea = pcr.ifthen(self.landmask, cellArea)

            self.segmentArea = pcr.areatotal(
                pcr.cover(cellArea, 0.0), self.allocSegments)
            self.segmentArea = pcr.ifthen(self.landmask, self.segmentArea)

        self.report = True
        try:
            self.outDailyTotNC = iniItems.groundwaterOptions['outDailyTotNC'].split(
                ",")
            self.outMonthTotNC = iniItems.groundwaterOptions['outMonthTotNC'].split(
                ",")
            self.outMonthAvgNC = iniItems.groundwaterOptions['outMonthAvgNC'].split(
                ",")
            self.outMonthEndNC = iniItems.groundwaterOptions['outMonthEndNC'].split(
                ",")
            self.outAnnuaTotNC = iniItems.groundwaterOptions['outAnnuaTotNC'].split(
                ",")
            self.outAnnuaAvgNC = iniItems.groundwaterOptions['outAnnuaAvgNC'].split(
                ",")
            self.outAnnuaEndNC = iniItems.groundwaterOptions['outAnnuaEndNC'].split(
                ",")
        except:
            self.report = False
        if self.report == True:
            self.outNCDir = iniItems.outNCDir
            self.netcdfObj = PCR2netCDF(iniItems)
            #
            # daily output in netCDF files:
            if self.outDailyTotNC[0] != "None":
                for var in self.outDailyTotNC:
                    # creating the netCDF files:
                    self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" +
                                                str(var)+"_dailyTot.nc",
                                                var, "undefined")
            # MONTHly output in netCDF files:
            # - cummulative
            if self.outMonthTotNC[0] != "None":
                for var in self.outMonthTotNC:
                    # initiating monthlyVarTot (accumulator variable):
                    vars(self)[var+'MonthTot'] = None
                    # creating the netCDF files:
                    self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" +
                                                str(var)+"_monthTot.nc",
                                                var, "undefined")
            # - average
            if self.outMonthAvgNC[0] != "None":
                for var in self.outMonthAvgNC:
                    # initiating monthlyTotAvg (accumulator variable)
                    vars(self)[var+'MonthTot'] = None
                    # initiating monthlyVarAvg:
                    vars(self)[var+'MonthAvg'] = None
                    # creating the netCDF files:
                    self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" +
                                                str(var)+"_monthAvg.nc",
                                                var, "undefined")
            # - last day of the month
            if self.outMonthEndNC[0] != "None":
                for var in self.outMonthEndNC:
                    # creating the netCDF files:
                    self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" +
                                                str(var)+"_monthEnd.nc",
                                                var, "undefined")
            # YEARly output in netCDF files:
            # - cummulative
            if self.outAnnuaTotNC[0] != "None":
                for var in self.outAnnuaTotNC:
                    # initiating yearly accumulator variable:
                    vars(self)[var+'AnnuaTot'] = None
                    # creating the netCDF files:
                    self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" +
                                                str(var)+"_annuaTot.nc",
                                                var, "undefined")
            # - average
            if self.outAnnuaAvgNC[0] != "None":
                for var in self.outAnnuaAvgNC:
                    # initiating annualyVarAvg:
                    vars(self)[var+'AnnuaAvg'] = None
                    # initiating annualyTotAvg (accumulator variable)
                    vars(self)[var+'AnnuaTot'] = None
                    # creating the netCDF files:
                    self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" +
                                                str(var)+"_annuaAvg.nc",
                                                var, "undefined")
            # - last day of the year
            if self.outAnnuaEndNC[0] != "None":
                for var in self.outAnnuaEndNC:
                    # creating the netCDF files:
                    self.netcdfObj.createNetCDF(str(self.outNCDir)+"/" +
                                                str(var)+"_annuaEnd.nc",
                                                var, "undefined")

        # get initial conditions
        self.getICs(iniItems, spinUp)
Esempio n. 7
0
    def getParameterFiles(self,
                          currTimeStep,
                          cellArea,
                          ldd,
                          cellLengthFD,
                          cellSizeInArcDeg,
                          initial_condition_dictionary=None):

        # parameters for Water Bodies: fracWat
        #                              waterBodyIds
        #                              waterBodyOut
        #                              waterBodyArea
        #                              waterBodyTyp
        #                              waterBodyCap

        # cell surface area (m2) and ldd
        self.cellArea = cellArea
        ldd = pcr.ifthen(self.landmask, ldd)

        # date used for accessing/extracting water body information
        date_used = currTimeStep.fulldate
        year_used = currTimeStep.year
        if self.onlyNaturalWaterBodies == True:
            date_used = self.dateForNaturalCondition
            year_used = self.dateForNaturalCondition[0:4]

        # fracWat = fraction of surface water bodies (dimensionless)
        self.fracWat = pcr.scalar(0.0)

        if self.useNetCDF:
            self.fracWat = vos.netcdf2PCRobjClone(
                self.ncFileInp,
                'fracWaterInp',
                date_used,
                useDoy='yearly',
                cloneMapFileName=self.cloneMap)
        else:
            self.fracWat = vos.readPCRmapClone(
                self.fracWaterInp + str(year_used) + ".map", self.cloneMap,
                self.tmpDir, self.inputDir)

        self.fracWat = pcr.cover(self.fracWat, 0.0)
        self.fracWat = pcr.max(0.0, self.fracWat)
        self.fracWat = pcr.min(1.0, self.fracWat)

        self.waterBodyIds = pcr.nominal(0)  # waterBody ids
        self.waterBodyOut = pcr.boolean(0)  # waterBody outlets
        self.waterBodyArea = pcr.scalar(0.)  # waterBody surface areas

        # water body ids
        if self.useNetCDF:
            self.waterBodyIds = vos.netcdf2PCRobjClone(
                self.ncFileInp,
                'waterBodyIds',
                date_used,
                useDoy='yearly',
                cloneMapFileName=self.cloneMap)
        else:
            self.waterBodyIds = vos.readPCRmapClone(
                self.waterBodyIdsInp + str(year_used) + ".map", self.cloneMap,
                self.tmpDir, self.inputDir, False, None, True)
        #
        self.waterBodyIds = pcr.ifthen(
            pcr.scalar(self.waterBodyIds) > 0., pcr.nominal(self.waterBodyIds))

        # ADDED: adjust waterBodyIds if ActivateCoupling is set to True
        # ----------------------------------------------------------------------------------------------------------------
        if self.ActivateCoupling == 'True':
            self.waterBodyIds = pcr.scalar(
                self.waterBodyIds) * self.waterBodyIdsAdjust
            self.waterBodyIds = pcr.nominal(self.waterBodyIds)
        # ----------------------------------------------------------------------------------------------------------------

        # water body outlets (correcting outlet positions)
        wbCatchment = pcr.catchmenttotal(pcr.scalar(1), ldd)
        self.waterBodyOut = pcr.ifthen(wbCatchment == pcr.areamaximum(
            wbCatchment, self.waterBodyIds), self.waterBodyIds)  # = outlet ids
        self.waterBodyOut = pcr.ifthen(
            pcr.scalar(self.waterBodyIds) > 0., self.waterBodyOut)
        # TODO: Please also consider endorheic lakes!

        # correcting water body ids
        self.waterBodyIds = pcr.ifthen(
            pcr.scalar(self.waterBodyIds) > 0.,
            pcr.subcatchment(ldd, self.waterBodyOut))

        # boolean map for water body outlets:
        self.waterBodyOut = pcr.ifthen(
            pcr.scalar(self.waterBodyOut) > 0., pcr.boolean(1))

        # reservoir surface area (m2):
        if self.useNetCDF:
            resSfArea = 1000. * 1000. * \
                vos.netcdf2PCRobjClone(self.ncFileInp, 'resSfAreaInp',
                                       date_used, useDoy='yearly',
                                       cloneMapFileName=self.cloneMap)
        else:
            resSfArea = 1000. * 1000. * vos.readPCRmapClone(
                self.resSfAreaInp + str(year_used) + ".map", self.cloneMap,
                self.tmpDir, self.inputDir)
        resSfArea = pcr.areaaverage(resSfArea, self.waterBodyIds)
        resSfArea = pcr.cover(resSfArea, 0.)

        # water body surface area (m2): (lakes and reservoirs)
        self.waterBodyArea = pcr.max(
            pcr.areatotal(pcr.cover(self.fracWat * self.cellArea, 0.0),
                          self.waterBodyIds),
            pcr.areaaverage(pcr.cover(resSfArea, 0.0), self.waterBodyIds))
        self.waterBodyArea = pcr.ifthen(self.waterBodyArea > 0.,
                                        self.waterBodyArea)

        # correcting water body ids and outlets (exclude all water bodies with surfaceArea = 0)
        self.waterBodyIds = pcr.ifthen(self.waterBodyArea > 0.,
                                       self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(pcr.boolean(self.waterBodyIds),
                                       self.waterBodyOut)

        # water body types:
        # - 2 = reservoirs (regulated discharge)
        # - 1 = lakes (weirFormula)
        # - 0 = non lakes or reservoirs (e.g. wetland)
        self.waterBodyTyp = pcr.nominal(0)

        if self.useNetCDF:
            self.waterBodyTyp = vos.netcdf2PCRobjClone(
                self.ncFileInp,
                'waterBodyTyp',
                date_used,
                useDoy='yearly',
                cloneMapFileName=self.cloneMap)
        else:
            self.waterBodyTyp = vos.readPCRmapClone(
                self.waterBodyTypInp + str(year_used) + ".map", self.cloneMap,
                self.tmpDir, self.inputDir, False, None, True)

        # excluding wetlands (waterBodyTyp = 0) in all functions related to lakes/reservoirs
        #
        self.waterBodyTyp = pcr.ifthen(
            pcr.scalar(self.waterBodyTyp) > 0, pcr.nominal(self.waterBodyTyp))
        self.waterBodyTyp = pcr.ifthen(
            pcr.scalar(self.waterBodyIds) > 0, pcr.nominal(self.waterBodyTyp))
        self.waterBodyTyp = pcr.areamajority(
            self.waterBodyTyp, self.waterBodyIds
        )  # choose only one type: either lake or reservoir
        self.waterBodyTyp = pcr.ifthen(
            pcr.scalar(self.waterBodyTyp) > 0, pcr.nominal(self.waterBodyTyp))
        self.waterBodyTyp = pcr.ifthen(pcr.boolean(self.waterBodyIds),
                                       self.waterBodyTyp)

        # correcting lakes and reservoirs ids and outlets
        self.waterBodyIds = pcr.ifthen(
            pcr.scalar(self.waterBodyTyp) > 0, self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(
            pcr.scalar(self.waterBodyIds) > 0, self.waterBodyOut)

        # reservoir maximum capacity (m3):
        self.resMaxCap = pcr.scalar(0.0)
        self.waterBodyCap = pcr.scalar(0.0)

        if self.useNetCDF:
            self.resMaxCap = 1000. * 1000. * \
                vos.netcdf2PCRobjClone(self.ncFileInp, 'resMaxCapInp',
                                       date_used, useDoy='yearly',
                                       cloneMapFileName=self.cloneMap)
        else:
            self.resMaxCap = 1000. * 1000. * vos.readPCRmapClone(
                self.resMaxCapInp + str(year_used) + ".map", self.cloneMap,
                self.tmpDir, self.inputDir)

        self.resMaxCap = pcr.ifthen(self.resMaxCap > 0, self.resMaxCap)
        self.resMaxCap = pcr.areaaverage(self.resMaxCap, self.waterBodyIds)

        # water body capacity (m3): (lakes and reservoirs)
        # Note: Most of lakes have capacities > 0.
        self.waterBodyCap = pcr.cover(self.resMaxCap, 0.0)
        self.waterBodyCap = pcr.ifthen(pcr.boolean(self.waterBodyIds),
                                       self.waterBodyCap)

        # correcting water body types:                                  # Reservoirs that have zero capacities will be assumed as lakes.
        self.waterBodyTyp = \
            pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,
                       self.waterBodyTyp)
        self.waterBodyTyp = pcr.ifthenelse(
            self.waterBodyCap > 0., self.waterBodyTyp,
            pcr.ifthenelse(
                pcr.scalar(self.waterBodyTyp) == 2, pcr.nominal(1),
                self.waterBodyTyp))

        # final corrections:
        self.waterBodyTyp = pcr.ifthen(
            self.waterBodyArea > 0., self.waterBodyTyp
        )  # make sure that all lakes and/or reservoirs have surface areas
        self.waterBodyTyp = \
            pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,
                       self.waterBodyTyp)                     # make sure that only types 1 and 2 will be considered in lake/reservoir functions
        self.waterBodyIds = pcr.ifthen(
            pcr.scalar(self.waterBodyTyp) > 0., self.waterBodyIds
        )  # make sure that all lakes and/or reservoirs have ids
        self.waterBodyOut = pcr.ifthen(
            pcr.scalar(self.waterBodyIds) > 0., self.waterBodyOut
        )  # make sure that all lakes and/or reservoirs have outlets

        # for a natural run (self.onlyNaturalWaterBodies == True)
        # which uses only the year 1900, assume all reservoirs are lakes
        if self.onlyNaturalWaterBodies == True and date_used == self.dateForNaturalCondition:
            logger.info(
                "WARNING!! Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes."
            )
            self.waterBodyTyp = \
                pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,
                           pcr.nominal(1))

        # check that all lakes and/or reservoirs have types, ids, surface areas and outlets:
        test = pcr.defined(self.waterBodyTyp) & pcr.defined(self.waterBodyArea) &\
            pcr.defined(self.waterBodyIds) & pcr.boolean(
                pcr.areamaximum(pcr.scalar(self.waterBodyOut), self.waterBodyIds))
        a, b, c = vos.getMinMaxMean(pcr.scalar(test) - pcr.scalar(1.0))
        threshold = 1e-3
        if abs(a) > threshold or abs(b) > threshold:
            logger.info(
                "WARNING !!!!! Missing information in some lakes and/or reservoirs."
            )

        # at the beginning of simulation period (timeStepPCR = 1)
        # - we have to define/get the initial conditions
        #
        if currTimeStep.timeStepPCR == 1:
            self.getICs(initial_condition_dictionary)

        # For each new reservoir (introduced at the beginning of the year)
        # initiating storage, average inflow and outflow
        #
        self.waterBodyStorage = pcr.cover(self.waterBodyStorage, 0.0)
        self.avgInflow = pcr.cover(self.avgInflow, 0.0)
        self.avgOutflow = pcr.cover(self.avgOutflow, 0.0)

        # cropping only in the landmask region:
        self.fracWat = pcr.ifthen(self.landmask, self.fracWat)
        self.waterBodyIds = pcr.ifthen(self.landmask, self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(self.landmask, self.waterBodyOut)
        self.waterBodyArea = pcr.ifthen(self.landmask, self.waterBodyArea)
        self.waterBodyTyp = pcr.ifthen(self.landmask, self.waterBodyTyp)
        self.waterBodyCap = pcr.ifthen(self.landmask, self.waterBodyCap)
        self.waterBodyStorage = pcr.ifthen(self.landmask,
                                           self.waterBodyStorage)
        self.avgInflow = pcr.ifthen(self.landmask, self.avgInflow)
        self.avgOutflow = pcr.ifthen(self.landmask, self.avgOutflow)