16 use mo_kind,
only: dp, i4
30 logical :: active = .false.
31 integer(i4) :: case = 0_i4
32 character(256) :: nml_name =
'config_riv_temp'
34 character(256),
dimension(:),
allocatable :: dir_riv_widths
35 character(256) :: riv_widths_file
36 character(256) :: riv_widths_name
37 real(dp),
public,
dimension(:),
allocatable :: l11_riv_widths
38 real(dp),
public,
dimension(:),
allocatable :: l11_riv_areas
40 real(dp) :: albedo_water
41 real(dp) :: pt_a_water
43 real(dp) :: emissivity_water
44 real(dp) :: turb_heat_ex_coeff
46 real(dp) :: delta_t = 0.1_dp
48 integer(i4) :: max_iter
49 real(dp) :: delta_iter
53 logical :: bisect_iter
54 real(dp) :: up_bnd_iter
55 real(dp) :: low_bnd_iter
57 real(dp),
dimension(:),
allocatable :: l1_runoff_e
58 real(dp),
dimension(:),
allocatable :: l1_acc_ssrd
59 real(dp),
dimension(:),
allocatable :: l1_acc_strd
60 real(dp),
dimension(:),
allocatable :: l1_acc_temp
61 real(dp),
dimension(:),
allocatable :: l1_ssrd_calc
62 real(dp),
dimension(:),
allocatable :: l1_strd_calc
63 real(dp),
dimension(:),
allocatable :: l1_tann_calc
68 real(dp),
dimension(:,:),
allocatable :: netnode_e_in
69 real(dp),
dimension(:,:),
allocatable :: netnode_e_r
70 real(dp),
dimension(:),
allocatable :: netnode_e_mod
71 real(dp),
dimension(:),
allocatable :: netnode_e_out
72 real(dp),
dimension(:),
allocatable :: l11_srad_net
73 real(dp),
dimension(:),
allocatable :: l11_lrad_in
74 real(dp),
dimension(:),
allocatable :: l11_air_temp
76 real(dp),
dimension(:),
allocatable :: river_temp
135 if (
allocated(self%L1_runoff_E) )
deallocate(self%L1_runoff_E)
136 if (
allocated(self%L1_acc_strd) )
deallocate(self%L1_acc_strd)
137 if (
allocated(self%L1_acc_ssrd) )
deallocate(self%L1_acc_ssrd)
138 if (
allocated(self%L1_acc_temp) )
deallocate(self%L1_acc_temp)
139 if (
allocated(self%dir_riv_widths) )
deallocate(self%dir_riv_widths)
140 if (
allocated(self%L11_riv_widths) )
deallocate(self%L11_riv_widths)
141 if (
allocated(self%L11_riv_areas) )
deallocate(self%L11_riv_areas)
142 if (
allocated(self%netNode_E_IN) )
deallocate(self%netNode_E_IN)
143 if (
allocated(self%netNode_E_R) )
deallocate(self%netNode_E_R)
144 if (
allocated(self%netNode_E_mod) )
deallocate(self%netNode_E_mod)
145 if (
allocated(self%netNode_E_out) )
deallocate(self%netNode_E_out)
146 if (
allocated(self%L11_srad_net) )
deallocate(self%L11_srad_net)
147 if (
allocated(self%L11_lrad_in) )
deallocate(self%L11_lrad_in)
148 if (
allocated(self%L11_air_temp) )
deallocate(self%L11_air_temp)
149 if (
allocated(self%river_temp) )
deallocate(self%river_temp)
151 if (
allocated(self%L1_ssrd_calc) )
deallocate(self%L1_ssrd_calc)
152 if (
allocated(self%L1_strd_calc) )
deallocate(self%L1_strd_calc)
153 if (
allocated(self%L1_tann_calc) )
deallocate(self%L1_tann_calc)
161 file_namelist_param &
167 USE mo_string_utils,
ONLY : num2str
173 character(*),
intent(in) :: file_namelist
174 character(*),
intent(in) :: file_namelist_param
176 integer(i4) :: iDomain, domainID
179 allocate(self%dir_riv_widths(
domainmeta%nDomains))
196 path=self%dir_riv_widths(idomain), &
197 text=
"(domain "//trim(num2str(domainid,
'(I3)'))//
") River widths directory:", &
211 use mo_append,
only : append
218 integer(i4),
intent(in) :: nCells
220 real(dp),
dimension(:),
allocatable :: dummy_Vector11
221 real(dp),
dimension(:, :),
allocatable :: dummy_Matrix11_IT
224 allocate(dummy_vector11(ncells))
226 dummy_vector11(:) = 0.0_dp
227 dummy_matrix11_it(:, :) = 0.0_dp
230 call append(self%netNode_E_mod, dummy_vector11)
232 call append(self%river_temp, dummy_vector11)
234 call append(self%netNode_E_out, dummy_vector11)
236 call append(self%netNode_E_IN, dummy_matrix11_it)
238 call append(self%netNode_E_R, dummy_matrix11_it)
241 deallocate(dummy_vector11)
242 deallocate(dummy_matrix11_it)
259 use mo_append,
only : append
265 integer(i4),
intent(in) :: iDomain
266 integer(i4),
dimension(:),
intent(in) :: L11_netPerm
267 integer(i4),
dimension(:),
intent(in) :: L11_fromN
268 real(dp),
dimension(:),
intent(in) :: L11_length
269 integer(i4),
intent(in) :: nLinks
270 integer(i4),
intent(in) :: nCells
271 integer(i4),
intent(in) :: ncols
272 integer(i4),
intent(in) :: nrows
273 logical,
dimension(:, :),
intent(in) :: L11_mask
275 real(dp),
dimension(:,:),
allocatable :: L11_data
276 real(dp),
dimension(:),
allocatable :: L11_riv_widths, L11_riv_areas
278 integer(i4) :: i, k, iNode
281 trim(self%dir_riv_widths(idomain)), &
284 self%riv_widths_name, &
286 self%riv_widths_file &
289 allocate(l11_riv_widths(ncells))
290 l11_riv_widths(:) = pack(l11_data(:,:), mask=l11_mask)
291 call append(self%L11_riv_widths, l11_riv_widths)
293 allocate(l11_riv_areas(ncells))
295 l11_riv_areas = 0.0_dp
300 l11_riv_areas(inode) = l11_length(i) * l11_riv_widths(inode)
302 call append(self%L11_riv_areas, l11_riv_areas)
305 deallocate(l11_riv_widths)
306 deallocate(l11_riv_areas)
326 real(dp),
dimension(:),
intent(in) :: temp_air
327 real(dp),
intent(in),
dimension(:) :: efecarea
328 integer(i4),
intent(in),
dimension(:) :: L1_L11_Id
329 real(dp),
intent(in),
dimension(:) :: L11_areacell
330 integer(i4),
intent(in),
dimension(:) :: L11_L1_Id
331 logical,
intent(in) :: map_flag
335 temp_air, efecarea, l1_l11_id, l11_areacell, l11_l1_id, map_flag, self%river_temp(self%s11 : self%e11))
338 self%river_temp(self%s11 : self%e11) = max(self%delta_T, self%river_temp(self%s11 : self%e11))
351 self%L1_runoff_E = 0.0_dp
352 self%L1_acc_strd = 0.0_dp
353 self%L1_acc_ssrd = 0.0_dp
354 self%L1_acc_temp = 0.0_dp
366 integer(i4),
intent(in) :: nCells
368 allocate(self%L1_runoff_E(ncells))
369 allocate(self%L1_acc_strd(ncells))
370 allocate(self%L1_acc_ssrd(ncells))
371 allocate(self%L1_acc_temp(ncells))
373 allocate(self%L1_ssrd_calc(ncells))
374 allocate(self%L1_strd_calc(ncells))
375 allocate(self%L1_tann_calc(ncells))
377 call self%reset_timestep()
389 deallocate(self%L1_runoff_E)
390 deallocate(self%L1_acc_strd)
391 deallocate(self%L1_acc_ssrd)
392 deallocate(self%L1_acc_temp)
393 deallocate(self%L1_ssrd_calc)
394 deallocate(self%L1_strd_calc)
395 deallocate(self%L1_tann_calc)
402 fSealed_area_fraction, &
415 real(dp),
dimension(:),
intent(in) :: fSealed_area_fraction
416 real(dp),
dimension(:),
intent(in) :: fast_interflow
417 real(dp),
dimension(:),
intent(in) :: slow_interflow
418 real(dp),
dimension(:),
intent(in) :: baseflow
419 real(dp),
dimension(:),
intent(in) :: direct_runoff
420 real(dp),
dimension(:),
intent(in) :: temp_air
423 self%ts_cnt = self%ts_cnt + 1_i4
428 fsealed_area_fraction, &
429 fast_interflow, slow_interflow, baseflow, direct_runoff, &
430 temp_air, self%L1_tann_calc, &
434 self%L1_acc_ssrd = self%L1_acc_ssrd + self%L1_ssrd_calc
435 self%L1_acc_strd = self%L1_acc_strd + self%L1_strd_calc
436 self%L1_acc_temp = self%L1_acc_temp + temp_air
457 real(dp),
intent(in),
dimension(:) :: efecarea
459 integer(i4),
intent(in),
dimension(:) :: L1_L11_Id
461 real(dp),
intent(in),
dimension(:) :: L11_areacell
463 integer(i4),
intent(in),
dimension(:) :: L11_L1_Id
465 integer(i4),
intent(in) :: timestep
467 logical,
intent(in) :: map_flag
470 if (
allocated(self%L11_srad_net) )
deallocate(self%L11_srad_net)
471 if (
allocated(self%L11_lrad_in) )
deallocate(self%L11_lrad_in)
472 if (
allocated(self%L11_air_temp) )
deallocate(self%L11_air_temp)
473 allocate(self%L11_srad_net(
size(l11_l1_id, dim = 1)))
474 allocate(self%L11_lrad_in(
size(l11_l1_id, dim = 1)))
475 allocate(self%L11_air_temp(
size(l11_l1_id, dim = 1)))
486 self%netNode_E_out(self%s11 : self%e11) &
490 self%L1_acc_ssrd = self%L1_acc_ssrd / real(self%ts_cnt, dp)
491 call l11_meteo_acc(self%L1_acc_ssrd, efecarea, l1_l11_id, l11_areacell, l11_l1_id, map_flag, self%L11_srad_net)
493 self%L11_srad_net = self%L11_srad_net * (1._dp - self%albedo_water)
495 self%L1_acc_strd = self%L1_acc_strd / real(self%ts_cnt, dp)
496 call l11_meteo_acc(self%L1_acc_strd, efecarea, l1_l11_id, l11_areacell, l11_l1_id, map_flag, self%L11_lrad_in)
498 self%L1_acc_temp = self%L1_acc_temp / real(self%ts_cnt, dp)
499 call l11_meteo_acc(self%L1_acc_temp, efecarea, l1_l11_id, l11_areacell, l11_l1_id, map_flag, self%L11_air_temp)
507 use mo_constants,
only: sigma_dp
513 real(dp),
intent(in) :: riv_temp
516 lrad_out = self%emissivity_water * sigma_dp * riv_temp ** 4_i4
522 real(dp) function
get_lat_heat(self, air_temp, netrad) result(lat_heat)
524 use mo_constants,
only : psychro_dp
531 real(dp),
intent(in) :: air_temp
533 real(dp),
intent(in) :: netrad
540 lat_heat = self%pt_a_water * delta / (psychro_dp + delta) * max(netrad, 0._dp)
551 real(dp),
intent(in) :: air_temp
552 real(dp),
intent(in) :: riv_temp
555 sens_heat = self%turb_heat_ex_coeff * (riv_temp - air_temp)
561 real(dp) function
get_e_io(self, riv_temp, cell) result(e_io)
563 use mo_constants,
only : t0_dp, cp_w_dp
570 real(dp),
intent(in) :: riv_temp
572 integer(i4),
intent(in) :: cell
574 real(dp) :: netrad, sens_heat, lat_heat
577 netrad = self%L11_srad_net(cell) + self%L11_lrad_in(cell) - self%get_lrad_out(riv_temp)
579 sens_heat = self%get_sens_heat(self%L11_air_temp(cell), riv_temp - t0_dp)
581 lat_heat = self%get_lat_heat(self%L11_air_temp(cell), netrad)
585 e_io = (netrad - sens_heat - lat_heat) / (
h2odens * cp_w_dp)
605 use mo_constants,
only : t0_dp
611 integer(i4),
intent(in) :: nLinks
613 integer(i4),
dimension(:),
intent(in) :: netPerm
615 integer(i4),
dimension(:),
intent(in) :: netLink_fromN
617 integer(i4),
dimension(:),
intent(in) :: netLink_toN
619 real(dp),
dimension(:),
intent(in) :: netLink_C1
621 real(dp),
dimension(:),
intent(in) :: netLink_C2
623 integer(i4),
intent(in) :: nInflowGauges
625 logical,
dimension(:),
intent(in) :: InflowHeadwater
627 integer(i4),
dimension(:),
intent(in) :: InflowNodeList
629 integer(i4),
dimension(:),
intent(in) :: sink_cells
631 real(dp),
intent(in),
dimension(:) :: L11_qTR
633 real(dp),
intent(in),
dimension(:) :: L11_Qmod
635 integer(i4) :: i, k, m, iNode, tNode, L11in, L11to
636 real(dp) :: E_IO_in, E_IO, T_est, T_rout
639 self%netNode_E_IN(self%s11 : self%e11, 2) = 0.0_dp
641 riv_loop:
do k = 1, nlinks
644 inode = netlink_fromn(i)
645 tnode = netlink_ton(i)
647 l11in = inode + self%s11 - 1_i4
648 l11to = tnode + self%s11 - 1_i4
651 self%netNode_E_IN(l11in, 2) = self%netNode_E_IN(l11in, 2) + self%netNode_E_out(l11in)
653 self%river_temp(l11in) = self%netNode_E_IN(l11in, 2) / l11_qmod(inode) - t0_dp
656 t_est = self%river_temp(l11in) + t0_dp
658 e_io_in = self%get_E_IO(t_est, inode)
661 call self%init_iter()
663 iterloop:
do m=1, self%max_iter
665 e_io = (e_io_in + self%get_E_IO(t_est, tnode)) * 0.5_dp * self%L11_riv_areas(l11in)
667 self%netNode_E_R(l11in, 2) = self%netNode_E_R(l11in, 1) &
668 + netlink_c1(i) * (self%netNode_E_IN(l11in, 1) - self%netNode_E_R(l11in, 1)) &
669 + netlink_c2(i) * (self%netNode_E_IN(l11in, 2) + e_io - self%netNode_E_IN(l11in, 1))
671 t_rout = self%netNode_E_R(l11in, 2) / l11_qtr(inode)
673 if ( abs(t_rout - t_est) < self%delta_iter )
exit iterloop
675 call self%next_iter(t_est, t_rout)
679 self%netNode_E_IN(l11in, 2) = self%netNode_E_IN(l11in, 2) + e_io
682 if (ninflowgauges .GT. 0)
then
683 do i = 1, ninflowgauges
685 if ((tnode == inflownodelist(i)) .AND. (.NOT. inflowheadwater(i))) &
686 self%netNode_E_R(l11in, 2) = 0.0_dp
691 self%netNode_E_IN(l11to, 2) = self%netNode_E_IN(l11to, 2) + self%netNode_E_R(l11in, 2)
697 do k = 1,
size(sink_cells)
698 tnode = sink_cells(k)
699 l11to = tnode + self%s11 - 1_i4
700 self%netNode_E_IN(l11to, 2) = self%netNode_E_IN(l11to, 2) + self%netNode_E_out(l11to)
701 self%river_temp(l11to) = self%netNode_E_IN(l11to, 2) / l11_qmod(tnode) - t0_dp
705 self%netNode_E_R(self%s11 : self%e11, 1) = self%netNode_E_R(self%s11 : self%e11, 2)
706 self%netNode_E_IN(self%s11 : self%e11, 1) = self%netNode_E_IN(self%s11 : self%e11, 2)
718 self%first_iter = .true.
720 self%bisect_iter = .false.
730 real(dp),
intent(inout) :: T_est
731 real(dp),
intent(in) :: T_rout
734 if ( .not. self%bisect_iter )
then
736 if ( self%first_iter )
then
737 self%first_iter = .false.
739 self%up_iter = ( t_rout > t_est )
742 if ( self%up_iter .eqv. ( t_rout > t_est ) )
then
743 if ( self%up_iter )
then
744 t_est = t_est + self%step_iter
746 t_est = t_est - self%step_iter
751 self%bisect_iter = .true.
753 if ( self%up_iter )
then
754 self%up_bnd_iter = t_est
755 self%low_bnd_iter = t_est - self%step_iter
757 self%up_bnd_iter = t_est + self%step_iter
758 self%low_bnd_iter = t_est
761 t_est = (self%up_bnd_iter + self%low_bnd_iter) / 2.0_dp
766 if ( t_rout < t_est )
then
767 self%up_bnd_iter = t_est
770 self%low_bnd_iter = t_est
773 t_est = (self%up_bnd_iter + self%low_bnd_iter) / 2.0_dp
subroutine, public check_dir(path, text, raise, tab, text_length)
Check if a given directory exists.
Provides constants commonly used by mHM, mRM and MPR.
integer(i4), parameter, public maxnodomains
integer(i4), parameter, public nodata_i4
Provides structures needed by mHM, mRM and/or mpr.
type(domain_meta), public domainmeta
Provides mHM specific constants.
real(dp), parameter, public h2odens
Provides mRM specific constants.
integer(i4), parameter, public nroutingstates
Performs pre-processing for routing for mHM at level L11.
subroutine, public l11_meteo_acc(meteo_all, efecarea, l1_l11_id, l11_areacell, l11_l1_id, map_flag, meteo_acc)
meteo forcing accumulation at L11 for temperature routing.
subroutine, public l11_runoff_acc(qall, efecarea, l1_l11_id, l11_areacell, l11_l1_id, ts, map_flag, qacc)
total runoff accumulation at L11.
subroutine, public calc_l1_runoff_e(fsealed_area_fraction, fast_interflow, slow_interflow, baseflow, direct_runoff, temp_air, mean_temp_air, lateral_e)
calculate lateral temperature energy from runoff components.
Class for the river temperature calculations.
real(dp) function get_sens_heat(self, air_temp, riv_temp)
sensible heat flux of riv_temp_type
real(dp) function get_lat_heat(self, air_temp, netrad)
latent heat flux of riv_temp_type
subroutine init_riv_temp(self, temp_air, efecarea, l1_l11_id, l11_areacell, l11_l1_id, map_flag)
initialize the river temperature of riv_temp_type class for the current domain
real(dp) function get_lrad_out(self, riv_temp)
get outgoing longwave radiation of riv_temp_type
subroutine dealloc_lateral(self)
deallocate lateral temp components of riv_temp_type
subroutine finalize_source_e(self, efecarea, l1_l11_id, l11_areacell, l11_l1_id, timestep, map_flag)
finalize energy sources of riv_temp_type
subroutine alloc_lateral(self, ncells)
allocate lateral temp components of riv_temp_type class for current domain
subroutine clean_up(self)
clean up
subroutine next_iter(self, t_est, t_rout)
execute next iteration with iterative solver of riv_temp_type
subroutine l11_routing_e(self, nlinks, netperm, netlink_fromn, netlink_ton, netlink_c1, netlink_c2, ninflowgauges, inflowheadwater, inflownodelist, sink_cells, l11_qtr, l11_qmod)
execute the temperature routing of riv_temp_type
subroutine init_iter(self)
initialize iterative solver of riv_temp_type
subroutine init_area(self, idomain, l11_netperm, l11_fromn, l11_length, nlinks, ncells, nrows, ncols, l11_mask)
initialize the river area of riv_temp_type class for the current domain
real(dp) function get_e_io(self, riv_temp, cell)
get complete energy source of riv_temp_type at given cell
subroutine acc_source_e(self, fsealed_area_fraction, fast_interflow, slow_interflow, baseflow, direct_runoff, temp_air)
accumulate energy sources of riv_temp_type
subroutine reset_timestep(self)
reset riv_temp_type class for next timestep
subroutine init(self, ncells)
initalize the riv_temp_type class for the current domain
subroutine config(self, file_namelist, file_namelist_param)
configure the riv_temp_type class from the mhm namelist
Module containing all namelists representations.
type(nml_config_riv_temp_t), public nml_config_riv_temp
'config_riv_temp' namelist content
Module for calculating reference/potential evapotranspiration [mm d-1].
elemental pure real(dp) function, public slope_satpressure(tavg)
slope of saturation vapour pressure curve
Reads forcing input data.
subroutine, public read_const_nc(folder, nrows, ncols, varname, data, filename)
Reads time independent forcing input in NetCDF file format.
This is a container to define the river temperature routing in the current time step.