5.13.3-dev0
mHM
The mesoscale Hydrological Model
Loading...
Searching...
No Matches
mo_mrm_write.f90
Go to the documentation of this file.
1!> \file mo_mrm_write.f90
2!> \brief \copybrief mo_mrm_write
3!> \details \copydetails mo_mrm_write
4
5!> \brief write of discharge and restart files
6!> \details This module contains the subroutines for writing the discharge files and optionally the restart files.
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_mrm_write_fluxes_states, only : outputdataset
17 use mo_message, only : message, error_message
18
19 implicit none
20
21 public :: mrm_write
23 public :: mrm_write_optifile
24
25 private
26
27contains
28
29 ! ------------------------------------------------------------------
30
31 ! NAME
32 ! mrm_write
33
34 ! PURPOSE
35 !> \brief write discharge and restart files
36
37 !> \details First, this subroutine calls the writing or restart files that only
38 !> succeeds if it happens after the write of mHM restart files because
39 !> mHM restart files must exist. Second, simulated discharge is aggregated to the daily
40 !> scale and then written to file jointly with observed discharge
41
42 ! HISTORY
43 !> \authors Juliane Mai, Rohini Kumar & Stephan Thober
44
45 !> \date Aug 2015
46
47 ! Modifications:
48 ! Robert Schweppe Jun 2018 - refactoring and reformatting
49 ! Pallav Shrestha, Husain Najafi Mar 2022 - refactoring for measured timestep output
50
51 subroutine mrm_write
52
59
60 implicit none
61
62 integer(i4) :: domainid, idomain
63
64 integer(i4) :: iday, isubday, is, ie
65
66 integer(i4) :: maxdailytimesteps, maxmeastimesteps
67
68 integer(i4) :: tt
69
70 integer(i4) :: gg
71
72 integer(i4) :: ntimesteps
73
74 real(dp), dimension(:, :), allocatable :: d_qmod, subd_qmod ! Sim discharge at daily and subdaily time step
75 real(dp), dimension(:, :), allocatable :: d_qobs, subd_qobs ! Obs discharge at daily and subdaily time step
76
77 ! between simulated and measured time scale
78 integer(i4) :: factor
79
80 ! simulated Timesteps per Day
81 integer(i4) :: tpd_sim
82
83 ! observed Timesteps per Day
84 integer(i4) :: tpd_obs
85
86 ! --------------------------------------------------------------------------
87 ! WRITE CONFIG FILE
88 ! --------------------------------------------------------------------------
89 if (mrm_coupling_mode .eq. 0_i4) call write_configfile()
90
91 ! --------------------------------------------------------------------------
92 ! WRITE RESTART
93 ! --------------------------------------------------------------------------
94 if (write_restart) then
95 do idomain = 1, domainmeta%nDomains
96 domainid = domainmeta%indices(idomain)
97 if (domainmeta%doRouting(idomain)) call mrm_write_restart(idomain, domainid, mrmfilerestartout)
98 end do
99 end if
100
101 ! --------------------------------------------------------------------------
102 ! STORE DAILY DISCHARGE TIMESERIES OF EACH GAUGING STATION
103 ! FOR SIMULATIONS DURING THE EVALUATION PERIOD
104 !
105 ! **** AT DAILY TIME STEPS ****
106 ! Note:: Observed Q are stored only for the evaluation period and not for
107 ! the warming days
108 ! --------------------------------------------------------------------------
109
110 if (ngaugestotal > 0 .and. nmeasperday > 0) then
111 ! copy time resolution to local variables
112 tpd_sim = ntstepday
113 tpd_obs = nmeasperday
114
115 ! check if modelled timestep is an integer multiple of measured timesteps
116 if (modulo(tpd_sim, tpd_obs) .eq. 0) then
117 factor = tpd_sim / tpd_obs
118 else
119 call error_message(' Error: Number of modelled datapoints is no multiple of measured datapoints per day')
120 end if
121
122
123 maxdailytimesteps = maxval(evalper(1 : domainmeta%nDomains)%julEnd - evalper(1 : domainmeta%nDomains)%julStart + 1)
124 maxmeastimesteps = maxval(evalper(1 : domainmeta%nDomains)%julEnd - evalper(1 : domainmeta%nDomains)%julStart + 1) * tpd_obs
125 allocate(d_qmod(maxdailytimesteps, ngaugestotal))
126 allocate(d_qobs(maxdailytimesteps, ngaugestotal))
127 allocate(subd_qmod( maxmeastimesteps, ngaugestotal))
128 allocate(subd_qobs( maxmeastimesteps, ngaugestotal))
129 d_qmod = nodata_dp
130 d_qobs = nodata_dp
131 subd_qmod = nodata_dp
132 subd_qobs = nodata_dp
133
134
135 ! loop over domains
136 do idomain = 1, domainmeta%nDomains
137 if (domainmeta%doRouting(idomain)) then
138 domainid = domainmeta%indices(idomain)
139
140 ! Convert simulated values to daily
141 ntimesteps = (simper(idomain)%julEnd - simper(idomain)%julStart + 1) * ntstepday
142 iday = 0
143 do tt = warmingdays(idomain) * ntstepday + 1, ntimesteps, ntstepday
144 is = tt
145 ie = tt + ntstepday - 1
146 iday = iday + 1
147 ! over gauges
148 do gg = 1, domain_mrm(idomain)%nGauges
149 ! simulation
150 d_qmod(iday, domain_mrm(idomain)%gaugeIndexList(gg)) = &
151 sum(mrm_runoff(is : ie, domain_mrm(idomain)%gaugeIndexList(gg))) / real(ntstepday, dp)
152 end do
153 end do
154
155 dailycheck: if (nmeasperday > 1) then
156 ! Convert observed values to daily
157 ntimesteps = (simper(idomain)%julEnd - simper(idomain)%julStart + 1) * nmeasperday
158 iday = 0
159 do tt = 1, ntimesteps, nmeasperday
160 is = tt
161 ie = tt + nmeasperday - 1
162 iday = iday + 1
163 ! over gauges
164 do gg = 1, domain_mrm(idomain)%nGauges
165 ! when -9999 value/s are present in current day, daily value remain -9999.
166 if (.not.(any(gauge%Q(is : ie, domain_mrm(idomain)%gaugeIndexList(gg)) == nodata_dp))) then
167 ! observation
168 d_qobs(iday, domain_mrm(idomain)%gaugeIndexList(gg)) = &
169 sum( gauge%Q(is : ie, domain_mrm(idomain)%gaugeIndexList(gg))) / real(nmeasperday, dp)
170 end if
171 end do
172 end do
173 else
174 ! observed values are already at daily (nMeasPerDay = 1) and stored for evalper
175 ! over gauges
176 do gg = 1, domain_mrm(idomain)%nGauges
177 ! observation
178 d_qobs(:, domain_mrm(idomain)%gaugeIndexList(gg)) = gauge%Q(:, domain_mrm(idomain)%gaugeIndexList(gg))
179 end do
180 end if dailycheck
181
182
183 subdailycheck: if (nmeasperday > 1) then
184
185 ! Convert simulated values to subdaily
186 ntimesteps = (simper(idomain)%julEnd - simper(idomain)%julStart + 1) * ntstepday
187 isubday = 0
188 do tt = warmingdays(idomain) * ntstepday + 1, ntimesteps, factor
189 is = tt
190 ie = tt + factor - 1
191 isubday = isubday + 1
192 ! over gauges
193 do gg = 1, domain_mrm(idomain)%nGauges
194 ! simulation
195 subd_qmod(isubday, domain_mrm(idomain)%gaugeIndexList(gg)) = &
196 sum(mrm_runoff(is : ie, domain_mrm(idomain)%gaugeIndexList(gg))) / real(factor, dp)
197 end do
198 end do
199
200 ! Convert observed values to subdaily
201
202 ! observed values are already at subdaily (nMeasPerDay) and stored for evalper
203 ! over gauges
204 do gg = 1, domain_mrm(idomain)%nGauges
205 ! observation
206 subd_qobs(:, domain_mrm(idomain)%gaugeIndexList(gg)) = gauge%Q(:, domain_mrm(idomain)%gaugeIndexList(gg))
207 end do
208
209 end if subdailycheck
210
211 end if
212 end do
213
214
215 ! write in an ASCII file ! OBS[nModeling_days X nGauges_total] , SIM[nModeling_days X nGauges_total]
216 ! ToDo: is this if statement reasonable
217 if (allocated(gauge%Q)) call write_daily_obs_sim_discharge(d_qobs(:, :), d_qmod(:, :))
218
219 ! write in an ASCII file ! OBS[nMeasPerDay X nGauges_total] , SIM[nMeasPerDay X nGauges_total]
220 if (nmeasperday > 1 .and. allocated(gauge%Q)) call write_subdaily_obs_sim_discharge(subd_qobs(:, :), subd_qmod(:, :), factor)
221 ! The subdaily routine is only called if subdaily Q data is provided
222
223 ! free space
224 deallocate(d_qmod, d_qobs, subd_qmod, subd_qobs)
225 end if
226 end subroutine mrm_write
227 ! ------------------------------------------------------------------
228
229 ! NAME
230 ! write_configfile
231
232 ! PURPOSE
233 !> \brief This modules writes the results of the configuration into an ASCII-file
234
235 !> \details TODO: add description
236
237 ! HISTORY
238 !> \authors Christoph Schneider
239
240 !> \date May 2013
241
242 ! Modifications:
243 ! Juliane Mai May 2013 - module version and documentation
244 ! Stephan Thober Jun 2014 - bug fix in L11 config print out
245 ! Stephan Thober Jun 2014 - updated read_restart
246 ! Rohini, Luis Jul 2015 - updated version, L1 level prints
247 ! Stephan Thober Sep 2015 - updated write of stream network
248 ! Stephan Thober Nov 2016 - adapted write to selected case for routing process
249 ! Robert Schweppe Jun 2018 - refactoring and reformatting
250
252
261 use mo_kind, only : dp, i4
262 use mo_mrm_file, only : version
266 use mo_string_utils, only : num2str
267 use mo_utils, only : ge
268 use mo_os, only : check_path_isdir
269
270 implicit none
271
272 character(256) :: fName
273
274 integer(i4) :: i, iDomain, domainID, j
275
276 integer(i4) :: err
277
278
279 fname = trim(adjustl(dirconfigout)) // trim(adjustl(file_config))
280 call message()
281 call message(' Log-file written to ', trim(fname))
282 !checking whether the directory exists where the file shall be created or opened
283 call check_path_isdir(trim(adjustl(dirconfigout)), raise=.true.)
284 open(uconfig, file = fname, status = 'unknown', action = 'write', iostat = err)
285 if (err .ne. 0) then
286 call error_message(' Problems while creating File. Error-Code ', num2str(err))
287 end if
288 write(uconfig, 200)
289 write(uconfig, 100) 'mRM-UFZ v-' // trim(version)
290 write(uconfig, 100) 'S. Thober, L. Samaniego & R. Kumar, UFZ'
291 write(uconfig, 200)
292 write(uconfig, 100)
293 write(uconfig, 201) ' M A I N mRM C O N F I G U R A T I O N I N F O R M A T I O N '
294 write(uconfig, 100)
295 write(uconfig, 103) 'Number of domains ', domainmeta%nDomains
296 write(uconfig, 103) 'Total No. of gauges ', ngaugestotal
297 write(uconfig, 103) 'Time Step [h] ', timestep
298 do idomain = 1, domainmeta%nDomains
299 domainid = domainmeta%indices(idomain)
300 write(uconfig, 103) 'Total No. of nodes ', level11(idomain)%nCells
301 write(uconfig, 103) 'No. of cells L0 ', level0(domainmeta%L0DataFrom(idomain))%nCells
302 write(uconfig, 103) 'No. of cells L1 ', level1(idomain)%nCells
303 write(uconfig, 103) 'No. of cells L11 ', level11(idomain)%nCells
304
305 ! select case (iFlag_cordinate_sys)
306 ! case (0)
307 write(uconfig, 301) 'domain ', domainid, ' Hydrology Resolution [m] ', resolutionhydrology(idomain)
308 write(uconfig, 301) 'domain ', domainid, ' Routing Resolution [m] ', resolutionrouting(idomain)
309 ! case(1)
310 ! write(uconfig, 302) 'domain ',domainID, ' Hydrology Resolution [o] ', resolutionHydrology(iDomain)
311 ! write(uconfig, 302) 'domain ',domainID, ' Routing Resolution [o] ', resolutionRouting(iDomain)
312 ! end select
313 end do
314 write(uconfig, 126) 'Flag READ restart ', read_restart
315 write(uconfig, 126) 'Flag WRITE restart ', write_restart
316 !
317 !******************
318 ! Model Run period
319 !******************
320 do idomain = 1, domainmeta%nDomains
321 domainid = domainmeta%indices(idomain)
322 write(uconfig, 115) ' Model Run Periods for domain ', num2str(domainid)
323 write(uconfig, 116) &
324 'From To', &
325 ' Day Month Year Day Month Year'
326 write(uconfig, 117) &
327 'Warming Period (1) ', &
328 warmper(idomain)%dStart, warmper(idomain)%mStart, warmper(idomain)%yStart, &
329 warmper(idomain)%dEnd, warmper(idomain)%mEnd, warmper(idomain)%yEnd
330 write(uconfig, 117) &
331 'Evaluation Period (2) ', &
332 evalper(idomain)%dStart, evalper(idomain)%mStart, evalper(idomain)%yStart, &
333 evalper(idomain)%dEnd, evalper(idomain)%mEnd, evalper(idomain)%yEnd
334 write(uconfig, 117) &
335 'Simulation Period (1)+(2) ', &
336 simper(idomain)%dStart, simper(idomain)%mStart, simper(idomain)%yStart, &
337 simper(idomain)%dEnd, simper(idomain)%mEnd, simper(idomain)%yEnd
338 end do
339
340 !*********************************
341 ! Model Land Cover Observations
342 !*********************************
343 if (processmatrix(8, 1) .eq. 1) then
344 do idomain = 1, domainmeta%nDomains
345 domainid = domainmeta%indices(idomain)
346 write(uconfig, 118) ' Land Cover Observations for domain ', num2str(domainid)
347 write(uconfig, 119) ' Start Year', ' End Year', ' Land cover scene', 'Land Cover File'
348 do i = 1, nlcoverscene
349 write(uconfig, 120) lc_year_start(i), lc_year_end(i), &
350 lcyearid(max(evalper(idomain)%yStart, lc_year_start(i)), idomain), trim(lcfilename(i))
351 end do
352 end do
353 end if
354 !*********************************
355 ! Initial Parameter Ranges
356 !*********************************
357 write(uconfig, 121) ' Initial Transfer Function Parameter Ranges (gammas) '
358 !
359 ! Transfer functions
360 write(uconfig, 122) &
361 ' i', ' min', ' max', ' current', &
362 ' name'
363 do i = 1, size(global_parameters, 1)
364 write(uconfig, 123) &
366 trim(adjustl(global_parameters_name(i)))
367 end do
368 ! domain runoff data
369 write(uconfig, 202) ' domain Runoff Data '
370 write(uconfig, 107) ' Gauge No.', ' domain Id', ' Qmax[m3/s]', ' Qmin[m3/s]'
371 do i = 1, ngaugestotal
372 if(any(gauge%Q(:, i) > nodata_dp)) then
373 write(uconfig, 108) i, gauge%domainId(i), maxval(gauge%Q(:, i), gauge%Q(:, i) > nodata_dp), &
374 minval(gauge%Q(:, i), gauge%Q(:, i) > nodata_dp)
375 else
376 write(uconfig, 108) i, gauge%domainId(i), nodata_dp, nodata_dp
377 end if
378 end do
379 ! inflow gauge data
380 if (ninflowgaugestotal .GT. 0) then
381 write(uconfig, 202) ' domain Inflow Data '
382 write(uconfig, 107) ' Gauge No.', ' domain Id', ' Qmax[m3/s]', ' Qmin[m3/s]'
383 do i = 1, ninflowgaugestotal
384 if(all(inflowgauge%Q(:, i) > nodata_dp)) then
385 write(uconfig, 108) i, inflowgauge%domainId(i), maxval(inflowgauge%Q(:, i), inflowgauge%Q(:, i) > nodata_dp), &
386 minval(inflowgauge%Q(:, i), inflowgauge%Q(:, i) > nodata_dp)
387 else
388 write(uconfig, 108) i, inflowgauge%domainId(i), nodata_dp, nodata_dp
389 end if
390 end do
391 end if
392 ! domain config
393 write(uconfig, 218) 'domain-wise Configuration'
394 do idomain = 1, domainmeta%nDomains
395 domainid = domainmeta%indices(idomain)
396 write(uconfig, 103) 'domain No. ', domainid, &
397 'No. of gauges ', domain_mrm(idomain)%nGauges
398
399 write(uconfig, 222) 'Directory list'
400
401 write(uconfig, 224) 'Directory to morphological input ', dirmorpho(idomain)
402 write(uconfig, 224) 'Directory to land cover input ', dirlcover(idomain)
403 write(uconfig, 224) 'Directory to gauging station input ', dirgauges(idomain)
404 if (mrm_coupling_mode .eq. 0) then
405 write(uconfig, 224) 'Directory to simulated runoff input ', dirtotalrunoff(idomain)
406 end if
407 write(uconfig, 224) 'Directory to write output by default ', dirout(idomain)
408 write(uconfig, 224) 'File to write mRM output when restarted ', mrmfilerestartout(idomain)
409
410 write(uconfig, 102) 'River Network (Routing level)'
411 write(uconfig, 100) 'Label 0 = intermediate draining cell '
412 write(uconfig, 100) 'Label 1 = headwater cell '
413 write(uconfig, 100) 'Label 2 = sink cell '
414
415 if (processmatrix(8, 1) .eq. 1_i4) then
416 write(uconfig, 104) ' Overall', &
417 ' From', &
418 ' To', &
419 ' Routing', &
420 ' Label', &
421 ' Length', &
422 ' Mean', &
423 ' Link', &
424 ' Routing', &
425 ' Routing', &
426 ' Sequence', &
427 ' ', &
428 ' ', &
429 ' Slope'
430 !
431 write(uconfig, 105) ' Id', &
432 ' Node', &
433 ' Node', &
434 '', &
435 '', &
436 ' [km]', &
437 ' [o/oo]'
438 !
439 do j = level11(idomain)%iStart, level11(idomain)%iEnd - 1
440 i = l11_netperm(j) + level11(idomain)%iStart - 1 ! adjust permutation for multi-domain option
441 write(uconfig, 106) i, l11_fromn(i), l11_ton(i), l11_rorder(i), l11_label(i), &
442 l11_length(i) / 1000.0_dp, l11_slope(i) * 1.0e3_dp
443 end do
444
445 else if (processmatrix(8, 1) .eq. 2_i4) then
446 write(uconfig, 134) ' Overall', &
447 ' From', &
448 ' To', &
449 ' Routing', &
450 ' Label', &
451 ' Link', &
452 ' Routing', &
453 ' Routing', &
454 ' Sequence', &
455 ' '
456 !
457 write(uconfig, 135) ' Id', &
458 ' Node', &
459 ' Node', &
460 '', &
461 ''
462 !
463 do j = level11(idomain)%iStart, level11(idomain)%iEnd - 1
464 i = l11_netperm(j) + level11(idomain)%iStart - 1 ! adjust permutation for multi-domain option
465 write(uconfig, 136) i, l11_fromn(i), l11_ton(i), l11_rorder(i), l11_label(i)
466 end do
467 end if
468 ! draining node at L11
469 write(uconfig, 109) ' Overall', ' domain', &
470 ' Cell', ' Routing', &
471 ' Id', ' Node Id'
472 do i = level11(idomain)%Id(1), level11(idomain)%Id(level11(idomain)%nCells)
473 write(uconfig, 110) i + level11(idomain)%iStart - 1, i
474 end do
475
476 ! L1 level information
477 write(uconfig, 111) ' Modeling', ' Routing', ' Effective', &
478 ' Cell', ' Cell Id', ' Area', &
479 ' Id', ' [-]', ' [km2]'
480 if (ge(resolutionrouting(idomain), resolutionhydrology(idomain))) then
481 do i = level1(idomain)%Id(1), level1(idomain)%Id(level1(idomain)%nCells)
482 write(uconfig, 113) i + level1(idomain)%iStart - 1, l1_l11_id(i + level1(idomain)%iStart - 1), &
483 level1(idomain)%CellArea(i) * 1.e-6_dp
484 domainid = domainmeta%indices(idomain)
485 end do
486 else
487 do i = level11(idomain)%Id(1), level11(idomain)%Id(level11(idomain)%nCells)
488 write(uconfig, 110) i + level11(idomain)%iStart - 1, l11_l1_id(i + level11(idomain)%iStart - 1)
489 end do
490 end if
491 write(uconfig, 114) ' Total[km2]', sum(level1(idomain)%CellArea) * 1.e-6_dp
492 end do
493
494 write(uconfig, *)
495 close(uconfig)
496
497 !! Formats
498 100 format (a80)
499 102 format (/ 30('-') / a30 / 30('-'))
500 103 format (a20, 10x, i10)
501 104 format (/ 75('-') / 5a10, 5x, 2a10 / 5a10, 5x, 2a10)
502 105 format (5a10, 5x, 2a10 / 75('-'))
503 106 format (5i10, 5x, 2f10.3)
504 107 format (2a10, 2a15)
505 108 format (2i10, 2f15.3)
506 !
507 109 format (/ 20('-') / 2a10 / 2a10 / 2a10 / 20('-'))
508 110 format (2i10)
509 !
510 111 format (/ 30('-') / 3a10 / 3a10 / 3a10 / 30('-'))
511 113 format ( 2i10, 1f10.3 )
512 114 format (30('-') / a15, 5x, 1f10.3 /)
513 !
514 115 format (/61('-')/ a50, a10 /61('-'))
515 116 format (39x, a22 / 25x, a36)
516 117 format (3(a25, 6(i6)))
517 !
518 118 format (/50('-')/ a40, a10 /50('-'))
519 119 format (a10, a10, a20, a20/)
520 120 format (i10, i10, 10x, i10, a20)
521 !
522 121 format (/55('-')/ a55 /55('-'))
523 122 format (a10, 3a15, a35)
524 123 format (i10, 3f15.3, a35)
525 !
526 126 format (a30, 9x, l1)
527 !
528 134 format (/ 50('-') / 5a10 / 5a10)
529 135 format (5a10 / 50('-'))
530 136 format (5i10)
531 !
532 200 format (80('-'))
533 201 format (a80)
534 202 format (/50('-')/ a50 /50('-'))
535 !
536 218 format (/ 80('-')/ 26x, a24, 26x, /80('-'))
537 222 format (/80('-')/ 26x, a21 /80('-'))
538 224 format (a40, 5x, a256)
539
540 301 format (a7, i2, a32, f15.0)
541 ! 302 format (a7, i2, a32,es20.8)
542 end Subroutine write_configfile
543
544 ! ------------------------------------------------------------------
545
546 ! NAME
547 ! write_daily_obs_sim_discharge
548
549 ! PURPOSE
550 !> \brief Write a file for the daily observed and simulated discharge timeseries
551 !> during the evaluation period for each gauging station
552
553 !> \details Write a file for the daily observed and simulated discharge timeseries
554 !> during the evaluation period for each gauging station
555
556 ! INTENT(IN)
557 !> \param[in] "real(dp), dimension(:, :) :: Qobs" daily time series of observed dischargedims = (nModeling_days
558 !> , nGauges_total)
559 !> \param[in] "real(dp), dimension(:, :) :: Qsim" daily time series of modeled dischargedims = (nModeling_days ,
560 !> nGauges_total)
561
562 ! HISTORY
563 !> \authors Rohini Kumar
564
565 !> \date August 2013
566
567 ! Modifications:
568 ! Robert Schweppe Jun 2018 - refactoring and reformatting
569
570 subroutine write_daily_obs_sim_discharge(Qobs, Qsim)
571
575 use mo_errormeasures, only : kge, nse
576 use mo_julian, only : dec2date
579 use mo_string_utils, only : num2str
580 use mo_utils, only : ge
581 use mo_netcdf, only : ncdataset, ncdimension, ncvariable
582
583 implicit none
584
585 ! daily time series of observed dischargedims = (nModeling_days , nGauges_total)
586 real(dp), dimension(:, :), intent(in) :: Qobs
587
588 ! daily time series of modeled dischargedims = (nModeling_days , nGauges_total)
589 real(dp), dimension(:, :), intent(in) :: Qsim
590
591 character(256) :: fName, formHeader, formData, dummy
592
593 integer(i4) :: domainID, iDomain, gg, tt, err
594
595 integer(i4) :: igauge_start, igauge_end
596
597 integer(i4) :: day, month, year
598
599 integer(i4) :: tlength
600
601 ! time axis
602 integer(i4), allocatable, dimension(:) :: taxis
603
604 real(dp) :: newTime
605
606 ! nc related variables
607 type(ncdataset) :: nc_out
608 type(ncdimension) :: dim, dim_bnd
609 type(ncvariable) :: var
610
611 ! initalize igauge_start
612 igauge_start = 1
613
614 ! domain loop
615 do idomain = 1, domainmeta%nDomains
616 domainid = domainmeta%indices(idomain)
617 if(domain_mrm(idomain)%nGauges .lt. 1) cycle
618
619 ! estimate igauge_end
620 igauge_end = igauge_start + domain_mrm(idomain)%nGauges - 1
621
622 ! check the existance of file
623 fname = trim(adjustl(dirout(idomain))) // trim(adjustl(file_daily_discharge))
624 open(udaily_discharge, file = trim(fname), status = 'unknown', action = 'write', iostat = err)
625 if(err .ne. 0) then
626 call error_message(' IOError while openening "', trim(fname), '". Error-Code ', num2str(err))
627 end if
628
629 ! header
630 write(formheader, *) '( 4a8, ', domain_mrm(idomain)%nGauges, '(2X, a5, i10.10, 2X, a5, i10.10) )'
631 write(udaily_discharge, formheader) 'No', 'Day', 'Mon', 'Year', &
632 ('Qobs_', gauge%gaugeId(gg), &
633 'Qsim_', gauge%gaugeId(gg), gg = igauge_start, igauge_end)
634
635 ! form data
636 write(formdata, *) '( 4I8, ', domain_mrm(idomain)%nGauges, '(2X, f15.7 , 2X, f15.7 ) )'
637
638 ! write data
639 newtime = real(evalper(idomain)%julStart, dp) - 0.5_dp
640
641 do tt = 1, (evalper(idomain)%julEnd - evalper(idomain)%julStart + 1)
642 call dec2date(newtime, yy = year, mm = month, dd = day)
643 write(udaily_discharge, formdata) tt, day, month, year, (qobs(tt, gg), qsim(tt, gg), gg = igauge_start, igauge_end)
644 newtime = newtime + 1.0_dp
645 end do
646
647 ! close file
648 close(udaily_discharge)
649
650 ! ======================================================================
651 ! write netcdf file
652 ! ======================================================================
653 fname = trim(adjustl(dirout(idomain))) // trim(adjustl(ncfile_discharge))
654 nc_out = ncdataset(trim(fname), "w")
655 tlength = evalper(idomain)%julEnd - evalper(idomain)%julStart + 1
656 ! write time
657 allocate(taxis(tlength))
658
659 ! tt is dependent on the unit of the time axis and is set to hours in mRM
660 select case( output_time_reference_mrm)
661 case(0)
662 forall(tt = 1 : tlength) taxis(tt) = (tt-1) * 24
663 case(1)
664 forall(tt = 1 : tlength) taxis(tt) = tt * 24 - 12
665 case(2)
666 forall(tt = 1 : tlength) taxis(tt) = tt * 24
667 end select
668
669 call dec2date(real(evalper(idomain)%julStart, dp) - 0.5_dp, yy = year, mm = month, dd = day)
670 dim = nc_out%setDimension("time", tlength)
671 var = nc_out%setVariable("time", "i32", [dim])
672 call var%setData(taxis)
673 call var%setAttribute( &
674 "units", &
675 'hours since '//trim(num2str(year))//'-'//trim(num2str(month, '(i2.2)'))//'-'//trim(num2str(day, '(i2.2)'))//' 00:00:00' &
676 )
677 call var%setAttribute("long_name", "time in hours")
678 call var%setAttribute("bounds", "time_bnds")
679 call var%setAttribute("axis", "T")
680 dim_bnd = nc_out%setDimension("bnds", 2)
681 var = nc_out%setVariable("time_bnds", "i32", [dim_bnd, dim])
682 do tt = 1, tlength
683 call var%setData((tt - 1) * 24, (/1, tt/))
684 call var%setData(tt * 24, (/2, tt/))
685 end do
686 deallocate(taxis)
687 ! write gauges
688 do gg = igauge_start, igauge_end
689 var = nc_out%setVariable('Qsim_' // trim(num2str(gauge%gaugeID(gg), '(i10.10)')), "f64", [dim])
690 call var%setFillValue(nodata_dp)
691 call var%setData(qsim(1 : tlength, gg))
692 call var%setAttribute("units", "m3 s-1")
693 call var%setAttribute("long_name", 'simulated discharge at gauge ' // trim(num2str(gauge%gaugeID(gg), '(i10.10)')))
694 call var%setAttribute("missing_value", nodata_dp)
695 ! write observed discharge at that gauge
696 var = nc_out%setVariable('Qobs_' // trim(num2str(gauge%gaugeID(gg), '(i10.10)')), "f64", [dim])
697 call var%setFillValue(nodata_dp)
698 call var%setData(qobs(1 : tlength, gg))
699 call var%setAttribute("units", "m3 s-1")
700 call var%setAttribute("long_name", 'observed discharge at gauge ' // trim(num2str(gauge%gaugeID(gg), '(i10.10)')))
701 call var%setAttribute("missing_value", nodata_dp)
702 end do
703 call nc_out%close()
704
705 ! ======================================================================
706 ! screen output
707 ! ======================================================================
708
709 ! if ( nMeasPerDay == 1_i4 ) then ! only print daily stats for daily Qobs
710
711 call message()
712 write(dummy, '(I3)') domainid
713 call message(' OUTPUT: saved daily discharge file for domain ', trim(adjustl(dummy)))
714 call message(' to ', trim(fname))
715 do gg = igauge_start, igauge_end
716 if (count(ge(qobs(:, gg), 0.0_dp)) > 1) then
717 call message(' KGE of daily discharge (gauge #', trim(adjustl(num2str(gg))), '): ', &
718 trim(adjustl(num2str(kge(qobs(:, gg), qsim(:, gg), mask = (ge(qobs(:, gg), 0.0_dp)))))))
719 call message(' NSE of daily discharge (gauge #', trim(adjustl(num2str(gg))), '): ', &
720 trim(adjustl(num2str(nse(qobs(:, gg), qsim(:, gg), mask = (ge(qobs(:, gg), 0.0_dp)))))))
721 end if
722 end do
723
724 ! end if
725
726 ! update igauge_start
727 igauge_start = igauge_end + 1
728 !
729 end do
730 !
731 end subroutine write_daily_obs_sim_discharge
732
733
734 ! ------------------------------------------------------------------
735
736 ! NAME
737 ! write_subdaily_obs_sim_discharge
738
739 ! PURPOSE
740 !> \brief Write a file for the simulated discharge timeseries
741 !> during the evaluation period for each gauging station
742
743 !> \details Write a file for the simulated discharge timeseries
744 !> during the evaluation period for each gauging station
745
746 ! INTENT(IN)
747 !> \param[in] "real(dp), dimension(:, :) :: Qobs" time series of observed discharge dims = (nMeasTimeSteps ,
748 !> nGauges_total)
749 !> \param[in] "real(dp), dimension(:, :) :: Qsim" time series of modeled discharge dims = (nMeasTimeSteps ,
750 !> nGauges_total)
751 !> \param[in] "integer(i4), :: factor" ratio of modelled time steps per day to observation time steps per day
752
753 ! HISTORY
754 !> \authors Rohini Kumar
755
756 !> \date August 2013
757
758 ! Modifications:
759 ! Robert Schweppe Jun 2018 - refactoring and reformatting
760 ! Pallav Shrestha Jul 2021 - ported for printing out simulations at hourly time step
761 ! Pallav Shrestha, Husain Najafi Mar 2022 - refactoring for subdaily timestep output
762
763 subroutine write_subdaily_obs_sim_discharge(Qobs, Qsim, factor)
764
768 use mo_errormeasures, only : kge, nse
769 use mo_julian, only : dec2date
773 use mo_string_utils, only : num2str
774 use mo_utils, only : ge
775 use mo_netcdf, only : ncdataset, ncdimension, ncvariable
776
777 implicit none
778
779 ! time series of observed discharge. dims = (nMeasTimeSteps , nGauges_total)
780 real(dp), dimension(:, :), intent(in) :: Qobs
781
782 ! time series of modeled discharge. dims = (nMeasTimeSteps , nGauges_total)
783 real(dp), dimension(:, :), intent(in) :: Qsim
784
785 ! ratio of modelled time steps per day to observation time steps per day
786 integer(i4), intent(in) :: factor
787
788 character(256) :: fName, formHeader, formData, dummy
789
790 integer(i4) :: domainID, iDomain, gg, tt, err
791
792 integer(i4) :: igauge_start, igauge_end
793
794 integer(i4) :: hour, day, month, year
795
796 integer(i4) :: tlength
797
798 ! time axis
799 integer(i4), allocatable, dimension(:) :: taxis
800
801 real(dp) :: newTime
802
803 ! nc related variables
804 type(ncdataset) :: nc_out
805 type(ncdimension) :: dim, dim_bnd
806 type(ncvariable) :: var
807
808 ! use minutes if needed
809 logical :: use_minutes
810 integer(i4) :: time_unit_factor
811
812 ! initalize igauge_start
813 igauge_start = 1
814
815 ! domain loop
816 do idomain = 1, domainmeta%nDomains
817 domainid = domainmeta%indices(idomain)
818 if(domain_mrm(idomain)%nGauges .lt. 1) cycle
819
820 ! estimate igauge_end
821 igauge_end = igauge_start + domain_mrm(idomain)%nGauges - 1
822
823
824 ! ======================================================================
825 ! write text file
826 ! ======================================================================
827
828 ! check the existance of file
829 fname = trim(adjustl(dirout(idomain))) // trim(adjustl(file_subdaily_discharge))
830 open(usubdaily_discharge, file = trim(fname), status = 'unknown', action = 'write', iostat = err)
831 if(err .ne. 0) then
832 call error_message(' IOError while openening "', trim(fname), '". Error-Code ', num2str(err))
833 end if
834
835 ! header
836 write(formheader, *) '( 5a8, ', domain_mrm(idomain)%nGauges, '(2X, a5, i10.10, 2X, a5, i10.10) )'
837 write(usubdaily_discharge, formheader) 'No', 'Hour', 'Day', 'Mon', 'Year', &
838 ('Qobs_', gauge%gaugeId(gg), &
839 'Qsim_', gauge%gaugeId(gg), gg = igauge_start, igauge_end)
840
841 ! form data
842 write(formdata, *) '( 5I8, ', domain_mrm(idomain)%nGauges, '(2X, f15.7 , 2X, f15.7 ) )'
843
844 ! write data
845 newtime = real(evalper(idomain)%julStart, dp) - 0.5_dp
846
847 do tt = 1, (evalper(idomain)%julEnd - evalper(idomain)%julStart + 1) * nmeasperday
848 call dec2date(newtime, yy = year, mm = month, dd = day, hh = hour)
849 write(usubdaily_discharge, formdata) tt, hour, day, month, year, (qobs(tt, gg), qsim(tt, gg), gg = igauge_start, igauge_end)
850 newtime = newtime + 1.0_dp / real(nmeasperday, dp)
851 end do
852
853 ! close file
855
856 ! ======================================================================
857 ! write netcdf file
858 ! ======================================================================
859 fname = trim(adjustl(dirout(idomain))) // trim(adjustl(ncfile_subdaily_discharge))
860 nc_out = ncdataset(trim(fname), "w")
861 tlength = (evalper(idomain)%julEnd - evalper(idomain)%julStart + 1) * nmeasperday
862 ! write time
863 allocate(taxis(tlength))
864
865 use_minutes = .false.
866 time_unit_factor = 1
867 if ( mod(factor, 2) == 1 ) then
868 use_minutes = .true.
869 time_unit_factor = 60
870 end if
871
872 ! tt is dependent on the unit of the time axis and is set to hours in mRM
873 select case( output_time_reference_mrm)
874 case(0)
875 forall(tt = 1 : tlength) taxis(tt) = (tt-1) * factor * time_unit_factor
876 case(1)
877 forall(tt = 1 : tlength) taxis(tt) = tt * factor - factor * time_unit_factor / 2
878 case(2)
879 forall(tt = 1 : tlength) taxis(tt) = tt * factor * time_unit_factor
880 end select
881
882 call dec2date(real(evalper(idomain)%julStart, dp) - 0.5_dp, yy = year, mm = month, dd = day, hh = hour)
883 dim = nc_out%setDimension("time", tlength)
884 var = nc_out%setVariable("time", "i32", [dim])
885 call var%setData(taxis)
886 if (use_minutes) then
887 call var%setAttribute( &
888 "units", &
889 'minutes since '//trim(num2str(year))//'-'//trim(num2str(month, '(i2.2)'))//'-'//trim(num2str(day, '(i2.2)'))//' '// &
890 trim(num2str(hour, '(i2.2)'))//':00:00' &
891 )
892 call var%setAttribute("long_name", "time in minutes")
893 else
894 call var%setAttribute( &
895 "units", &
896 'hours since '//trim(num2str(year))//'-'//trim(num2str(month, '(i2.2)'))//'-'//trim(num2str(day, '(i2.2)'))//' '// &
897 trim(num2str(hour, '(i2.2)'))//':00:00' &
898 )
899 call var%setAttribute("long_name", "time in hours")
900 end if
901 call var%setAttribute("bounds", "time_bnds")
902 call var%setAttribute("axis", "T")
903 dim_bnd = nc_out%setDimension("bnds", 2)
904 var = nc_out%setVariable("time_bnds", "i32", [dim_bnd, dim])
905 do tt = 1, tlength
906 call var%setData((tt - 1) * factor * time_unit_factor, (/1, tt/))
907 call var%setData(tt * factor * time_unit_factor, (/2, tt/))
908 end do
909 deallocate(taxis)
910 ! write gauges
911 do gg = igauge_start, igauge_end
912 var = nc_out%setVariable('Qsim_' // trim(num2str(gauge%gaugeID(gg), '(i10.10)')), "f64", [dim])
913 call var%setFillValue(nodata_dp)
914 call var%setData(qsim(1 : tlength, gg))
915 call var%setAttribute("units", "m3 s-1")
916 call var%setAttribute("long_name", 'simulated discharge at gauge ' // trim(num2str(gauge%gaugeID(gg), '(i10.10)')))
917 call var%setAttribute("missing_value", nodata_dp)
918 ! write observed discharge at that gauge
919 var = nc_out%setVariable('Qobs_' // trim(num2str(gauge%gaugeID(gg), '(i10.10)')), "f64", [dim])
920 call var%setFillValue(nodata_dp)
921 call var%setData(qobs(1 : tlength, gg))
922 call var%setAttribute("units", "m3 s-1")
923 call var%setAttribute("long_name", 'observed discharge at gauge ' // trim(num2str(gauge%gaugeID(gg), '(i10.10)')))
924 call var%setAttribute("missing_value", nodata_dp)
925 end do
926 call nc_out%close()
927
928 ! ======================================================================
929 ! screen output
930 ! ======================================================================
931 call message()
932 write(dummy, '(I3)') domainid
933 call message(' OUTPUT: saved subdaily discharge file for domain ', trim(adjustl(dummy)))
934 call message(' to ', trim(fname))
935 do gg = igauge_start, igauge_end
936 if (count(ge(qobs(:, gg), 0.0_dp)) > 1) then
937 call message(' KGE of subdaily discharge (gauge #', trim(adjustl(num2str(gg))), '): ', &
938 trim(adjustl(num2str(kge(qobs(:, gg), qsim(:, gg), mask = (ge(qobs(:, gg), 0.0_dp)))))))
939 call message(' NSE of subdaily discharge (gauge #', trim(adjustl(num2str(gg))), '): ', &
940 trim(adjustl(num2str(nse(qobs(:, gg), qsim(:, gg), mask = (ge(qobs(:, gg), 0.0_dp)))))))
941 end if
942 end do
943
944 ! update igauge_start
945 igauge_start = igauge_end + 1
946 !
947 end do
948 !
950
951 ! ------------------------------------------------------------------
952
953 ! NAME
954 ! mrm_write_optifile
955
956 ! PURPOSE
957 !> \brief Write briefly final optimization results.
958
959 !> \details Write overall best objective function and the best optimized parameter set to a file_opti.
960
961 ! INTENT(IN)
962 !> \param[in] "real(dp) :: best_OF" best objective function value as returnedby the
963 !> optimization routine
964 !> \param[in] "real(dp), dimension(:) :: best_paramSet" best associated global parameter setCalled only
965 !> when optimize is .TRUE.
966 !> \param[in] "character(len = *), dimension(:) :: param_names"
967
968 ! HISTORY
969 !> \authors David Schaefer
970
971 !> \date July 2013
972
973 ! Modifications:
974 ! Rohini Kumar Aug 2013 - change in structure of the code including call statements
975 ! Juliane Mai Oct 2013 - clear parameter names added
976 ! - double precision written
977 ! Stephan Thober Oct 2015 - ported to mRM
978 ! Robert Schweppe Jun 2018 - refactoring and reformatting
979
980 subroutine mrm_write_optifile(best_OF, best_paramSet, param_names)
981
984 use mo_string_utils, only : num2str
985
986 implicit none
987
988 ! best objective function value as returnedby the optimization routine
989 real(dp), intent(in) :: best_of
990
991 ! best associated global parameter setCalled only when optimize is .TRUE.
992 real(dp), dimension(:), intent(in) :: best_paramset
993
994 character(len = *), dimension(:), intent(in) :: param_names
995
996 character(256) :: fname, formheader, formparams
997
998 integer(i4) :: ii, err, n_params
999
1000
1001 ! number of parameters
1002 n_params = size(best_paramset)
1003
1004 ! open file
1005 fname = trim(adjustl(dirconfigout)) // trim(adjustl(file_opti))
1006 open(uopti, file = fname, status = 'unknown', action = 'write', iostat = err, recl = (n_params + 1) * 40)
1007 if(err .ne. 0) then
1008 call error_message(' IOError while openening "', trim(fname), '" Error-Code ', num2str(err))
1009 end if
1010
1011 ! header
1012 write(formheader, *) '(a40,', n_params, 'a40)'
1013 ! len(param_names(1))=256 but only 39 characters taken here
1014 ! write(uopti, formHeader) 'OF', (trim(adjustl(param_names(ii))), ii=1, n_params)
1015 write(uopti, formheader) 'OF', (trim(adjustl(param_names(ii)(1 : 39))), ii = 1, n_params)
1016
1017 ! output
1018 write(formparams, *) '( es40.14, ', n_params, '(es40.14) )'
1019 write(uopti, formparams) best_of, (best_paramset(ii), ii = 1, n_params)
1020
1021 ! close file
1022 close(uopti)
1023
1024 ! screen output
1025 call message()
1026 call message(' Optimized parameters written to ', trim(fname))
1027
1028 end subroutine mrm_write_optifile
1029
1030 ! ------------------------------------------------------------------
1031
1032 ! NAME
1033 ! mrm_write_optinamelist
1034
1035 ! PURPOSE
1036 !> \brief Write final, optimized parameter set in a namelist format.
1037
1038 !> \details Write final, optimized parameter set in a namelist format.
1039
1040 ! INTENT(IN)
1041 !> \param[in] "real(dp), dimension(:, :) :: parameters" (min, max, opti)
1042 !> \param[in] "logical, dimension(size(parameters, 1)) :: maskpara" .true. if parameter was
1043 !> calibrated
1044 !> \param[in] "character(len = *), dimension(size(parameters, 1)) :: parameters_name" clear names of parameters
1045
1046 ! HISTORY
1047 !> \authors Juliane Mai
1048
1049 !> \date Dec 2013
1050
1051 ! Modifications:
1052 ! Stephan Thober Oct 2015 - adapted to mRM
1053 ! Stephan Thober Nov 2016 - adapt header to routing process
1054 ! Robert Schweppe Jun 2018 - refactoring and reformatting
1055
1056 subroutine mrm_write_optinamelist(parameters, maskpara, parameters_name)
1057
1060 use mo_string_utils, only : num2str
1061
1062 implicit none
1063
1064 ! (min, max, opti)
1065 real(dp), dimension(:, :), intent(in) :: parameters
1066
1067 ! .true. if parameter was calibrated
1068 logical, dimension(size(parameters, 1)), intent(in) :: maskpara
1069
1070 ! clear names of parameters
1071 character(len = *), dimension(size(parameters, 1)), intent(in) :: parameters_name
1072
1073 character(256) :: fname
1074
1075 character(3) :: flag
1076
1077 integer(i4) :: err
1078
1079 integer(i4) :: ipar
1080
1081
1082 ! open file
1083 fname = trim(adjustl(dirconfigout)) // trim(adjustl(file_opti_nml))
1084 open(uopti_nml, file = fname, status = 'unknown', action = 'write', iostat = err)
1085 if(err .ne. 0) then
1086 call message (' IOError while openening "', trim(fname), '" Error-Code ', num2str(err))
1087 end if
1088
1089 write(uopti_nml, *) '!global_parameters'
1090 write(uopti_nml, *) '!PARAMETER lower_bound upper_bound value FLAG SCALING'
1091
1092 write(uopti_nml, *) '! ', trim(adjustl('routing'))
1093
1094 if (processmatrix(8, 1) .eq. 1_i4) write(uopti_nml, *) '&routing1'
1095 if (processmatrix(8, 1) .eq. 2_i4) write(uopti_nml, *) '&routing2'
1096 if (processmatrix(8, 1) .eq. 3_i4) write(uopti_nml, *) '&routing3'
1097
1098 do ipar = 1, size(parameters, 1)
1099 if (maskpara(ipar)) then
1100 flag = ' 1 '
1101 else
1102 flag = ' 0 '
1103 end if
1104 write(uopti_nml, *) trim(adjustl(parameters_name(ipar))), ' = ', &
1105 parameters(ipar, 1), ' , ', &
1106 parameters(ipar, 2), ' , ', &
1107 parameters(ipar, 3), ' , ', &
1108 flag, ', 1 '
1109 end do
1110
1111 write(uopti_nml, *) '/'
1112 write(uopti_nml, *) ' '
1113
1114 ! close file
1115 close(uopti_nml)
1116
1117 ! screen output
1118 call message()
1119 call message(' Optimized parameters written in namelist format to ', trim(fname))
1120
1121 end subroutine mrm_write_optinamelist
1122
1123
1124end module mo_mrm_write
Provides constants commonly used by mHM, mRM and MPR.
real(dp), parameter, public nodata_dp
Provides file names and units for mRM.
integer, parameter uconfig
Unit for file defining mHM's outputs.
character(len= *), parameter file_config
file defining mHM's outputs
Provides file names and units for mHM.
integer, parameter uopti
Unit for file optimization outputs (objective and parameter set)
character(len=*), parameter file_opti
file defining optimization outputs (objective and parameter set)
character(len=*), parameter file_opti_nml
file defining optimization outputs in a namelist format (parameter set)
integer, parameter uopti_nml
Unit for file optimization outputs in a namelist format (parameter set)
Provides structures needed by mHM, mRM and/or mpr.
type(period), dimension(:), allocatable, public warmper
real(dp), dimension(:), allocatable, public resolutionrouting
integer(i4), dimension(:), allocatable, public warmingdays
integer(i4), dimension(:, :), allocatable, public lcyearid
type(period), dimension(:), allocatable, public simper
type(period), dimension(:), allocatable, public evalper
Provides structures needed by mHM, mRM and/or mpr.
real(dp), dimension(:), allocatable, public resolutionhydrology
logical, public write_restart
real(dp), dimension(:, :), allocatable, target, public global_parameters
character(256), dimension(:), allocatable, public lcfilename
character(256), dimension(:), allocatable, public global_parameters_name
type(domain_meta), public domainmeta
character(256), public dirconfigout
integer(i4), public nlcoverscene
character(256), dimension(:), allocatable, public dirlcover
integer(i4), dimension(:), allocatable, public lc_year_end
character(256), dimension(:), allocatable, public dirout
character(256), dimension(:), allocatable, public dirmorpho
integer(i4), dimension(nprocesses, 3), public processmatrix
character(256), dimension(:), allocatable, public mrmfilerestartout
type(grid), dimension(:), allocatable, target, public level1
type(grid), dimension(:), allocatable, target, public level0
integer(i4), dimension(:), allocatable, public lc_year_start
Provides file names and units for mRM.
integer, parameter udaily_discharge
Unit for file optimazation outputs.
integer, parameter usubdaily_discharge
Unit for file optimazation outputs.
character(len=*), parameter version
Current mHM model version.
character(len=*), parameter ncfile_subdaily_discharge
file containing simulated discharge at observat time step
character(len=*), parameter file_daily_discharge
file defining optimazation outputs
character(len=*), parameter file_subdaily_discharge
file defining optimazation outputs
character(len=*), parameter ncfile_discharge
file defining optimazation outputs
Global variables for mRM only.
type(gaugingstation), public inflowgauge
integer(i4), dimension(:), allocatable, public l11_netperm
integer(i4), dimension(:), allocatable, public l11_l1_id
integer(i4), dimension(:), allocatable, public l1_l11_id
integer(i4), dimension(:), allocatable, public l11_label
real(dp), dimension(:, :), allocatable, public mrm_runoff
character(256), dimension(:), allocatable, public dirgauges
integer(i4) output_time_reference_mrm
time reference point location in output nc files
type(gaugingstation), public gauge
integer(i4), dimension(:), allocatable, public l11_fromn
real(dp), dimension(:), allocatable, public l11_length
integer(i4), dimension(:), allocatable, public l11_ton
type(domaininfo_mrm), dimension(:), allocatable, target, public domain_mrm
type(grid), dimension(:), allocatable, target, public level11
real(dp), dimension(:), allocatable, public l11_slope
character(256), dimension(:), allocatable, public dirtotalrunoff
integer(i4), public ninflowgaugestotal
integer(i4), dimension(:), allocatable, public l11_rorder
Restart routines.
subroutine, public mrm_write_restart(idomain, domainid, outfile)
write routing states and configuration
Creates NetCDF output for different fluxes and state variables of mHM.
write of discharge and restart files
subroutine write_daily_obs_sim_discharge(qobs, qsim)
Write a file for the daily observed and simulated discharge timeseries during the evaluation period f...
subroutine, public mrm_write_optifile(best_of, best_paramset, param_names)
Write briefly final optimization results.
subroutine, public mrm_write_optinamelist(parameters, maskpara, parameters_name)
Write final, optimized parameter set in a namelist format.
subroutine write_subdaily_obs_sim_discharge(qobs, qsim, factor)
Write a file for the simulated discharge timeseries during the evaluation period for each gauging sta...
subroutine, public mrm_write
write discharge and restart files
subroutine write_configfile
This modules writes the results of the configuration into an ASCII-file.