--- trunk/Sources/phylmd/CV30_routines/cv30_unsat.f 2016/05/12 13:22:19 193 +++ trunk/Sources/phylmd/CV30_routines/cv30_unsat.f 2016/05/24 12:25:29 197 @@ -5,49 +5,57 @@ contains SUBROUTINE cv30_unsat(icb, inb, t, q, qs, gz, u, v, p, ph, th, tv, lv, cpn, & - ep, sigp, clw, m, ment, elij, delt, plcl, mp, qp, up, vp, wt, water, & - evap, b) + ep, clw, m, ment, elij, delt, plcl, mp, qp, up, vp, wt, water, evap, b) + + ! Unsaturated (precipitating) downdrafts use cv30_param_m, only: nl, sigd use cv_thermo_m, only: cpd, ginv, grav - USE dimphy, ONLY: klon, klev integer, intent(in):: icb(:) ! (ncum) + ! {2 <= icb <= nl - 3} integer, intent(in):: inb(:) ! (ncum) ! first model level above the level of neutral buoyancy of the ! parcel (1 <= inb <= nl - 1) - real, intent(in):: t(:, :), q(:, :), qs(:, :) ! (klon, klev) + real, intent(in):: t(:, :), q(:, :), qs(:, :) ! (ncum, nl) real, intent(in):: gz(:, :) ! (klon, klev) real, intent(in):: u(:, :), v(:, :) ! (klon, klev) - real, intent(in):: p(klon, klev), ph(klon, klev + 1) - real, intent(in):: th(klon, klev) - real, intent(in):: tv(klon, klev) - real, intent(in):: lv(klon, klev) - real, intent(in):: cpn(klon, klev) - real, intent(in):: ep(:, :), sigp(:, :), clw(:, :) ! (ncum, klev) + real, intent(in):: p(:, :) ! (klon, klev) pressure at full level, in hPa + real, intent(in):: ph(:, :) ! (ncum, klev + 1) + real, intent(in):: th(:, :) ! (ncum, nl - 1) + real, intent(in):: tv(:, :) ! (klon, klev) + real, intent(in):: lv(:, :) ! (klon, klev) + real, intent(in):: cpn(:, :) ! (klon, klev) + real, intent(in):: ep(:, :) ! (ncum, klev) + real, intent(in):: clw(:, :) ! (ncum, klev) real, intent(in):: m(:, :) ! (ncum, klev) real, intent(in):: ment(:, :, :) ! (ncum, klev, klev) real, intent(in):: elij(:, :, :) ! (ncum, klev, klev) real, intent(in):: delt - real, intent(in):: plcl(klon) + real, intent(in):: plcl(:) ! (ncum) - ! outputs: - real, intent(out):: mp(klon, klev) + real, intent(out):: mp(:, :) ! (klon, klev) real, intent(out):: qp(:, :), up(:, :), vp(:, :) ! (ncum, nl) - real wt(klon, klev), water(klon, klev), evap(klon, klev) + real, intent(out):: wt(:, :) ! (ncum, nl) + real, intent(out):: water(:, :), evap(:, :) ! (ncum, nl) real, intent(out):: b(:, :) ! (ncum, nl - 1) ! Local: + + real, parameter:: sigp = 0.15 + ! fraction of precipitation falling outside of cloud, \sig_s in + ! Emanuel (1991 928) + integer ncum - integer i, j, il, imax + integer i, il, imax real tinv, delti - real awat, afac, afac1, afac2, bfac - real pr1, pr2, sigt, b6, c6, revap, tevap, delth + real afac, afac1, afac2, bfac + real pr1, sigt, b6, c6, revap, tevap, delth real amfac, amp2, xf, tf, fac2, ur, sru, fac, d, af, bf real ampmax - real lvcp(klon, klev) + real lvcp(size(icb), nl) ! (ncum, nl) real wdtrain(size(icb)) ! (ncum) logical lwork(size(icb)) ! (ncum) @@ -86,29 +94,15 @@ ! and condensed water flux ! Calculate detrained precipitation - - do il = 1, ncum - if (i <= inb(il) .and. lwork(il)) then - wdtrain(il) = grav * ep(il, i) * m(il, i) * clw(il, i) - endif - enddo - - if (i > 1) then - do j = 1, i - 1 - do il = 1, ncum - if (i <= inb(il) .and. lwork(il)) then - awat = elij(il, j, i) - (1. - ep(il, i)) * clw(il, i) - awat = max(awat, 0.) - wdtrain(il) = wdtrain(il) + grav * awat * ment(il, j, i) - endif - enddo - end do - endif + forall (il = 1:ncum, inb(il) >= i .and. lwork(il)) wdtrain(il) = grav & + * (ep(il, i) * m(il, i) * clw(il, i) & + + sum(max(elij(il, :i - 1, i) - (1. - ep(il, i)) * clw(il, i), 0.) & + * ment(il, :i - 1, i))) ! Find rain water and evaporation using provisional ! estimates of qp(i) and qp(i - 1) - do il = 1, ncum + loop_horizontal: do il = 1, ncum if (i <= inb(il) .and. lwork(il)) then wt(il, i) = 45. @@ -142,22 +136,25 @@ afac = max(afac, 0.) bfac = 1. / (sigd * wt(il, i)) - ! Prise en compte de la variation progressive de sigt dans - ! les couches icb et icb - 1: - ! pour plcl < ph(i + 1), pr1 = 0 et pr2 = 1 - ! pour plcl > ph(i), pr1 = 1 et pr2 = 0 - ! pour ph(i + 1) < plcl < ph(i), pr1 est la proportion \`a cheval - ! sur le nuage, et pr2 est la proportion sous la base du - ! nuage. - pr1 = (plcl(il) - ph(il, i + 1)) / (ph(il, i) - ph(il, i + 1)) - pr1 = max(0., min(1., pr1)) - pr2 = (ph(il, i) - plcl(il)) / (ph(il, i) - ph(il, i + 1)) - pr2 = max(0., min(1., pr2)) - sigt = sigp(il, i) * pr1 + pr2 + if (i <= icb(il)) then + ! Prise en compte de la variation progressive de sigt dans + ! les couches icb et icb - 1 : + ! pour plcl <= ph(i + 1), pr1 = 0 + ! pour plcl >= ph(i), pr1 = 1 + ! pour ph(i + 1) < plcl < ph(i), pr1 est la proportion + ! \`a cheval sur le nuage. + pr1 = max(0., min(1., & + (plcl(il) - ph(il, i + 1)) / (ph(il, i) - ph(il, i + 1)))) + sigt = sigp * pr1 + 1. - pr1 + else + ! {i >= icb(il) + 1} + sigt = sigp + end if b6 = bfac * 50. * sigd * (ph(il, i) - ph(il, i + 1)) * sigt * afac c6 = water(il, i + 1) + bfac * wdtrain(il) - 50. * sigd * bfac & * (ph(il, i) - ph(il, i + 1)) * evap(il, i + 1) + if (c6 > 0.) then revap = 0.5 * (- b6 + sqrt(b6 * b6 + 4. * c6)) evap(il, i) = sigt * afac * revap @@ -270,7 +267,7 @@ qp(il, i) = max(qp(il, i), 0.) endif endif - end do + end do loop_horizontal end DO downdraft_loop end SUBROUTINE cv30_unsat