5.13.2-dev0
mHM
The mesoscale Hydrological Model
Loading...
Searching...
No Matches
mo_mhm_bfi.f90
Go to the documentation of this file.
1!> \file mo_mhm_bfi.f90
2!> \brief \copybrief mo_mhm_bfi
3!> \details \copydetails mo_mhm_bfi
4
5!> \brief Module to calculate BFI form gauging stations in mHM.
6!> \version 0.1
7!> \authors Sebastian Mueller
8!> \date Apr 2022
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_mhm
13
14 use mo_kind, only: i4, dp
15
16 implicit none
17 private
18 public :: calculate_bfi
19
20contains
21
22 !> \brief Calculate BFI from given discharge observation.
23 subroutine calculate_bfi()
27 use mo_message, only : error_message, message
28 use mo_string_utils, only : num2str
29 use mo_utils, only : ge
31 use mo_orderpack, only: sort_index
32 use mo_eckhardt_filter, only: eckhardt_filter_fit, bfi
33
34 implicit none
35 real(dp), allocatable :: baseflow(:), runoff_obs(:)
36 logical, allocatable :: runoff_obs_mask(:)
37 integer(i4), allocatable :: id_sort(:)
38 integer(i4) :: idomain, id, length, mask_length, tt
39
40 ! check for daily timesteps
41 if ( nmeasperday > 1 ) call error_message("BFI: calculation only possible with daily discharge values!")
42
43 ! extract domain Id from gauge Id
44 if (size(gauge%domainId) /= domainmeta%nDomains) call error_message("BFI: number of gauges and domains need to be equal!")
45 allocate(id_sort(size(gauge%domainId)))
46 id_sort = sort_index(gauge%domainId)
47
48 call message()
49 do idomain = 1, domainmeta%nDomains
50 ! skip current calculation if BFI is given
51 if ( .not. (bfi_obs(idomain) < 0.0_dp) ) then
52 call message( &
53 " BFI: using given BFI value ", &
54 trim(adjustl(num2str(bfi_obs(idomain)))), &
55 " for domain ", &
56 trim(adjustl(num2str(idomain))) &
57 )
58 cycle
59 end if
60
61 id = id_sort(idomain)
62 if (gauge%domainId(id) /= idomain) call error_message("BFI: exactly one gauge per domain required!")
63
64 ! get length of evaluation period times
65 length = (evalper(idomain)%julEnd - evalper(idomain)%julStart + 1) * nmeasperday
66
67 ! extract measurements
68 if (allocated(runoff_obs_mask)) deallocate(runoff_obs_mask)
69 if (allocated(runoff_obs)) deallocate(runoff_obs)
70 if (allocated(baseflow)) deallocate(baseflow)
71 allocate(runoff_obs_mask(length))
72 allocate(runoff_obs(length))
73 runoff_obs = gauge%Q(1 : length, id)
74
75 ! create mask of observed runoff
76 forall(tt = 1 : length) runoff_obs_mask(tt) = ge(runoff_obs(tt), 0.0_dp)
77
78 ! calculate BFI
79 baseflow = eckhardt_filter_fit(runoff_obs, mask=runoff_obs_mask)
80 bfi_obs(idomain) = bfi(baseflow, runoff_obs, mask=runoff_obs_mask)
81
82 call message( &
83 " BFI: calculated BFI value ", &
84 trim(adjustl(num2str(bfi_obs(idomain)))), &
85 " for domain ", &
86 trim(adjustl(num2str(idomain))) &
87 )
88 end do
89
90 end subroutine calculate_bfi
91
92end module mo_mhm_bfi
Provides structures needed by mHM, mRM and/or mpr.
integer(i4), dimension(:), allocatable, public warmingdays
type(period), dimension(:), allocatable, public evalper
Provides structures needed by mHM, mRM and/or mpr.
type(domain_meta), public domainmeta
Main global variables for mHM.
real(dp), dimension(:), allocatable, public bfi_obs
given base-flow index per domain
Module to calculate BFI form gauging stations in mHM.
subroutine, public calculate_bfi()
Calculate BFI from given discharge observation.
Global variables for mRM only.
type(gaugingstation), public gauge