def soilStorageVolume(self, state, cellAreaMap): if self.numberOfLayers == 2: \ return vos.getMapVolume(\ state['landSurface']['topWaterLayer'] + state['landSurface']['storUpp'] +\ + state['landSurface']['storLow'] +\ state['groundwater']['storGroundwater'], cellAreaMap) # unit: m3 if self.numberOfLayers == 3: \ return vos.getMapVolume(\ state['landSurface']['topWaterLayer'] + state['landSurface']['storUpp000005'] +\ state['landSurface']['storUpp005030'] + state['landSurface']['storLow030150'] +\ state['groundwater']['storGroundwater'], cellAreaMap) # unit: m3
def totalStorageVolume(self, state, cellAreaMap): return self.soilStorageVolume(state, cellAreaMap) + self.groundwaterStorageVolume(state, cellAreaMap) +\ vos.getMapVolume(\ state['landSurface']['interceptStor'] +\ state['landSurface']['snowFreeWater'] +\ state['landSurface']['snowCoverSWE'], cellAreaMap) # unit: m3
def getIniStates(self, model): if self.numberOfLayers == 2: self.iniSoilSto = max(1E-20,\ vos.getMapVolume(\ model.landSurface.topWaterLayer +\ model.landSurface.storUpp +\ model.landSurface.storLow +\ model.groundwater.storGroundwater, model.routing.cellArea)) # unit: m3 if self.numberOfLayers == 3: self.iniSoilSto = max(1E-20,\ vos.getMapVolume(\ model.landSurface.topWaterLayer +\ model.landSurface.storUpp000005 +\ model.landSurface.storUpp005030 +\ model.landSurface.storLow030150 +\ model.groundwater.storGroundwater, model.routing.cellArea)) # unit: m3 self.iniGwatSto = max(1E-20,\ vos.getMapVolume(\ model.groundwater.storGroundwater, model.routing.cellArea)) # unit: m3 self.iniChanSto = max(1E-20,\ vos.getMapVolume(\ model.routing.channelStorage,1)) # unit: m3 self.iniTotlSto = max(1E-20,\ self.iniSoilSto + self.iniChanSto +\ vos.getMapVolume(\ model.landSurface.interceptStor +\ model.landSurface.snowFreeWater +\ model.landSurface.snowCoverSWE, model.routing.cellArea)) # unit: m3
def report(self): #report the state. which states are written when is based on the configuration #set total to 0 on first day of the year if self._modelTime.doy == 1 or self._modelTime.isFirstTimestep(): # set all accumulated variables to zero self.precipitationAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.baseflowAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.runoffAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) # accumulating until the last day of the year: self.precipitationAcc += self.meteo.precipitation self.baseflowAcc += self.routing.baseflow self.runoffAcc += self.routing.runoff if self._modelTime.isLastDayOfMonth(): self.dumpState(self._configuration.endStateDir) totalCellArea = vos.getMapTotal(pcr.ifthen(self.landmask,self.routing.cellArea)) msg = 'Total area = %e km2'\ % (totalCellArea/1e6) logging.getLogger("model").info(msg) # reporting the endStates at the end of the Year: variableList = ['precipitation', 'baseflow', 'runoff'] for var in variableList: volume = vos.getMapVolume(\ self.__getattribute__(var + 'Acc'),\ self.routing.cellArea) msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\ % (var,int(self._modelTime.doy),\ int(self._modelTime.year),volume/1e9,volume*1000/totalCellArea) logging.getLogger("model").info(msg)
def channelStorageVolume(self, state, cellAreaMap): return vos.getMapVolume(state['routing']['channelStorage'], cellAreaMap) # unit: m3
def groundwaterStorageVolume(self, state, cellAreaMap): return vos.getMapVolume(state['groundwater']['storGroundwater'], cellAreaMap) # unit: m3
def report_summary(self, landWaterStoresAtBeginning, landWaterStoresAtEnd,\ surfaceWaterStoresAtBeginning, surfaceWaterStoresAtEnd): # set total to 0 on first day of the year if self._modelTime.doy == 1 or self._modelTime.isFirstTimestep(): # set all accumulated variables to zero self.precipitationAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) for var in self.landSurface.fluxVars: vars(self)[var+'Acc'] = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.baseflowAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.surfaceWaterInfAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.runoffAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.unmetDemandAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.waterBalanceAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.absWaterBalanceAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) # non irrigation water use (unit: m) self.nonIrrigationWaterUseAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) # non irrigation return flow to water body and water body evaporation (unit: m) self.nonIrrReturnFlowAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.waterBodyEvaporationAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) # surface water input/loss volume (m3) and outgoing volume (m3) at pits self.surfaceWaterInputAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.dischargeAtPitAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) # also save the storages at the first day of the year (or the first time step) # - land surface storage (unit: m) self.storageAtFirstDay = pcr.ifthen(self.landmask, landWaterStoresAtBeginning) # - channel storages (unit: m3) self.channelVolumeAtFirstDay = pcr.ifthen(self.landmask, surfaceWaterStoresAtBeginning) # accumulating until the last day of the year: self.precipitationAcc += self.meteo.precipitation for var in self.landSurface.fluxVars: vars(self)[var+'Acc'] += vars(self.landSurface)[var] self.baseflowAcc += self.groundwater.baseflow self.surfaceWaterInfAcc += self.groundwater.surfaceWaterInf self.runoffAcc += self.routing.runoff self.unmetDemandAcc += self.groundwater.unmetDemand self.waterBalance = \ (landWaterStoresAtBeginning - landWaterStoresAtEnd +\ self.meteo.precipitation + self.landSurface.irrGrossDemand + self.groundwater.surfaceWaterInf -\ self.landSurface.actualET - self.routing.runoff - self.groundwater.nonFossilGroundwaterAbs) self.waterBalanceAcc += self.waterBalance self.absWaterBalanceAcc += pcr.abs(self.waterBalance) # consumptive water use for non irrigation demand (m) self.nonIrrigationWaterUseAcc += self.routing.nonIrrWaterConsumption self.nonIrrReturnFlowAcc += self.routing.nonIrrReturnFlow self.waterBodyEvaporationAcc += self.routing.waterBodyEvaporation self.surfaceWaterInputAcc += self.routing.local_input_to_surface_water # unit: m3 self.dischargeAtPitAcc += self.routing.outgoing_volume_at_pits # unit: m3 #TODO: hack for eWatercycle operational spinup #if self._modelTime.isLastDayOfMonth() or self._modelTime.isLastTimestep(): #TODO: extra hack! dump every state self.dumpStateDir(self._configuration.endStateDir) if self._modelTime.isLastDayOfYear(): self.dumpState(self._configuration.endStateDir) logger.info("") msg = 'The following summary values do not include storages in surface water bodies (lake, reservoir and channel storages).' logger.info(msg) # TODO: Improve these water balance checks. totalCellArea = vos.getMapTotal(pcr.ifthen(self.landmask,self.routing.cellArea)) msg = 'Total area = %e km2'\ % (totalCellArea/1e6) logger.info(msg) deltaStorageOneYear = vos.getMapVolume( \ pcr.ifthen(self.landmask,landWaterStoresAtBeginning) - \ pcr.ifthen(self.landmask,self.storageAtFirstDay), self.routing.cellArea) msg = 'Delta total storage days 1 to %i in %i = %e km3 = %e mm'\ % ( int(self._modelTime.doy),\ int(self._modelTime.year),\ deltaStorageOneYear/1e9,\ deltaStorageOneYear*1000/totalCellArea) logger.info(msg) variableList = ['precipitation', 'baseflow', 'surfaceWaterInf', 'runoff', 'unmetDemand'] variableList += self.landSurface.fluxVars variableList += ['waterBalance','absWaterBalance','irrigationWaterUse','nonIrrigationWaterUse'] # consumptive water use for irrigation (unit: m) self.irrigationWaterUseAcc = vos.getValDivZero(self.irrGrossDemandAcc,\ self.precipitationAcc + self.irrGrossDemandAcc) * self.actualETAcc for var in variableList: volume = vos.getMapVolume(\ self.__getattribute__(var + 'Acc'),\ self.routing.cellArea) msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\ % (var,int(self._modelTime.doy),\ int(self._modelTime.year),volume/1e9,volume*1000/totalCellArea) logger.info(msg) logger.info("") msg = 'The following summary is for surface water bodies.' logger.info(msg) deltaChannelStorageOneYear = vos.getMapTotal( \ pcr.ifthen(self.landmask,surfaceWaterStoresAtEnd) - \ pcr.ifthen(self.landmask,self.channelVolumeAtFirstDay)) msg = 'Delta surface water storage days 1 to %i in %i = %e km3 = %e mm'\ % ( int(self._modelTime.doy),\ int(self._modelTime.year),\ deltaChannelStorageOneYear/1e9,\ deltaChannelStorageOneYear*1000/totalCellArea) logger.info(msg) variableList = ['nonIrrReturnFlow','waterBodyEvaporation'] for var in variableList: volume = vos.getMapVolume(\ self.__getattribute__(var + 'Acc'),\ self.routing.cellArea) msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\ % (var,int(self._modelTime.doy),\ int(self._modelTime.year),volume/1e9,volume*1000/totalCellArea) logger.info(msg) # surface water balance check surfaceWaterInputTotal = vos.getMapTotal(self.surfaceWaterInputAcc) msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\ % ("surfaceWaterInput",int(self._modelTime.doy),\ int(self._modelTime.year),surfaceWaterInputTotal/1e9,surfaceWaterInputTotal*1000/totalCellArea) logger.info(msg) dischargeAtPitTotal = vos.getMapTotal(self.dischargeAtPitAcc) msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\ % ("dischargeAtPitTotal",int(self._modelTime.doy),\ int(self._modelTime.year),dischargeAtPitTotal/1e9, dischargeAtPitTotal*1000/totalCellArea) logger.info(msg) surfaceWaterBalance = surfaceWaterInputTotal - dischargeAtPitTotal + deltaChannelStorageOneYear msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\ % ("surfaceWaterBalance",int(self._modelTime.doy),\ int(self._modelTime.year),surfaceWaterBalance/1e9, surfaceWaterBalance*1000/totalCellArea) logger.info(msg)
def report(self, storesAtBeginning, storesAtEnd): #report the state. which states are written when is based on the configuration #set total to 0 on first day of the year if self._modelTime.doy == 1 or self._modelTime.isFirstTimestep(): # set all accumulated variables to zero self.precipitationAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) for var in self.landSurface.fluxVars: vars(self)[var+'Acc'] = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.nonFossilGroundwaterAbsAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.allocNonFossilGroundwaterAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.baseflowAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.surfaceWaterInfAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.runoffAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.unmetDemandAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.waterBalanceAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) self.absWaterBalanceAcc = pcr.ifthen(self.landmask, pcr.scalar(0.0)) # also save the storage at the first day of the year (or the first time step) self.storageAtFirstDay = pcr.ifthen(self.landmask, storesAtBeginning) # accumulating until the last day of the year: self.precipitationAcc += self.meteo.precipitation for var in self.landSurface.fluxVars: vars(self)[var+'Acc'] += vars(self.landSurface)[var] self.nonFossilGroundwaterAbsAcc += self.groundwater.nonFossilGroundwaterAbs self.allocNonFossilGroundwaterAcc += self.groundwater.allocNonFossilGroundwater self.baseflowAcc += self.groundwater.baseflow self.surfaceWaterInfAcc += self.groundwater.surfaceWaterInf self.runoffAcc += self.routing.runoff self.unmetDemandAcc += self.groundwater.unmetDemand self.waterBalance = \ (storesAtBeginning - storesAtEnd +\ self.meteo.precipitation + self.landSurface.irrGrossDemand + self.groundwater.surfaceWaterInf -\ self.landSurface.actualET - self.routing.runoff - self.groundwater.nonFossilGroundwaterAbs) self.waterBalanceAcc = self.waterBalanceAcc + self.waterBalance self.absWaterBalanceAcc = self.absWaterBalanceAcc + pcr.abs(self.waterBalance) if self._modelTime.isLastDayOfYear(): self.dumpState(self._configuration.endStateDir) msg = 'The following waterBalance checks assume fracWat = 0 for all cells (not including surface water bodies).' logging.getLogger("model").info(msg) # TODO: Improve these water balance checks. totalCellArea = vos.getMapTotal(pcr.ifthen(self.landmask,self.routing.cellArea)) msg = 'Total area = %e km2'\ % (totalCellArea/1e6) logging.getLogger("model").info(msg) deltaStorageOneYear = vos.getMapVolume( \ pcr.ifthen(self.landmask,storesAtEnd) - \ pcr.ifthen(self.landmask,self.storageAtFirstDay), self.routing.cellArea) msg = 'Delta total storage days 1 to %i in %i = %e km3 = %e mm'\ % ( int(self._modelTime.doy),\ int(self._modelTime.year),\ deltaStorageOneYear/1e9,\ deltaStorageOneYear*1000/totalCellArea) logging.getLogger("model").info(msg) # reporting the endStates at the end of the Year: variableList = ['precipitation', 'nonFossilGroundwaterAbs', 'allocNonFossilGroundwater', 'baseflow', 'surfaceWaterInf', 'runoff', 'unmetDemand'] variableList += self.landSurface.fluxVars variableList += ['waterBalance','absWaterBalance'] for var in variableList: volume = vos.getMapVolume(\ self.__getattribute__(var + 'Acc'),\ self.routing.cellArea) msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\ % (var,int(self._modelTime.doy),\ int(self._modelTime.year),volume/1e9,volume*1000/totalCellArea) logging.getLogger("model").info(msg)
def dynamic(self): # re-calculate current model time using current pcraster timestep value self.modelTime.update(self.currentTimeStep()) # for the first day of the year or the first timestep # - initiate accumulative flux variables (for calculating yearly total) if self.modelTime.timeStepPCR == 1 or self.modelTime.doy == 1: for var in self.debug_flux_variables: vars(self)[var + 'AnnuaTot'] = pcr.ifthen( self.landmask, pcr.scalar(0.0)) # reading variables from pcraster files, then report them as netcdf files also accumulate annual total values # - timeStamp for reporting timeStamp = datetime.datetime(self.modelTime.year,\ self.modelTime.month,\ self.modelTime.day, 0) for var in self.debug_variables: pcraster_map_file_name = self.results_folder + "/" +\ pcr.framework.frameworkBase.generateNameT(varDicts.pcr_short_name[var],\ self.modelTime.timeStepPCR) logger.debug("Reading the variable %s from the file %s ", var, pcraster_map_file_name) pcr_map_values = pcr.readmap(str(pcraster_map_file_name)) if var in self.debug_flux_variables: logger.debug("Accumulating variable %s ", var) vars(self)[var + 'AnnuaTot'] += pcr_map_values netcdf_file_name = self.netcdf_folder + "/" + str( var) + "_dailyTot_output_version_one.nc" logger.debug("Saving to the file %s ", netcdf_file_name) short_name = varDicts.netcdf_short_name[var] self.netcdf_report.data2NetCDF(netcdf_file_name, short_name,\ pcr.pcr2numpy(pcr_map_values, vos.MV),\ timeStamp) # at the last day of the year, report yearly accumulative values (to the logger) if self.modelTime.isLastDayOfYear() or self.modelTime.isLastTimeStep(): logger.info("") msg = '\n' msg += '=======================================================================================================================\n' msg += '=======================================================================================================================\n' msg += 'Summary of yearly annual flux values of PCR-GLOBWB 1.0.\n' msg += 'The following summary values do not include storages in surface water bodies (lake, reservoir and channel storages).\n' msg += '=======================================================================================================================\n' msg += '=======================================================================================================================\n' msg += '\n' msg += '\n' logger.info(msg) totalCellArea = vos.getMapTotal( pcr.ifthen(self.landmask, self.cellArea)) msg = 'Total area = %e km2'\ % (totalCellArea/1e6) logger.info(msg) for var in self.debug_flux_variables: volume = vos.getMapVolume(\ self.__getattribute__(var + 'AnnuaTot'),\ self.cellArea) msg = 'Accumulated %s from PCR-GLOBWB 1.0 days 1 to %i in %i = %e km3 = %e mm'\ % (var,int(self.modelTime.doy), \ int(self.modelTime.year),volume/1e9,volume*1000/totalCellArea) logger.info(msg) msg = '\n' msg += '\n' msg += '\n' msg += '=======================================================================================================================\n' msg += '\n' msg += '\n' logger.info(msg) # at the last time step, compare the output of version 1 to the one of version 2 if self.modelTime.isLastTimeStep(): self.compare_output()
def getIniStates(self, model): self.iniChanSto = max(1E-20,\ vos.getMapVolume(\ model.routing.channelStorage,1))