5.13.2-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] "integer :: unamelist, unamelist_param"
38 !> \param[in] "character(*) :: file_namelist, file_namelist_param"
39 !> \param[in] "integer :: unamelist, unamelist_param"
40 !> \param[in] "logical :: do_message" - flag for writing mHM standard messages
41
42 ! HISTORY
43 !> \authors Stephan Thober
44
45 !> \date Aug 2015
46
47 ! Modifications:
48 ! Stephan Thober Sep 2015 - removed stop condition when routing resolution is smaller than hydrologic resolution
49 ! Stephan Thober Oct 2015 - added NLoutputResults namelist, fileLatLon to directories_general namelist, and readLatLon flag
50 ! Robert Schweppe Jun 2018 - refactoring and reformatting
51
52 subroutine mrm_read_config(file_namelist, unamelist, file_namelist_param, unamelist_param, do_message)
53
66 use mo_nml, only : close_nml, open_nml, position_nml
67 use mo_string_utils, only : num2str
68
69 implicit none
70
71 character(*), intent(in) :: file_namelist, file_namelist_param
72
73 integer, intent(in) :: unamelist, unamelist_param
74
75 ! - flag for writing mHM standard messages
76 logical, intent(in) :: do_message
77
78 integer(i4), dimension(maxNoDomains) :: nogauges_domain
79
80 integer(i4), dimension(maxNoDomains, maxNoGauges) :: gauge_id
81
82 character(256), dimension(maxNoDomains, maxNoGauges) :: gauge_filename
83
84 integer(i4), dimension(maxNoDomains) :: noinflowgauges_domain
85
86 integer(i4), dimension(maxNoDomains, maxNoGauges) :: inflowgauge_id
87
88 character(256), dimension(maxNoDomains, maxNoGauges) :: inflowgauge_filename
89
90 logical, dimension(maxNoDomains, maxNoGauges) :: inflowgauge_headwater
91
92 integer(i4) :: domainid, idomain
93
94 integer(i4) :: igauge
95
96 integer(i4) :: idx
97
98 character(256), dimension(maxNoDomains) :: dir_gauges
99
100 character(256), dimension(maxNoDomains) :: dir_total_runoff
101
102 character(256), dimension(maxNoDomains) :: dir_bankfull_runoff
103
104 logical :: file_exists
105
106 type(domaininfo_mrm), pointer :: domain_mrm_idomain
107
108
109 ! namelist spatial & temporal resolution, optmization information
110 namelist /mainconfig_mrm/ alma_convention, &
112 ! namelist directories
113 namelist /directories_mrm/ dir_gauges, dir_total_runoff, dir_bankfull_runoff
114 namelist /evaluation_gauges/ ngaugestotal, nogauges_domain, gauge_id, gauge_filename
115 ! namelist for inflow gauges
116 namelist /inflow_gauges/ ninflowgaugestotal, noinflowgauges_domain, inflowgauge_id, &
117 inflowgauge_filename, inflowgauge_headwater
118 ! name list regarding output
119 namelist /nloutputresults/ &
125
126 !===============================================================
127 ! INITIALIZATION
128 !===============================================================
129 is_start = .true.
131 nogauges_domain = nodata_i4
132 gauge_id = nodata_i4
133 gauge_filename = num2str(nodata_i4)
134
135 ! default arguments
136 alma_convention = .false.
137 filenametotalrunoff = 'total_runoff'
138 varnametotalrunoff = 'total_runoff'
139 gw_coupling = .false.
140
141 !===============================================================
142 ! Read namelist main directories
143 !===============================================================
144 call open_nml(file_namelist, unamelist, quiet = .true.)
145
146 !===============================================================
147 ! Read namelist for mainconfig for mRM
148 !===============================================================
149 call position_nml('mainconfig_mrm', unamelist)
150 read(unamelist, nml = mainconfig_mrm)
151
152 !===============================================================
153 ! Read namelist for mainpaths
154 !===============================================================
155 call position_nml('directories_mRM', unamelist)
156 read(unamelist, nml = directories_mrm)
157
158 allocate(dirgauges(domainmeta%nDomains), dirtotalrunoff(domainmeta%nDomains), dirbankfullrunoff(domainmeta%nDomains))
159 do idomain = 1, domainmeta%nDomains
160 domainid = domainmeta%indices(idomain)
161 dirgauges(idomain) = dir_gauges(domainid)
162 dirtotalrunoff(idomain) = dir_total_runoff(domainid)
163 dirbankfullrunoff(idomain) = dir_bankfull_runoff(domainid)
164 end do
165
166 !===============================================================
167 ! READ EVALUATION GAUGES
168 !===============================================================
169 call position_nml('evaluation_gauges', unamelist)
170 read(unamelist, nml = evaluation_gauges)
171
172 if (ngaugestotal .GT. maxnogauges) then
173 call error_message('***ERROR: ', trim(file_namelist), ': Total number of evaluation gauges is restricted to', &
174 num2str(maxnogauges), raise=.false.)
175 call error_message(' Error occured in namlist: evaluation_gauges')
176 end if
177
178 ! ToDo: check
179 ngaugeslocal = 0
180 do idomain = 1, domainmeta%nDomains
181 domainid = domainmeta%indices(idomain)
182 ngaugeslocal = ngaugeslocal + nogauges_domain(domainid)
183 end do
184 ! End ToDo
185
186 allocate(gauge%gaugeId(ngaugeslocal)) ; gauge%gaugeId = nodata_i4
187 allocate(gauge%domainId(ngaugeslocal)) ; gauge%domainId = nodata_i4
188 allocate(gauge%fName (ngaugeslocal))
189 if (ngaugeslocal > 0) then
190 gauge%fName(1) = num2str(nodata_i4)
191 end if
192 allocate(domain_mrm(domainmeta%nDomains))
193
194 idx = 0
195 do idomain = 1, domainmeta%nDomains
196 domainid = domainmeta%indices(idomain)
197 domain_mrm_idomain => domain_mrm(idomain)
198 ! initialize
199 domain_mrm_idomain%nGauges = nodata_i4
200 allocate(domain_mrm_idomain%gaugeIdList(maxval(nogauges_domain(:))))
201 domain_mrm_idomain%gaugeIdList = nodata_i4
202 allocate(domain_mrm_idomain%gaugeIndexList(maxval(nogauges_domain(:))))
203 domain_mrm_idomain%gaugeIndexList = nodata_i4
204 allocate(domain_mrm_idomain%gaugeNodeList(maxval(nogauges_domain(:))))
205 domain_mrm_idomain%gaugeNodeList = nodata_i4
206 ! check if NoGauges_domain has a valid value
207 if (nogauges_domain(domainid) .EQ. nodata_i4) then
208 call error_message('***ERROR: ', trim(file_namelist), ': Number of evaluation gauges for subdomain ', &
209 trim(adjustl(num2str(domainid))), ' is not defined!', raise=.false.)
210 call error_message(' Error occured in namelist: evaluation_gauges')
211 end if
212
213 domain_mrm_idomain%nGauges = nogauges_domain(domainid)
214
215 do igauge = 1, nogauges_domain(domainid)
216 ! check if NoGauges_domain has a valid value
217 if (gauge_id(domainid, igauge) .EQ. nodata_i4) then
218 call error_message('***ERROR: ', trim(file_namelist), ': ID ', &
219 trim(adjustl(num2str(gauge_id(domainid, igauge)))), ' of evaluation gauge ', &
220 trim(adjustl(num2str(igauge))), ' for subdomain ', &
221 trim(adjustl(num2str(idomain))), ' is not defined!', raise=.false.)
222 call error_message(' Error occured in namelist: evaluation_gauges')
223 else if (trim(gauge_filename(domainid, igauge)) .EQ. trim(num2str(nodata_i4))) then
224 call error_message('***ERROR: ', trim(file_namelist), ': Filename of evaluation gauge ', &
225 trim(adjustl(num2str(igauge))), ' for subdomain ', &
226 trim(adjustl(num2str(idomain))), ' is not defined!', raise=.false.)
227 call error_message(' Error occured in namelist: evaluation_gauges')
228 end if
229 !
230 idx = idx + 1
231 gauge%domainId(idx) = idomain
232 gauge%gaugeId(idx) = gauge_id(domainid, igauge)
233 gauge%fname(idx) = trim(dirgauges(idomain)) // trim(gauge_filename(domainid, igauge))
234 domain_mrm_idomain%gaugeIdList(igauge) = gauge_id(domainid, igauge)
235 domain_mrm_idomain%gaugeIndexList(igauge) = idx
236 end do
237 end do
238
239 if (ngaugeslocal .NE. idx) then
240 call error_message('***ERROR: ', trim(file_namelist), ': Total number of evaluation gauges (', &
241 trim(adjustl(num2str(ngaugeslocal))), &
242 ') different from sum of gauges in subdomains (', trim(adjustl(num2str(idx))), ')!', raise=.false.)
243 call error_message(' Error occured in namelist: evaluation_gauges')
244 end if
245
246 !===============================================================
247 ! Read inflow gauge information
248 !===============================================================
249
251 noinflowgauges_domain = 0
252 inflowgauge_id = nodata_i4
253 inflowgauge_filename = num2str(nodata_i4)
254
255 call position_nml('inflow_gauges', unamelist)
256 read(unamelist, nml = inflow_gauges)
257
258 if (ninflowgaugestotal .GT. maxnogauges) then
259 call error_message('***ERROR: ', trim(file_namelist), &
260 ':read_gauge_lut: Total number of inflow gauges is restricted to', num2str(maxnogauges), raise=.false.)
261 call error_message(' Error occured in namlist: inflow_gauges')
262 end if
263
264 ! allocation - max() to avoid allocation with zero, needed for mhm call
265 allocate(inflowgauge%gaugeId (max(1, ninflowgaugestotal)))
266 allocate(inflowgauge%domainId (max(1, ninflowgaugestotal)))
267 allocate(inflowgauge%fName (max(1, ninflowgaugestotal)))
268 ! dummy initialization
269 inflowgauge%gaugeId = nodata_i4
270 inflowgauge%domainId = nodata_i4
271 inflowgauge%fName = num2str(nodata_i4)
272
273 idx = 0
274 do idomain = 1, domainmeta%nDomains
275 domainid = domainmeta%indices(idomain)
276 domain_mrm_idomain => domain_mrm(idomain)
277
278 allocate(domain_mrm_idomain%InflowGaugeIdList (max(1, maxval(noinflowgauges_domain(:)))))
279 allocate(domain_mrm_idomain%InflowGaugeHeadwater (max(1, maxval(noinflowgauges_domain(:)))))
280 allocate(domain_mrm_idomain%InflowGaugeIndexList (max(1, maxval(noinflowgauges_domain(:)))))
281 allocate(domain_mrm_idomain%InflowGaugeNodeList (max(1, maxval(noinflowgauges_domain(:)))))
282 ! dummy initialization
283 domain_mrm_idomain%nInflowGauges = 0
284 domain_mrm_idomain%InflowGaugeIdList = nodata_i4
285 domain_mrm_idomain%InflowGaugeHeadwater = .false.
286 domain_mrm_idomain%InflowGaugeIndexList = nodata_i4
287 domain_mrm_idomain%InflowGaugeNodeList = nodata_i4
288 ! no inflow gauge for subdomain i
289 if (noinflowgauges_domain(domainid) .EQ. nodata_i4) then
290 noinflowgauges_domain(domainid) = 0
291 end if
292
293 domain_mrm_idomain%nInflowGauges = noinflowgauges_domain(domainid)
294
295 do igauge = 1, noinflowgauges_domain(domainid)
296 ! check if NoInflowGauges_domain has a valid value
297 if (inflowgauge_id(domainid, igauge) .EQ. nodata_i4) then
298 call error_message('***ERROR: ', trim(file_namelist), ':ID of inflow gauge ', &
299 trim(adjustl(num2str(igauge))), ' for subdomain ', &
300 trim(adjustl(num2str(idomain))), ' is not defined!', raise=.false.)
301 call error_message(' Error occured in namlist: inflow_gauges')
302 else if (trim(inflowgauge_filename(domainid, igauge)) .EQ. trim(num2str(nodata_i4))) then
303 call error_message('***ERROR: ', trim(file_namelist), ':Filename of inflow gauge ', &
304 trim(adjustl(num2str(igauge))), ' for subdomain ', &
305 trim(adjustl(num2str(idomain))), ' is not defined!', raise=.false.)
306 call error_message(' Error occured in namlist: inflow_gauges')
307 end if
308 !
309 idx = idx + 1
310 inflowgauge%domainId(idx) = idomain
311 inflowgauge%gaugeId(idx) = inflowgauge_id(domainid, igauge)
312 inflowgauge%fname(idx) = trim(dirgauges(domainid)) // trim(inflowgauge_filename(domainid, igauge))
313 domain_mrm_idomain%InflowGaugeIdList(igauge) = inflowgauge_id(domainid, igauge)
314 domain_mrm_idomain%InflowGaugeHeadwater(igauge) = inflowgauge_headwater(domainid, igauge)
315 domain_mrm_idomain%InflowGaugeIndexList(igauge) = idx
316 end do
317 end do
318
319 if (ninflowgaugestotal .NE. idx) then
320 call error_message('***ERROR: ', trim(file_namelist), ': Total number of inflow gauges (', &
321 trim(adjustl(num2str(ninflowgaugestotal))), &
322 ') different from sum of inflow gauges in subdomains (', trim(adjustl(num2str(idx))), ')!', raise=.false.)
323 call error_message(' Error occured in namlist: inflow_gauges')
324 end if
325
326 call common_check_resolution(do_message, .true.)
327
328 call close_nml(unamelist)
329
330 !===============================================================
331 ! Read namelist global parameters
332 !===============================================================
333 call read_mrm_routing_params(processmatrix(8, 1), file_namelist_param, unamelist_param)
334
335 !===============================================================
336 ! Read Output specifications for mRM
337 !===============================================================
341 outputflxstate_mrm = .false.
343 inquire(file = file_defoutput, exist = file_exists)
344 if (file_exists) then
345 ! file exists
346 call open_nml(file_defoutput, udefoutput, quiet = .true.)
347 call position_nml('NLoutputResults', udefoutput)
348 read(udefoutput, nml = nloutputresults)
349 call close_nml(udefoutput)
350 else
351 call message('')
352 call message('No file specifying mRM output fluxes exists')
353 end if
355
356 if (any(outputflxstate_mrm)) then
357 call message('')
358 call message(' Following output will be written:')
359 call message(' NetCDF deflate level: ', adjustl(trim(num2str(output_deflate_level_mrm))))
361 call message(' NetCDF output precision: double')
362 else
363 call message(' NetCDF output precision: single')
364 end if
365 select case(output_time_reference_mrm)
366 case(0)
367 call message(' NetCDF output time reference point: start of time interval')
368 case(1)
369 call message(' NetCDF output time reference point: center of time interval')
370 case(2)
371 call message(' NetCDF output time reference point: end of time interval')
372 end select
373 call message(' FLUXES:')
374 if (outputflxstate_mrm(1)) then
375 call message(' routed streamflow (L11_qMod) [m3 s-1]')
376 end if
377 if (outputflxstate_mrm(2)) then
378 call message(' river temperature (RivTemp) [deg C]')
379 end if
380 if (gw_coupling) then
381 call message(' river head (river_head) [m]')
382 end if
383 end if
384
385 call message('')
386 call message(' FINISHED reading config')
387 call message('')
388
389 end subroutine mrm_read_config
390
391 ! ---------------------------------------------------------------------------
392 ! SUBROUTINE READ_MRM_ROUTING_PARAMS
393 ! ---------------------------------------------------------------------------
394 ! NAME
395 ! read_mrm_routing_params
396
397 ! PURPOSE
398 !> \brief TODO: add description
399
400 !> \details TODO: add description
401
402 ! INTENT(IN)
403 !> \param[in] "integer(i4) :: processCase" it is the default case, should be one
404 !> \param[in] "character(*) :: file_namelist_param" file name containing parameter namelist
405 !> \param[in] "integer(i4) :: unamelist_param" file name id containing parameter namelist
406
407 ! HISTORY
408 !> \authors Robert Schweppe
409
410 !> \date Jun 2018
411
412 ! Modifications:
413
414 subroutine read_mrm_routing_params(processCase, file_namelist_param, unamelist_param)
415
416 use mo_common_constants, only : ncolpars
417 use mo_common_functions, only : in_bound
419 use mo_nml, only : close_nml, open_nml, position_nml
420
421 implicit none
422
423 ! it is the default case, should be one
424 integer(i4), intent(in) :: processCase
425
426 ! file name containing parameter namelist
427 character(*), intent(in) :: file_namelist_param
428
429 ! file name id containing parameter namelist
430 integer(i4), intent(in) :: unamelist_param
431
432 ! equals sum of previous parameters
433 integer(i4) :: start_index
434
435 real(dp), dimension(nColPars) :: muskingumTravelTime_constant
436
437 real(dp), dimension(nColPars) :: muskingumTravelTime_riverLength
438
439 real(dp), dimension(nColPars) :: muskingumTravelTime_riverSlope
440
441 real(dp), dimension(nColPars) :: muskingumTravelTime_impervious
442
443 real(dp), dimension(nColPars) :: muskingumAttenuation_riverSlope
444
445 real(dp), dimension(nColPars) :: streamflow_celerity
446 real(dp), dimension(nColPars) :: slope_factor
447
448 namelist /routing1/ muskingumtraveltime_constant, muskingumtraveltime_riverlength, &
449 muskingumtraveltime_riverslope, muskingumtraveltime_impervious, muskingumattenuation_riverslope
450 namelist /routing2/ streamflow_celerity
451 namelist /routing3/ slope_factor
452 !
453 call open_nml(file_namelist_param, unamelist_param, quiet = .true.)
454
455 if (processcase .eq. 1_i4) then
456 call position_nml('routing1', unamelist_param)
457 read(unamelist_param, nml = routing1)
458 else if (processcase .eq. 2_i4) then
459 call position_nml('routing2', unamelist_param)
460 read(unamelist_param, nml = routing2)
461 else if (processcase .eq. 3_i4) then
462 call position_nml('routing3', unamelist_param)
463 read(unamelist_param, nml = routing3)
464 end if
465
466 ! -------------------------------------------------------------------------
467 ! INCLUDE MRM PARAMETERS IN PARAMETERS OF MHM
468 ! -------------------------------------------------------------------------
469 ! Muskingum routing parameters with MPR
470 if (processcase .eq. 1_i4) then
471 ! insert parameter values and names at position required by mhm
472 processmatrix(8, 1) = processcase
473 processmatrix(8, 2) = 5_i4
474 processmatrix(8, 3) = sum(processmatrix(1 : 8, 2))
475 start_index = processmatrix(8, 3) - processmatrix(8, 2)
476 global_parameters(start_index + 1, :) = muskingumtraveltime_constant
477 global_parameters(start_index + 2, :) = muskingumtraveltime_riverlength
478 global_parameters(start_index + 3, :) = muskingumtraveltime_riverslope
479 global_parameters(start_index + 4, :) = muskingumtraveltime_impervious
480 global_parameters(start_index + 5, :) = muskingumattenuation_riverslope
481
482 global_parameters_name(start_index + 1 : start_index + processmatrix(8, 2)) = (/ &
483 'muskingumTravelTime_constant ', &
484 'muskingumTravelTime_riverLength', &
485 'muskingumTravelTime_riverSlope ', &
486 'muskingumTravelTime_impervious ', &
487 'muskingumAttenuation_riverSlope'/)
488 ! adaptive timestep routing
489 else if (processcase .eq. 2_i4) then
490 processmatrix(8, 1) = processcase
491 processmatrix(8, 2) = 1_i4
492 processmatrix(8, 3) = sum(processmatrix(1 : 8, 2))
493 start_index = processmatrix(8, 3) - processmatrix(8, 2)
494 global_parameters(start_index + 1, :) = streamflow_celerity
495
496 global_parameters_name(start_index + 1 : start_index + processmatrix(8, 2)) = (/ &
497 'streamflow_celerity'/)
498 ! adaptive timestep routing - varying celerity
499 else if (processcase .eq. 3_i4) then
500 ! insert parameter values and names at position required by mhm
501 processmatrix(8, 1) = processcase
502 processmatrix(8, 2) = 1_i4
503 processmatrix(8, 3) = sum(processmatrix(1:8, 2))
504 start_index = processmatrix(8, 3) - processmatrix(8, 2)
505 global_parameters(start_index + 1, :) = slope_factor
506
507 global_parameters_name(start_index + 1 : start_index + processmatrix(8,2)) = (/ &
508 'slope_factor'/)
509 end if
510
511 ! check if parameter are in range
512 if (.not. in_bound(global_parameters)) then
513 call error_message('***ERROR: parameter in routing namelist out of bound in ', &
514 trim(adjustl(file_namelist_param)))
515 end if
516
517 call close_nml(unamelist_param)
518
519 end subroutine read_mrm_routing_params
520end 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
integer, parameter udefoutput
Unit for 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 read_mrm_routing_params(processcase, file_namelist_param, unamelist_param)
TODO: add description.
subroutine, public mrm_read_config(file_namelist, unamelist, file_namelist_param, unamelist_param, do_message)
Read the general config of mRM.