LCOV - code coverage report
Current view: top level - common - mo_common_mHM_mRM_read_config.f90 (source / functions) Hit Total Coverage
Test: mHM coverage Lines: 106 118 89.8 %
Date: 2024-04-15 17:48:09 Functions: 4 4 100.0 %

          Line data    Source code
       1             : !> \file mo_common_mHM_mRM_read_config.f90
       2             : !> \brief \copybrief mo_common_mhm_mrm_read_config
       3             : !> \details \copydetails mo_common_mhm_mrm_read_config
       4             : 
       5             : !> \brief Reading of main model configurations.
       6             : !> \details This routine reads the configurations of common program parts
       7             : !> \authors Matthias Zink
       8             : !> \date Dec 2012
       9             : !> \copyright Copyright 2005-\today, the mHM Developers, Luis Samaniego, Sabine Attinger: All rights reserved.
      10             : !! mHM is released under the LGPLv3+ license \license_note
      11             : !> \ingroup f_common
      12             : MODULE mo_common_mHM_mRM_read_config
      13             : 
      14             :   use mo_kind, only : i4, dp
      15             :   use mo_message, only : message, error_message
      16             : 
      17             :   IMPLICIT NONE
      18             : 
      19             :   PRIVATE
      20             : 
      21             :   PUBLIC :: common_mHM_mRM_read_config, common_check_resolution, check_optimization_settings
      22             : 
      23             : CONTAINS
      24             : 
      25             : 
      26             :   !> \brief Read main configurations for common parts
      27             :   !> \changelog
      28             :   !! - Robert Schweppe Dec  2017
      29             :   !!   - based on mhm_read_config
      30             :   !! - Stephan Thober Jan 2022
      31             :   !!   - added nTStepForcingDay
      32             :   !> \authors Matthias Zink
      33             :   !> \date Dec 2012
      34          14 :   subroutine common_mHM_mRM_read_config(file_namelist, unamelist)
      35             : 
      36             :     use mo_common_constants, only : maxNoDomains, nodata_i4
      37             :     use mo_common_mHM_mRM_variables, only : LCyearId, dds_r, mhmFileRestartIn, mrmFileRestartIn, evalPer,&
      38             :                                             mcmc_error_params, mcmc_opti, nIterations, &
      39             :                                             nTStepDay, opti_function, opti_method, optimize, optimize_restart, &
      40             :                                             read_restart, mrm_read_river_network, resolutionRouting, sa_temp, &
      41             :                                             sce_ngs, sce_npg, sce_nps, seed, &
      42             :                                             simPer, timestep, warmPer, warmingDays, read_old_style_restart_bounds, &
      43             :                                             restart_reset_fluxes_states
      44             :     use mo_common_read_config, only : set_land_cover_scenes_id
      45             :     use mo_common_types, only: period
      46             :     use mo_common_variables, only : LCfilename, domainMeta, processMatrix
      47             :     use mo_julian, only : caldat, julday
      48             :     use mo_nml, only : close_nml, open_nml, position_nml
      49             :     use mo_string_utils, only : num2str
      50             : 
      51             :     implicit none
      52             : 
      53             :     character(*), intent(in) :: file_namelist !< namelist file name
      54             :     integer, intent(in) :: unamelist !< unit to open namelist file
      55             : 
      56             :     integer(i4) :: jday
      57             : 
      58             :     integer(i4) :: domainID, iDomain
      59             : 
      60             :     integer(i4), dimension(maxNoDomains) :: warming_Days
      61             : 
      62             :     type(period), dimension(maxNoDomains) :: eval_Per
      63             : 
      64         714 :     real(dp), dimension(maxNoDomains) :: resolution_Routing
      65             : 
      66             :     character(256), dimension(maxNoDomains) :: mhm_file_RestartIn
      67             :     character(256), dimension(maxNoDomains) :: mrm_file_RestartIn
      68             : 
      69             : 
      70             :     ! namelist spatial & temporal resolution, otmization information
      71             :     namelist /mainconfig_mhm_mrm/ timestep, resolution_Routing, optimize, &
      72             :             optimize_restart, opti_method, opti_function, &
      73             :             read_restart, mrm_read_river_network, read_old_style_restart_bounds, restart_reset_fluxes_states, &
      74             :             mhm_file_RestartIn, mrm_file_RestartIn
      75             :     ! namelist for optimization settings
      76             :     namelist /Optimization/ nIterations, seed, dds_r, sa_temp, sce_ngs, &
      77             :             sce_npg, sce_nps, mcmc_opti, mcmc_error_params
      78             :     ! namelist for time settings
      79             :     namelist /time_periods/ warming_Days, eval_Per
      80             : 
      81             :     ! set default values for optional arguments
      82          14 :     mrm_read_river_network = .false.
      83          14 :     read_old_style_restart_bounds = .false.
      84          14 :     restart_reset_fluxes_states = .false.
      85             : 
      86             :     !===============================================================
      87             :     !  Read namelist main directories
      88             :     !===============================================================
      89          14 :     call open_nml(file_namelist, unamelist, quiet = .true.)
      90             : 
      91             :     !===============================================================
      92             :     !  Read namelist specifying the model configuration
      93             :     !===============================================================
      94          14 :     call position_nml('mainconfig_mhm_mrm', unamelist)
      95          14 :     read(unamelist, nml = mainconfig_mhm_mrm)
      96             :     ! consistency between read_restart and mrm_read_river_network
      97          14 :     if (read_restart) then
      98           1 :        if (.not. mrm_read_river_network) then
      99           1 :           call message('***WARNING: mrm_read_river_network is set to .true. because read_restart is .true.')
     100             :        end if
     101           1 :        mrm_read_river_network = .true.
     102             :     end if
     103             : 
     104          42 :     allocate(resolutionRouting(domainMeta%nDomains))
     105          42 :     allocate(mhmFileRestartIn(domainMeta%nDomains))
     106          28 :     allocate(mrmFileRestartIn(domainMeta%nDomains))
     107          40 :     do iDomain = 1, domainMeta%nDomains
     108          26 :       domainID = domainMeta%indices(iDomain)
     109          26 :       mhmFileRestartIn(iDomain) = mhm_file_RestartIn(domainID)
     110          26 :       mrmFileRestartIn(iDomain) = mrm_file_RestartIn(domainID)
     111          40 :       resolutionRouting(iDomain) = resolution_Routing(domainID)
     112             :     end do
     113             : 
     114             :     ! check for optimize and read restart
     115          14 :     if ((read_restart) .and. (optimize)) then
     116           0 :       call message()
     117           0 :       call error_message('***ERROR: cannot read states from restart file when optimizing')
     118             :     end if
     119             : 
     120          40 :     do iDomain = 1, domainMeta%nDomains
     121          26 :       domainID = domainMeta%indices(iDomain)
     122          40 :       if (processMatrix(8, 1) > 0 .and. domainMeta%optidata(iDomain) > 1 .and. optimize) then
     123           5 :         domainMeta%doRouting(iDomain) = .FALSE.
     124           5 :         call message('Warning: although defined in namelist, routing is switched off for domain', trim(num2str(domainID)))
     125           5 :         call message('         since the calibration of Q is not possible with the chosen opti input')
     126             :       end if
     127             :     end do
     128             : 
     129             :     !===============================================================
     130             :     !  INIT !!! (merged from mo_startup and mo_mrm_read_config)
     131             :     !===============================================================
     132             :     ! transformation of time units & constants
     133          14 :     if (mod(24, timeStep) > 0) then
     134           0 :       call error_message('mo_startup: timeStep must be a divisor of 24: ', num2str(timeStep))
     135             :     end if
     136          14 :     nTStepDay = 24_i4 / timeStep            ! # of time steps per day
     137             : 
     138             :     ! allocate time periods
     139          42 :     allocate(simPer(domainMeta%nDomains))
     140          28 :     allocate(evalPer(domainMeta%nDomains))
     141          42 :     allocate(warmingDays(domainMeta%nDomains))
     142          28 :     allocate(warmPer(domainMeta%nDomains))
     143             : 
     144             :     !===============================================================
     145             :     !  read simulation time periods incl. warming days
     146             :     !===============================================================
     147          14 :     call position_nml('time_periods', unamelist)
     148          14 :     read(unamelist, nml = time_periods)
     149          40 :     do iDomain = 1, domainMeta%nDomains
     150          26 :       domainID = domainMeta%indices(iDomain)
     151          26 :       warmingDays(iDomain) = warming_Days(domainID)
     152             :       ! this will be a procedure subroutine
     153             :       ! therefore inout first, in second
     154          40 :       call period_copy_period_data(evalPer(iDomain), eval_Per(domainID))
     155             :     end do
     156             :     ! evalPer = eval_Per(1 : domainMeta%nDomains)
     157             : 
     158             :     !===============================================================
     159             :     !  determine simulation time period incl. warming days for each
     160             :     !  domain
     161             :     !===============================================================
     162          40 :     do iDomain = 1, domainMeta%nDomains
     163             :       ! julian days for evaluation period
     164          26 :       jday = julday(dd = evalPer(iDomain)%dStart, mm = evalPer(iDomain)%mStart, yy = evalPer(iDomain)%yStart)
     165          26 :       evalPer(iDomain)%julStart = jday
     166             : 
     167          26 :       jday = julday(dd = evalPer(iDomain)%dEnd, mm = evalPer(iDomain)%mEnd, yy = evalPer(iDomain)%yEnd)
     168          26 :       evalPer(iDomain)%julEnd = jday
     169             : 
     170             :       ! determine warming period
     171          26 :       warmPer(iDomain)%julStart = evalPer(iDomain)%julStart - warmingDays(iDomain)
     172          26 :       warmPer(iDomain)%julEnd = evalPer(iDomain)%julStart - 1
     173             : 
     174           0 :       call caldat(warmPer(iDomain)%julStart, dd = warmPer(iDomain)%dStart, mm = warmPer(iDomain)%mStart, &
     175          26 :                   yy = warmPer(iDomain)%yStart)
     176           0 :       call caldat(warmPer(iDomain)%julEnd, dd = warmPer(iDomain)%dEnd, mm = warmPer(iDomain)%mEnd, &
     177          26 :                   yy = warmPer(iDomain)%yEnd)
     178             : 
     179             :       ! simulation Period = warming Period + evaluation Period
     180          26 :       simPer(iDomain)%dStart = warmPer(iDomain)%dStart
     181          26 :       simPer(iDomain)%mStart = warmPer(iDomain)%mStart
     182          26 :       simPer(iDomain)%yStart = warmPer(iDomain)%yStart
     183          26 :       simPer(iDomain)%julStart = warmPer(iDomain)%julStart
     184          26 :       simPer(iDomain)%dEnd = evalPer(iDomain)%dEnd
     185          26 :       simPer(iDomain)%mEnd = evalPer(iDomain)%mEnd
     186          26 :       simPer(iDomain)%yEnd = evalPer(iDomain)%yEnd
     187          92 :       simPer(iDomain)%julEnd = evalPer(iDomain)%julEnd
     188             :     end do
     189             : 
     190             :     call set_land_cover_scenes_id(simPer, LCyearId)
     191             : 
     192             :     !===============================================================
     193             :     ! Settings for Optimization
     194             :     !===============================================================
     195             :     ! namelist for Optimization settings
     196          14 :     call position_nml('Optimization', unamelist)
     197          14 :     read(unamelist, nml = Optimization)
     198             :     ! checking of settings and default value initialization moved to new subroutine
     199             :     ! because global_parameters need to be set, which is not the case right now
     200          14 :     call close_nml(unamelist)
     201             : 
     202          14 :   end subroutine common_mHM_mRM_read_config
     203             : 
     204             : 
     205             :   !> \brief check optimization settings
     206             :   !> \authors Robert Schweppe
     207             :   !> \date Jun 2018
     208          14 :   subroutine check_optimization_settings
     209             : 
     210          14 :     use mo_common_mHM_mRM_variables, only : dds_r, nIterations, sce_ngs, sce_npg, sce_nps
     211             :     use mo_common_variables, only : global_parameters
     212             : 
     213             :     implicit none
     214             : 
     215             :     integer(i4) :: n_true_pars
     216             : 
     217             : 
     218             :     ! check and set default values
     219          14 :     if (nIterations .le. 0_i4) then
     220           0 :       call error_message('Number of iterations for Optimization (nIterations) must be greater than zero')
     221             :     end if
     222          14 :     if (dds_r .lt. 0.0_dp .or. dds_r .gt. 1.0_dp) then
     223           0 :       call error_message('dds_r must be between 0.0 and 1.0')
     224             :     end if
     225          14 :     if (sce_ngs .lt. 1_i4) then
     226           0 :       call error_message('number of complexes in SCE (sce_ngs) must be at least 1')
     227             :     end if
     228             :     ! number of points in each complex: default = 2n+1
     229          14 :     if (sce_npg .lt. 0_i4) then
     230         757 :       n_true_pars = count(nint(global_parameters(:, 4)) .eq. 1)
     231          14 :       sce_npg = 2 * n_true_pars + 1_i4
     232             :     end if
     233             :     ! number of points in each sub-complex: default = n+1
     234          14 :     if (sce_nps .lt. 0_i4) then
     235         757 :       n_true_pars = count(nint(global_parameters(:, 4)) .eq. 1)
     236          14 :       sce_nps = n_true_pars + 1_i4
     237             :     end if
     238          14 :     if (sce_npg .lt. sce_nps) then
     239           0 :       call error_message('number of points per complex (sce_npg) must be greater or', raise=.false.)
     240           0 :       call error_message('equal number of points per sub-complex (sce_nps)')
     241             :     end if
     242             : 
     243          14 :   end subroutine check_optimization_settings
     244             : 
     245             : 
     246             :   !> \brief check resolution
     247             :   !> \authors Robert Schweppe
     248             :   !> \date Jun 2018
     249          28 :   subroutine common_check_resolution(do_message, allow_subgrid_routing)
     250             : 
     251          14 :     use mo_common_mHM_mRM_variables, only : resolutionRouting
     252             :     use mo_common_variables, only : domainMeta, resolutionHydrology
     253             :     use mo_string_utils, only : num2str
     254             : 
     255             :     implicit none
     256             : 
     257             :     logical, intent(in) :: do_message !< flag to print messages
     258             :     logical, intent(in) :: allow_subgrid_routing !< flag to allow subgrid routing
     259             : 
     260             :     integer(i4) :: iDomain, domainID
     261             : 
     262             :     ! conversion factor L11 to L1
     263          28 :     real(dp) :: cellFactorRbyH
     264             : 
     265             : 
     266             :     !===============================================================
     267             :     ! check matching of resolutions: hydrology, forcing and routing
     268             :     !===============================================================
     269          80 :     do iDomain = 1, domainMeta%nDomains
     270          52 :       domainID = domainMeta%indices(iDomain)
     271          52 :       cellFactorRbyH = resolutionRouting(iDomain) / resolutionHydrology(iDomain)
     272          52 :       if (do_message) then
     273          26 :         call message()
     274          26 :         call message('domain ', trim(adjustl(num2str(domainID))), ': ')
     275             :         call message('resolution Hydrology (domain ', trim(adjustl(num2str(domainID))), ')     = ', &
     276          26 :                 trim(adjustl(num2str(resolutionHydrology(iDomain)))))
     277             :         call message('resolution Routing (domain ', trim(adjustl(num2str(domainID))), ')       = ', &
     278          26 :                 trim(adjustl(num2str(resolutionRouting(iDomain)))))
     279             :       end if
     280             :       !
     281          80 :       if(nint(cellFactorRbyH * 100.0_dp) .eq. 100) then
     282          50 :         if (do_message) then
     283          25 :           call message()
     284          25 :           call message('Resolution of routing and hydrological modeling are equal!')
     285             :         end if
     286             : 
     287           2 :       else if ((nint(cellFactorRbyH * 100.0_dp) .gt. 100) .and. .not.allow_subgrid_routing) then
     288           1 :         if(nint(mod(cellFactorRbyH, 2.0_dp) * 100.0_dp) .ne. 0) then
     289           0 :           call error_message('***ERROR: Resolution of routing is not a multiple of hydrological model resolution!', raise=.false.)
     290           0 :           call error_message('   FILE: mhm.nml, namelist: mainconfig, variable: resolutionRouting')
     291             :         end if
     292             :         !
     293           1 :         if (do_message) then
     294           1 :           call message()
     295             :           call message('Resolution of routing is bigger than hydrological model resolution by ', &
     296           1 :                   trim(adjustl(num2str(nint(cellFactorRbyH)))), ' times !')
     297             :         end if
     298             :       end if
     299             :       !
     300             :     end do
     301             : 
     302          28 :   end subroutine common_check_resolution
     303             : 
     304             : 
     305             :   ! ToDo: make this a procedure of period
     306             :   !> \brief copy period data
     307          26 :   subroutine period_copy_period_data(toPeriod, fromPeriod)
     308          28 :     use mo_common_types, only: period
     309             :     type(period), intent(inout) :: toPeriod !< copy to this period
     310             :     type(period), intent(in)    :: fromPeriod !< copy from this period
     311             : 
     312          26 :     toPeriod%dStart   = fromPeriod%dStart    ! first day
     313          26 :     toPeriod%mStart   = fromPeriod%mStart    ! first month
     314          26 :     toPeriod%yStart   = fromPeriod%yStart    ! first year
     315          26 :     toPeriod%dEnd     = fromPeriod%dEnd      ! last  day
     316          26 :     toPeriod%mEnd     = fromPeriod%mEnd      ! last  month
     317          26 :     toPeriod%yEnd     = fromPeriod%yEnd      ! last  year
     318          26 :     toPeriod%julStart = 0 ! first julian day
     319          26 :     toPeriod%julEnd   = 0 ! last  julian day
     320          26 :     toPeriod%nObs     = 0 ! total number of observations
     321             : 
     322          26 :   end subroutine period_copy_period_data
     323             : 
     324             : END MODULE mo_common_mHM_mRM_read_config

Generated by: LCOV version 1.16