!! Perform hydrological simulation
!|author: Giovanni Ravazzani
! license: GPL
!
!```
! ________ _______ ________ _________
! |\ _____\|\ ___ \ |\ ____\ |\___ ___\
! \ \ \__/ \ \ __/| \ \ \___|_ \|___ \ \_|
! \ \ __\ \ \ \_|/__ \ \_____ \ \ \ \
! \ \ \_| \ \ \_|\ \ \|____|\ \ \ \ \
! \ \__\ \ \_______\ ____\_\ \ \ \__\
! \|__| \|_______| |\_________\ \|__|
! \|_________|
! S P A T I A L L Y - D I S T R I B U T E D
! H Y D R O L O G I C A L - M O D E L
!```
!### Description
! _FeST_ is a spatially distributed physically based hydrological
! model. _FeST_ is the acronym of “flash–Flood Event–based Spatially
! distributed rainfall–runoff Transformation”. It was initially developed
! by Mancini (1990), as a model oriented to the simulation of
! rainfall-runoff transformation of single flood events.
! Later the _FeST_ model was merged with the soil water balance scheme
! from TOPLATS model (Famiglietti and Wood, 1994), transforming it into a
! continuous model (Montaldo et al., 2007). Then the _FeST_ code was
! redesigned and rewritten from scratch while keeping the basic assumptions
! of the previous release (Rabuffetti et al., 2008). In 2011 the _FeST_
! was upgraded with a routine to solve the system of water mass and
! energy balance in order to better simulate the actual evapotranspiration
! and interface the model to remotely sensed data (Corbari et al., 2011;
! Corbari & Mancini, 2014). At the same year, 2011, a new module for
! simulating groundwater flux and river-groundwater interaction
! was developed and implemented in the _FeST_ (Ravazzani et al., 2011).
! In 2013 a new version of the code was released built on top of
! the MOSAICO library (Ravazzani, 2013). In 2014 the _FeST_
! was upgraded with a module for glaciers modelling (Boscarello et al., 2014).
! In 2021 a forest growth component was implemented in the _FeST_
! (Feki et al., 2021).
!
!
!### References
!
! Boscarello, L., Ravazzani, G., Rabuffetti, D., & Mancini, M.. (2014).
! Integrating glaciers raster-based modelling in large catchments
! hydrological balance: the Rhone case study.
! Hydrological processes, 28, 496–508.
!
!
! Corbari, C., & Mancini, M. (2014). Calibration and validation of a distributed
! energy–water balance model using satellite data of land surface temperature
! and ground discharge measurements. Journal of hydrometeorology, 15(1), 376-392.
!
! Corbari, C., Ravazzani, G., & Mancini, M. (2011). A distributed thermodynamic
! model for energy and mass balance computation: FEST–EWB.
! Hydrological Processes, 25(9), 1443-1452.
!
! Famiglietti, J.S., & Wood, E.F. (1994). Multiscale modeling of spatially
! variable water and energy balanceprocess. Water Resour. Res.,
! 30, 3061–3078, https://doi.org/10.1029/94WR01498.
!
! Feki, M., Ravazzani, G., Ceppi, A., Pellicone, G., & Caloiero, T.. (2021).
! Integration of forest growth component in the fest-wb distributed
! hydrological model: the bonis catchment case study. Forests, 12(12).
!
! Mancini, M.. (1990). La modellazione distribuita della risposta idrologica:
! effetti della variabilità spaziale e della scala di rappresentazione
! del fenomeno dell'assorbimento. PhD thesis. Politecnico di Milano,
! Istituto di idraulica
!
! Montaldo, N., Ravazzani, G., & Mancini, M.. (2007). On the
! prediction of the toce alpine basin floods with distributed
! hydrologic models. Hydrological processes, 21, 608–621
!
! Rabuffetti, D., Ravazzani, G., Corbari, C., & Mancini, M.. (2008).
! Verification of operational quantitative discharge forecast (QDF)
! for a regional warning system – the AMPHORE case studies in the
! upper Po river. Natural hazards and earth system sciences, 8, 161–173.
!
! Ravazzani, G.. (2013). Mosaico, a library for raster based hydrological
! applications. Computers & geosciences, 51, 1–6.
!
! Ravazzani, G., Rametta, D., & Mancini, M.. (2011). Macroscopic
! cellular automata for groundwater modelling: a first approach.
! Environmental modelling & software, 26(5), 634–643.
!
!
!
!### License
! license: GNU GPL
!
PROGRAM Fest
USE IniLib, ONLY: &
!Imported derived types:
IniList, &
!Imported routines:
IniOpen, IniClose, &
IniReadInt, IniReadReal, IniReadDouble, &
IniReadString, SectionIsPresent, &
KeyIsPresent
USE HydroNetwork, ONLY : &
!imported definitions:
!NetworkSurfaceFlow,
NetworkGroundwater
USE Reservoirs, ONLY : &
!imported definitions:
Reservoir, &
!Imported variables:
dtReservoir, &
!Imported routines:
ReservoirSaveStatus
USE Diversions, ONLY : &
!imported variables:
dtDiversion, &
!imported routines:
DiversionSaveStatus
USE SpatialAverage, ONLY : &
!imported routines:
InitSpatialAverageMeteo, &
InitSpatialAverageBalance, &
InitSpatialAverageSnow, &
InitSpatialAverageGlaciers, &
InitSpatialAverageSediment, &
InitSpatialAverageCanopy, &
InitSpatialAveragePlants, &
ComputeSpatialAverageMeteo,&
ComputeSpatialAverageBalance, &
ComputeSpatialAverageSnow, &
ComputeSpatialAverageGlaciers, &
ComputeSpatialAverageSediment, &
ComputeSpatialAverageCanopy, &
ComputeSpatialAveragePlants, &
ExportSpatialAverageMeteo, &
ExportSpatialAverageBalance, &
ExportSpatialAverageSnow, &
ExportSpatialAverageGlaciers, &
ExportSpatialAverageSediment, &
ExportSpatialAverageCanopy, &
ExportSpatialAveragePlants, &
timeSpatialAverageMeteo, &
timeSpatialAverageBalance,&
timeSpatialAverageSnow, &
timeSpatialAverageIce, &
timeSpatialAverageSediment, &
timeSpatialAverageCanopy, &
timeSpatialAveragePlants
USE BasinAverage, ONLY : &
!Imported routines:
InitBasinAverage, &
ReadPointFileBasinAverage, &
ExportBasinAverage, &
!Imported variables:
dtBasinAverage
USE RasterExport, ONLY : &
!Imported routines:
InitRasterExport, &
ExportMaps
USE Snow, ONLY : &
!imported routines:
SnowInit, SnowUpdate, &
SnowPointInit, &
!Imported variables:
dtSnow, meltCoefficient, &
swe, waterInSnow, snowMelt, &
rainfallRate
USE Glacier, ONLY : &
!imported routines:
GlacierInit, GlacierPointInit, &
GlacierUpdate, &
!imported variables:
dtIce, icewe, waterInIce, iceMelt
USE SoilBalance, ONLY : &
!imported routines
InitSoilBalance, SolveSoilBalance, &
!imported variables:
soilMoisture, soilMoistureRZ, &
soilMoistureTZ, soilSatRZ, &
soilSatTZ, sEff, rainFlag, &
runoff, infilt, percolation, caprise, &
soilDepth, wiltingPoint, fieldCapacity, &
psdi, ksat, et, pet, dtSoilBalance, &
QinSoilSub, soilSat, balanceError, &
interstormDuration, deltaSoilMoisture
USE Infiltration, ONLY : &
!imported variables:
infiltrationModel, SCS_CN, &
PHILIPEQ, GREEN_AMPT, &
sEff, raincum, cuminf
USE Groundwater, ONLY : &
!Imported routines:
GroundwaterInit, &
GroundwaterUpdate, &
GroundwaterPointInit, &
GroundwaterOutputInit, &
GroundwaterOutput, &
GroundwaterRiverUpdate, &
!imported variables:
dtGroundwater, &
vadoseDepth, &
riverGroundwaterInteract, &
riverToGroundwater, &
groundwaterToRiver
USE DischargeRouting, ONLY : &
!imported routines:
InitDischargeRouting, DischargeRoute, &
DischargePointInit, &
!imported variables:
Qin, Qout, Pin, Pout, Plat, &
dtDischargeRouting, &
topWidth, waterDepth
USE Irrigation, ONLY : &
!Imported routines:
IrrigationConfig, IrrigationUpdate, &
!Imported variables:
dtIrrigation, &
irrigationFlux
USE Sediment, ONLY: &
!Imported routines:
SedimentInit, InterrillDetachmentRate, &
SedimentRouting, &
!imported variables:
interrillErosion, routeSediment, QoutSed, deltaSed
USE DomainProperties, ONLY: &
!imported variables:
mask, albedoGround, albedo, &
albedo_loaded, &
!imported routines:
DomainInit
USE MorphologicalProperties, ONLY: &
!imported variables:
dem, dem_loaded, &
flowDirection, &
streamNetwork, &
!imported routines:
MorphologyInit
USE Meteo, ONLY: &
!Imported routines:
MeteoInit, MeteoRead , &
MeteoPointInit, &
!Imported variables:
dtMeteo
USE Precipitation, ONLY: &
!imported variables:
precipitationRate
USE PrecipitationDaily, ONLY: &
!imported variables:
precipitationRateDaily
USE AirTemperature, ONLY: &
!imported variables:
temperatureAir
USE AirTemperatureDailyMean, ONLY: &
!imported variables:
temperatureAirDailyMean
USE AirTemperatureDailyMax, ONLY: &
!imported variables:
temperatureAirDailyMax
USE AirTemperatureDailyMin, ONLY: &
!imported variables:
temperatureAirDailyMin
USE SolarRadiation, ONLY: &
!imported variables:
radiation, netRadiation
USE AirRelativeHumidity, ONLY: &
!imported variables:
relHumidityAir
USE WindFlux, ONLY: &
!imported variables:
windSpeed
USE Plants, ONLY : &
!imported routines:
PlantsConfig, PlantsGrow, &
PlantsParameterUpdate, &
!imported variables:
dtPlants, lai, fvcover, &
gpp, npp, carbonroot, &
carbonstem, carbonleaf, dbh, &
plantsHeight, density, stemyield, &
rsMinLoaded, updatePlantsParameters
USE PlantsInterception, ONLY: &
!imported variables:
dtCanopyInterception, canopyStorage, &
canopyPT, &
!imported routines:
InterceptionInit, Throughfall, &
AdjustPT
USE DataTypeSizes, ONLY: &
!Imported parameters:
short, long, float
USE LogLib, ONLY: &
!Imported routines:
LogInit, LogStop, Catch, &
!Imported variables:
verbose
USE GeoLib, ONLY: &
!Imported routines:
GeoInit
USE Chronos, ONLY: &
!Imported routines:
GetMinute, GetHour, GetMonth, &
GetDay, GetDayOfWeek, &
!Imported definitions:
DateTime, &
!Imported variables:
timeString, &
!Imported operators:
ASSIGNMENT (=), &
OPERATOR (+), &
OPERATOR (-), &
OPERATOR (==), &
OPERATOR (>), &
OPERATOR (<), &
OPERATOR (<=)
USE GridOperations, ONLY : &
!Imported operators:
ASSIGNMENT (=)
USE GridLib, ONLY : &
!imported definition:
grid_real, &
!imported routines:
NewGrid, ExportGrid, &
!imported parameters:
ESRI_BINARY
USE StringManipulation, ONLY : &
!imported routines
StringCompact, StringTokenize, &
StringToLong
USE CronSchedule, ONLY : &
!Imported types:
CronTab, &
!Imported routines:
CronParseString, &
CronIsTime
IMPLICIT NONE
!configuration
TYPE (IniList) :: festIni
CHARACTER (len = 300) :: arg !! command line arguments
CHARACTER (len = 1000) :: string
LOGICAL :: iniFound !!says if configuration file has been passed as command argument
!simulation time
TYPE (DateTime) :: time !current step time
TYPE (DateTime) :: timeStart !start time
TYPE (DateTime) :: timeStop !stop time
!meteo
TYPE (DateTime) :: timeNewMeteo
TYPE (DateTime) :: timeOutMeteo
INTEGER (KIND = short) :: dtOutMeteo
!irrigation
TYPE (DateTime) :: timeNewIrrigation
TYPE (DateTime) :: timeOutIrrigation
INTEGER (KIND = short) :: dtOutIrrigation
!snow
TYPE (DateTime) :: timeNewSnow
TYPE (DateTime) :: timeOutSnow
INTEGER (KIND = short) :: dtOutSnow
!glacier
TYPE(DateTime) :: timeNewIce
TYPE(DateTime) :: timeOutIce
INTEGER (KIND = short) :: dtOutIce
!canopy interception
TYPE(DateTime) :: timeNewCanopyInterception
TYPE(grid_real) :: raineff ! throughfall[m/s]
INTEGER (KIND = short) :: dtOutCanopy
TYPE (DateTime) :: timeOutCanopy
!forest dynamic
TYPE(DateTime) :: timeNewPlants
INTEGER (KIND = short) :: dtOutPlants
TYPE (DateTime) :: timeOutPlants
!soil balance
TYPE(DateTime) timeNewSoilBalance
!bilancio energetico
TYPE (grid_real)Ts !temperatura supeficiale
TYPE (grid_real)Rnetta
TYPE (grid_real)Xle
TYPE (grid_real)Hse
TYPE (grid_real)Ge
TYPE (grid_real)Ta_prec !temperatura aria istante precedente
TYPE (grid_real)Ts_prec !temperatura suolo istante precedente
!output
TYPE(DateTime) :: timeOutSoilBalance
INTEGER :: dtOutSoilBalance
! groundwater
INTEGER (KIND = short) :: dtOutGroundwater
TYPE(DateTime) :: timeNewGroundwater
TYPE(DateTime) :: timeOutGroundwater
!sediment
INTEGER :: dtCalcSediment
TYPE(DateTime) :: timeUpdateSediment
INTEGER :: dtOutSediment
TYPE(DateTime) :: timeOutSediment
!sediment routing
INTEGER :: dtCalcSedimentRouting
TYPE(DateTime) :: timeUpdateSedimentRouting
INTEGER :: dtOutSedimentRouting
TYPE(DateTime) :: timeOutSedimentRouting
! TYPE(rete_osservativa) :: xsOutSedimentRouting
! discharge routing
TYPE (DateTime) :: timeNewDischargeRouting
TYPE(grid_real)Velocita
TYPE (grid_real) storageChannelSurf
!basin average
TYPE (DateTime) :: timeNewBasinAverage
INTEGER (KIND = short) :: dtOutBasinAverage
!raster export
TYPE (DateTime) :: timeNewRasterExport
!hotstart
CHARACTER (len=1000) :: pathHotstart
LOGICAL :: saveLast
LOGICAL :: hotstart
CHARACTER (LEN = 300) :: cron
TYPE (CronTab) :: cronHotstart
!general variables
INTEGER (KIND = short) :: dtCalc !calculation time step
INTEGER (KIND = short) :: dtArray (4)
CHARACTER (len = 1000) :: path_out
INTEGER :: k,i,j
LOGICAL :: fatta_previ = .FALSE.
!--------------------------end of declaration----------------------------------
! splash screen
IF ( verbose ) THEN
CALL Splash ()
END IF
!------------------------------------------------------------------------------
! initialize log
!------------------------------------------------------------------------------
CALL LogInit
!------------------------------------------------------------------------------
! initialize cartographic engine
!------------------------------------------------------------------------------
CALL GeoInit ('GeoLib.ini')
!------------------------------------------------------------------------------
! check command line arguments to read configuration file name
!------------------------------------------------------------------------------
i = 1
iniFound = .FALSE.
DO WHILE ( .not. (arg == '') )
CALL Getarg ( i, arg )
SELECT CASE (arg)
CASE ( '-inifile' )
i = i + 1
CALL Getarg ( i , string )
iniFound = .TRUE.
CASE DEFAULT
!case unknown
END SELECT
i = i + 1
END DO
!------------------------------------------------------------------------------
! read name of configuration file if not yet defined
!------------------------------------------------------------------------------
IF ( .NOT. iniFound) THEN
WRITE(*,*) 'Insert the name of configuration file and press enter'
READ(*,*) string
END IF
CALL Catch ('info', 'Fest', &
'start configuration from file: ', argument = string )
!------------------------------------------------------------------------------
! read configuration file
!------------------------------------------------------------------------------
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) 'Loading configuration...'
END IF
string = "./conf-test/fest.ini"
CALL IniOpen (string, festIni)
!------------------------------------------------------------------------------
! configure time
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'time configuration' )
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring time...'
END IF
!check whether time is present
IF ( .NOT. SectionIsPresent ('time', festIni) ) THEN !section is mandatory
CALL Catch ('error', 'Fest', 'time section missing in configuration file' )
END IF
!start time
IF (KeyIsPresent('start', festIni, section = 'time')) THEN
timeString = IniReadString ('start', festIni, section = 'time')
ELSE
CALL Catch ('error', 'Fest', 'start missing in time' )
END IF
timeStart = timeString
CALL Catch ('info', 'Fest', 'start time: ', argument = timeString )
!stop time
IF (KeyIsPresent('stop', festIni, section = 'time')) THEN
timeString = IniReadString ('stop', festIni, section = 'time')
ELSE
CALL Catch ('error', 'Fest', 'stop missing in time' )
END IF
timeStop = timeString
CALL Catch ('info', 'Fest', 'stop time: ', argument = timeString )
!------------------------------------------------------------------------------
! result folder
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'result folder configuration' )
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...setting folder for results...'
END IF
!check whether section is present
IF ( .NOT. SectionIsPresent ('result', festIni) ) THEN !section is mandatory
CALL Catch ('error', 'Fest', 'result section missing in configuration file' )
END IF
!folder
IF (KeyIsPresent('folder', festIni, section = 'result')) THEN
path_out = IniReadString ('folder', festIni, section = 'result')
ELSE
CALL Catch ('error', 'Fest', 'folder missing in result' )
END IF
CALL Catch ('info', 'Fest', 'result folder: ', argument = TRIM(path_out) )
!------------------------------------------------------------------------------
! configure simulation domain
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'simulation domain configuration' )
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring simulation domain...'
END IF
!check whether section is present
IF ( .NOT. SectionIsPresent ('domain', festIni) ) THEN !section is mandatory
CALL Catch ('error', 'Fest', 'domain section missing in configuration file' )
END IF
!find configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'domain')) THEN
string = IniReadString ('conf-file', festIni, section = 'domain')
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in domain' )
END IF
!read data
CALL DomainInit (string)
!------------------------------------------------------------------------------
! morphological properties
!------------------------------------------------------------------------------
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring morphological properties...'
END IF
!check whether section is present. Optional section
IF ( .NOT. SectionIsPresent ('morphology', festIni) ) THEN !section is mandatory
CALL Catch ('info', 'Fest', 'morphological properties configuration' )
END IF
!find configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'morphology')) THEN
string = IniReadString ('conf-file', festIni, section = 'morphology')
!read data
CALL MorphologyInit (string, mask)
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in morphology' )
END IF
!------------------------------------------------------------------------------
! configure meteo input
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'meteo input configuration' )
IF ( verbose ) THEN
WRITE (*,*)
WRITE (*,*) '...configuring meteorological forcings...'
END IF
!check whether section is present
IF ( .NOT. SectionIsPresent ('meteo', festIni) ) THEN !section is mandatory
CALL Catch ('error', 'Fest', 'meteo section missing in configuration file')
END IF
!time step
IF (KeyIsPresent('dt', festIni, section = 'meteo')) THEN
dtMeteo = IniReadInt ('dt', festIni, section = 'meteo')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in meteo' )
END IF
!find configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'meteo')) THEN
string = IniReadString ('conf-file', festIni, section = 'meteo')
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in meteo' )
END IF
!read data
CALL MeteoInit (string, timeStart, mask, dem, dem_loaded, albedo_loaded)
!spatial data out dt
IF (KeyIsPresent('dt-out-spatial', festIni, section = 'meteo')) THEN
dtOutMeteo = IniReadInt ('dt-out-spatial', festIni, section = 'meteo')
IF ( dtOutMeteo > 0 ) THEN
timeOutMeteo = timeStart
ELSE
timeOutMeteo = timeStart + (-1)
END IF
ELSE
CALL Catch ('warning', 'Fest', 'dt-out-spatial missing in meteo' )
dtOutMeteo = - 1
timeOutMeteo = timeStart + (-1)
END IF
!point data out
IF (KeyIsPresent('out-point-file', festIni, section = 'meteo')) THEN
string = IniReadString ('out-point-file', festIni, section = 'meteo')
CALL MeteoPointInit (string, path_out, timeStart)
END IF
timeNewMeteo = timeStart
!------------------------------------------------------------------------------
! irrigation
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'irrigation configuration' )
!check whether section is present
IF ( SectionIsPresent ('irrigation', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring irrigation...'
END IF
!time step
IF (KeyIsPresent('dt', festIni, section = 'irrigation')) THEN
dtIrrigation = IniReadInt ('dt', festIni, section = 'irrigation')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in irrigation' )
END IF
!dt output
IF (KeyIsPresent('dt-out', festIni, section = 'irrigation')) THEN
dtOutIrrigation = IniReadInt ('dt-out', festIni, section = 'irrigation')
IF ( dtOutIrrigation > 0 ) THEN
timeOutIrrigation = timeStart
ELSE
timeOutIrrigation = timeStart + (-1)
END IF
ELSE
CALL Catch ('error', 'Fest', 'dt-out missing in irrigation' )
END IF
!configuration file
IF ( dtIrrigation > 0 ) THEN
IF (KeyIsPresent('conf-file', festIni, section = 'irrigation')) THEN
string = IniReadString ('conf-file', festIni, section = 'irrigation')
CALL IrrigationConfig (string, path_out, dtOutIrrigation )
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in irrigation' )
END IF
timeNewIrrigation = timeStart
END IF
ELSE
dtIrrigation = 0
END IF
!------------------------------------------------------------------------------
! canopy interception
!------------------------------------------------------------------------------
!_________________________________________
! da implementare che se c'è neve non calcolo intercettazione BO! serve?
!________________________
CALL Catch ('info', 'Fest', 'canopy interception configuration' )
!raineff is used even when canopy interception is not simulated
CALL NewGrid (raineff, mask, 0.)
!check whether section is present
IF ( SectionIsPresent ('canopy-interception', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring canopy interception...'
END IF
!dt
IF (KeyIsPresent('dt', festIni, section = 'canopy-interception')) THEN
dtCanopyInterception = IniReadInt ('dt', festIni, section = 'canopy-interception')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in canopy-interception' )
END IF
IF ( dtCanopyInterception > 0 ) THEN
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'canopy-interception')) THEN
string = IniReadString ('conf-file', festIni, section = 'canopy-interception')
CALL InterceptionInit ( string, mask )
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in canopy-interception' )
END IF
!spatial data out dt
IF (KeyIsPresent('dt-out-spatial', festIni, section = 'canopy-interception')) THEN
dtOutCanopy = IniReadInt ('dt-out-spatial', festIni, section = 'canopy-interception')
ELSE
CALL Catch ('error', 'Fest', 'dt-out-spatial missing in canopy-interception' )
END IF
timeNewCanopyInterception = timeStart
IF (dtOutCanopy > 0) THEN
timeOutCanopy = timeStart
ELSE
timeOutCanopy = timeStart + (-1)
END IF
ELSE
dtOutCanopy = 0
timeNewCanopyInterception = timeStart + (-1)
timeOutCanopy = timeStart + (-1)
END IF
ELSE
dtCanopyInterception = 0
dtOutCanopy = 0
timeNewCanopyInterception = timeStart + (-1)
timeOutCanopy = timeStart + (-1)
END IF
!------------------------------------------------------------------------------
! Plants dynamic simulation
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'plants configuration' )
!check whether section is present
IF ( SectionIsPresent ('plants', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring plants simulation...'
END IF
!dt
IF (KeyIsPresent('dt', festIni, section = 'plants')) THEN
dtPlants = IniReadInt ('dt', festIni, section = 'plants')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in plants' )
END IF
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'plants')) THEN
string = IniReadString ('conf-file', festIni, section = 'plants')
CALL PlantsConfig (string, mask, timeStart, timeStop)
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in plants' )
END IF
!spatial data out dt
IF (KeyIsPresent('dt-out-spatial', festIni, section = 'plants')) THEN
dtOutPlants = IniReadInt ('dt-out-spatial', festIni, section = 'plants')
ELSE
CALL Catch ('warning', 'Fest', 'dt-out-spatial missing in plants' )
dtOutPlants = 0
END IF
IF (dtOutPlants > 0) THEN
timeOutPlants = timeStart
END IF
IF ( dtPlants > 0 ) THEN
timeNewPlants = timeStart
ELSE
dtOutPlants = 0
timeNewPlants = timeStart + (-1)
timeOutPlants = timeStart + (-1)
END IF
ELSE
dtPlants = 0
dtOutPlants = 0
timeNewPlants = timeStart + (-1)
timeOutPlants = timeStart + (-1)
END IF
!------------------------------------------------------------------------------
! snow accumulation and melting
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'snow configuration' )
!rainfallRate is used even when snow is not simulated
CALL NewGrid (rainfallRate, mask, 0.)
!check whether section is present
IF ( SectionIsPresent ('snow', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring snow accumulation and melting...'
END IF
!dt
IF (KeyIsPresent('dt', festIni, section = 'snow')) THEN
dtSnow = IniReadInt ('dt', festIni, section = 'snow')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in snow' )
END IF
IF (dtSnow > 0) THEN
!check dt
IF ( dtSnow /= dtMeteo ) THEN
dtSnow=dtMeteo
WRITE(*,*)'WARNING: dtSnow \E8 posto uguale a dt_acquisizione_meteo'
END IF
timeNewSnow = timeStart
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'snow')) THEN
string = IniReadString ('conf-file', festIni, section = 'snow')
CALL SnowInit (string, mask, timeStart )
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in snow' )
END IF
!spatial data out dt
IF (KeyIsPresent('dt-out-spatial', festIni, section = 'snow')) THEN
dtOutSnow = IniReadInt ('dt-out-spatial', festIni, section = 'snow')
ELSE
CALL Catch ('error', 'Fest', 'dt-out-spatial missing in snow' )
END IF
IF ( dtOutSnow > 0 ) THEN
timeOutSnow = timeStart
END IF
!point data out
IF (KeyIsPresent('out-point-file', festIni, section = 'snow')) THEN
string = IniReadString ('out-point-file', festIni, section = 'snow')
CALL SnowPointInit ( string, path_out, timeStart )
END IF
ELSE
dtOutSnow = 0
timenEWSnow = timeStart + (-1)
timeOutSnow = timeStart + (-1)
END IF
ELSE
dtSnow = 0
dtOutSnow = 0
timenEWSnow = timeStart + (-1)
timeOutSnow = timeStart + (-1)
END IF
!------------------------------------------------------------------------------
! glacier
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'glacer configuration' )
!check whether section is present
IF ( SectionIsPresent ('glacier', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring glacier accumulation and ablation...'
END IF
!dt
IF (KeyIsPresent('dt', festIni, section = 'glacier')) THEN
dtIce = IniReadInt ('dt', festIni, section = 'glacier')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in glacier' )
END IF
IF (dtIce > 0) THEN
!check dt
IF ( dtIce /= dtMeteo ) THEN
dtIce = dtMeteo
CALL Catch ('info', 'Fest', 'dtIce set equal to dtMeteo' )
END IF
timeNewIce = timeStart
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'glacier')) THEN
string = IniReadString ('conf-file', festIni, section = 'glacier')
CALL GlacierInit (string, mask, timeStart )
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in glacier' )
END IF
!spatial data out dt
IF (KeyIsPresent('dt-out-spatial', festIni, section = 'glacier')) THEN
dtOutIce = IniReadInt ('dt-out-spatial', festIni, section = 'glacier')
ELSE
CALL Catch ('error', 'Fest', 'dt-out-spatial missing in glacier' )
END IF
IF ( dtOutIce > 0 ) THEN
timeOutIce = timeStart
END IF
!point data out
IF (KeyIsPresent('out-point-file', festIni, section = 'glacier')) THEN
string = IniReadString ('out-point-file', festIni, section = 'glacier')
CALL GlacierPointInit ( string, path_out, timeStart )
END IF
ELSE
dtOutIce = 0
timeNewIce = timeStart + (-1)
timeOutIce = timeStart + (-1)
END IF
ELSE
dtIce = 0
dtOutIce = 0
timeNewIce = timeStart + (-1)
timeOutIce = timeStart + (-1)
END IF
!------------------------------------------------------------------------------
! Soil balance
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'soil balance configuration' )
!check whether section is present
IF ( SectionIsPresent ('soil-balance', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring soil water balance...'
END IF
!dt
IF (KeyIsPresent('dt', festIni, section = 'soil-balance')) THEN
dtSoilBalance = IniReadInt ('dt', festIni, section = 'soil-balance')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in soil-balance' )
END IF
IF ( dtSoilBalance > 0 ) THEN
timeNewSoilBalance = timeStart
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'soil-balance')) THEN
string = IniReadString ('conf-file', festIni, section = 'soil-balance')
CALL InitSoilBalance (string, flowDirection, timeStart)
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in soil-balance' )
END IF
!spatial data out dt
IF (KeyIsPresent('dt-out-spatial', festIni, section = 'soil-balance')) THEN
dtOutSoilBalance = IniReadInt ('dt-out-spatial', festIni, &
section = 'soil-balance')
ELSE
dtOutSoilBalance = 0
END IF
IF (dtOutSoilBalance > 0) THEN
timeOutSoilBalance = timeStart
END IF
ELSE
dtOutSoilBalance = 0
timeNewSoilBalance = timeStart + (-1)
timeOutSoilBalance = timeStart + (-1)
END IF
ELSE
dtSoilBalance = 0
dtOutSoilBalance = 0
timeNewSoilBalance = timeStart + (-1)
timeOutSoilBalance = timeStart + (-1)
END IF
!------------------------------------------------------------------------------
! groundwater
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'groundwater configuration' )
!check whether section is present
IF ( SectionIsPresent ('groundwater', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring groundwater...'
END IF
!dt
IF (KeyIsPresent('dt', festIni, section = 'groundwater')) THEN
dtGroundwater = IniReadInt ('dt', festIni, section = 'groundwater')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in groundwater' )
END IF
IF ( dtGroundwater > 0 ) THEN
timeNewGroundwater = timeStart
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'groundwater')) THEN
string = IniReadString ('conf-file', festIni, section = 'groundwater')
CALL GroundwaterInit (string)
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in groundwater' )
END IF
!spatial data out dt
IF (KeyIsPresent('dt-out-aquifer', festIni, section = 'groundwater')) THEN
dtOutGroundwater = IniReadInt ('dt-out-aquifer', festIni, section = 'groundwater')
IF ( dtOutGroundwater > 0 ) THEN
timeOutGroundwater = timeStart
CALL GroundwaterOutputInit ( path_out)
ELSE
timeOutGroundwater = timeStart + (-1)
END IF
ELSE
CALL Catch ('error', 'Fest', 'dt-out-aquifer missing in groundwater' )
END IF
!point data out
IF (KeyIsPresent('out-point-file', festIni, section = 'groundwater')) THEN
string = IniReadString ('out-point-file', festIni, section = 'groundwater')
CALL GroundwaterPointInit ( string, path_out, timestart )
END IF
ELSE
dtOutGroundwater = 0
timeNewGroundwater = timeStart + (-1)
timeOutGroundwater = timeStart + (-1)
END IF
ELSE
dtGroundwater = 0
dtOutGroundwater = 0
timeNewGroundwater = timeStart + (-1)
timeOutGroundwater = timeStart + (-1)
END IF
!------------------------------------------------------------------------------
! soil erosion and sediment transport
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'sediment erosion configuration' )
!check whether section is present
IF ( SectionIsPresent ('sediment', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring soil erosion and sediment transport...'
END IF
!dt
IF (KeyIsPresent('dt', festIni, section = 'sediment')) THEN
dtCalcSediment = IniReadInt ('dt', festIni, section = 'sediment')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in sediment' )
END IF
IF ( dtCalcSediment > 0 ) THEN
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'sediment')) THEN
string = IniReadString ('conf-file', festIni, section = 'sediment')
CALL SedimentInit (string, dtCalcSedimentRouting, string)
timeUpdateSediment = timeStart
timeUpdateSedimentRouting = timeStart
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in sediment' )
END IF
!spatial data out dt
IF (KeyIsPresent('dt-out-spatial', festIni, section = 'sediment')) THEN
dtOutSediment = IniReadInt ('dt-out-spatial', festIni, section = 'sediment')
ELSE
CALL Catch ('error', 'Fest', 'dt-out-spatial missing in sediment' )
END IF
IF (dtOutSediment > 0) THEN
timeOutSoilBalance = timeStart
END IF
timeOutSediment = timeStart
ELSE
dtOutSediment = 0
timeUpdateSediment = timeStart + (-1)
timeOutSediment = timeStart + (-1)
END IF
ELSE
dtCalcSediment = 0
dtOutSediment = 0
timeUpdateSediment = timeStart + (-1)
timeOutSediment = timeStart + (-1)
END IF
!TODO
! IF (routeSediment) THEN
! !set file for output of sediment routing
! fileunit_out_sediment_routing = GetUnit ()
! OPEN (fileunit_out_sediment_routing,file=string)
! WRITE(*,*)'nome file anagrafica out punti propagazione sedimenti: ',string(1:LEN_TRIM(string))
! CALL leggi_anagrafica(xsOutSedimentRouting,fileunit_out_sediment_routing)
! !check dt out sediment routing
! IF(.not.(mod(xsOutSedimentRouting%cadenza_misure,dtCalcSedimentRouting)==0)) THEN
! xsOutSedimentRouting%cadenza_misure=dtCalcSedimentRouting
! WRITE(*,*)'WARNING: xsOutSedimentRouting%cadenza_misure non multiplo di dtCalcSedimentRouting'
! WRITE(*,*)' si impone: xsOutSedimentRouting%cadenza_misure = dtCalcSedimentRouting'
! END IF
! WRITE(*,*)xsOutSedimentRouting%num_staz,' sezioni per risultati propagazione sedimenti'
! DO k=1,xsOutSedimentRouting%num_staz
! xsOutSedimentRouting%staz_oss(k)%misura=0.
! END DO
! CALL righe_colonne(xsOutSedimentRouting,grid_r=QoutSed)
! CLOSE (fileunit_out_sediment_routing)
!
! !write header in output file
! fileunit_out_sediment_routing = GetUnit ()
! OPEN (fileunit_out_sediment_routing,file=path_out(1:LEN_TRIM(path_out))//'sediment_routing.fest')
! WRITE(fileunit_out_sediment_routing,'(a)')'FEST-EWB: stima dei sedimentogrammi'
! WRITE(fileunit_out_sediment_routing,'(a)')'anagrafica'
! CALL scrivi_anagrafica(xsOutSedimentRouting,fileunit_out_sediment_routing)
! WRITE(fileunit_out_sediment_routing,'(a)')
! WRITE(fileunit_out_sediment_routing,'(a)')
! WRITE(fileunit_out_sediment_routing,'(a)')'dati'
! WRITE(fileunit_out_sediment_routing,'(a," ",\)')'#'
! DO k=1,xsOutSedimentRouting%num_staz-1
! WRITE(fileunit_out_sediment_routing,'(a," ",\)')(xsOutSedimentRouting%staz_oss(k)%denominazione)
! END DO
! WRITE(fileunit_out_sediment_routing,'(a)')(xsOutSedimentRouting%staz_oss(xsOutSedimentRouting%num_staz)%denominazione)
!
! !time
! timeOutSedimentRouting = timeStart
!END IF
!
!------------------------------------------------------------------------------
! spatial average
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'spatial-average configuration' )
!check whether section is present
IF ( SectionIsPresent ('spatial-average', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring spatial average for output...'
END IF
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'spatial-average')) THEN
string = IniReadString ('conf-file', festIni, section = 'spatial-average')
CALL InitSpatialAverageMeteo (string, path_out, temperatureAir, &
temperatureAirDailyMean, temperatureAirDailyMax, &
temperatureAirDailyMin, precipitationRate, &
relHumidityAir, radiation,netRadiation, &
windSpeed, precipitationRateDaily, irrigationFlux )
CALL InitSpatialAverageBalance (string, path_out, soilMoisture, &
soilMoistureRZ, soilMoistureRZ, &
runoff, infilt, percolation, &
et, pet, caprise, balanceError)
CALL InitSpatialAverageSnow (string, path_out, rainfallRate, swe, &
meltCoefficient, waterInSnow, snowMelt )
CALL InitSpatialAverageGlaciers (string, path_out, icewe, waterInIce, iceMelt )
CALL InitSpatialAverageSediment (string, path_out, interrillErosion)
CALL InitSpatialAverageCanopy (string, path_out, canopyStorage, raineff, canopyPT )
CALL InitSpatialAveragePlants (string, path_out, lai, gpp, npp, carbonstem, &
carbonroot, carbonleaf, fvcover, dbh, plantsHeight, &
density, stemyield )
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in spatial-average' )
END IF
!initialize meteo output file
IF ( dtOutMeteo > 0 ) THEN
CALL ComputeSpatialAverageMeteo (dtMeteo, temperatureAir, &
temperatureAirDailyMean, &
temperatureAirDailyMax, temperatureAirDailyMin, &
precipitationRate, relHumidityAir, radiation, &
netRadiation, windSpeed, precipitationRateDaily, &
irrigationFlux)
CALL ExportSpatialAverageMeteo ( init = .TRUE. )
END IF
!initialize snow output file
IF ( dtOutSnow > 0 ) THEN
CALL ComputeSpatialAverageSnow ( dtOutSnow, rainfallRate, &
swe, meltCoefficient, waterInSnow, &
snowMelt )
CALL ExportSpatialAverageSnow (init = .TRUE.)
END IF
!initialize glaciers output file
IF ( dtOutIce > 0 ) THEN
CALL ComputeSpatialAverageGlaciers (dtOutIce, icewe, &
waterInIce, iceMelt )
CALL ExportSpatialAverageGlaciers (init = .TRUE.)
END IF
!initailize vegetation canopy output file
IF (dtOutCanopy > 0) THEN
CALL ExportSpatialAverageCanopy (init = .TRUE.)
END IF
!initailize plants output file
IF (dtOutPlants > 0) THEN
CALL ExportSpatialAveragePlants (init = .TRUE.)
END IF
!initailize soil balance output file
IF (dtOutSoilBalance>0) THEN
CALL ExportSpatialAverageBalance (init = .TRUE.)
END IF
!initailize sediment output file
IF (dtCalcSediment > 0) THEN
CALL ExportSpatialAverageSediment (init = .TRUE.)
END IF
END IF
!------------------------------------------------------------------------------
! basin average
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'basin-average configuration' )
!check whether section is present
IF ( SectionIsPresent ('basin-average', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring basin average for output...'
END IF
!output file
IF (KeyIsPresent('out-point-file', festIni, section = 'basin-average')) THEN
string = IniReadString ('out-point-file', festIni, section = 'basin-average')
CALL ReadPointFileBasinAverage ( string )
ELSE
CALL Catch ('error', 'Fest', 'out-point-file missing in basin-average' )
END IF
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'basin-average')) THEN
string = IniReadString ('conf-file', festIni, section = 'basin-average')
CALL InitBasinAverage (string, path_out, temperatureAir, &
temperatureAirDailyMean, temperatureAirDailyMax, &
temperatureAirDailyMin, precipitationRate, &
relHumidityAir, radiation,netRadiation, &
windSpeed, precipitationRateDaily, irrigationFlux, &
swe, soilMoisture, runoff, infilt, percolation, &
et, pet, deltaSoilMoisture, snowMelt, icewe, &
iceMelt)
!set first export time
timeNewBasinAverage = timeStart
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in basin-average' )
END IF
ELSE
timeNewBasinAverage = timeStart + (-1)
END IF
!------------------------------------------------------------------------------
! raster export
!------------------------------------------------------------------------------
CALL Catch ('info', 'FeST', 'raster-export configuration' )
!check whether section is present
IF ( SectionIsPresent ('raster-export', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring raster export for output...'
END IF
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'raster-export')) THEN
string = IniReadString ('conf-file', festIni, section = 'raster-export')
CALL InitRasterExport (string, temperatureAir, precipitationRate, &
relHumidityAir, radiation, netRadiation, &
windSpeed,swe, soilMoisture, runoff, infilt, &
percolation, et, pet )
!set first time
timeNewRasterExport = timeStart
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in raster-export' )
END IF
ELSE
timeNewRasterExport = timeStart + (-1)
END IF
!------------------------------------------------------------------------------
! discharge routing
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'surface routing configuration' )
!check whether section is present
IF ( SectionIsPresent ('discharge-routing', festIni) ) THEN !section is optional
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring discharge routing...'
END IF
!dt
IF (KeyIsPresent('dt', festIni, section = 'discharge-routing')) THEN
dtDischargeRouting = IniReadInt ('dt', festIni, section = 'discharge-routing')
ELSE
CALL Catch ('error', 'Fest', 'dt missing in discharge-routing' )
END IF
IF ( dtDischargeRouting > 0 ) THEN
timeNewDischargeRouting = timeStart
!configuration file
IF (KeyIsPresent('conf-file', festIni, section = 'discharge-routing')) THEN
string = IniReadString ('conf-file', festIni, section = 'discharge-routing')
CALL InitDischargeRouting (fileini = string, time = timeStart, &
path_out = path_out, &
flowdirection = flowDirection, &
domain = mask , &
storage = storageChannelSurf, &
netRainfall = runoff, &
dtrk = dtReservoir )
ELSE
CALL Catch ('error', 'Fest', 'conf-file missing in discharge-routing' )
END IF
!output data file
IF (KeyIsPresent('out-point-file', festIni, section = 'discharge-routing')) THEN
string = IniReadString ('out-point-file', festIni, section = 'discharge-routing')
CALL DischargePointInit (string, path_out, timeStart)
END IF
ELSE
timeNewDischargeRouting = timeStart + (-1)
END IF
ELSE
dtDischargeRouting = 0
timeNewDischargeRouting = timeStart + (-1)
END IF
!------------------------------------------------------------------------------
! hot start
!------------------------------------------------------------------------------
CALL Catch ('info', 'Fest', 'save-hot-start configuration' )
!check whether section is present
IF ( SectionIsPresent ('save-hot-start', festIni) ) THEN !section is optional
hotstart = .TRUE.
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '...configuring hot start...'
END IF
!time
IF (KeyIsPresent('time', festIni, section = 'save-hot-start')) THEN
cron = IniReadString ('time', festIni, section = 'save-hot-start')
CALL CronParseString (cron, cronHotstart )
!CALL ConfigureHotStart (cron)
ELSE
CALL Catch ('error', 'Fest', 'time missing in save-hot-start' )
END IF
!folder
IF (KeyIsPresent('folder', festIni, section = 'save-hot-start')) THEN
pathHotstart = IniReadString ('folder', festIni, section = 'save-hot-start')
ELSE
CALL Catch ('error', 'Fest', 'folder missing in save-hot-start' )
END IF
!save last time
IF (KeyIsPresent('save-last', festIni, section = 'save-hot-start')) THEN
IF ( IniReadInt ('save-last', festIni, section = 'save-hot-start') == 1 ) THEN
saveLast = .TRUE.
ELSE
saveLast = .FALSE.
END IF
ELSE !set to default
saveLast = .FALSE.
END IF
!IF ( dtHotstart > 0 ) THEN
!
! timeNewHotstart = timeStart
!
! !folder
! IF (KeyIsPresent('folder', festIni, section = 'save-hot-start')) THEN
! pathHotstart = IniReadString ('folder', festIni, section = 'save-hot-start')
! ELSE
! CALL Catch ('error', 'Fest', 'folder missing in save-hot-start' )
! END IF
!
!ELSE
! timeNewHotstart = timeStart + (-1)
!END IF
!ELSE
! dtHotstart = 0
! timeNewHotstart = timeStart + (-1)
ELSE
hotstart = .FALSE.
END IF
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) '....configuration completed!'
END IF
!------------------------------------------------------------------------------
! set calculation time step
!------------------------------------------------------------------------------
dtArray (1) = dtMeteo
dtArray (2) = dtSoilBalance
dtArray (3) = dtGroundwater
dtArray (4) = dtDischargeRouting
dtCalc = HUGE ( dtCalc )
DO i = 1, SIZE (dtArray)
IF ( dtArray (i) > 0 .AND. dtArray (i) < dtCalc ) THEN
dtCalc = dtArray (i)
END IF
END DO
!------------------------------------------------------------------------------
! start simulation
!------------------------------------------------------------------------------
IF ( verbose ) THEN
WRITE(*,*)
WRITE(*,*) 'starting simulation...'
WRITE(*,*)
WRITE(*,'(a,I10,a)') 'computation time step: ', dtCalc, ' second'
END IF
time = timeStart
!DO WHILE( .NOT. ( time < timeStop) )
DO WHILE( time <= timeStop )
timeString = time
IF ( verbose ) THEN
WRITE(*,'(a25)') timeString
END IF
!-----------------------------------------------------------------------------
! read meteorological forcings
!-----------------------------------------------------------------------------
IF (time == timeNewMeteo) THEN
IF ( verbose ) THEN
WRITE(*,*)'read meteorological forcings'
END IF
CALL MeteoRead (time,dem, albedo)
timeNewMeteo = timeNewMeteo + dtMeteo
IF ( dtOutMeteo > 0 ) THEN
timeSpatialAverageMeteo = time
CALL ComputeSpatialAverageMeteo (dtMeteo, temperatureAir, &
temperatureAirDailyMean, &
temperatureAirDailyMax, temperatureAirDailyMin, &
precipitationRate, relHumidityAir, radiation, &
netRadiation, windSpeed, precipitationRateDaily, &
irrigationFlux)
END IF
END IF
!-----------------------------------------------------------------------------
! update irrigation
!-----------------------------------------------------------------------------
IF (time == timeNewIrrigation) THEN
IF ( verbose ) THEN
WRITE(*,*) 'update irrigation'
END IF
CALL IrrigationUpdate (time, soilSat, Qin, dtOutIrrigation, &
timeOutIrrigation)
timeNewIrrigation = timeNewIrrigation + dtIrrigation
END IF
!-----------------------------------------------------------------------------
! snow
!-----------------------------------------------------------------------------
IF (dtSnow>0) THEN
IF (time == timeNewSnow) THEN
IF ( verbose ) THEN
WRITE(*,*)'snow'
END IF
CALL SnowUpdate (time, mask)
timeNewSnow = timeNewSnow + dtSnow
timeSpatialAverageSnow = time
CALL ComputeSpatialAverageSnow (dtOutSnow, rainfallRate, swe, &
meltCoefficient, waterInSnow, &
snowMelt)
END IF
ELSE
rainfallRate = precipitationRate
END IF
!-----------------------------------------------------------------------------
! glacier
!-----------------------------------------------------------------------------
IF ( time == timeNewIce ) THEN
IF ( verbose ) THEN
WRITE(*,*) 'glaciers'
END IF
CALL GlacierUpdate (time, mask, rainfallRate )
timeNewIce = timeNewIce + dtIce
timeSpatialAverageIce = time
CALL ComputeSpatialAverageGlaciers (dtOutIce, icewe, &
waterInIce, iceMelt)
END IF
!-----------------------------------------------------------------------------
!CANOPY INTERCEPTION
!-----------------------------------------------------------------------------
IF ( dtCanopyInterception > 0 ) THEN
IF ( time == timeNewCanopyInterception) THEN
IF ( verbose ) THEN
WRITE(*,*) 'canopy interception'
END IF
CALL Throughfall (rainfallRate , lai, mask, fvcover, raineff)
!CALL AdjustPT(fvcover, mask, tp_oss, dtetp)
timeNewCanopyInterception = timeNewCanopyInterception + dtCanopyInterception
timeSpatialAverageCanopy = time
CALL ComputeSpatialAverageCanopy (dtCanopyInterception, canopyStorage, raineff, canopyPT)
END IF
ELSE !copy rainfallRate into raineff
raineff = rainfallRate
END IF
!-------------------------------------------------------------------------------------------------------------
!FOREST DYNAMIC
!-------------------------------------------------------------------------------------------------------------
!check if plants parameters need update
IF ( updatePlantsParameters ) THEN
CALL PlantsParameterUpdate ( time )
END IF
IF ( dtPlants > 0 ) THEN
IF ( time == timeNewPlants) THEN
IF ( verbose ) THEN
WRITE(*,*) 'plants'
END IF
! CALL PlantsGrow (t, radiation, temperatureAir, soilMoisture, fieldCapacity, wiltingPoint, relHumidityAir, co2 % npd (1) % value)
timeNewPlants = timeNewPlants + dtPlants
timeSpatialAveragePlants = time
CALL ComputeSpatialAveragePlants (dtPlants, lai, gpp, npp, carbonstem, carbonroot, carbonleaf, fvcover, dbh, plantsHeight, density, stemyield)
END IF
END IF
!-----------------------------------------------------------------------------
! soil water balance
!-----------------------------------------------------------------------------
IF ( dtSoilBalance > 0 ) THEN
IF ( time == timeNewSoilBalance ) THEN
IF ( verbose ) THEN
WRITE(*,*)'soil water balance'
END IF
CALL SolveSoilBalance ( time, raineff, irrigationFlux, &
flowDirection, fvcover, vadoseDepth)
timeSpatialAverageBalance = time
CALL ComputeSpatialAverageBalance (dtSoilBalance, soilMoisture, &
soilMoistureRZ, soilMoistureTZ, &
runoff, infilt, percolation, &
et, pet, caprise, balanceError)
timeNewSoilBalance = timeNewSoilBalance + dtSoilBalance
END IF
ELSE
IF ( ALLOCATED (runoff % mat) ) THEN
DO i = 1, raineff % idim
DO j = 1, raineff % jdim
runoff % mat(i,j) = raineff % mat(i,j)
!percolation%mat(i,j)=0.0
END DO
END DO
END IF
END IF
!--------------------------------------------------------------------------
! groundwater
!--------------------------------------------------------------------------
IF (time == timeNewGroundwater) THEN
IF ( verbose ) THEN
WRITE(*,*) 'groundwater'
END IF
!update river groundwater interaction discharge
IF (riverGroundwaterInteract ) THEN
CALL GroundwaterRiverUpdate ( waterDepth, topWidth )
END IF
!update groundwater head
CALL GroundwaterUpdate ( time, QinSoilSub, percolation, caprise )
IF ( time == timeOutGroundwater) THEN
CALL GroundwaterOutput (time)
timeOutGroundwater = timeOutGroundwater + dtOutGroundwater
END IF
timeNewGroundwater = timeNewGroundwater + dtGroundwater
ENDIF
!-----------------------------------------------------------------------------
! discharge routing
!-----------------------------------------------------------------------------
IF ( time == timeNewDischargeRouting ) THEN
IF ( verbose ) THEN
WRITE(*,*)'discharge routing'
END IF
CALL DischargeRoute (dt = dtDischargeRouting, time = time, &
flowdir = flowDirection, &
runoff = runoff, dtrk = dtReservoir, &
riverToGroundwater = riverToGroundwater, &
groundwaterToriver = groundwaterToRiver, &
storage = storageChannelSurf)
timeNewDischargeRouting = timeNewDischargeRouting + dtDischargeRouting
END IF
!-----------------------------------------------------------------------------
! sediment detachment
!-----------------------------------------------------------------------------
IF (time == timeUpdateSediment) THEN
CALL Catch ('info', 'FEST-EWB', 'update sediment erosion and deposition')
CALL InterrillDetachmentRate (raineff)
timeUpdateSediment = timeUpdateSediment + dtCalcSediment
timeSpatialAverageSediment = time
CALL ComputeSpatialAverageSediment (dtCalcSediment, interrillErosion)
END IF
!sediment routing
IF (routeSediment) THEN
IF (time == timeUpdateSedimentRouting) THEN
CALL SedimentRouting (dtCalcSedimentRouting, Qin, Velocita, waterDepth)
!update timeUpdateSedimentRouting
timeUpdateSedimentRouting = timeUpdateSedimentRouting + dtCalcSedimentRouting
END IF
END IF
!-----------------------------------------------------------------------------
! write spatial average results
!-----------------------------------------------------------------------------
!output meteo spatial average
IF (time == timeOutMeteo) THEN
IF ( verbose ) THEN
WRITE(*,*) 'export meteo'
END IF
timeOutMeteo = timeOutMeteo + dtOutMeteo
CALL ExportSpatialAverageMeteo ()
END IF
!output canopy interception spatial average
IF ( time == timeOutCanopy ) THEN
IF ( verbose ) THEN
WRITE(*,*) 'export canopy interception'
END IF
timeOutCanopy = timeOutCanopy + dtOutCanopy
CALL ExportSpatialAverageCanopy ()
END IF
!output plants spatial average
IF ( time == timeOutPlants ) THEN
IF ( verbose ) THEN
WRITE(*,*) 'export plants'
END IF
timeOutPlants = timeOutPlants + dtOutPlants
CALL ExportSpatialAveragePlants ()
END IF
!output snow spatial average
IF (time==timeOutSnow) THEN
IF ( verbose ) THEN
WRITE(*,*) 'export snow'
END IF
timeOutSnow = timeOutSnow + dtOutSnow
CALL ExportSpatialAverageSnow ()
END IF
!output glaciers spatial average
IF (time == timeOutIce) THEN
IF ( verbose ) THEN
WRITE(*,*) 'export glaciers'
END IF
timeOutIce = timeOutIce + dtOutIce
CALL ExportSpatialAverageGlaciers ()
END IF
!output soil balance spatial average
IF ( time == timeOutSoilBalance ) THEN
IF ( verbose ) THEN
WRITE(*,*) 'export soil balance'
END IF
CALL ExportSpatialAverageBalance ()
timeOutSoilBalance = timeOutSoilBalance + dtOutSoilBalance
END IF
!!output ragguagli falda
!IF ( time == timeOutGroundwater ) THEN
! IF ( verbose ) THEN
! WRITE(*,*) 'export groundwater'
! END IF
! timeOutGroundwater = timeOutGroundwater+dtOutGroundwater
! !CALL esporta_ragguagli_falda(path_out)
!END IF
!output sediment spatial average
IF (time == timeOutSediment) THEN
IF ( verbose ) THEN
WRITE(*,*) 'export sediment'
END IF
timeOutSediment = timeOutSediment + dtOutSediment
CALL ExportSpatialAverageSediment ()
END IF
!output sediment routing
!IF (time == timeOutSedimentRouting) THEN
! xsOutSedimentRouting % istante = time
! CALL celle2stazioni(QoutSed,xsOutSedimentRouting)
! CALL scrivi_dato(xsOutSedimentRouting,fileunit_out_sediment_routing)
! !t
! timeOutSedimentRouting = timeOutSedimentRouting + xsOutSedimentRouting % cadenza_misure
!
!END IF
!-----------------------------------------------------------------------------
! basin average
!-----------------------------------------------------------------------------
IF ( time == timeNewBasinAverage ) THEN
IF ( verbose ) THEN
WRITE (*,*) 'export basin average'
END IF
CALL ExportBasinAverage (time, temperatureAir, &
temperatureAirDailyMean, temperatureAirDailyMax, &
temperatureAirDailyMin, precipitationRate, &
relHumidityAir, radiation,netRadiation, &
windSpeed, precipitationRateDaily, irrigationFlux, &
swe, soilMoisture, runoff, infilt, percolation, &
et, pet, deltaSoilMoisture, snowMelt, icewe, iceMelt )
timeNewBasinAverage = timeNewBasinAverage + dtBasinAverage
END IF
!-----------------------------------------------------------------------------
! raster export
!-----------------------------------------------------------------------------
IF ( time == timeNewRasterExport ) THEN
IF ( verbose ) THEN
WRITE (*,*) 'update raster maps'
END IF
CALL ExportMaps (time, dtCalc, temperatureAir, precipitationRate, &
relHumidityAir, radiation, netRadiation, &
windSpeed, swe, soilMoisture, runoff, &
infilt, percolation, et, pet )
timeNewRasterExport = timeNewRasterExport + dtCalc
END IF
!-----------------------------------------------------------------------------
! save status
!-----------------------------------------------------------------------------
IF ( hotstart ) THEN
!IF ( IsTimeHotStart (time) ) THEN
IF ( CronIsTime (time, cronHotstart) ) THEN
IF ( verbose ) THEN
WRITE (*,*) 'save state variables for hot start'
END IF
CALL SaveHotStart (time)
END IF
END IF
!-----------------------------------------------------------------------------
! time forward
!-----------------------------------------------------------------------------
time = time + dtCalc
IF ( time > timeStop ) THEN
IF ( hotstart ) THEN
IF ( saveLast > 0 ) THEN
IF ( verbose ) THEN
WRITE (*,*) 'save final state variables for hot start'
END IF
CALL SaveHotStart
END IF
END IF
END IF
END DO
!final message
IF ( verbose ) THEN
WRITE(*,*) 'simulation finished'
END IF
!-----------------------------------------
! terminate log
!-----------------------------------------
CALL LogStop ()
CONTAINS
!==============================================================================
!| Description:
! Save state variables for starting a new simulation from the current condition
!
SUBROUTINE SaveHotStart &
!
(time)
IMPLICIT NONE
TYPE(DateTime), OPTIONAL :: time
CHARACTER (LEN = 26) :: prefix
CHARACTER (LEN = 300) :: file
!-------------------------end of declarations----------------------------------
IF (PRESENT(time)) THEN
prefix = time
prefix = prefix (1:19) // '_'
prefix (14:14) = '-'
prefix (17:17) = '-'
ELSE
prefix = ' '
END IF
!snow
IF ( dtSnow > 0 ) THEN
!swe
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'swe'
CALL ExportGrid (layer = swe, fileName = file, &
fileFormat = ESRI_BINARY)
!water in snow
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'water-snow'
CALL ExportGrid (layer = waterInSnow, fileName = file, &
fileFormat = ESRI_BINARY)
END IF
!glaciers
IF ( dtIce > 0 ) THEN
!ice water equivalent
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'icewe'
CALL ExportGrid (layer = icewe, fileName = file, &
fileFormat = ESRI_BINARY)
!water in ice
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'water-ice'
CALL ExportGrid (layer = waterInIce, fileName = file, &
fileFormat = ESRI_BINARY)
END IF
!soil balance
IF ( dtSoilBalance > 0 ) THEN
!soil saturation root zone
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'sat-rz'
CALL ExportGrid (layer = soilSatRZ, fileName = file, &
fileFormat = ESRI_BINARY)
!soil saturation transmission zone
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'sat-tz'
CALL ExportGrid (layer = soilSatTZ, fileName = file, &
fileFormat = ESRI_BINARY)
!precipitation status
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'rainflag'
CALL ExportGrid (layer = rainFlag, fileName = file, &
fileFormat = ESRI_BINARY)
!interstorm duration
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'interstorm'
CALL ExportGrid (layer = interstormDuration, fileName = file, &
fileFormat = ESRI_BINARY)
IF ( infiltrationModel == SCS_CN ) THEN
!soil retention
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'seff'
CALL ExportGrid (layer = sEff, fileName = file, &
fileFormat = ESRI_BINARY)
!cumulative precipitation
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'raincum'
CALL ExportGrid (layer = raincum, fileName = file, &
fileFormat = ESRI_BINARY)
END IF
IF ( infiltrationModel == PHILIPEQ .OR. &
infiltrationModel == GREEN_AMPT ) THEN
!cumulative infiltration
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'cuminf'
CALL ExportGrid (layer = cuminf, fileName = file, &
fileFormat = ESRI_BINARY)
END IF
END IF
! discharge routing
IF ( dtDischargeRouting > 0 ) THEN
!Qin
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'Qin'
CALL ExportGrid (layer = Qin, fileName = file, &
fileFormat = ESRI_BINARY)
!Qout
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'Qout'
CALL ExportGrid (layer = Qout, fileName = file, &
fileFormat = ESRI_BINARY)
!Qlat
file = pathHotstart (1:LEN_TRIM (pathHotstart)) // &
prefix (1:LEN_TRIM(prefix)) // 'Qlat'
CALL ExportGrid (layer = Plat, fileName = file, &
fileFormat = ESRI_BINARY)
! diversions
IF ( dtDiversion > 0 ) THEN
IF ( PRESENT (time) ) THEN
CALL DiversionSaveStatus ( pathHotstart, time )
ELSE
CALL DiversionSaveStatus ( pathHotstart )
END IF
END IF
! reservoirs
IF ( dtReservoir > 0 ) THEN
IF ( PRESENT (time) ) THEN
CALL ReservoirSaveStatus ( pathHotstart, time )
ELSE
CALL ReservoirSaveStatus ( pathHotstart )
END IF
END IF
END IF
! !Falda
!IF (dtGroundwater > 0) THEN
! DO I=1,AltezzaPiezometrica%NumeroStrati
!
! CALL write_raster_bin(path_hotstart(1:LEN_TRIM(path_hotstart))// &
! pref_s(1:LEN_TRIM(pref_s))//'strato'//CHAR(64+I), &
! matrice_real=AltezzaPiezometrica%piezometria(I))
!
! IF (interazione_falda_fiume ) THEN
!
! CALL write_raster_bin(path_hotstart(1:LEN_TRIM(path_hotstart))// &
! pref_s(1:LEN_TRIM(pref_s))//'baseflow_falda', &
! matrice_real=BaseFlow_falda)
!
! CALL write_raster_bin(path_hotstart(1:LEN_TRIM(path_hotstart))// &
! pref_s(1:LEN_TRIM(pref_s))//'ricarica_falda', &
! matrice_real=ricarica_falda_fiume)
!
! END IF
! ENDDO
!END IF
!sediment
!IF (dtCalcSediment > 0) THEN
! CALL write_raster_bin(path_hotstart(1:LEN_TRIM(path_hotstart))// &
! pref_s(1:LEN_TRIM(pref_s))//'deltaSed',matrice_real=deltaSed)
!END IF
!
!IF (dtCalcSedimentRouting > 0) THEN
!
!!to do
!
!END IF
END SUBROUTINE SaveHotStart
SUBROUTINE Splash ()
WRITE (*,*)
!WRITE (*,'(a)') ' ______ ______ _____ _______ '
!WRITE (*,'(a)') ' | ____| ____|/ ____|__ __|'
!WRITE (*,'(a)') ' | |__ | |__ | (___ | | '
!WRITE (*,'(a)') ' | __| | __| \___ \ | | '
!WRITE (*,'(a)') ' | | | |____ ____) | | | '
!WRITE (*,'(a)') ' |_| |______|_____/ |_| '
!WRITE (*,'(a)')
!WRITE (*,'(a)') '-o--o o--o o-o o--O-o '
!WRITE (*,'(a)') ' | | | | '
!WRITE (*,'(a)') ' O-o O-o o-o | '
!WRITE (*,'(a)') ' | | | | '
!WRITE (*,'(a)') ' o o--o o--o o '
!WRITE (*,'(a)')
WRITE (*,'(a)') ' ________ _______ ________ _________ '
WRITE (*,'(a)') '|\ _____\|\ ___ \ |\ ____\ |\___ ___\ '
WRITE (*,'(a)') '\ \ \__/ \ \ __/| \ \ \___|_ \|___ \ \_| '
WRITE (*,'(a)') ' \ \ __\ \ \ \_|/__ \ \_____ \ \ \ \ '
WRITE (*,'(a)') ' \ \ \_| \ \ \_|\ \ \|____|\ \ \ \ \ '
WRITE (*,'(a)') ' \ \__\ \ \_______\ ____\_\ \ \ \__\ '
WRITE (*,'(a)') ' \|__| \|_______| |\_________\ \|__| '
WRITE (*,'(a)') ' \|_________| '
WRITE (*,'(a)') ' '
! (*,'(a)') ' E N E R G Y - W A T E R - B A L A N C E '
WRITE (*,'(a)') ' S P A T I A L L Y - D I S T R I B U T E D '
WRITE (*,'(a)') ' H Y D R O L O G I C A L - M O D E L '
!WRITE (*,'(a)') ' Flood Event Spatially distributed rainfall-runoff Transformation model'
WRITE (*,'(a)')
RETURN
END SUBROUTINE Splash
!-------------------------------------------------------------------------------------------------------------
!-------------------------------------------------------------------------------------------------------------
END PROGRAM Fest