LCOV - code coverage report
Current view: top level - mHM - mo_mhm_bfi.f90 (source / functions) Hit Total Coverage
Test: mHM coverage Lines: 0 28 0.0 %
Date: 2024-04-15 17:48:09 Functions: 0 1 0.0 %

          Line data    Source code
       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
      12             : module mo_mhm_bfi
      13             : 
      14             :   use mo_kind,       only: i4, dp
      15             : 
      16             :   implicit none
      17             :   private
      18             :   public :: calculate_BFI
      19             : 
      20             : contains
      21             : 
      22             :   !> \brief Calculate BFI from given discharge observation.
      23           0 :   subroutine calculate_BFI()
      24             :     use mo_common_mhm_mrm_variables, only : evalPer, nTstepDay, warmingDays
      25             :     use mo_common_variables, only : domainMeta
      26             :     use mo_global_variables, only : BFI_obs
      27             :     use mo_message, only : error_message, message
      28             :     use mo_string_utils, only : num2str
      29             :     use mo_utils, only : ge
      30             :     use mo_mrm_global_variables, only : gauge, nMeasPerDay
      31             :     use mo_orderpack, only: sort_index
      32             :     use mo_eckhardt_filter, only: eckhardt_filter_fit, BFI
      33             : 
      34             :     implicit none
      35           0 :     real(dp), allocatable :: baseflow(:), runoff_obs(:)
      36           0 :     logical, allocatable :: runoff_obs_mask(:)
      37           0 :     integer(i4), allocatable :: id_sort(:)
      38             :     integer(i4) :: iDomain, id, length, mask_length, tt
      39             : 
      40             :     ! check for daily timesteps
      41           0 :     if ( nMeasPerDay > 1 ) call error_message("BFI: calculation only possible with daily discharge values!")
      42             : 
      43             :     ! extract domain Id from gauge Id
      44           0 :     if (size(gauge%domainId) /= domainMeta%nDomains) call error_message("BFI: number of gauges and domains need to be equal!")
      45           0 :     allocate(id_sort(size(gauge%domainId)))
      46           0 :     id_sort = sort_index(gauge%domainId)
      47             : 
      48           0 :     call message()
      49           0 :     do iDomain = 1, domainMeta%nDomains
      50             :       ! skip current calculation if BFI is given
      51           0 :       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           0 :         )
      58           0 :         cycle
      59             :       end if
      60             : 
      61           0 :       id = id_sort(iDomain)
      62           0 :       if (gauge%domainId(id) /= iDomain) call error_message("BFI: exactly one gauge per domain required!")
      63             : 
      64             :       ! get length of evaluation period times
      65           0 :       length = (evalPer(iDomain)%julEnd - evalPer(iDomain)%julStart + 1) * nMeasPerDay
      66             : 
      67             :       ! extract measurements
      68           0 :       if (allocated(runoff_obs_mask)) deallocate(runoff_obs_mask)
      69           0 :       if (allocated(runoff_obs)) deallocate(runoff_obs)
      70           0 :       if (allocated(baseflow)) deallocate(baseflow)
      71           0 :       allocate(runoff_obs_mask(length))
      72           0 :       allocate(runoff_obs(length))
      73           0 :       runoff_obs = gauge%Q(1 : length, id)
      74             : 
      75             :       ! create mask of observed runoff
      76           0 :       forall(tt = 1 : length) runoff_obs_mask(tt) = ge(runoff_obs(tt), 0.0_dp)
      77             : 
      78             :       ! calculate BFI
      79           0 :       baseflow = eckhardt_filter_fit(runoff_obs, mask=runoff_obs_mask)
      80           0 :       BFI_obs(iDomain) = BFI(baseflow, runoff_obs, mask=runoff_obs_mask)
      81             : 
      82             :       call message( &
      83             :         "  BFI:  calculated BFI value ", &
      84           0 :         trim(adjustl(num2str(BFI_obs(iDomain)))), &
      85             :         " for domain ", &
      86             :         trim(adjustl(num2str(iDomain))) &
      87           0 :       )
      88             :     end do
      89             : 
      90           0 :   end subroutine calculate_BFI
      91             : 
      92             : end module mo_mhm_bfi

Generated by: LCOV version 1.16