!> Parametrization of vertical diffusion ! ! Three different processes are modelled by the vertical diffusion scheme: ! 1) Shallow convection - A redistribution of moisture and dry static energy ! between the lowest two layers where there is conditional instability ! 2) A slow diffusion of moisture in stable conditions ! 3) A fast redistribution of dry static energy where the lapse rate is close to ! the dry adiabatic limit module vertical_diffusion use types, only : p use params implicit none private public get_vertical_diffusion_tend ! Constants for vertical diffusion and shallow convection. real(p), parameter :: trshc = 6.0 !! Relaxation time (in hours) for shallow convection real(p), parameter :: trvdi = 24.0 !! Relaxation time (in hours) for moisture diffusion real(p), parameter :: trvds = 6.0 !! Relaxation time (in hours) for super-adiabatic conditions real(p), parameter :: redshc = 0.5 !! Reduction factor of shallow convection in areas of deep !! convection real(p), parameter :: rhgrad = 0.5 !! Maximum gradient of relative humidity (d_RH/d_sigma) real(p), parameter :: segrad = 0.1 !! Minimum gradient of dry static energy (d_DSE/d_phi) contains !> Compute tendencies of momentum, energy and moisture due to vertical diffusion ! and shallow convection subroutine get_vertical_diffusion_tend(se, rh, qa, qsat, phi, icnv, utenvd, vtenvd, & ttenvd, qtenvd, fsg, dhs, sigh) use physical_constants, only : cp, alhc real(p), intent(in) :: se(ix, il, kx) !! Dry static energy real(p), intent(in) :: rh(ix, il, kx) !! Relative humidity real(p), intent(in) :: qa(ix, il, kx) !! Specific humidity [g/kg] real(p), intent(in) :: qsat(ix, il, kx) !! Saturated specific humidity [g/kg] real(p), intent(in) :: phi(ix, il, kx) !! Geopotential integer, intent(in) :: icnv(ix, il) !! Sigma-level index of deep convection real(p), intent(out) :: utenvd(ix, il, kx) !! u-wind tendency real(p), intent(out) :: vtenvd(ix, il, kx) !! v-wind tendency real(p), intent(out) :: ttenvd(ix, il, kx) !! Temperature tendency real(p), intent(out) :: qtenvd(ix, il, kx) !! Specific humidity tendency real(p), intent(in) :: dhs(kx) !! Sigma level thicknesses real(p), intent(in) :: fsg(kx) !! Full sigma levels real(p), intent(in) :: sigh(0:kx) !! Half-level sigma integer :: nl1, i, j, k, k1 real(p) :: cshc, cvdi, fshcq, fshcse, fvdiq, fvdise, drh0, fvdiq2, dmse, drh real(p) :: fluxse, fluxq, fcnv, se0 real(p), dimension(kx) :: rsig, rsig1 ! 1. Initalization ! N.B. In this routine, fluxes of dry static energy and humidity ! are scaled in such a way that: ! d_T/dt = d_F'(SE)/d_sigma, d_Q/dt = d_F'(Q)/d_sigma nl1 = kx - 1 cshc = dhs(kx) / 3600.0 cvdi = (sigh(nl1) - sigh(1)) / ((nl1 - 1) * 3600.0) fshcq = cshc / trshc fshcse = cshc / (trshc * cp) fvdiq = cvdi / trvdi fvdise = cvdi / (trvds * cp) do k = 1, nl1 rsig(k) = 1.0 / dhs(k) rsig1(k) = 1.0 / (1.0 - sigh(k)) end do rsig(kx) = 1.0 / dhs(kx) utenvd = 0.0 vtenvd = 0.0 ttenvd = 0.0 qtenvd = 0.0 ! 2. Shallow convection drh0 = rhgrad * (fsg(kx) - fsg(nl1)) fvdiq2 = fvdiq * sigh(nl1) do i = 1, ix do j = 1, il dmse = se(i, j, kx) - se(i, j, nl1) + alhc * (qa(i, j, kx) - qsat(i, j, nl1)) drh = rh(i, j, kx) - rh(i, j, nl1) fcnv = 1.0 if (dmse >= 0.0) then if (icnv(i, j) > 0) fcnv = redshc fluxse = fcnv * fshcse * dmse ttenvd(i, j, nl1) = fluxse * rsig(nl1) ttenvd(i, j, kx) = -fluxse * rsig(kx) if (drh >= 0.0) then fluxq = fcnv * fshcq * qsat(i, j, kx) * drh qtenvd(i, j, nl1) = fluxq * rsig(nl1) qtenvd(i, j, kx) = -fluxq * rsig(kx) end if else if (drh > drh0) then fluxq = fvdiq2 * qsat(i, j, nl1) * drh qtenvd(i, j, nl1) = fluxq * rsig(nl1) qtenvd(i, j, kx) = -fluxq * rsig(kx) end if end do end do ! 3. Vertical diffusion of moisture above the PBL do k = 3, kx - 2 if (sigh(k) > 0.5) then drh0 = rhgrad * (fsg(k + 1) - fsg(k)) fvdiq2 = fvdiq * sigh(k) do i = 1, ix do j = 1, il drh = rh(i, j, k + 1) - rh(i, j, k) if (drh >= drh0) then fluxq = fvdiq2 * qsat(i, j, k) * drh qtenvd(i, j, k) = qtenvd(i, j, k) + fluxq * rsig(k) qtenvd(i, j, k + 1) = qtenvd(i, j, k + 1) - fluxq * rsig(k + 1) end if end do end do end if end do ! 4. Damping of super-adiabatic lapse rate do k = 1, nl1 do i = 1, ix do j = 1, il se0 = se(i, j, k + 1) + segrad * (phi(i, j, k) - phi(i, j, k + 1)) if (se(i, j, k) < se0) then fluxse = fvdise * (se0 - se(i, j, k)) ttenvd(i, j, k) = ttenvd(i, j, k) + fluxse * rsig(k) do k1 = k + 1, kx ttenvd(i, j, k1) = ttenvd(i, j, k1) - fluxse * rsig1(k) end do end if end do end do end do end end module