120 subroutine mpr_smhorizons(param, processMatrix, iFlag_soil, nHorizons_mHM, HorizonDepth, LCOVER0, soilID0, nHorizons, &
121 nTillHorizons, thetaS_till, thetaFC_till, thetaPW_till, thetaS, thetaFC, thetaPW, Wd, Db, &
122 DbM, RZdepth, mask0, cell_id0, upp_row_L1, low_row_L1, lef_col_L1, rig_col_L1, nL0_in_L1, &
123 L1_beta, L1_SMs, L1_FC, L1_PW, L1_fRoots, &
125 latWat_till , & ! lattice water upto tillage depth
126 COSMIC_L3_till, & ! COSMIC parameter L3 upto tillage depth
127 latWat , & ! lattice water
128 COSMIC_L3 , & ! COSMIC paramter L3
129 L1_bulkDens , & ! L bulk density
130 L1_latticeWater,& ! L1 lattice water content
133 use mo_message,
only : message, error_message
134 use mo_string_utils,
only : num2str
141 real(dp),
dimension(:),
intent(in) :: param
144 integer(i4),
dimension(:, :),
intent(in) :: processmatrix
147 integer(i4),
intent(in) :: iflag_soil
150 integer(i4),
intent(in) :: nhorizons_mhm
154 real(dp),
dimension(:),
intent(in) :: horizondepth
157 integer(i4),
dimension(:),
intent(in) :: lcover0
160 integer(i4),
dimension(:, :),
intent(in) :: soilid0
163 integer(i4),
dimension(:),
intent(in) :: nhorizons
166 integer(i4),
dimension(:),
intent(in) :: ntillhorizons
171 real(dp),
dimension(:, :, :),
intent(in) :: thetas_till
176 real(dp),
dimension(:, :, :),
intent(in) :: thetafc_till
181 real(dp),
dimension(:, :, :),
intent(in) :: thetapw_till
185 real(dp),
dimension(:, :),
intent(in) :: thetas
188 real(dp),
dimension(:, :),
intent(in) :: thetafc
192 real(dp),
dimension(:, :),
intent(in) :: thetapw
197 real(dp),
dimension(:, :, :),
intent(in) :: wd
200 real(dp),
dimension(:, :, :),
intent(in) :: db
203 real(dp),
dimension(:, :),
intent(in) :: dbm
206 real(dp),
dimension(:),
intent(in) :: rzdepth
209 logical,
dimension(:, :),
intent(in) :: mask0
212 integer(i4),
dimension(:),
intent(in) :: cell_id0
215 integer(i4),
dimension(:),
intent(in) :: upp_row_l1
218 integer(i4),
dimension(:),
intent(in) :: low_row_l1
221 integer(i4),
dimension(:),
intent(in) :: lef_col_l1
224 integer(i4),
dimension(:),
intent(in) :: rig_col_l1
227 integer(i4),
dimension(:),
intent(in) :: nl0_in_l1
232 real(dp),
dimension(:, :),
intent(inout) :: l1_beta
235 real(dp),
dimension(:, :),
intent(inout) :: l1_sms
238 real(dp),
dimension(:, :),
intent(inout) :: l1_fc
241 real(dp),
dimension(:, :),
intent(inout) :: l1_pw
244 real(dp),
dimension(:, :),
intent(inout) :: l1_froots
247 real(dp),
dimension(:,:,:),
intent(in) :: latwat_till
248 real(dp),
dimension(:,:,:),
intent(in) :: cosmic_l3_till
249 real(dp),
dimension(:,:),
intent(in) :: latwat
250 real(dp),
dimension(:,:),
intent(in) :: cosmic_l3
252 real(dp),
dimension(:,:),
intent(inout) :: l1_bulkdens
253 real(dp),
dimension(:,:),
intent(inout) :: l1_latticewater
254 real(dp),
dimension(:,:),
intent(inout) :: l1_cosmicl3
273 real(dp) :: ftotroots
276 real(dp),
dimension(size(LCOVER0, 1)) :: beta0
279 real(dp),
dimension(size(LCOVER0, 1)) :: bd0
282 real(dp),
dimension(size(LCOVER0, 1)) :: sms0
285 real(dp),
dimension(size(LCOVER0, 1)) :: fc0
288 real(dp),
dimension(size(LCOVER0, 1)) :: pw0
291 real(dp),
dimension(size(LCOVER0,1)) :: lw0
292 real(dp),
dimension(size(LCOVER0,1)) :: l30
296 real(dp),
dimension(size(LCOVER0, 1)) :: froots0
298 real(dp) :: tmp_rootfractioncoefficient_forest
300 real(dp) :: tmp_rootfractioncoefficient_impervious
302 real(dp) :: tmp_rootfractioncoefficient_pervious
306 real(dp) :: tmp_rootfractioncoefficient_perviousfc
310 real(dp) :: tmp_rootfractioncoefficient_sand
314 real(dp) :: tmp_rootfractioncoefficient_clay
316 real(dp) :: fcmin_glob
320 real(dp) :: fcmax_glob
324 integer(i4) :: min_nth
327 min_nth = minval(ntillhorizons(:))
328 tmp_rootfractioncoefficient_forest = param(1)
329 tmp_rootfractioncoefficient_impervious = param(2)
332 select case (processmatrix(3, 1))
335 tmp_rootfractioncoefficient_pervious = param(1) - param(3)
341 tmp_rootfractioncoefficient_pervious = param(3)
343 tmp_rootfractioncoefficient_sand = param(6) - param(5)
345 tmp_rootfractioncoefficient_clay = param(6)
347 fcmax_glob=param(7)+param(8)
359 SELECT CASE(iflag_soil)
362 do h = 1, nhorizons_mhm
369 tmp_rootfractioncoefficient_perviousfc =
nodata_dp
379 dpth_t = horizondepth(h)
381 if( (h .gt. 1) .and. (h .lt. nhorizons_mhm) )
then
382 dpth_f = horizondepth(h-1)
383 dpth_t = horizondepth(h)
388 cellloop0 :
do k = 1,
size(lcover0, 1)
392 bd0(k) = sum(db(s, : ntillhorizons(s), l) * wd(s, h, 1 : ntillhorizons(s)), &
393 wd(s, h, 1 : ntillhorizons(s)) > 0.0_dp) &
394 + sum(dbm(s, ntillhorizons(s) + 1 : nhorizons(s)) &
395 * wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)), &
396 wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)) >= 0.0_dp)
398 sms0(k) = sum(thetas_till(s, : ntillhorizons(s), l) &
399 * wd(s, h, 1 : ntillhorizons(s)), &
400 wd(s, h, 1 : ntillhorizons(s)) > 0.0_dp) &
401 + sum(thetas(s, ntillhorizons(s) + 1 - min_nth : nhorizons(s) - min_nth) &
402 * wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)), &
403 wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)) > 0.0_dp)
405 fc0(k) = sum(thetafc_till(s, : ntillhorizons(s), l) &
406 * wd(s, h, 1 : ntillhorizons(s)), &
407 wd(s, h, 1 : ntillhorizons(s)) > 0.0_dp) &
408 + sum(thetafc(s, ntillhorizons(s) + 1 - min_nth : nhorizons(s) - min_nth) &
409 * wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)), &
410 wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)) > 0.0_dp)
412 pw0(k) = sum(thetapw_till(s, : ntillhorizons(s), l) &
413 * wd(s, h, 1 : ntillhorizons(s)), &
414 wd(s, h, 1 : ntillhorizons(s)) > 0.0_dp) &
415 + sum(thetapw(s, ntillhorizons(s) + 1 - min_nth : nhorizons(s) - min_nth) &
416 * wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)), &
417 wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)) > 0.0_dp)
420 lw0(k) = sum( latwat_till(s, : ntillhorizons(s), l) &
421 * wd(s, h, 1 : ntillhorizons(s) ), &
422 wd(s, h, 1 : ntillhorizons(s)) > 0.0_dp ) &
423 + sum( latwat(s,ntillhorizons(s) + 1 - min_nth : nhorizons(s) - min_nth) &
424 * wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)), &
425 wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)) > 0.0_dp )
427 l30(k) = sum( cosmic_l3_till(s, : ntillhorizons(s), l) &
428 * wd(s, h, 1 : ntillhorizons(s) ), &
429 wd(s, h, 1 : ntillhorizons(s)) > 0.0_dp ) &
430 + sum( cosmic_l3(s,ntillhorizons(s) + 1 - min_nth : nhorizons(s) - min_nth) &
431 * wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)), &
432 wd(s, h, ntillhorizons(s) + 1 : nhorizons(s)) > 0.0_dp )
437 if(h .eq. nhorizons_mhm)
then
438 dpth_f = horizondepth(nhorizons_mhm - 1)
442 sms0(k) = sms0(k) * (dpth_t - dpth_f)
443 fc0(k) = fc0(k) * (dpth_t - dpth_f)
444 pw0(k) = pw0(k) * (dpth_t - dpth_f)
445 lw0(k) = lw0(k) * (dpth_t - dpth_f)
453 celllloop0 :
do k = 1,
size(lcover0, 1)
493 froots0(k) = (1.0_dp - tmp_rootfractioncoefficient_forest**(dpth_t * 0.1_dp)) &
494 - (1.0_dp - tmp_rootfractioncoefficient_forest**(dpth_f * 0.1_dp))
497 froots0(k) = (1.0_dp - tmp_rootfractioncoefficient_impervious**(dpth_t * 0.1_dp)) &
498 - (1.0_dp - tmp_rootfractioncoefficient_impervious**(dpth_f * 0.1_dp))
501 select case (processmatrix(3, 1))
504 froots0(k) = (1.0_dp - tmp_rootfractioncoefficient_pervious**(dpth_t * 0.1_dp)) &
505 - (1.0_dp - tmp_rootfractioncoefficient_pervious**(dpth_f * 0.1_dp))
513 fcnorm = (((fc0(k) / (dpth_t - dpth_f)) - fcmin_glob) / (fcmax_glob - fcmin_glob))
515 if(fcnorm .lt. 0.0_dp)
then
518 else if(fcnorm .gt. 1.0_dp)
then
523 tmp_rootfractioncoefficient_perviousfc = (fcnorm * tmp_rootfractioncoefficient_clay) &
524 + ((1 - fcnorm) * tmp_rootfractioncoefficient_sand)
526 froots0(k) = (1.0_dp - tmp_rootfractioncoefficient_perviousfc**(dpth_t * 0.1_dp)) &
527 - (1.0_dp - tmp_rootfractioncoefficient_perviousfc**(dpth_f * 0.1_dp))
531 if((froots0(k) .lt. 0.0_dp) .OR. (froots0(k) .gt. 1.0_dp))
then
533 call message(
'***ERROR: Fraction of roots out of range [0,1]. Cell', &
534 num2str(k),
' has value ', num2str(froots0(k)))
543 beta0 = bd0 * param(4)
549 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, sms0)
551 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, beta0)
553 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, pw0)
555 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, fc0)
557 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, froots0)
561 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, bd0 )
563 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, lw0 )
565 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, l30 )
572 do h = 1, nhorizons_mhm
578 tmp_rootfractioncoefficient_perviousfc =
nodata_dp
587 dpth_t = horizondepth(h)
590 dpth_f = horizondepth(h - 1)
591 dpth_t = horizondepth(h)
596 cellloop1 :
do k = 1,
size(lcover0, 1)
599 if (h .le. ntillhorizons(1))
then
601 sms0(k)= thetas_till(s, 1, l) * (dpth_t - dpth_f)
602 fc0(k) = thetafc_till(s, 1, l) * (dpth_t - dpth_f)
603 pw0(k) = thetapw_till(s, 1, l) * (dpth_t - dpth_f)
604 lw0(k) = latwat_till(s, 1, l) * (dpth_t - dpth_f)
607 sms0(k)= thetas(s, 1) * (dpth_t - dpth_f)
608 fc0(k) = thetafc(s, 1) * (dpth_t - dpth_f)
609 pw0(k) = thetapw(s, 1) * (dpth_t - dpth_f)
610 lw0(k) = latwat(s, 1) * (dpth_t - dpth_f)
620 celllloop1 :
do k = 1,
size(lcover0, 1)
631 froots0(k) = (1.0_dp - tmp_rootfractioncoefficient_forest**(dpth_t * 0.1_dp)) &
632 - (1.0_dp - tmp_rootfractioncoefficient_forest**(dpth_f * 0.1_dp))
635 froots0(k) = (1.0_dp - tmp_rootfractioncoefficient_impervious**(dpth_t * 0.1_dp)) &
636 - (1.0_dp - tmp_rootfractioncoefficient_impervious**(dpth_f * 0.1_dp))
639 select case (processmatrix(3, 1))
642 froots0(k) = (1.0_dp - tmp_rootfractioncoefficient_pervious**(dpth_t * 0.1_dp)) &
643 - (1.0_dp - tmp_rootfractioncoefficient_pervious**(dpth_f * 0.1_dp))
650 fcnorm = (((fc0(k) / (dpth_t - dpth_f)) - fcmin_glob) / (fcmax_glob - fcmin_glob))
652 if(fcnorm .lt. 0.0_dp)
then
655 else if(fcnorm .gt. 1.0_dp)
then
660 tmp_rootfractioncoefficient_perviousfc = (fcnorm * tmp_rootfractioncoefficient_clay) &
661 + ((1 - fcnorm) * tmp_rootfractioncoefficient_sand)
664 froots0(k) = (1.0_dp - tmp_rootfractioncoefficient_perviousfc**(dpth_t * 0.1_dp)) &
665 - (1.0_dp - tmp_rootfractioncoefficient_perviousfc**(dpth_f * 0.1_dp))
669 if((froots0(k) .lt. 0.0_dp) .OR. (froots0(k) .gt. 1.0_dp))
then
671 call message(
'***ERROR: Fraction of roots out of range [0,1]. Cell', &
672 num2str(k),
' has value ', num2str(froots0(k)))
682 beta0 = bd0 * param(4)
686 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, sms0)
688 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, beta0)
690 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, pw0)
692 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, fc0)
694 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, froots0)
698 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, bd0 )
700 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, lw0 )
702 lef_col_l1, rig_col_l1, cell_id0, mask0,
nodata_dp, l30 )
707 call error_message(
'***ERROR: iFlag_soilDB option given does not exist. Only 0 and 1 is taken at the moment.')
720 l1_fc = merge(l1_sms - 0.01_dp * l1_sms, l1_fc, l1_fc .gt. l1_sms)
721 l1_pw = merge(l1_fc - 0.01_dp * l1_fc, l1_pw, l1_pw .gt. l1_fc )
723 l1_sms = merge(0.0001_dp, l1_sms, l1_sms .lt. 0.0_dp)
724 l1_fc = merge(0.0001_dp, l1_fc, l1_fc .lt. 0.0_dp)
725 l1_pw = merge(0.0001_dp, l1_pw, l1_pw .lt. 0.0_dp)
728 do k = 1,
size(l1_froots, 1)
729 ftotroots = sum(l1_froots(k, :), l1_froots(k, :) .gt. 0.0_dp)
731 if (ftotroots .gt. 0.0_dp)
then
732 l1_froots(k, :) = l1_froots(k, :) / ftotroots
734 l1_froots(k, :) = 0.0_dp