LCOV - code coverage report
Current view: top level - MPR - mo_multi_param_reg.f90 (source / functions) Hit Total Coverage
Test: mHM coverage Lines: 256 278 92.1 %
Date: 2024-04-15 17:48:09 Functions: 7 7 100.0 %

          Line data    Source code
       1             : !> \file mo_multi_param_reg.f90
       2             : !> \brief \copybrief mo_multi_param_reg
       3             : !> \details \copydetails mo_multi_param_reg
       4             : 
       5             : !> \brief Multiscale parameter regionalization (MPR).
       6             : !> \details This module provides the routines for multiscale parameter regionalization (MPR).
       7             : !> \authors Stephan Thober, Rohini Kumar
       8             : !> \date Dec 2012
       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_mpr
      12             : MODULE mo_multi_param_reg
      13             : 
      14             :   use mo_kind, only : i4, dp
      15             :   use mo_common_constants, only : nodata_dp, nodata_i4
      16             :   use mo_message, only : message, error_message
      17             : 
      18             :   implicit none
      19             : 
      20             :   private
      21             : 
      22             :   PUBLIC :: mpr                     ! calculates effective regionalised parameters
      23             :   PUBLIC :: canopy_intercept_param  ! estimate effective max. canopy interception
      24             : 
      25             : contains
      26             : 
      27             :   !> \brief Regionalizing and Upscaling process parameters
      28             :   !> \details calculating process parameters at L0 scale (Regionalization), like:
      29             :   !! - Baseflow recession parameter
      30             :   !! - Soil moisture parameters
      31             :   !! - PET correction for aspect
      32             :   !!
      33             :   !! and upscale these parameters to retrieve effective parameters at scale L1.
      34             :   !! Further parameter regionalizations are done for:
      35             :   !! - snow accumulation and melting parameters
      36             :   !! - threshold parameter for runoff generation on impervious layer
      37             :   !! - karstic percolation loss
      38             :   !! - setting up the Regionalized Routing Parameters
      39             :   !!
      40             :   !> \changelog
      41             :   !! - Stephan Thober           Jan 2013
      42             :   !!   - updated calling sequence for upscaling operators
      43             :   !! - Luis Samaniego           Feb 2013
      44             :   !!   - calling sequence, initial CHECK, call mpr_runoff
      45             :   !! - Stephan Thober           Feb 2013
      46             :   !!   - added subroutine for karstic percolation loss removed L1_, L0_ in variable names
      47             :   !! - Stephan Thober           Aug 2015
      48             :   !!   - moved regionalization of routing to mRM
      49             :   !! - Rohini Kumar             Mar 2016
      50             :   !!   - changes for handling multiple soil database options
      51             :   !! - Zink M. & Demirel M.C.   Mar 2017
      52             :   !!   - Added Jarvis soil water stress function at SM process(3)
      53             :   !! - Demirel M.C. & S. Stisen Apr 2017
      54             :   !!   - Added FC dependency on root fraction coefficient at SM process(3)
      55             :   !! - Robert Schweppe          Dec 2017
      56             :   !!   - added loop over LCscenes inside MPR, renamed variables rewrite
      57             :   !! - Robert Schweppe          Jun 2018
      58             :   !!   - refactoring and reformatting
      59             :   !! - Demirel M.C. & S. Stisen Jun 2020
      60             :   !!   - Added Feddes and global FC dependency on root fraction coefficient at SM process(3)=4
      61             :   !! - Rohini Kumar             Oct 2021
      62             :   !!   - Added Neutron count module to mHM integrate into develop branch (5.11.2)
      63             :   !! - Sebastian Müller         Mar 2023
      64             :   !!   - made L1_alpha, L1_kSlowFlow, L1_kBaseFlow and L1_kPerco land cover dependent
      65             :   !> \authors Stephan Thober, Rohini Kumar
      66             :   !> \date Dec 2012
      67         621 : subroutine mpr(mask0, geoUnit0, soilId0, Asp0, gridded_LAI0, LCover0, slope_emp0, y0, Id0, upper_bound1, lower_bound1, &
      68        1035 :        left_bound1, right_bound1, n_subcells1, fSealed1, alpha1, degDayInc1, degDayMax1, degDayNoPre1, fAsp1, &
      69         621 :        HarSamCoeff1, PrieTayAlpha1, aeroResist1, surfResist1, fRoots1, kFastFlow1, kSlowFlow1, kBaseFlow1, &
      70         621 :        kPerco1, karstLoss1, soilMoistFC1, soilMoistSat1, soilMoistExp1, jarvis_thresh_c1, tempThresh1, &
      71         621 :        unsatThresh1, sealedThresh1, wiltingPoint1, maxInter1, petLAIcorFactor, &
      72         414 :        No_Count1, bulkDens1, latticeWater1, COSMICL31, &
      73         207 :        parameterset )
      74             : 
      75             :     use mo_common_variables, only : global_parameters, processMatrix
      76             :     use mo_mpr_SMhorizons, only : mpr_SMhorizons
      77             :     use mo_mpr_global_variables, only : HorizonDepth_mHM, fracSealed_CityArea, iFlag_soilDB, nSoilHorizons_mHM, &
      78             :          soilDB
      79             :     use mo_mpr_pet, only : bulksurface_resistance, pet_correctbyASP, pet_correctbyLAI, priestley_taylor_alpha
      80             :     use mo_mpr_runoff, only : mpr_runoff
      81             :     use mo_mpr_soilmoist, only : mpr_sm
      82             :     use mo_upscaling_operators, only : L0_fractionalCover_in_Lx, &
      83             :          upscale_arithmetic_mean
      84             :     use mo_mpr_neutrons,        only: mpr_neutrons
      85             :     implicit none
      86             : 
      87             :     !> mask at level 0 field
      88             :     logical, dimension(:, :), intent(in) :: mask0
      89             :     !> L0 geological units
      90             :     integer(i4), dimension(:), intent(in) :: geoUnit0
      91             :     !> soil Ids at level 0
      92             :     integer(i4), dimension(:, :), intent(in) :: soilId0
      93             :     !> [degree] Aspect at Level 0
      94             :     real(dp), dimension(:), intent(in) :: Asp0
      95             :     !> LAI grid at level 0, with dim2 = time
      96             :     real(dp), dimension(:, :), intent(in) :: gridded_LAI0
      97             :     !> land cover at level 0
      98             :     integer(i4), dimension(:, :), intent(in) :: LCOVER0
      99             :     !> Empirical quantiles of slope
     100             :     real(dp), dimension(:), intent(in) :: slope_emp0
     101             :     !> Cell ids at level 0
     102             :     integer(i4), dimension(:), intent(in) :: Id0
     103             :     !> Upper row of hi res block
     104             :     integer(i4), dimension(:), intent(in) :: upper_bound1
     105             :     !> Lower row of hi res block
     106             :     integer(i4), dimension(:), intent(in) :: lower_bound1
     107             :     !> Left column of hi res block
     108             :     integer(i4), dimension(:), intent(in) :: left_bound1
     109             :     !> Right column of hi res block
     110             :     integer(i4), dimension(:), intent(in) :: right_bound1
     111             :     !> Number of L0 cells within a L1 cell
     112             :     integer(i4), dimension(:), intent(in) :: n_subcells1
     113             :     !> y0 at level 0
     114             :     real(dp), dimension(:), intent(in) :: y0
     115             :     !> [1] fraction of sealed area
     116             :     real(dp), dimension(:, :, :), intent(inout) :: fSealed1
     117             :     !> Parameter that determines the rel. contribution to SM, upscal. Bulk den.
     118             :     real(dp), dimension(:, :, :), intent(inout) :: soilMoistExp1
     119             :     !> [1] jarvis critical value for norm SWC
     120             :     real(dp), dimension(:, :, :), intent(inout) :: jarvis_thresh_c1
     121             :     !> [10^-3 m] depth of saturated SM
     122             :     real(dp), dimension(:, :, :), intent(inout) :: soilMoistSat1
     123             :     !> [10^-3 m] field capacity
     124             :     real(dp), dimension(:, :, :), intent(inout) :: soilMoistFC1
     125             :     !> [10^-3 m] permanent wilting point
     126             :     real(dp), dimension(:, :, :), intent(inout) :: wiltingPoint1
     127             :     !> fraction of roots in soil horizon
     128             :     real(dp), dimension(:, :, :), intent(inout) :: fRoots1
     129             :     !> [degreeC] threshold temperature for snow rain
     130             :     real(dp), dimension(:, :, :), intent(inout) :: tempThresh1
     131             :     !> [mm-1 degreeC-1] Degree-day factor with no precipitation
     132             :     real(dp), dimension(:, :, :), intent(inout) :: degDayNoPre1
     133             :     !> [mm-1 degreeC-1] Maximum Degree-day factor
     134             :     real(dp), dimension(:, :, :), intent(inout) :: degDayMax1
     135             :     !> [d-1 degreeC-1]  Increase of the Degree-day factor per mm of increase in precipitation
     136             :     real(dp), dimension(:, :, :), intent(inout) :: degDayInc1
     137             :     !> [1]     PET correction for Aspect at level 1
     138             :     real(dp), dimension(:, :, :), intent(inout) :: fAsp1
     139             :     !> [1]     PET Hargreaves Samani coeff. at level 1
     140             :     real(dp), dimension(:, :, :), intent(inout) :: HarSamCoeff1
     141             :     !> [1]     PET Priestley Taylor coeff. at level 1
     142             :     real(dp), dimension(:, :, :), intent(inout) :: PrieTayAlpha1
     143             :     !> [s m-1] PET aerodynamical resitance at level 1
     144             :     real(dp), dimension(:, :, :), intent(inout) :: aeroResist1
     145             :     !> [s m-1] PET bulk surface resitance at level 1
     146             :     real(dp), dimension(:, :, :), intent(inout) :: surfResist1
     147             :     !> threshold parameter
     148             :     real(dp), dimension(:, :, :), intent(inout) :: sealedThresh1
     149             :     !> [10^-3 m] Threshhold water depth in upper reservoir (for Runoff contribution)
     150             :     real(dp), dimension(:, :, :), intent(inout) :: unsatThresh1
     151             :     !> [10^-3 m] Recession coefficient of the upper reservoir, upper outlet
     152             :     real(dp), dimension(:, :, :), intent(inout) :: kFastFlow1
     153             :     !> [10^-3 m] Recession coefficient of the upper reservoir, lower outlet
     154             :     real(dp), dimension(:, :, :), intent(inout) :: kSlowFlow1
     155             :     !> Level 1 baseflow recession
     156             :     real(dp), dimension(:, :, :), intent(inout) :: kBaseFlow1
     157             :     !> [1] Exponent for the upper reservoir
     158             :     real(dp), dimension(:, :, :), intent(inout) :: alpha1
     159             :     !> [d-1] percolation coefficient
     160             :     real(dp), dimension(:, :, :), intent(inout) :: kPerco1
     161             :     !> karstic percolation loss
     162             :     real(dp), dimension(:, :, :), intent(inout) :: karstLoss1
     163             :     !> max interception
     164             :     real(dp), dimension(:, :, :), intent(inout) :: maxInter1
     165             :     !> pet cor factor at level-1
     166             :     real(dp), dimension(:, :, :), intent(inout) :: petLAIcorFactor
     167             :     !> [-] inital neutron count
     168             :     real(dp), dimension(:, :, :), intent(inout) :: No_Count1
     169             :     !> [gcm-3] bulk density
     170             :     real(dp), dimension(:, :, :), intent(inout) :: bulkDens1
     171             :     !> [mm/mm] lattice water content
     172             :     real(dp), dimension(:, :, :), intent(inout) :: latticeWater1
     173             :     !> [-] cosmic L3 parameter
     174             :     real(dp), dimension(:, :, :), intent(inout) :: COSMICL31
     175             : 
     176             :     !> array of global parameters
     177             :     real(dp), dimension(:), intent(in), optional, target :: parameterset
     178             : 
     179             :     ! array of global parameters
     180         207 :     real(dp), dimension(:), pointer :: param
     181             : 
     182         207 :     real(dp), dimension(:, :, :), allocatable :: thetaS_till
     183             : 
     184         207 :     real(dp), dimension(:, :, :), allocatable :: thetaFC_till
     185             : 
     186         207 :     real(dp), dimension(:, :, :), allocatable :: thetaPW_till
     187             : 
     188             :     ! saturated hydraulic conductivity
     189         207 :     real(dp), dimension(:, :, :), allocatable :: Ks
     190             : 
     191             :     ! Bulk density
     192         207 :     real(dp), dimension(:, :, :), allocatable :: Db
     193         207 :     real(dp), dimension(:, :), allocatable :: thetaS
     194         207 :     real(dp), dimension(:, :), allocatable :: thetaFC
     195         207 :     real(dp), dimension(:, :), allocatable :: thetaPW
     196             : 
     197             :     ! neutron count
     198         207 :     real(dp), dimension(:,:,:), allocatable :: latWat_till
     199         207 :     real(dp), dimension(:,:,:), allocatable :: COSMIC_L3_till
     200         207 :     real(dp), dimension(:,:), allocatable   :: latWat         ! lattice water
     201         207 :     real(dp), dimension(:,:), allocatable   :: COSMIC_L3      ! COSMIC parameter L3
     202             : 
     203             : 
     204             :     ! relative variability of saturated
     205             :     ! hydraulic cound. for Horizantal flow
     206         207 :     real(dp), dimension(:), allocatable :: KsVar_H0
     207             : 
     208             :     ! relative variability of saturated
     209             :     ! hydraulic cound. for vertical flow
     210         207 :     real(dp), dimension(:), allocatable :: KsVar_V0
     211             : 
     212             :     ! soil mositure deficit from
     213             :     ! field cap. w.r.t to saturation
     214         207 :     real(dp), dimension(:), allocatable :: SMs_FC0
     215             : 
     216             :     ! L0 baseflow parameter
     217     9583982 :     real(dp), dimension(size(Id0, 1)) :: k2_0
     218             : 
     219             :     ! L1 baseflow parameter
     220         207 :     real(dp), dimension(:), allocatable :: k2_1
     221             : 
     222             :     ! L0 Aspect
     223     9584189 :     real(dp), dimension(size(Id0, 1)) :: fAsp0
     224             : 
     225             :     ! number of soil classes
     226             :     integer(i4) :: mSoil
     227             : 
     228             :     ! maximum of number of Tillage horizons
     229             :     integer(i4) :: mTill
     230             : 
     231             :     ! maximum number of horizons
     232             :     integer(i4) :: mHor
     233             : 
     234             :     ! number of Landcover classes
     235             :     integer(i4) :: mLC
     236             : 
     237             :     ! indexing of parameter vector - start
     238             :     integer(i4) :: iStart
     239             : 
     240             :     ! indexing of parameter vector - end
     241             :     integer(i4) :: iEnd
     242             : 
     243             :     ! 2nd indexing of parameter vector - start
     244             :     integer(i4) :: iStart2
     245             : 
     246             :     ! 2nd indexing of parameter vector - end
     247             :     integer(i4) :: iEnd2
     248             : 
     249             :     ! counter for looping over LCscenes
     250             :     integer(i4) :: iiLC
     251             : 
     252             :     ! [1]  Fraction of forest cover
     253        8022 :     real(dp), dimension(size(fSealed1, dim = 1)) :: fForest1
     254             : 
     255             :     ! [1]  Fraction of permeable cover
     256        8022 :     real(dp), dimension(size(fSealed1, dim = 1)) :: fPerm1
     257             : 
     258             : 
     259         207 :     if (present(parameterset)) then
     260         207 :        param => parameterset
     261             :     else
     262           0 :        param => global_parameters(:, 3)
     263             :     end if
     264             : 
     265             : 
     266             :     ! loop over all LCover scenes
     267         621 :     do iiLC = 1, size(LCover0, 2)
     268             : 
     269             :        ! estimate land cover fractions for dominant landcover class
     270             :        ! fSealed is intent inout, the rest only intent in
     271             :        fForest1(:) = L0_fractionalCover_in_Lx(LCover0(:, iiLC), 1, mask0, &
     272             :             upper_bound1, &
     273             :             lower_bound1, &
     274             :             left_bound1, &
     275             :             right_bound1, &
     276         414 :             n_subcells1)
     277         828 :        fSealed1(:, 1, iiLC) = L0_fractionalCover_in_Lx(LCover0(:, iiLC), 2, mask0, &
     278             :             upper_bound1, &
     279             :             lower_bound1, &
     280             :             left_bound1, &
     281             :             right_bound1, &
     282       16458 :             n_subcells1)
     283             :        fPerm1(:) = L0_fractionalCover_in_Lx(LCover0(:, iiLC), 3, mask0, &
     284             :             upper_bound1, &
     285             :             lower_bound1, &
     286             :             left_bound1, &
     287             :             right_bound1, &
     288         414 :             n_subcells1)
     289             :        !---------------------------------------------------------
     290             :        ! Update fractions of sealed area fractions
     291             :        ! based on the sealing fraction[0-1] in cities
     292             :        !---------------------------------------------------------
     293             :        ! a factor is applied to the sealed area, effectively reducing it
     294       15630 :        fSealed1(:, 1, iiLC) = fracSealed_CityArea * fSealed1(:, 1, iiLC)
     295             :        ! the forest area is kept constant, but the permeable area is increased so that the
     296             :        ! sum off all fractions equals 1 again
     297       16044 :        fPerm1(:) = 1.0_dp - fSealed1(:, 1, iiLC) - fForest1(:)
     298             : 
     299             :        ! ------------------------------------------------------------------
     300             :        ! snow parameters
     301             :        ! ------------------------------------------------------------------
     302         828 :        select case(processMatrix(2,1))
     303             :        case(1)
     304             : 
     305         414 :           iStart = processMatrix(2, 3) - processMatrix(2, 2) + 1
     306         414 :           iEnd = processMatrix(2, 3)
     307             : 
     308           0 :           call snow_acc_melt_param(param(iStart : iEnd), & ! intent(in)
     309             :                fForest1, fSealed1(:, 1, iiLC), fPerm1, & ! intent(in)
     310             :                tempThresh1(:, 1, iiLC), degDayNoPre1(:, 1, iiLC), & ! intent(out)
     311             :                degDayInc1(:, 1, iiLC), degDayMax1(:, 1, iiLC) & ! intent(out)
     312         414 :                )
     313             :        case DEFAULT
     314         414 :           call error_message('***ERROR: Process description for process "snow pack" does not exist! mo_multi_param_reg')
     315             :        end select
     316             : 
     317             :        ! ------------------------------------------------------------------
     318             :        ! Soil moisture parametrization
     319             :        ! ------------------------------------------------------------------
     320         414 :        msoil = size(soilDB%is_present, 1)
     321    19167964 :        mLC = maxval(LCover0(:, iiLC), (LCover0(:, iiLC) .ne. nodata_i4))
     322             : 
     323             :        ! depending on which kind of soil database processing is to be performed
     324         414 :        if(iFlag_soilDB .eq. 0)then
     325      611064 :           mtill = maxval(soilDB%nTillHorizons, (soilDB%nTillHorizons .ne. nodata_i4))
     326      611064 :           mHor  = maxval(soilDB%nHorizons,     (soilDB%nHorizons     .ne. nodata_i4))
     327           0 :        else if(iFlag_soilDB .eq. 1) then
     328             :           ! here for each soil type both till and non-till soil hydraulic properties are to be estimated
     329             :           ! since a given soil type can lie in any horizon (till or non-till ones)
     330             :           ! adopt it in a way that it do not break the consistency of iFlag_soilDB = 0
     331             :           ! ** NOTE: SDB_nTillHorizons and SDB_nHorizons are also assigned in
     332             :           !          this flag option (see mo_soildatabase.f90 file - read_soil_LUT).
     333             :           !          But we are not using those variables here since in this case we have not
     334             :           !          varying number of soil horizons or either tillage horizons.
     335             :           !          So assigning them with a value = 1 is more than enough.
     336           0 :           mtill = 1
     337           0 :           mHor  = 1
     338             :        end if
     339             : 
     340        2070 :        allocate(thetaS_till(msoil, mtill,  mLC))
     341        1656 :        allocate(thetaFC_till(msoil, mtill, mLC))
     342        1656 :        allocate(thetaPW_till(msoil, mtill, mLC))
     343        1656 :        allocate(thetaS(msoil,  mHor))
     344        1242 :        allocate(thetaFC(msoil, mHor))
     345        1242 :        allocate(thetaPW(msoil, mHor))
     346        2070 :        allocate(Ks(msoil, mHor, mLC))
     347        1656 :        allocate(Db(msoil, mHor, mLC))
     348             : 
     349             :        ! neutron count related ones
     350             :        ! allocate and initalize here
     351        1656 :        allocate(   latWat_till(msoil, mtill, mLC))
     352        1656 :        allocate(COSMIC_L3_till(msoil, mtill, mLC))
     353        1242 :        allocate(        latWat(msoil, mHor      ))
     354        1242 :        allocate(     COSMIC_L3(msoil, mHor      ))
     355     1835262 :        latWat_till    = 0.000001_dp
     356     1835262 :        COSMIC_L3_till = 0.000001_dp
     357     1834020 :        COSMIC_L3      = 0.000001_dp
     358     1834020 :        latWat         = 0.000001_dp
     359             : 
     360             : 
     361             : 
     362             :        ! earlier these variables were allocated with  size(soilId0,1)
     363             :        ! in which the variable "soilId0" changes according to the iFlag_soilDB
     364             :        ! so better to use other variable which is common to both soilDB (0 AND 1) flags
     365        1656 :        allocate(KsVar_H0(size(Id0, 1)))
     366         828 :        allocate(KsVar_V0(size(Id0, 1)))
     367         828 :        allocate( SMs_FC0(size(Id0, 1)))
     368             : 
     369         822 :        select case(processMatrix(3,1))
     370             :        case(1)
     371             :           ! first thirteen parameters go to this routine
     372         408 :           iStart = processMatrix(3, 3) - processMatrix(3, 2) + 1
     373         408 :           iEnd = processMatrix(3, 3) - 4
     374             : 
     375             :           ! next four parameters go here
     376             :           ! (the first three for the fRoots and the fourth one for the beta)
     377         408 :           iStart2 = processMatrix(3, 3) - 4 + 1
     378         408 :           iEnd2 = processMatrix(3, 3)
     379             : 
     380             :        case(2)
     381             :           ! first thirteen parameters go to this routine
     382           2 :           iStart = processMatrix(3, 3) - processMatrix(3, 2) + 1
     383           2 :           iEnd = processMatrix(3, 3) - 5
     384             : 
     385             :           ! next four parameters go here
     386             :           ! (the first three for the fRoots and the fourth one for the beta)
     387           2 :           iStart2 = processMatrix(3, 3) - 5 + 1
     388           2 :           iEnd2 = processMatrix(3, 3) - 1
     389             :           ! last parameter is jarvis parameter - no need to be regionalized
     390          74 :           jarvis_thresh_c1 = param(processMatrix(3, 3))
     391             :           !write(*,*) 'jarvis_thresh_c1 = ', jarvis_thresh_c1
     392             :           !write(*,*) 'iStart, iEnd, iStart2, iEnd2 = ', iStart, iEnd, iStart2, iEnd2
     393             : 
     394             :        case(3)
     395             :           ! first thirteen parameters go to this routine
     396           2 :           iStart = processMatrix(3, 3) - processMatrix(3, 2) + 1
     397           2 :           iEnd = processMatrix(3, 3) - 9
     398             : 
     399             :           ! next four parameters go here
     400             :           ! (the first three for the fRoots and the fourth one for the beta)
     401           2 :           iStart2 = processMatrix(3, 3) - 8
     402           2 :           iEnd2 = processMatrix(3, 3) - 1
     403             : 
     404             :           ! last parameter is jarvis parameter - no need to be regionalized
     405          74 :           jarvis_thresh_c1 = param(processMatrix(3, 3))
     406             : 
     407             :           !write(*,*) 'iStart, iEnd, iStart2, iEnd2 = ', iStart, iEnd, iStart2, iEnd2
     408             :           !write(*,*) 'jarvis_thresh_c1 = ', jarvis_thresh_c1
     409             : 
     410             :        case(4)
     411             :           ! first thirteen parameters go to this routine
     412           2 :           iStart = processMatrix(3, 3) - processMatrix(3, 2) + 1
     413           2 :           iEnd = processMatrix(3, 3) - 8
     414             : 
     415             :           ! next four parameters go here
     416             :           ! (the first three for the fRoots and the fourth one for the beta)
     417           2 :           iStart2 = processMatrix(3, 3) - 7
     418           2 :           iEnd2 = processMatrix(3, 3)
     419             :           !write(*,*) 'iStart, iEnd, iStart2, iEnd2 = ', iStart, iEnd, iStart2, iEnd2
     420             : 
     421             :        case DEFAULT
     422             :           call error_message('***ERROR: Process description for process "soil moisture parametrization"', &
     423         414 :                'does not exist! mo_multi_param_reg')
     424             :        end select
     425             : 
     426           0 :        call mpr_sm(param(iStart : iEnd), processMatrix, &
     427             :             soilDB%is_present, soilDB%nHorizons, soilDB%nTillHorizons, &
     428             :             soilDB%sand, soilDB%clay, soilDB%DbM, &
     429             :             Id0, soilId0, LCover0(:, iiLC), &
     430             :             thetaS_till, thetaFC_till, thetaPW_till, thetaS, &
     431         414 :             thetaFC, thetaPW, Ks, Db, KsVar_H0, KsVar_V0, SMs_FC0)
     432             : 
     433             :        ! >> neutron count related parameters
     434         414 :        if ( processMatrix(10,1) .GT. 0 ) &
     435             :             call mpr_neutrons( processMatrix(10,1), &  ! IN: processmatrix case
     436           0 :             param( processMatrix(10,3)-processMatrix(10,2)+1:processMatrix(10,3) ) , & ! IN:  global parameter set
     437             :             soilDB%is_present       , & ! IN:  flag indicating presence of soil
     438             :             soilDB%nHorizons        , & ! IN:  Number of Horizons of Soiltype
     439             :             soilDB%nTillHorizons    , & ! IN:  Number of tillage Horizons
     440             :             LCover0(:, iiLC)        , & ! IN:  land cover ids at level 0
     441             :             soilDB%clay             , & ! IN:  clay content
     442             :             soilDB%DbM              , & ! IN:  mineral Bulk density
     443             :             Db                      , & ! IN: Bulk density
     444             :             COSMIC_L3_till          , & ! OUT: COSMIC parameter L3 tillage layer
     445             :             latWat_till             , & ! OUT: COSMIC parameter Lattice Water tillage layer
     446             :             COSMIC_L3               , & ! OUT: COSMIC parameter L3
     447             :             latWat                    & ! OUT: COSMIC parameter Lattice Water
     448          12 :             )
     449             : 
     450           0 :        call mpr_SMhorizons(param(iStart2:iEnd2), processMatrix, &
     451             :             iFlag_soilDB, nSoilHorizons_mHM, HorizonDepth_mHM, &
     452             :             LCover0(:, iiLC), soilId0, &
     453             :             soilDB%nHorizons, soilDB%nTillHorizons, &
     454             :             thetaS_till, thetaFC_till, thetaPW_till, &
     455             :             thetaS, thetaFC, thetaPW, &
     456             :             soilDB%Wd, Db, soilDB%DbM, soilDB%RZdepth, &
     457             :             mask0, Id0, &
     458             :             upper_bound1, lower_bound1, left_bound1, right_bound1, n_subcells1, &
     459             :             soilMoistExp1(:, :, iiLC), soilMoistSat1(:, :, iiLC), soilMoistFC1(:, :, iiLC), &
     460             :             wiltingPoint1(:, :, iiLC), fRoots1(:, :, iiLC), &
     461             :             ! >>>>>> neutron count
     462             :             latWat_till, COSMIC_L3_till, latWat, COSMIC_L3, &
     463             :             bulkDens1(:,:,iiLC), latticeWater1(:,:,iiLC), COSMICL31(:,:,iiLC) &
     464         414 :             )
     465             : 
     466         414 :        deallocate(thetaS_till)
     467         414 :        deallocate(thetaFC_till)
     468         414 :        deallocate(thetaPW_till)
     469         414 :        deallocate(thetaS)
     470         414 :        deallocate(thetaFC)
     471         414 :        deallocate(thetaPW)
     472         414 :        deallocate(Ks)
     473         414 :        deallocate(Db)
     474             : 
     475             :        ! neutron count
     476         414 :        deallocate( latWat_till    )
     477         414 :        deallocate( COSMIC_L3_till )
     478         414 :        deallocate( latWat     )
     479         414 :        deallocate( COSMIC_L3  )
     480             : 
     481             :        ! ------------------------------------------------------------------
     482             :        ! potential evapotranspiration (PET)
     483             :        ! ------------------------------------------------------------------
     484             :        ! Penman-Monteith method is only method that is LCscene dependent
     485         414 :        if (processMatrix(5, 1) == 3) then
     486          12 :           iStart = processMatrix(5, 3) - processMatrix(5, 2) + 1
     487          12 :           iEnd = processMatrix(5, 3)
     488           0 :           call aerodynamical_resistance(gridded_LAI0, LCover0(:, iiLC), param(iStart : iEnd - 1), mask0, &
     489             :                Id0, n_subcells1, upper_bound1, lower_bound1, left_bound1, right_bound1, &
     490          12 :                aeroResist1(:, :, iiLC))
     491         402 :        else if (processMatrix(5, 1) == -1) then
     492           4 :           iStart = processMatrix(5, 3) - processMatrix(5, 2) + 1
     493           4 :           iEnd = processMatrix(5, 3)
     494             : 
     495           0 :           call pet_correctbyLAI(param(iStart : iEnd), nodata_dp, &
     496             :                LCover0(:, iiLC), gridded_LAI0, mask0, Id0, &
     497             :                upper_bound1, lower_bound1, left_bound1, &
     498           4 :                right_bound1, n_subcells1, petLAIcorFactor(:, :, iiLC))
     499             :        end if
     500             : 
     501             :        ! ------------------------------------------------------------------
     502             :        ! interflow
     503             :        ! ------------------------------------------------------------------
     504         828 :        select case(processMatrix(6, 1))
     505             :        case (1)
     506             :           !
     507         414 :           iStart = processMatrix(6, 3) - processMatrix(6, 2) + 1
     508         414 :           iEnd = processMatrix(6, 3)
     509             :           ! TODO: this subroutine should be split into each param (or at least extract kFastFlow1)
     510             :           ! because it is in the loop unnecessarily
     511             :           call mpr_runoff(LCover0(:, iiLC), mask0, SMs_FC0, slope_emp0, &
     512           0 :                KsVar_H0, param(iStart : iEnd), Id0, upper_bound1, lower_bound1, &
     513             :                left_bound1, right_bound1, n_subcells1, unsatThresh1(:, 1, 1), kFastFlow1(:, 1, iiLC), &
     514         414 :                kSlowFlow1(:, 1, iiLC), alpha1(:, 1, iiLC))
     515             :        case DEFAULT
     516         414 :           call error_message('***ERROR: Process description for process "interflow" does not exist! mo_multi_param_reg')
     517             :        END select
     518             : 
     519             :        ! ------------------------------------------------------------------
     520             :        ! percolation cofficient, karstic percolation loss
     521             :        ! ------------------------------------------------------------------
     522         828 :        select case(processMatrix(7, 1))
     523             :        case(1)
     524             : 
     525         414 :           iStart = processMatrix(7, 3) - processMatrix(7, 2) + 1
     526         414 :           iEnd = processMatrix(7, 3)
     527             :           call karstic_layer(& ! In
     528           0 :                param(iStart : iEnd), & ! In
     529             :                geoUnit0, mask0, & ! In
     530             :                SMs_FC0, KsVar_V0, Id0, & ! In
     531             :                n_subcells1, upper_bound1, lower_bound1, left_bound1, right_bound1, & ! In
     532             :                karstLoss1(:, 1, 1), kPerco1(:, 1, iiLC)                            & ! Out
     533         414 :                )
     534             : 
     535             :        case DEFAULT
     536         414 :           call error_message('***ERROR: Process description for process "percolation" does not exist! mo_multi_param_reg')
     537             :        end select
     538             : 
     539         414 :        deallocate(KsVar_H0)
     540         414 :        deallocate(KsVar_V0)
     541         621 :        deallocate(SMs_FC0)
     542             : 
     543             :     end do !! >>>>>>> LAND COVER SCENE LOOP
     544             : 
     545             : 
     546             :     ! ------------------------------------------------------------------
     547             :     ! sealed area threshold for runoff generation
     548             :     ! ------------------------------------------------------------------
     549         414 :     select case(processMatrix(4, 1))
     550             :     case (1)
     551         207 :        iStart = processMatrix(4, 3) - processMatrix(4, 2) + 1
     552         207 :        iEnd = processMatrix(4, 3)
     553         207 :        call iper_thres_runoff(param(iStart : iEnd), sealedThresh1)
     554             :     case DEFAULT
     555         207 :        call error_message('***ERROR: Process description for process "runoff_generation" does not exist! mo_multi_param_reg')
     556             :     end select
     557             : 
     558             :     ! ------------------------------------------------------------------
     559             :     ! potential evapotranspiration (PET)
     560             :     ! ------------------------------------------------------------------
     561         207 :     select case(processMatrix(5, 1))
     562             :     case(-1) ! LAI correction of input PET
     563         404 :        iEnd = -9999 ! dummy statement
     564             :     case(0) ! aspect correction of input PET
     565         197 :        iStart = processMatrix(5, 3) - processMatrix(5, 2) + 1
     566         197 :        iEnd = processMatrix(5, 3)
     567         197 :        call pet_correctbyASP(Id0, y0, Asp0, param(iStart : iEnd), nodata_dp, fAsp0)
     568         197 :        fAsp1(:, 1, 1) = upscale_arithmetic_mean(n_subcells1, upper_bound1, lower_bound1, &
     569        7662 :             left_bound1, right_bound1, Id0, mask0, nodata_dp, fAsp0)
     570             :     case(1) ! Hargreaves-Samani method
     571           1 :        iStart = processMatrix(5, 3) - processMatrix(5, 2) + 1
     572           1 :        iEnd = processMatrix(5, 3)
     573           1 :        call pet_correctbyASP(Id0, y0, Asp0, param(iStart : iEnd - 1), nodata_dp, fAsp0)
     574           1 :        fAsp1(:, 1, 1) = upscale_arithmetic_mean(n_subcells1, upper_bound1, lower_bound1, &
     575          36 :             left_bound1, right_bound1, Id0, mask0, nodata_dp, fAsp0)
     576          37 :        HarSamCoeff1 = param(iEnd)
     577             :     case(2) ! Priestley-Taylor Method
     578           1 :        iStart = processMatrix(5, 3) - processMatrix(5, 2) + 1
     579           1 :        iEnd = processMatrix(5, 3)
     580           0 :        call priestley_taylor_alpha(gridded_LAI0, param(iStart : iEnd), &
     581             :             mask0, nodata_dp, Id0, n_subcells1, upper_bound1, lower_bound1, left_bound1, right_bound1, &
     582           1 :             PrieTayAlpha1(:, :, 1))
     583             :     case(3) ! Penman-Monteith method
     584             :        ! aerodynamic resistance is calculated inside LCscene loop
     585           6 :        iStart = processMatrix(5, 3) - processMatrix(5, 2) + 1
     586           6 :        iEnd = processMatrix(5, 3)
     587           0 :        call bulksurface_resistance(gridded_LAI0, param(iEnd), mask0, &
     588             :             nodata_dp, Id0, n_subcells1, upper_bound1, lower_bound1, left_bound1, right_bound1, &
     589           6 :             surfResist1(:, :, 1))
     590             :     case default
     591         207 :        call error_message('***ERROR: Process description for process "pet correction" does not exist! mo_multi_param_reg')
     592             :     end select
     593             :     ! ------------------------------------------------------------------
     594             :     ! baseflow recession parameter
     595             :     ! ------------------------------------------------------------------
     596         414 :     select case(processMatrix(9, 1))
     597             :       case(1)
     598             :         ! the number of process parameters, so the number in processMatrix(9,2) has
     599             :         ! to be equal to the size of geo_unit_list
     600         207 :         iStart = processMatrix(9, 3) - processMatrix(9, 2) + 1
     601         207 :         iEnd = processMatrix(9, 3)
     602             : 
     603         207 :         call baseflow_param(param(iStart : iEnd), geoUnit0, k2_0)
     604             : 
     605             :         ! Upscale by arithmetic mean
     606         621 :         allocate(k2_1(size(kBaseFlow1, 1)))
     607             :         k2_1 = upscale_arithmetic_mean(n_subcells1, upper_bound1, lower_bound1, &
     608         207 :             left_bound1, right_bound1, Id0, mask0, nodata_dp, k2_0)
     609             :         ! loop over all LCover scenes
     610         621 :         do iiLC = 1, size(LCover0, 2)
     611       15837 :           kBaseFlow1(:, 1, iiLC) = k2_1
     612             :         end do
     613         207 :         deallocate(k2_1)
     614             : 
     615             :         ! correction and unit conversion
     616             :         ! if percolation is ON: correct K2 such that it is at least k1
     617             :         ! since kSlowFlow1 is LCover dependent, kBaseFlow1 is too
     618       16458 :         if (processMatrix(7, 1) .gt. 0) kBaseFlow1 = merge(kSlowFlow1, kBaseFlow1, kBaseFlow1 .lt. kSlowFlow1)
     619             : 
     620             :       case DEFAULT
     621         207 :         call error_message('***ERROR: Process description for process "baseflow Recession" does not exist! mo_multi_param_reg')
     622             :     end select
     623             : 
     624             :     ! ------------------------------------------------------------------
     625             :     ! Neutron count related parameters
     626             :     ! >> only N0 parameter - others are defined above in soil parameters
     627             :     ! ------------------------------------------------------------------
     628         213 :     select case(processMatrix(10, 1))
     629             :     case(0)
     630             :        ! do nothing
     631             :     case(1)
     632             :        ! the number of process parameters, so the number in processMatrix(9,2) has
     633           6 :        iStart = processMatrix(10, 3) - processMatrix(10, 2) + 1
     634           6 :        iEnd = processMatrix(10, 3)
     635         672 :        No_Count1 = param(iStart)  ! >> 1st parameter --> N0 parameter
     636             :     case(2)
     637             :        ! the number of process parameters, so the number in processMatrix(9,2) has
     638           0 :        iStart = processMatrix(10, 3) - processMatrix(10, 2) + 1
     639           0 :        iEnd = processMatrix(10, 3)
     640           0 :        No_Count1 = param(iStart)  ! >> 1st parameter --> N0 parameter
     641             :     case DEFAULT
     642         207 :        call error_message('***ERROR: Process description for process "Neutron count" does not exist! mo_multi_param_reg')
     643             :     end select
     644             : 
     645             : 
     646             :     !-------------------------------------------------------------------
     647             :     ! call regionalization of parameters related to LAI
     648             :     ! it is now outside of mHM since LAI is now dynamic variable
     649             :     !-------------------------------------------------------------------
     650             :     call canopy_intercept_param(processMatrix, param(:), &
     651             :          gridded_LAI0, n_subcells1, upper_bound1, lower_bound1, left_bound1, right_bound1, Id0, mask0, &
     652         207 :          nodata_dp, maxInter1(:, :, 1))
     653             : 
     654         414 :   end subroutine mpr
     655             : 
     656             :   ! ----------------------------------------------------------------------------
     657             : 
     658             :   !    NAME
     659             :   !        baseflow_param
     660             : 
     661             :   !    PURPOSE
     662             :   !>       \brief baseflow recession parameter
     663             : 
     664             :   !>       \details This subroutine calculates the baseflow recession parameter
     665             :   !>       based on the geological units at the Level 0 scale. For each level 0
     666             :   !>       cell, it assigns the value specified in the parameter array param for the
     667             :   !>       geological unit in this cell.
     668             :   !>       Global parameters needed (see mhm_parameter.nml):
     669             :   !>       - param(1) = GeoParam(1,:)
     670             :   !>       - param(2) = GeoParam(2,:)
     671             :   !>       - ...
     672             : 
     673             :   !    INTENT(IN)
     674             :   !>       \param[in] "real(dp), dimension(:) :: param"       list of required parameters
     675             :   !>       \param[in] "integer(i4), dimension(:) :: geoUnit0" ids of geological units at L0
     676             : 
     677             :   !    INTENT(OUT)
     678             :   !>       \param[out] "real(dp), dimension(:) :: k2_0" - baseflow recession parameter at Level 0
     679             : 
     680             :   !    HISTORY
     681             :   !>       \authors Stephan Thober, Rohini Kumar
     682             : 
     683             :   !>       \date Dec 2012
     684             : 
     685             :   ! Modifications:
     686             :   ! Stephan Thober  Dec 2013 - changed intent(inout) to intent(out)
     687             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
     688             : 
     689         414 :   subroutine baseflow_param(param, geoUnit0, k2_0)
     690             : 
     691         207 :     use mo_mpr_global_variables, only : GeoUnitList
     692             :     !$ use omp_lib
     693             : 
     694             :     implicit none
     695             : 
     696             :     ! list of required parameters
     697             :     real(dp), dimension(:), intent(in) :: param
     698             : 
     699             :     ! ids of geological units at L0
     700             :     integer(i4), dimension(:), intent(in) :: geoUnit0
     701             : 
     702             :     ! - baseflow recession parameter at Level 0
     703             :     real(dp), dimension(:), intent(out) :: k2_0
     704             : 
     705             :     ! loop variable
     706             :     integer(i4) :: ii
     707             : 
     708             :     ! geo unit
     709             :     integer(i4), dimension(1) :: gg
     710             : 
     711             : 
     712         207 :     if (size(param) .ne. size(geoUnitList)) &
     713           0 :           call error_message(' mo_multi_param_reg: baseflow_param: size mismatch, subroutine baseflow parameters ')
     714             : 
     715     9583982 :     k2_0 = nodata_dp
     716             : 
     717             :     !$OMP PARALLEL
     718             :     !$OMP DO PRIVATE(gg) SCHEDULE(STATIC)
     719     9583982 :     do ii = 1, size(k2_0)
     720             :        ! get parameter index in geoUnitList
     721   105421525 :        gg = minloc(abs(geoUnitList - geoUnit0(ii)))
     722     9583982 :        k2_0(ii) = param(gg(1))
     723             :     end do
     724             :     !$OMP END DO
     725             :     !$OMP END PARALLEL
     726             : 
     727         207 :   end subroutine baseflow_param
     728             : 
     729             :   ! ----------------------------------------------------------------------------
     730             : 
     731             :   !    NAME
     732             :   !        snow_acc_melt_param
     733             : 
     734             :   !    PURPOSE
     735             :   !>       \brief Calculates the snow parameters.
     736             : 
     737             :   !>       \details This subroutine calculates the snow parameters
     738             :   !>       threshold temperature (TT), degree-day factor without precipitation (DD)
     739             :   !>       and maximum degree-day factor (DDmax) as well as increase of degree-day
     740             :   !>       factor per mm of increase in precipitation (IDDP).
     741             : 
     742             :   !>       Global parameters needed (see mhm_parameter.nml):
     743             :   !>       - param(1) = snowTreshholdTemperature
     744             :   !>       - param(2) = degreeDayFactor_forest
     745             :   !>       - param(3) = degreeDayFactor_impervious
     746             :   !>       - param(4) = degreeDayFactor_pervious
     747             :   !>       - param(5) = increaseDegreeDayFactorByPrecip
     748             :   !>       - param(6) = maxDegreeDayFactor_forest
     749             :   !>       - param(7) = maxDegreeDayFactor_impervious
     750             :   !>       - param(8) = maxDegreeDayFactor_pervious
     751             :   !>       INTENT(IN)
     752             : 
     753             :   !    INTENT(IN)
     754             :   !>       \param[in] "real(dp), dimension(8) :: param"    eight global parameters
     755             :   !>       \param[in] "real(dp), dimension(:) :: fForest1" [1] fraction of forest cover
     756             :   !>       \param[in] "real(dp), dimension(:) :: fIperm1"  [1] fraction of sealed area
     757             :   !>       \param[in] "real(dp), dimension(:) :: fPerm1"   [1] fraction of permeable area
     758             : 
     759             :   !    INTENT(OUT)
     760             :   !>       \param[out] "real(dp), dimension(:) :: tempThresh1"  [degreeC] threshold temperature for snow rain
     761             :   !>       \param[out] "real(dp), dimension(:) :: degDayNoPre1" [mm-1 degreeC-1] Degree-day factor with
     762             :   !>       \param[out] "real(dp), dimension(:) :: degDayInc1"   [d-1 degreeC-1]  Increase of the Degree-day
     763             :   !>       \param[out] "real(dp), dimension(:) :: degDayMax1"   [mm-1 degreeC-1] Maximum Degree-day factor
     764             : 
     765             :   !    HISTORY
     766             :   !>       \authors Stephan Thober, Rohini Kumar
     767             : 
     768             :   !>       \date Dec 2012
     769             : 
     770             :   ! Modifications:
     771             :   ! Juliane Mai    Oct 2013 - OLD parametrization --> param(1) = snowTreshholdTemperature
     772             :   !                                                --> param(2) = degreeDayFactor_forest
     773             :   !                                                --> param(3) = degreeDayFactor_impervious
     774             :   !                                                --> param(4) = degreeDayFactor_pervious
     775             :   !                                                --> param(5) = increaseDegreeDayFactorByPrecip
     776             :   !                                                --> param(6) = maxDegreeDayFactor_forest
     777             :   !                                                --> param(7) = maxDegreeDayFactor_impervious
     778             :   !                                                --> param(8) = maxDegreeDayFactor_pervious
     779             :   !                                             -------------------------------
     780             :   !                                             degreeDayFactor_impervious    = degreeDayFactor_forest + delta_1 + delta_2
     781             :   !                                             degreeDayFactor_pervious      = degreeDayFactor_forest + delta_1
     782             :   !                                             maxDegreeDayFactor_forest     = degreeDayFactor_forest + delta_3
     783             :   !                                             maxDegreeDayFactor_impervious = degreeDayFactor_impervious + delta_5
     784             :   !                                                                           = degreeDayFactor_forest + delta_1 + delta_2 + delta_5
     785             :   !                                             maxDegreeDayFactor_pervious   = degreeDayFactor_pervious + delta_4
     786             :   !                                                                           = degreeDayFactor_forest + delta_1 + delta_4
     787             :   !                                             -------------------------------
     788             :   !                                             NEW parametrization
     789             :   !                                                --> param(1) = snowTreshholdTemperature
     790             :   !                                                --> param(2) = degreeDayFactor_forest
     791             :   !                                                --> param(3) = delta_2
     792             :   !                                                --> param(4) = delta_1
     793             :   !                                                --> param(5) = increaseDegreeDayFactorByPrecip
     794             :   !                                                --> param(6) = delta_3
     795             :   !                                                --> param(7) = delta_5
     796             :   !                                                --> param(8) = delta_4
     797             :   ! Stephan Thober Dec 2013 - changed intent(inout) to intent(out)
     798             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
     799             : 
     800         828 :   subroutine snow_acc_melt_param(param, fForest1, fIperm1, fPerm1, tempThresh1, degDayNoPre1, degDayInc1, &
     801         414 :        degDayMax1)
     802             :     implicit none
     803             : 
     804             :     ! eight global parameters
     805             :     real(dp), dimension(8), intent(in) :: param
     806             : 
     807             :     ! [1] fraction of forest cover
     808             :     real(dp), dimension(:), intent(in) :: fForest1
     809             : 
     810             :     ! [1] fraction of sealed area
     811             :     real(dp), dimension(:), intent(in) :: fIperm1
     812             : 
     813             :     ! [1] fraction of permeable area
     814             :     real(dp), dimension(:), intent(in) :: fPerm1
     815             : 
     816             :     ! [degreeC] threshold temperature for snow rain
     817             :     real(dp), dimension(:), intent(out) :: tempThresh1
     818             : 
     819             :     ! [mm-1 degreeC-1] Degree-day factor with
     820             :     real(dp), dimension(:), intent(out) :: degDayNoPre1
     821             : 
     822             :     ! [mm-1 degreeC-1] Maximum Degree-day factor
     823             :     real(dp), dimension(:), intent(out) :: degDayMax1
     824             : 
     825             :     ! [d-1 degreeC-1]  Increase of the Degree-day
     826             :     real(dp), dimension(:), intent(out) :: degDayInc1
     827             : 
     828         414 :     real(dp) :: tmp_degreeDayFactor_forest, tmp_degreeDayFactor_impervious, tmp_degreeDayFactor_pervious
     829             : 
     830         414 :     real(dp) :: tmp_maxDegreeDayFactor_forest, tmp_maxDegreeDayFactor_impervious, tmp_maxDegreeDayFactor_pervious
     831             : 
     832             : 
     833         414 :     tmp_degreeDayFactor_forest = param(2)                                    ! OLD: param(2)
     834         414 :     tmp_degreeDayFactor_impervious = param(2) + param(4) + param(3)              ! OLD: param(3)
     835         414 :     tmp_degreeDayFactor_pervious = param(2) + param(4)                         ! OLD: param(4)
     836         414 :     tmp_maxDegreeDayFactor_forest = param(2) + param(6)   ! OLD: param(6)
     837         414 :     tmp_maxDegreeDayFactor_impervious = param(2) + param(4) + param(3) + param(7)   ! OLD: param(7)
     838         414 :     tmp_maxDegreeDayFactor_pervious = param(2) + param(4) + param(8)   ! OLD: param(8)
     839             : 
     840       15630 :     tempThresh1 = param(1)
     841       15630 :     degDayInc1 = param(5)
     842             : 
     843           0 :     degDayNoPre1 = (&
     844             :          tmp_degreeDayFactor_forest * fForest1 + &
     845           0 :          tmp_degreeDayFactor_impervious * fIperm1 + &
     846       16044 :          tmp_degreeDayFactor_pervious * fPerm1)
     847           0 :     degDayMax1 = (&
     848             :          tmp_maxDegreeDayFactor_forest * fForest1 + &
     849             :          tmp_maxDegreeDayFactor_impervious * fIperm1 + &
     850       16044 :          tmp_maxDegreeDayFactor_pervious * fPerm1)
     851             : 
     852         207 :   end subroutine snow_acc_melt_param
     853             : 
     854             :   ! ----------------------------------------------------------------------------
     855             : 
     856             :   !    NAME
     857             :   !        iper_thres_runoff
     858             : 
     859             :   !    PURPOSE
     860             :   !>       \brief sets the impervious layer threshold parameter for runoff generation
     861             : 
     862             :   !>       \details to be done by Kumar
     863             :   !>       ....
     864             : 
     865             :   !>       Global parameters needed (see mhm_parameter.nml):
     866             :   !>       - param(1) = imperviousStorageCapacity
     867             : 
     868             :   !    INTENT(IN)
     869             :   !>       \param[in] "real(dp), dimension(1) :: param" - given threshold parameter
     870             : 
     871             :   !    INTENT(OUT)
     872             :   !>       \param[out] "real(dp), dimension(:, :, :) :: sealedThresh1"
     873             : 
     874             :   !    HISTORY
     875             :   !>       \authors Stephan Thober, Rohini Kumar
     876             : 
     877             :   !>       \date Dec 2012
     878             : 
     879             :   ! Modifications:
     880             :   ! Stephan Thober Dec 2013 - changed intent(inout) to intent(out)
     881             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
     882             : 
     883         207 :   subroutine iper_thres_runoff(param, sealedThresh1)
     884             :     implicit none
     885             : 
     886             :     ! - given threshold parameter
     887             :     real(dp), dimension(1), intent(in) :: param
     888             : 
     889             :     real(dp), dimension(:, :, :), intent(out) :: sealedThresh1
     890             : 
     891             : 
     892        8229 :     sealedThresh1 = param(1)
     893             : 
     894         414 :   end subroutine iper_thres_runoff
     895             : 
     896             :   ! ----------------------------------------------------------------------------
     897             : 
     898             :   !    NAME
     899             :   !        karstic_layer
     900             : 
     901             :   !    PURPOSE
     902             :   !>       \brief calculates the Karstic percolation loss
     903             : 
     904             :   !>       \details This subroutine calls first the karstic_fraction upscaling
     905             :   !>       routine for determine the karstic fraction area for every Level 1
     906             :   !>       cell. Then, the karstic percolation loss is estimated given two
     907             :   !>       shape parameters by
     908             :   !>       \f[ karstLoss1 = 1 + ( fKarArea * param(1)) *( (-1)**INT(param(2),i4) ) \f]
     909             :   !>       where \f$ karstLoss1 \f$ is the karstic percolation loss and \f$ fKarArea \f$
     910             :   !>       is the fraction of karstic area at level 1
     911             :   !>       Global parameters needed (see mhm_parameter.nml):
     912             :   !>       - param(1) = rechargeCoefficient
     913             :   !>       - param(2) = rechargeFactor_karstic
     914             :   !>       - param(3) = gain_loss_GWreservoir_karstic
     915             : 
     916             :   !    INTENT(IN)
     917             :   !>       \param[in] "real(dp), dimension(3) :: param"           parameters
     918             :   !>       \param[in] "integer(i4), dimension(:) :: geoUnit0"     id of the Karstic formation
     919             :   !>       \param[in] "logical, dimension(:, :) :: mask0"         mask at level 0
     920             :   !>       \param[in] "real(dp), dimension(:) :: SMs_FC0"         [-] soil mositure deficit from field
     921             :   !>       capacity w.r.t to saturation
     922             :   !>       \param[in] "real(dp), dimension(:) :: KsVar_V0"        [-] relative variability of saturated
     923             :   !>       \param[in] "integer(i4), dimension(:) :: Id0"          Cell ids of hi res field
     924             :   !>       \param[in] "integer(i4), dimension(:) :: n_subcells1"  number of l0 cells within a l1 cell
     925             :   !>       \param[in] "integer(i4), dimension(:) :: upper_bound1" upper row of a l1 cell in l0 grid
     926             :   !>       \param[in] "integer(i4), dimension(:) :: lower_bound1" lower row of a l1 cell in l0 grid
     927             :   !>       \param[in] "integer(i4), dimension(:) :: left_bound1"  left col of a l1 cell in l0 grid
     928             :   !>       \param[in] "integer(i4), dimension(:) :: right_bound1" right col of a l1 cell in l0 grid
     929             : 
     930             :   !    INTENT(OUT)
     931             :   !>       \param[out] "real(dp), dimension(:) :: karstLoss1" [-]    Karstic percolation loss
     932             :   !>       \param[out] "real(dp), dimension(:) :: L1_Kp"      [d-1] percolation coefficient
     933             : 
     934             :   !    HISTORY
     935             :   !>       \authors Rohini Kumar, Stephan Thober
     936             : 
     937             :   !>       \date Feb 2013
     938             : 
     939             :   ! Modifications:
     940             :   ! Stephan Thober Dec 2013 - changed intent(inout) to intent(out)
     941             :   ! Stephan Thober Dec 2013 - changed intent(inout) to intent(out)
     942             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
     943             : 
     944        1242 :   subroutine karstic_layer(param, geoUnit0, mask0, SMs_FC0, KsVar_V0, Id0, n_subcells1, upper_bound1, lower_bound1, &
     945         828 :        left_bound1, right_bound1, karstLoss1, L1_Kp)
     946             : 
     947         207 :     use mo_mpr_global_variables, only : GeoUnitList, geoUnitKar
     948             :     use mo_upscaling_operators, only : L0_fractionalCover_in_Lx, upscale_arithmetic_mean
     949             :     !$ use omp_lib
     950             : 
     951             :     implicit none
     952             : 
     953             :     ! parameters
     954             :     real(dp), dimension(3), intent(in) :: param
     955             : 
     956             :     ! id of the Karstic formation
     957             :     integer(i4), dimension(:), intent(in) :: geoUnit0
     958             : 
     959             :     ! mask at level 0
     960             :     logical, dimension(:, :), intent(in) :: mask0
     961             : 
     962             :     ! [-] soil mositure deficit from field
     963             :     ! capacity w.r.t to saturation
     964             :     real(dp), dimension(:), intent(in) :: SMs_FC0
     965             : 
     966             :     ! [-] relative variability of saturated
     967             :     real(dp), dimension(:), intent(in) :: KsVar_V0
     968             : 
     969             :     ! Cell ids of hi res field
     970             :     integer(i4), dimension(:), intent(in) :: Id0
     971             : 
     972             :     ! number of l0 cells within a l1 cell
     973             :     integer(i4), dimension(:), intent(in) :: n_subcells1
     974             : 
     975             :     ! upper row of a l1 cell in l0 grid
     976             :     integer(i4), dimension(:), intent(in) :: upper_bound1
     977             : 
     978             :     ! lower row of a l1 cell in l0 grid
     979             :     integer(i4), dimension(:), intent(in) :: lower_bound1
     980             : 
     981             :     ! left col of a l1 cell in l0 grid
     982             :     integer(i4), dimension(:), intent(in) :: left_bound1
     983             : 
     984             :     ! right col of a l1 cell in l0 grid
     985             :     integer(i4), dimension(:), intent(in) :: right_bound1
     986             : 
     987             :     ! [-]    Karstic percolation loss
     988             :     real(dp), dimension(:), intent(out) :: karstLoss1
     989             : 
     990             :     ! [d-1] percolation coefficient
     991             :     real(dp), dimension(:), intent(out) :: L1_Kp
     992             : 
     993             :     ! fraction of karstic area
     994         414 :     real(dp), dimension(:), allocatable :: fKarArea
     995             : 
     996             :     ! temporal variable
     997    19168378 :     real(dp), dimension(size(SMs_FC0, 1)) :: tmp
     998             : 
     999             :     integer(i4) :: nGeoUnits
    1000             : 
    1001             :     integer(i4) :: i
    1002             : 
    1003             : 
    1004             :     ! ------------------------------------------------------------------
    1005             :     ! PERCOLATION; 1/Kp = f(Ks)
    1006             :     ! ------------------------------------------------------------------
    1007             :     ! Regionalise Kp with variability of last soil layer property
    1008             :     !$OMP PARALLEL
    1009         414 :     tmp = merge(param(1) * (1.0_dp + SMs_FC0) / (1.0_dp + KsVar_V0), &
    1010    19168378 :          nodata_dp, Id0 .ne. nodata_i4)
    1011             :     !$OMP END PARALLEL
    1012             : 
    1013             :     L1_Kp = upscale_arithmetic_mean(n_subcells1, upper_bound1, lower_bound1, &
    1014         414 :          left_bound1, right_bound1, Id0, mask0, nodata_dp, tmp)
    1015             : 
    1016             :     ! minimum constrains
    1017       15630 :     L1_Kp = merge(2.0_dp, L1_Kp, L1_Kp .lt. 2.0_dp)
    1018             : 
    1019         414 :     nGeoUnits = size(geoUnitlist, 1)
    1020             : 
    1021             :     ! 1st calculate fraction of Karstic area
    1022        1242 :     allocate(fKarArea(size(karstLoss1, 1)))
    1023       16044 :     fKarArea = 0.0_dp
    1024             : 
    1025        4554 :     do i = 1, nGeoUnits
    1026        4140 :        if(GeoUnitKar(i) .eq. 0) cycle
    1027           0 :        fKarArea(:) = L0_fractionalCover_in_Lx(geoUnit0, geoUnitlist(i), mask0, &
    1028        4554 :             upper_bound1, lower_bound1, left_bound1, right_bound1, n_subcells1)
    1029             :     end do
    1030             : 
    1031             :     ! 2nd calculate karstLoss1
    1032       15630 :     karstLoss1 = 1.0_dp - (fKarArea * param(2))
    1033             : 
    1034         414 :     deallocate(fKarArea)
    1035             : 
    1036         414 :   end subroutine karstic_layer
    1037             : 
    1038             :   ! ----------------------------------------------------------------------------
    1039             : 
    1040             :   !    NAME
    1041             :   !        canopy_intercept_param
    1042             : 
    1043             :   !    PURPOSE
    1044             :   !>       \brief estimate effective maximum interception capacity at L1
    1045             : 
    1046             :   !>       \details estimate effective maximum interception capacity at L1 for a given
    1047             :   !>       Leaf Area Index field.
    1048             :   !>       Global parameters needed (see mhm_parameter.nml):
    1049             :   !>       Process Case 1:
    1050             :   !>       - param(1) = canopyInterceptionFactor
    1051             : 
    1052             :   !    INTENT(IN)
    1053             :   !>       \param[in] "integer(i4), dimension(:, :) :: processMatrix" indicate processes
    1054             :   !>       \param[in] "real(dp), dimension(:) :: param"               array of global parameters
    1055             :   !>       \param[in] "real(dp), dimension(:, :) :: LAI0"             LAI at level-0(nCells0, time)
    1056             :   !>       \param[in] "integer(i4), dimension(:) :: n_subcells1"      Number of L0 cells within a L1 cell
    1057             :   !>       \param[in] "integer(i4), dimension(:) :: upper_bound1"     Upper row of high resolution block
    1058             :   !>       \param[in] "integer(i4), dimension(:) :: lower_bound1"     Lower row of high resolution block
    1059             :   !>       \param[in] "integer(i4), dimension(:) :: left_bound1"      Left column of high resolution block
    1060             :   !>       \param[in] "integer(i4), dimension(:) :: right_bound1"     Right column of high resolution block
    1061             :   !>       \param[in] "integer(i4), dimension(:) :: Id0"              Cell ids at level 0
    1062             :   !>       \param[in] "logical, dimension(:, :) :: mask0"             mask at level 0 field
    1063             :   !>       \param[in] "real(dp) :: nodata"                            - nodata value
    1064             : 
    1065             :   !    INTENT(OUT)
    1066             :   !>       \param[out] "real(dp), dimension(:, :) :: max_intercept1" max interception at level-1(nCells1, time)
    1067             : 
    1068             :   !    HISTORY
    1069             :   !>       \authors Rohini Kumar
    1070             : 
    1071             :   !>       \date Aug. 2013
    1072             : 
    1073             :   ! Modifications:
    1074             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
    1075             : 
    1076         621 :   subroutine canopy_intercept_param(processMatrix, param, LAI0, n_subcells1, upper_bound1, lower_bound1, left_bound1, &
    1077         621 :        right_bound1, Id0, mask0, nodata, max_intercept1)
    1078             : 
    1079         414 :     use mo_string_utils, only : num2str
    1080             :     use mo_upscaling_operators, only : upscale_arithmetic_mean
    1081             : 
    1082             :     implicit none
    1083             : 
    1084             :     ! indicate processes
    1085             :     integer(i4), dimension(:, :), intent(in) :: processMatrix
    1086             : 
    1087             :     ! array of global parameters
    1088             :     real(dp), dimension(:), intent(in) :: param
    1089             : 
    1090             :     ! LAI at level-0(nCells0, time)
    1091             :     real(dp), dimension(:, :), intent(in) :: LAI0
    1092             : 
    1093             :     ! Number of L0 cells within a L1 cell
    1094             :     integer(i4), dimension(:), intent(in) :: n_subcells1
    1095             : 
    1096             :     ! Upper row of high resolution block
    1097             :     integer(i4), dimension(:), intent(in) :: upper_bound1
    1098             : 
    1099             :     ! Lower row of high resolution block
    1100             :     integer(i4), dimension(:), intent(in) :: lower_bound1
    1101             : 
    1102             :     ! Left column of high resolution block
    1103             :     integer(i4), dimension(:), intent(in) :: left_bound1
    1104             : 
    1105             :     ! Right column of high resolution block
    1106             :     integer(i4), dimension(:), intent(in) :: right_bound1
    1107             : 
    1108             :     ! Cell ids at level 0
    1109             :     integer(i4), dimension(:), intent(in) :: Id0
    1110             : 
    1111             :     ! mask at level 0 field
    1112             :     logical, dimension(:, :), intent(in) :: mask0
    1113             : 
    1114             :     ! - nodata value
    1115             :     real(dp), intent(in) :: nodata
    1116             : 
    1117             :     ! max interception at level-1(nCells1, time)
    1118             :     real(dp), dimension(:, :), intent(out) :: max_intercept1
    1119             : 
    1120             :     integer(i4) :: iStart, iEnd, it
    1121             : 
    1122         207 :     real(dp), dimension(:), allocatable :: max_intercept0
    1123             : 
    1124         207 :     real(dp), dimension(:), allocatable :: gamma_intercept
    1125             : 
    1126             : 
    1127             :     ! ------------------------------------------------------------------
    1128             :     ! Maximum interception parameter
    1129             :     ! ------------------------------------------------------------------
    1130         207 :     select case(processMatrix(1, 1))
    1131             :     case(1)
    1132         207 :        iStart = processMatrix(1, 3) - processMatrix(1, 2) + 1
    1133         207 :        iEnd = processMatrix(1, 3)
    1134             : 
    1135             :        ! allocate space
    1136         621 :        allocate(gamma_intercept(iEnd - iStart + 1))
    1137         621 :        allocate(max_intercept0 (size(Id0, 1)))
    1138             : 
    1139             :        ! estimate max. intercept at Level-0
    1140         414 :        gamma_intercept(:) = param(iStart : iEnd)
    1141             : 
    1142        2709 :        do it = 1, size(LAI0, 2)
    1143             :           !$OMP PARALLEL
    1144   115845612 :           max_intercept0(:) = LAI0(:, it) * gamma_intercept(1)
    1145             :           !$OMP END PARALLEL
    1146             : 
    1147             :           ! Upscale by arithmetic mean
    1148             :           max_intercept1(:, it) = upscale_arithmetic_mean(n_subcells1, upper_bound1, lower_bound1, left_bound1, &
    1149        2709 :                right_bound1, Id0, mask0, nodata, max_intercept0(:))
    1150             : 
    1151             :        end do
    1152             : 
    1153         207 :        deallocate(gamma_intercept)
    1154         207 :        deallocate(max_intercept0)
    1155             :     CASE DEFAULT
    1156         207 :        call error_message('mo_multi_param_reg: This processMatrix=', num2str(processMatrix(1, 1)), ' is not implemented!')
    1157             :     end select
    1158             : 
    1159         207 :   end subroutine canopy_intercept_param
    1160             : 
    1161             : 
    1162             :   ! ----------------------------------------------------------------------------
    1163             : 
    1164             :   !    NAME
    1165             :   !        aerodynamical_resistance
    1166             : 
    1167             :   !    PURPOSE
    1168             :   !>       \brief Regionalization of aerodynamic resistance
    1169             : 
    1170             :   !>       \details estimation of aerodynamical resistance
    1171             :   !>       Global parameters needed (see mhm_parameter.nml):
    1172             :   !>       - param(1) = canopyheigth_forest
    1173             :   !>       - param(2) = canopyheigth_impervious
    1174             :   !>       - param(3) = canopyheigth_pervious
    1175             :   !>       - param(4) = displacementheight_coeff
    1176             :   !>       - param(5) = roughnesslength_momentum_coeff
    1177             :   !>       - param(6) = roughnesslength_heat_coeff
    1178             : 
    1179             :   !    INTENT(IN)
    1180             :   !>       \param[in] "real(dp), dimension(:, :) :: LAI0"         LAI at level-0
    1181             :   !>       \param[in] "integer(i4), dimension(:) :: LCover0"      land cover field
    1182             :   !>       \param[in] "real(dp), dimension(6) :: param"           input parameter
    1183             :   !>       \param[in] "logical, dimension(:, :) :: mask0"         mask at level 0
    1184             :   !>       \param[in] "integer(i4), dimension(:) :: Id0"          Cell ids of hi res field
    1185             :   !>       \param[in] "integer(i4), dimension(:) :: n_subcells1"  number of l0 cells within a l1 cell
    1186             :   !>       \param[in] "integer(i4), dimension(:) :: upper_bound1" upper row of a l1 cell in l0 grid
    1187             :   !>       \param[in] "integer(i4), dimension(:) :: lower_bound1" lower row of a l1 cell in l0 grid
    1188             :   !>       \param[in] "integer(i4), dimension(:) :: left_bound1"  left col of a l1 cell in l0 grid
    1189             :   !>       \param[in] "integer(i4), dimension(:) :: right_bound1" right col of a l1 cell in l0 grid
    1190             : 
    1191             :   !    INTENT(OUT)
    1192             :   !>       \param[out] "real(dp), dimension(:, :) :: aerodyn_resistance1" aerodynmaical resistance
    1193             : 
    1194             :   !    HISTORY
    1195             :   !>       \authors Matthias Zink
    1196             : 
    1197             :   !>       \date Apr 2013
    1198             : 
    1199             :   ! Modifications:
    1200             :   ! Matthias Zink Jun 2017 - moved from mo_multi_scale_param_reg.f90 to mo_mpr_pet.f90
    1201             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
    1202             : 
    1203          36 :   subroutine aerodynamical_resistance(LAI0, LCover0, param, mask0, Id0, n_subcells1, upper_bound1, lower_bound1, &
    1204          24 :        left_bound1, right_bound1, aerodyn_resistance1)
    1205             : 
    1206         207 :     use mo_common_constants, only : eps_dp
    1207             :     use mo_mpr_constants, only : WindMeasHeight, karman
    1208             :     use mo_upscaling_operators, only : upscale_arithmetic_mean
    1209             : 
    1210             :     implicit none
    1211             : 
    1212             :     ! LAI at level-0
    1213             :     real(dp), dimension(:, :), intent(in) :: LAI0
    1214             : 
    1215             :     ! land cover field
    1216             :     integer(i4), dimension(:), intent(in) :: LCover0
    1217             : 
    1218             :     ! input parameter
    1219             :     real(dp), dimension(6), intent(in) :: param
    1220             : 
    1221             :     ! mask at level 0
    1222             :     logical, dimension(:, :), intent(in) :: mask0
    1223             : 
    1224             :     ! Cell ids of hi res field
    1225             :     integer(i4), dimension(:), intent(in) :: Id0
    1226             : 
    1227             :     ! number of l0 cells within a l1 cell
    1228             :     integer(i4), dimension(:), intent(in) :: n_subcells1
    1229             : 
    1230             :     ! upper row of a l1 cell in l0 grid
    1231             :     integer(i4), dimension(:), intent(in) :: upper_bound1
    1232             : 
    1233             :     ! lower row of a l1 cell in l0 grid
    1234             :     integer(i4), dimension(:), intent(in) :: lower_bound1
    1235             : 
    1236             :     ! left col of a l1 cell in l0 grid
    1237             :     integer(i4), dimension(:), intent(in) :: left_bound1
    1238             : 
    1239             :     ! right col of a l1 cell in l0 grid
    1240             :     integer(i4), dimension(:), intent(in) :: right_bound1
    1241             : 
    1242             :     ! aerodynmaical resistance
    1243             :     real(dp), dimension(:, :), intent(out) :: aerodyn_resistance1
    1244             : 
    1245             :     integer(i4) :: tt
    1246             : 
    1247          12 :     real(dp), dimension(:), allocatable :: maxLAI
    1248             : 
    1249          12 :     real(dp), dimension(:), allocatable :: zm
    1250             : 
    1251          12 :     real(dp), dimension(:), allocatable :: canopy_height0
    1252             : 
    1253          12 :     real(dp), dimension(:), allocatable :: zm_zero, zh_zero, displace
    1254             : 
    1255             :     ! dim 1 = number of cells on level 0,
    1256             :     ! dim2=month of year
    1257          12 :     real(dp), dimension(:, :), allocatable :: aerodyn_resistance0
    1258             : 
    1259             : 
    1260             :     ! initialize some things
    1261      558576 :     allocate(zm                  (size(LCover0, dim = 1))) ; zm = nodata_dp
    1262      558564 :     allocate(zm_zero             (size(LCover0, dim = 1))) ; zm_zero = nodata_dp
    1263      558564 :     allocate(zh_zero             (size(LCover0, dim = 1))) ; zh_zero = nodata_dp
    1264      558564 :     allocate(displace            (size(LCover0, dim = 1))) ; displace = nodata_dp
    1265      558564 :     allocate(canopy_height0      (size(LCover0, dim = 1))) ; canopy_height0 = nodata_dp
    1266     6702672 :     allocate(aerodyn_resistance0 (size(LCover0, dim = 1), size(LAI0, 2))) ; aerodyn_resistance0 = nodata_dp
    1267      558564 :     allocate(maxLAI              (size(LCover0, dim = 1))) ; maxLAI = nodata_dp
    1268             : 
    1269             :     ! regionalization of canopy height
    1270             :     ! substitute with canopy height
    1271      558564 :     canopy_height0 = merge(param(1), canopy_height0, LCover0 == 1)  ! forest
    1272      558564 :     canopy_height0 = merge(param(2), canopy_height0, LCover0 == 2)  ! impervious
    1273             : 
    1274             :     ! old implementation used values from LUT statically for all cells (Jan-Dec, 12 values):
    1275             :     ! 7 Intensive-orchards: 2.0, 2.0,  2.0,  2.0,  3.0, 3.5,  4.0,  4.0,  4.0,  2.5,  2.0,  2.0
    1276          12 :     maxLAI = MAXVAL(LAI0, dim=2)
    1277             : 
    1278         156 :     do tt = 1, size(LAI0, 2)
    1279             : 
    1280             :        ! pervious canopy height is scaled with LAI
    1281     6702768 :        canopy_height0 = merge((param(3) * LAI0(:, tt) / maxLAI), canopy_height0, LCover0 == 3)  ! pervious
    1282             : 
    1283             :        ! estimation of the aerodynamic resistance on the lower level
    1284             :        ! see FAO Irrigation and Drainage Paper No. 56 (p. 19 ff) for more information
    1285     6702624 :        zm = WindMeasHeight
    1286             :        ! correction: if wind measurement height is below canopy height loagarithm becomes negative
    1287     6702768 :        zm = merge(canopy_height0 + zm, zm, ((abs(zm - nodata_dp) .GT. eps_dp) .AND. (zm .LT. canopy_height0)))
    1288             : 
    1289             :        ! zh       = zm
    1290     6702768 :        displace = param(4) * canopy_height0
    1291     6702768 :        zm_zero = param(5) * canopy_height0
    1292     6702768 :        zh_zero = param(6) * zm_zero
    1293             :        !
    1294             :        ! calculate aerodynamic resistance (changes monthly)
    1295     6702624 :        aerodyn_resistance0(:, tt) = log((zm - displace) / zm_zero) * log((zm - displace) / zh_zero) / (karman**2.0_dp)
    1296             :        aerodyn_resistance1(:, tt) = upscale_arithmetic_mean(n_subcells1, upper_bound1, lower_bound1, &
    1297         156 :             left_bound1, right_bound1, Id0, mask0, nodata_dp, aerodyn_resistance0(:, tt))
    1298             : 
    1299             :     end do
    1300             : 
    1301          12 :   end subroutine aerodynamical_resistance
    1302             : 
    1303             : END MODULE mo_multi_param_reg

Generated by: LCOV version 1.16