5.13.3-dev0
mHM
The mesoscale Hydrological Model
Loading...
Searching...
No Matches
mo_mrm_read_config.f90
Go to the documentation of this file.
1!> \file mo_mrm_read_config.f90
2!> \brief \copybrief mo_mrm_read_config
3!> \details \copydetails mo_mrm_read_config
4
5!> \brief read mRM config
6!> \details This module contains all mRM subroutines related to reading the mRM configuration either from file or copy from mHM.
7!> \authors Stephan Thober
8!> \date Aug 2015
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_mrm
13
14 use mo_kind, only : i4, dp
15 use mo_message, only: message, error_message
16
17 implicit none
18
19 public :: mrm_read_config
20
21contains
22
23 ! ------------------------------------------------------------------
24
25 ! NAME
26 ! mrm_read_config
27
28 ! PURPOSE
29 !> \brief Read the general config of mRM
30
31 !> \details Depending on the variable mrm_coupling_config, the
32 !> mRM config is either read from mrm.nml and parameters from
33 !> mrm_parameter.nml or copied from mHM.
34
35 ! INTENT(IN)
36 !> \param[in] "character(*) :: file_namelist, file_namelist_param"
37 !> \param[in] "character(*) :: file_namelist, file_namelist_param"
38 !> \param[in] "logical :: do_message" - flag for writing mHM standard messages
39
40 ! HISTORY
41 !> \authors Stephan Thober
42
43 !> \date Aug 2015
44
45 ! Modifications:
46 ! Stephan Thober Sep 2015 - removed stop condition when routing resolution is smaller than hydrologic resolution
47 ! Stephan Thober Oct 2015 - added NLoutputResults namelist, fileLatLon to directories_general namelist, and readLatLon flag
48 ! Robert Schweppe Jun 2018 - refactoring and reformatting
49
50 subroutine mrm_read_config(file_namelist, file_namelist_param, do_message)
51
56 use mo_mrm_file, only : file_defoutput
64 use mo_string_utils, only : num2str
65 use mo_namelists, only : &
71
72 implicit none
73
74 character(*), intent(in) :: file_namelist, file_namelist_param
75
76 ! - flag for writing mHM standard messages
77 logical, intent(in) :: do_message
78
79 integer(i4), dimension(maxNoDomains) :: nogauges_domain
80 integer(i4), dimension(maxNoDomains, maxNoGauges) :: gauge_id
81 character(256), dimension(maxNoDomains, maxNoGauges) :: gauge_filename
82
83 integer(i4), dimension(maxNoDomains) :: noinflowgauges_domain
84 integer(i4), dimension(maxNoDomains, maxNoGauges) :: inflowgauge_id
85 character(256), dimension(maxNoDomains, maxNoGauges) :: inflowgauge_filename
86 logical, dimension(maxNoDomains, maxNoGauges) :: inflowgauge_headwater
87
88 integer(i4) :: domainid, idomain
89
90 integer(i4) :: igauge
91
92 integer(i4) :: idx
93
94 character(256), dimension(maxNoDomains) :: dir_gauges
95 character(256), dimension(maxNoDomains) :: dir_total_runoff
96 character(256), dimension(maxNoDomains) :: dir_bankfull_runoff
97
98 logical :: file_exists
99
100 type(domaininfo_mrm), pointer :: domain_mrm_idomain
101
102 !===============================================================
103 ! INITIALIZATION
104 !===============================================================
105 is_start = .true.
106
107 !===============================================================
108 ! Read namelist for mainconfig for mRM
109 !===============================================================
110 call nml_mainconfig_mrm%read(file_namelist)
111 alma_convention = nml_mainconfig_mrm%ALMA_convention
112 filenametotalrunoff = nml_mainconfig_mrm%filenameTotalRunoff
113 varnametotalrunoff = nml_mainconfig_mrm%varnameTotalRunoff
114 gw_coupling = nml_mainconfig_mrm%gw_coupling
115
116 !===============================================================
117 ! Read namelist for mainpaths
118 !===============================================================
119 call nml_directories_mrm%read(file_namelist)
120 dir_gauges = nml_directories_mrm%dir_Gauges
121 dir_total_runoff = nml_directories_mrm%dir_Total_Runoff
122 dir_bankfull_runoff = nml_directories_mrm%dir_Bankfull_Runoff
123
124 allocate(dirgauges(domainmeta%nDomains), dirtotalrunoff(domainmeta%nDomains), dirbankfullrunoff(domainmeta%nDomains))
125 do idomain = 1, domainmeta%nDomains
126 domainid = domainmeta%indices(idomain)
127 dirgauges(idomain) = dir_gauges(domainid)
128 dirtotalrunoff(idomain) = dir_total_runoff(domainid)
129 dirbankfullrunoff(idomain) = dir_bankfull_runoff(domainid)
130 end do
131
132 !===============================================================
133 ! READ EVALUATION GAUGES
134 !===============================================================
135 call nml_evaluation_gauges%read(file_namelist)
137 nogauges_domain = nml_evaluation_gauges%NoGauges_domain
138 gauge_id = nml_evaluation_gauges%Gauge_id
139 gauge_filename = nml_evaluation_gauges%gauge_filename
140
141 if (ngaugestotal .GT. maxnogauges) then
142 call error_message('***ERROR: ', trim(file_namelist), ': Total number of evaluation gauges is restricted to', &
143 num2str(maxnogauges), raise=.false.)
144 call error_message(' Error occured in namlist: evaluation_gauges')
145 end if
146
147 ! ToDo: check
148 ngaugeslocal = 0
149 do idomain = 1, domainmeta%nDomains
150 domainid = domainmeta%indices(idomain)
151 ngaugeslocal = ngaugeslocal + nogauges_domain(domainid)
152 end do
153 ! End ToDo
154
155 allocate(gauge%gaugeId(ngaugeslocal)) ; gauge%gaugeId = nodata_i4
156 allocate(gauge%domainId(ngaugeslocal)) ; gauge%domainId = nodata_i4
157 allocate(gauge%fName (ngaugeslocal))
158 if (ngaugeslocal > 0) then
159 gauge%fName(1) = num2str(nodata_i4)
160 end if
161 allocate(domain_mrm(domainmeta%nDomains))
162
163 idx = 0
164 do idomain = 1, domainmeta%nDomains
165 domainid = domainmeta%indices(idomain)
166 domain_mrm_idomain => domain_mrm(idomain)
167 ! initialize
168 domain_mrm_idomain%nGauges = nodata_i4
169 allocate(domain_mrm_idomain%gaugeIdList(maxval(nogauges_domain(:))))
170 domain_mrm_idomain%gaugeIdList = nodata_i4
171 allocate(domain_mrm_idomain%gaugeIndexList(maxval(nogauges_domain(:))))
172 domain_mrm_idomain%gaugeIndexList = nodata_i4
173 allocate(domain_mrm_idomain%gaugeNodeList(maxval(nogauges_domain(:))))
174 domain_mrm_idomain%gaugeNodeList = nodata_i4
175 ! check if NoGauges_domain has a valid value
176 if (nogauges_domain(domainid) .EQ. nodata_i4) then
177 call error_message('***ERROR: ', trim(file_namelist), ': Number of evaluation gauges for subdomain ', &
178 trim(adjustl(num2str(domainid))), ' is not defined!', raise=.false.)
179 call error_message(' Error occured in namelist: evaluation_gauges')
180 end if
181
182 domain_mrm_idomain%nGauges = nogauges_domain(domainid)
183
184 do igauge = 1, nogauges_domain(domainid)
185 ! check if NoGauges_domain has a valid value
186 if (gauge_id(domainid, igauge) .EQ. nodata_i4) then
187 call error_message('***ERROR: ', trim(file_namelist), ': ID ', &
188 trim(adjustl(num2str(gauge_id(domainid, igauge)))), ' of evaluation gauge ', &
189 trim(adjustl(num2str(igauge))), ' for subdomain ', &
190 trim(adjustl(num2str(idomain))), ' is not defined!', raise=.false.)
191 call error_message(' Error occured in namelist: evaluation_gauges')
192 else if (trim(gauge_filename(domainid, igauge)) .EQ. trim(num2str(nodata_i4))) then
193 call error_message('***ERROR: ', trim(file_namelist), ': Filename of evaluation gauge ', &
194 trim(adjustl(num2str(igauge))), ' for subdomain ', &
195 trim(adjustl(num2str(idomain))), ' is not defined!', raise=.false.)
196 call error_message(' Error occured in namelist: evaluation_gauges')
197 end if
198 !
199 idx = idx + 1
200 gauge%domainId(idx) = idomain
201 gauge%gaugeId(idx) = gauge_id(domainid, igauge)
202 gauge%fname(idx) = trim(dirgauges(idomain)) // trim(gauge_filename(domainid, igauge))
203 domain_mrm_idomain%gaugeIdList(igauge) = gauge_id(domainid, igauge)
204 domain_mrm_idomain%gaugeIndexList(igauge) = idx
205 end do
206 end do
207
208 if (ngaugeslocal .NE. idx) then
209 call error_message('***ERROR: ', trim(file_namelist), ': Total number of evaluation gauges (', &
210 trim(adjustl(num2str(ngaugeslocal))), &
211 ') different from sum of gauges in subdomains (', trim(adjustl(num2str(idx))), ')!', raise=.false.)
212 call error_message(' Error occured in namelist: evaluation_gauges')
213 end if
214
215 !===============================================================
216 ! Read inflow gauge information
217 !===============================================================
218
219 call nml_inflow_gauges%read(file_namelist)
220 ninflowgaugestotal = nml_inflow_gauges%nInflowGaugesTotal
221 noinflowgauges_domain = nml_inflow_gauges%NoInflowGauges_domain
222 inflowgauge_id = nml_inflow_gauges%InflowGauge_id
223 inflowgauge_filename = nml_inflow_gauges%InflowGauge_filename
224 inflowgauge_headwater = nml_inflow_gauges%InflowGauge_Headwater
225
226 if (ninflowgaugestotal .GT. maxnogauges) then
227 call error_message('***ERROR: ', trim(file_namelist), &
228 ':read_gauge_lut: Total number of inflow gauges is restricted to', num2str(maxnogauges), raise=.false.)
229 call error_message(' Error occured in namlist: inflow_gauges')
230 end if
231
232 ! allocation - max() to avoid allocation with zero, needed for mhm call
233 allocate(inflowgauge%gaugeId (max(1, ninflowgaugestotal)))
234 allocate(inflowgauge%domainId (max(1, ninflowgaugestotal)))
235 allocate(inflowgauge%fName (max(1, ninflowgaugestotal)))
236 ! dummy initialization
237 inflowgauge%gaugeId = nodata_i4
238 inflowgauge%domainId = nodata_i4
239 inflowgauge%fName = num2str(nodata_i4)
240
241 idx = 0
242 do idomain = 1, domainmeta%nDomains
243 domainid = domainmeta%indices(idomain)
244 domain_mrm_idomain => domain_mrm(idomain)
245
246 allocate(domain_mrm_idomain%InflowGaugeIdList (max(1, maxval(noinflowgauges_domain(:)))))
247 allocate(domain_mrm_idomain%InflowGaugeHeadwater (max(1, maxval(noinflowgauges_domain(:)))))
248 allocate(domain_mrm_idomain%InflowGaugeIndexList (max(1, maxval(noinflowgauges_domain(:)))))
249 allocate(domain_mrm_idomain%InflowGaugeNodeList (max(1, maxval(noinflowgauges_domain(:)))))
250 ! dummy initialization
251 domain_mrm_idomain%nInflowGauges = 0
252 domain_mrm_idomain%InflowGaugeIdList = nodata_i4
253 domain_mrm_idomain%InflowGaugeHeadwater = .false.
254 domain_mrm_idomain%InflowGaugeIndexList = nodata_i4
255 domain_mrm_idomain%InflowGaugeNodeList = nodata_i4
256 ! no inflow gauge for subdomain i
257 if (noinflowgauges_domain(domainid) .EQ. nodata_i4) then
258 noinflowgauges_domain(domainid) = 0
259 end if
260
261 domain_mrm_idomain%nInflowGauges = noinflowgauges_domain(domainid)
262
263 do igauge = 1, noinflowgauges_domain(domainid)
264 ! check if NoInflowGauges_domain has a valid value
265 if (inflowgauge_id(domainid, igauge) .EQ. nodata_i4) then
266 call error_message('***ERROR: ', trim(file_namelist), ':ID of inflow gauge ', &
267 trim(adjustl(num2str(igauge))), ' for subdomain ', &
268 trim(adjustl(num2str(idomain))), ' is not defined!', raise=.false.)
269 call error_message(' Error occured in namlist: inflow_gauges')
270 else if (trim(inflowgauge_filename(domainid, igauge)) .EQ. trim(num2str(nodata_i4))) then
271 call error_message('***ERROR: ', trim(file_namelist), ':Filename of inflow gauge ', &
272 trim(adjustl(num2str(igauge))), ' for subdomain ', &
273 trim(adjustl(num2str(idomain))), ' is not defined!', raise=.false.)
274 call error_message(' Error occured in namlist: inflow_gauges')
275 end if
276 !
277 idx = idx + 1
278 inflowgauge%domainId(idx) = idomain
279 inflowgauge%gaugeId(idx) = inflowgauge_id(domainid, igauge)
280 inflowgauge%fname(idx) = trim(dirgauges(domainid)) // trim(inflowgauge_filename(domainid, igauge))
281 domain_mrm_idomain%InflowGaugeIdList(igauge) = inflowgauge_id(domainid, igauge)
282 domain_mrm_idomain%InflowGaugeHeadwater(igauge) = inflowgauge_headwater(domainid, igauge)
283 domain_mrm_idomain%InflowGaugeIndexList(igauge) = idx
284 end do
285 end do
286
287 if (ninflowgaugestotal .NE. idx) then
288 call error_message('***ERROR: ', trim(file_namelist), ': Total number of inflow gauges (', &
289 trim(adjustl(num2str(ninflowgaugestotal))), &
290 ') different from sum of inflow gauges in subdomains (', trim(adjustl(num2str(idx))), ')!', raise=.false.)
291 call error_message(' Error occured in namlist: inflow_gauges')
292 end if
293
294 call common_check_resolution(do_message, .true.)
295
296 !===============================================================
297 ! Read namelist global parameters
298 !===============================================================
299 call read_mrm_routing_params(processmatrix(8, 1), file_namelist_param)
300
301 !===============================================================
302 ! Read Output specifications for mRM
303 !===============================================================
305 output_deflate_level_mrm = nml_mrm_outputs%output_deflate_level_mrm
306 output_double_precision_mrm = nml_mrm_outputs%output_double_precision_mrm
307 output_time_reference_mrm = nml_mrm_outputs%output_time_reference_mrm
308 timestep_model_outputs_mrm = nml_mrm_outputs%timeStep_model_outputs_mrm
309 outputflxstate_mrm = nml_mrm_outputs%outputFlxState_mrm
310
312
313 if (any(outputflxstate_mrm)) then
314 call message('')
315 call message(' Following output will be written:')
316 call message(' NetCDF deflate level: ', adjustl(trim(num2str(output_deflate_level_mrm))))
318 call message(' NetCDF output precision: double')
319 else
320 call message(' NetCDF output precision: single')
321 end if
322 select case(output_time_reference_mrm)
323 case(0)
324 call message(' NetCDF output time reference point: start of time interval')
325 case(1)
326 call message(' NetCDF output time reference point: center of time interval')
327 case(2)
328 call message(' NetCDF output time reference point: end of time interval')
329 end select
330 call message(' FLUXES:')
331 if (outputflxstate_mrm(1)) then
332 call message(' routed streamflow (L11_qMod) [m3 s-1]')
333 end if
334 if (outputflxstate_mrm(2)) then
335 call message(' river temperature (RivTemp) [deg C]')
336 end if
337 if (gw_coupling) then
338 call message(' river head (river_head) [m]')
339 end if
340 end if
341
342 call message('')
343 call message(' FINISHED reading config')
344 call message('')
345
346 end subroutine mrm_read_config
347
348 ! ---------------------------------------------------------------------------
349 ! SUBROUTINE READ_MRM_ROUTING_PARAMS
350 ! ---------------------------------------------------------------------------
351 ! NAME
352 ! read_mrm_routing_params
353
354 ! PURPOSE
355 !> \brief TODO: add description
356
357 !> \details TODO: add description
358
359 ! INTENT(IN)
360 !> \param[in] "integer(i4) :: processCase" it is the default case, should be one
361 !> \param[in] "character(*) :: file_namelist_param" file name containing parameter namelist
362
363 ! HISTORY
364 !> \authors Robert Schweppe
365
366 !> \date Jun 2018
367
368 ! Modifications:
369
370 subroutine read_mrm_routing_params(processCase, file_namelist_param)
371
372 use mo_common_constants, only : ncolpars
373 use mo_common_functions, only : in_bound
375 use mo_message, only : message
376 use mo_namelists, only : &
377 nml_routing1, &
378 nml_routing2, &
380
381 implicit none
382
383 ! it is the default case, should be one
384 integer(i4), intent(in) :: processCase
385
386 ! file name containing parameter namelist
387 character(*), intent(in) :: file_namelist_param
388
389 ! equals sum of previous parameters
390 integer(i4) :: start_index
391
392 real(dp), dimension(nColPars) :: muskingumTravelTime_constant
393 real(dp), dimension(nColPars) :: muskingumTravelTime_riverLength
394 real(dp), dimension(nColPars) :: muskingumTravelTime_riverSlope
395 real(dp), dimension(nColPars) :: muskingumTravelTime_impervious
396 real(dp), dimension(nColPars) :: muskingumAttenuation_riverSlope
397
398 real(dp), dimension(nColPars) :: streamflow_celerity
399 real(dp), dimension(nColPars) :: slope_factor
400
401 if (processcase .eq. 1_i4) then
402 call nml_routing1%read(file_namelist_param)
403 muskingumtraveltime_constant = nml_routing1%muskingumTravelTime_constant
404 muskingumtraveltime_riverlength = nml_routing1%muskingumTravelTime_riverLength
405 muskingumtraveltime_riverslope = nml_routing1%muskingumTravelTime_riverSlope
406 muskingumtraveltime_impervious = nml_routing1%muskingumTravelTime_impervious
407 muskingumattenuation_riverslope = nml_routing1%muskingumAttenuation_riverSlope
408 else if (processcase .eq. 2_i4) then
409 call nml_routing2%read(file_namelist_param)
410 streamflow_celerity = nml_routing2%streamflow_celerity
411 else if (processcase .eq. 3_i4) then
412 call nml_routing3%read(file_namelist_param)
413 slope_factor = nml_routing3%slope_factor
414 end if
415
416 ! -------------------------------------------------------------------------
417 ! INCLUDE MRM PARAMETERS IN PARAMETERS OF MHM
418 ! -------------------------------------------------------------------------
419 ! Muskingum routing parameters with MPR
420 if (processcase .eq. 1_i4) then
421 ! insert parameter values and names at position required by mhm
422 processmatrix(8, 1) = processcase
423 processmatrix(8, 2) = 5_i4
424 processmatrix(8, 3) = sum(processmatrix(1 : 8, 2))
425 start_index = processmatrix(8, 3) - processmatrix(8, 2)
426 global_parameters(start_index + 1, :) = muskingumtraveltime_constant
427 global_parameters(start_index + 2, :) = muskingumtraveltime_riverlength
428 global_parameters(start_index + 3, :) = muskingumtraveltime_riverslope
429 global_parameters(start_index + 4, :) = muskingumtraveltime_impervious
430 global_parameters(start_index + 5, :) = muskingumattenuation_riverslope
431
432 global_parameters_name(start_index + 1 : start_index + processmatrix(8, 2)) = (/ &
433 'muskingumTravelTime_constant ', &
434 'muskingumTravelTime_riverLength', &
435 'muskingumTravelTime_riverSlope ', &
436 'muskingumTravelTime_impervious ', &
437 'muskingumAttenuation_riverSlope'/)
438 ! adaptive timestep routing
439 else if (processcase .eq. 2_i4) then
440 processmatrix(8, 1) = processcase
441 processmatrix(8, 2) = 1_i4
442 processmatrix(8, 3) = sum(processmatrix(1 : 8, 2))
443 start_index = processmatrix(8, 3) - processmatrix(8, 2)
444 global_parameters(start_index + 1, :) = streamflow_celerity
445
446 global_parameters_name(start_index + 1 : start_index + processmatrix(8, 2)) = (/ &
447 'streamflow_celerity'/)
448 ! adaptive timestep routing - varying celerity
449 else if (processcase .eq. 3_i4) then
450 ! insert parameter values and names at position required by mhm
451 processmatrix(8, 1) = processcase
452 processmatrix(8, 2) = 1_i4
453 processmatrix(8, 3) = sum(processmatrix(1:8, 2))
454 start_index = processmatrix(8, 3) - processmatrix(8, 2)
455 global_parameters(start_index + 1, :) = slope_factor
456
457 global_parameters_name(start_index + 1 : start_index + processmatrix(8,2)) = (/ &
458 'slope_factor'/)
459 end if
460
461 ! check if parameter are in range
462 if (.not. in_bound(global_parameters)) then
463 call error_message('***ERROR: parameter in routing namelist out of bound in ', &
464 trim(adjustl(file_namelist_param)))
465 end if
466
467 end subroutine read_mrm_routing_params
468end module mo_mrm_read_config
Provides constants commonly used by mHM, mRM and MPR.
integer(i4), parameter, public ncolpars
integer(i4), parameter, public maxnodomains
integer(i4), parameter, public nodata_i4
Provides small utility functions used by multiple parts of the code (mHM, mRM, MPR)
logical function, public in_bound(params)
TODO: add description.
Reading of main model configurations.
subroutine, public common_check_resolution(do_message, allow_subgrid_routing)
check resolution
Provides structures needed by mHM, mRM and/or mpr.
real(dp), dimension(:, :), allocatable, target, public global_parameters
character(256), dimension(:), allocatable, public global_parameters_name
type(domain_meta), public domainmeta
integer(i4), dimension(nprocesses, 3), public processmatrix
Provides mRM specific constants.
integer(i4), parameter, public maxnogauges
Provides file names and units for mRM.
character(:), allocatable file_defoutput
file defining mRM's outputs
Global variables for mRM only.
type(gaugingstation), public inflowgauge
logical output_double_precision_mrm
float precision in output nc files
character(256), dimension(:), allocatable, public dirbankfullrunoff
character(256), dimension(:), allocatable, public dirgauges
integer(i4) output_time_reference_mrm
time reference point location in output nc files
type(gaugingstation), public gauge
logical, dimension(noutflxstate) outputflxstate_mrm
Define model outputs see "mhm_outputs.nml".
type(domaininfo_mrm), dimension(:), allocatable, target, public domain_mrm
character(256), public varnametotalrunoff
integer(i4) timestep_model_outputs_mrm
timestep for writing model outputs
character(256), dimension(:), allocatable, public dirtotalrunoff
integer(i4), public ninflowgaugestotal
integer(i4) output_deflate_level_mrm
compression of output nc files
character(256), public filenametotalrunoff
subroutine, public mrm_read_config(file_namelist, file_namelist_param, do_message)
Read the general config of mRM.
subroutine read_mrm_routing_params(processcase, file_namelist_param)
TODO: add description.
Module containing all namelists representations.
type(nml_evaluation_gauges_t), public nml_evaluation_gauges
'evaluation_gauges' namelist content
type(nml_directories_mrm_t), public nml_directories_mrm
'directories_mrm' namelist content
type(nml_mainconfig_mrm_t), public nml_mainconfig_mrm
'mainconfig_mrm' namelist content
type(nml_routing3_t), public nml_routing3
'routing3' namelist content
type(nml_routing1_t), public nml_routing1
'routing1' namelist content
type(nml_inflow_gauges_t), public nml_inflow_gauges
'inflow_gauges' namelist content
type(nml_mrm_outputs_t), public nml_mrm_outputs
'mrm_outputs' namelist content
type(nml_routing2_t), public nml_routing2
'routing2' namelist content