31 public :: atmos_phy_mp_saturation_adjustment
36 interface atmos_phy_mp_saturation_adjustment
38 end interface atmos_phy_mp_saturation_adjustment
61 KA, KS, KE, IA, IS, IE, JA, JS, JE, QLA, QIA, &
75 atmos_hydrometeor_lhv, &
76 atmos_hydrometeor_lhs, &
84 integer,
intent(in) ::
ka,
ks,
ke
85 integer,
intent(in) ::
ia,
is,
ie
86 integer,
intent(in) ::
ja,
js,
je
87 integer,
intent(in) :: qla, qia
89 real(
rp),
intent(in) :: limit_negative
91 real(
rp),
intent(inout) :: dens (
ka,
ia,
ja)
92 real(
rp),
intent(inout) :: temp (
ka,
ia,
ja)
93 real(
rp),
intent(inout) :: cvtot(
ka,
ia,
ja)
94 real(
rp),
intent(inout) :: cptot(
ka,
ia,
ja)
95 real(
rp),
intent(inout) :: qv (
ka,
ia,
ja)
96 real(
rp),
intent(inout) :: qtrc (
ka,
ia,
ja,qla+qia)
98 real(
rp),
intent(out),
optional :: rhoh (
ka,
ia,
ja)
99 real(
rp),
intent(out),
optional :: dens_diff(
ka,
ia,
ja)
100 real(
rp),
intent(out),
optional :: engi_diff(
ka,
ia,
ja)
105 real(
rp) :: eng0 (
ka)
106 real(
rp) :: dens0(
ka)
107 real(
rp) :: diffq(
ka)
108 real(
rp) :: diffq_min
115 integer ::
k, i, j, iq
120 rhoh_out =
present( rhoh )
121 dens_out =
present( dens_diff )
122 engi_out =
present( engi_diff )
144 eng(
k) = cvtot(
k,i,j) * temp(
k,i,j)
154 call atmos_hydrometeor_lhv(
ka,
ks,
ke, temp(:,i,j), lhv(:) )
158 work = - min( qtrc(
k,i,j,iq), 0.0_rp )
159 if ( work > 0.0_rp )
then
160 eng(
k) = eng(
k) + work * lhv(
k)
161 diffq(
k) = diffq(
k) - work
165 qtrc(
k,i,j,iq) = 0.0_rp
172 call atmos_hydrometeor_lhs(
ka,
ks,
ke, temp(:,i,j), lhs(:) )
174 do iq = qla+1, qla+qia
176 work = - min( qtrc(
k,i,j,iq), 0.0_rp )
177 if ( work > 0.0_rp )
then
178 eng(
k) = eng(
k) + work * lhs(
k)
179 diffq(
k) = diffq(
k) - work
183 qtrc(
k,i,j,iq) = 0.0_rp
190 if ( abs(limit_negative) > 0.0_rp )
then
193 if ( diffq(
k) < - abs(limit_negative) )
then
194 diffq_min = min( diffq_min, diffq(
k) )
196 log_error(
"ATMOS_PHY_MP_negative_fixer",*)
'large negative is found'
197 log_error_cont(*)
'value = ', diffq(
k),
' at (',
k,
',', i,
',', j,
')'
204 if ( diffq(
k) < 0.0_rp )
then
206 qv(
k,i,j) = qv(
k,i,j) + diffq(
k)
212 rhoh(
k,i,j) = ( eng(
k) - eng0(
k) ) * dens(
k,i,j)
219 dens0(
k) = dens(
k,i,j)
224 eng0(
k) = eng(
k) * dens(
k,i,j)
230 work = - min( qv(
k,i,j), 0.0_rp )
231 if ( work > 0.0_rp )
then
233 dens(
k,i,j) = dens(
k,i,j) * ( 1.0_rp + work )
234 cvtot(
k,i,j) = ( cvtot(
k,i,j) + work *
cv_vapor ) / ( 1.0_rp + work )
235 cptot(
k,i,j) = ( cptot(
k,i,j) + work *
cp_vapor ) / ( 1.0_rp + work )
236 eng(
k) = ( eng(
k) + work *
cv_vapor * temp(
k,i,j) ) / ( 1.0_rp + work )
242 temp(
k,i,j) = eng(
k) / cvtot(
k,i,j)
247 dens_diff(
k,i,j) = dens(
k,i,j) - dens0(
k)
252 engi_diff(
k,i,j) = eng(
k) * dens(
k,i,j) - eng0(
k)
261 if ( abs(limit_negative) > 0.0_rp &
262 .AND. abs(limit_negative) < abs(diffq_min) )
then
263 log_error_cont(*)
'maximum negative hydrometeor ', diffq_min,
' < ', - abs(limit_negative)
276 KA, KS, KE, IA, IS, IE, JA, JS, JE, &
295 atmos_saturation_moist_conversion_dens_all, &
296 atmos_saturation_moist_conversion_dens_liq
299 integer,
intent(in) :: KA, KS, KE
300 integer,
intent(in) :: IA, IS, IE
301 integer,
intent(in) :: JA, JS, JE
303 real(RP),
intent(in) :: DENS(KA,IA,JA)
304 logical ,
intent(in) :: flag_liquid
306 real(RP),
intent(inout) :: TEMP (KA,IA,JA)
307 real(RP),
intent(inout) :: QV (KA,IA,JA)
308 real(RP),
intent(inout) :: QC (KA,IA,JA)
309 real(RP),
intent(inout) :: QI (KA,IA,JA)
310 real(RP),
intent(inout) :: CPtot(KA,IA,JA)
311 real(RP),
intent(inout) :: CVtot(KA,IA,JA)
313 real(RP),
intent(out) :: RHOE_d(KA,IA,JA)
322 logical :: converged, error
331 if ( flag_liquid )
then
350 emoist = temp(k,i,j) * cvtot(k,i,j) &
353 call atmos_saturation_moist_conversion_dens_liq( dens(k,i,j), emoist, &
354 temp(k,i,j), qv1, qc1, &
355 cptot(k,i,j), cvtot(k,i,j), &
358 if ( .NOT. converged )
then
361 log_error(
"ATMOS_PHY_MP_saturation_adjustment_3D",*)
'moist_conversion not converged! ', k,i,j, dens(k,i,j), emoist, temp(k,i,j), qv(k,i,j), qc(k,i,j), cptot(k,i,j), cvtot(k,i,j)
366 rhoe_d(k,i,j) = -
lhv * ( qv1 - qv(k,i,j) ) * dens(k,i,j)
378 log_error(
"ATMOS_PHY_MP_saturation_adjustment_3D",*)
'moist_conversion not converged!'
401 emoist = temp(k,i,j) * cvtot(k,i,j) &
405 call atmos_saturation_moist_conversion_dens_all( dens(k,i,j), emoist, &
406 temp(k,i,j), qv1, qc1, qi1, &
407 cptot(k,i,j), cvtot(k,i,j), &
410 if ( .NOT. converged )
then
413 log_error(
"ATMOS_PHY_MP_saturation_adjustment_3D",*)
'moist_conversion not converged! ', k,i,j, dens(k,i,j), emoist, temp(k,i,j), qv(k,i,j), qc(k,i,j), qi(k,i,j), cptot(k,i,j), cvtot(k,i,j)
418 rhoe_d(k,i,j) = ( -
lhv * ( qv1 - qv(k,i,j) ) &
419 +
lhf * ( qi1 - qi(k,i,j) ) ) * dens(k,i,j)
432 log_error(
"ATMOS_PHY_MP_saturation_adjustment_3D",*)
'moist_conversion not converged!'
446 KA, KS, KE, QHA, QLA, QIA, &
447 TEMP, vterm, FDZ, RCDZ, dt, &
449 DENS, RHOQ, CPtot, CVtot, RHOE, &
460 integer,
intent(in),
value ::
ka,
ks,
ke
461 integer,
intent(in),
value :: qha, qla, qia
463 real(
rp),
intent(in) :: temp (
ka)
464 real(
rp),
intent(in) :: vterm(
ka,qha)
465 real(
rp),
intent(in) :: fdz (
ka)
466 real(
rp),
intent(in) :: rcdz (
ka)
467 real(
rp),
intent(in) :: dt
468 integer,
intent(in) :: i, j
470 real(
rp),
intent(inout) :: dens (
ka)
471 real(
rp),
intent(inout) :: rhoq (
ka,qha)
472 real(
rp),
intent(inout) :: cptot(
ka)
473 real(
rp),
intent(inout) :: cvtot(
ka)
474 real(
rp),
intent(inout) :: rhoe (
ka)
476 real(
rp),
intent(out) :: mflx (
ka)
477 real(
rp),
intent(out) :: sflx (2)
478 real(
rp),
intent(out) :: esflx
487 #define RHOCP_pu(k) RHOCP_pu
488 #define RHOCV_pu(k) RHOCV_pu
492 real(
rp) :: rhocp_pu(
ka)
493 real(
rp) :: rhocv_pu(
ka)
516 rhocp_pu(
k) = cptot(
k) * dens(
k)
517 rhocv_pu(
k) = cvtot(
k) * dens(
k)
528 qflx0 = vterm(
ks,iq) * rhoq(
ks,iq)
530 qflx0 = 0.5_rp * ( vterm(
k,iq) + vterm(
k-1,iq) ) * rhoq(
k,iq)
535 qflx1 = 0.5_rp * ( vterm(
k+1,iq) + vterm(
k,iq) ) * rhoq(
k+1,iq)
538 qflx(
ks-1) = vterm(
ks,iq) * rhoq(
ks,iq)
540 qflx(
k) = 0.5_rp * ( vterm(
k+1,iq) + vterm(
k,iq) ) * rhoq(
k+1,iq)
546 rhoq(
k,iq) = rhoq(
k,iq) - dt * ( qflx1 - qflx0 ) * rcdz(
k)
549 rhoq(
k,iq) = rhoq(
k,iq) - dt * ( qflx(
k) - qflx(
k-1) ) * rcdz(
k)
554 if ( iq > qla + qia ) cycle
557 mflx(
k-1) = mflx(
k-1) + qflx0
560 mflx(
k) = mflx(
k) + qflx(
k)
568 if (
k ==
ks ) sflx(2) = sflx(2) + qflx0
570 sflx(2) = sflx(2) + qflx(
ks-1)
576 if (
k ==
ks ) sflx(1) = sflx(1) + qflx0
578 sflx(1) = sflx(1) + qflx(
ks-1)
584 ddens = - ( qflx1 - qflx0 ) * rcdz(
k) * dt
587 ddens = - ( qflx(
k) - qflx(
k-1) ) * rcdz(
k) * dt
589 rhocp_pu(
k) = rhocp_pu(
k) + cp * ddens
590 rhocv_pu(
k) = rhocv_pu(
k) + cv * ddens
591 dens(
k) = dens(
k) + ddens
595 eflx0 = qflx0 * temp(
k ) * cv
596 eflx1 = qflx1 * temp(
k+1) * cv
597 if (
k ==
ks ) esflx = esflx + eflx0
602 eflx(
k) = qflx(
k) * temp(
k+1) * cv
604 esflx = esflx + eflx(
ks-1)
609 rhoe(
k) = rhoe(
k) - ( ( eflx1 - eflx0 ) &
610 + qflx1 * fdz(
k) * grav &
614 rhoe(
k) = rhoe(
k) - ( ( eflx(
k) - eflx(
k-1) ) &
615 + qflx(
k) * fdz(
k) * grav &
625 cptot(
k) = rhocp_pu(
k) / dens(
k)
626 cvtot(
k) = rhocv_pu(
k) / dens(
k)
636 KA, KS, KE, QHA, QLA, QIA, &
637 TEMP, vterm, FZ, FDZ, RCDZ, dt, &
639 DENS, RHOQ, CPtot, CVtot, RHOE, &
650 integer,
intent(in),
value ::
ka,
ks,
ke
651 integer,
intent(in),
value :: qha, qla, qia
653 real(
rp),
intent(in) :: temp (
ka)
654 real(
rp),
intent(in) :: vterm(
ka,qha)
655 real(
rp),
intent(in) :: fz (
ka)
656 real(
rp),
intent(in) :: fdz (
ka)
657 real(
rp),
intent(in) :: rcdz (
ka)
658 real(
rp),
intent(in) :: dt
659 integer,
intent(in) :: i, j
661 real(
rp),
intent(inout) :: dens (
ka)
662 real(
rp),
intent(inout) :: rhoq (
ka,qha)
663 real(
rp),
intent(inout) :: cptot(
ka)
664 real(
rp),
intent(inout) :: cvtot(
ka)
665 real(
rp),
intent(inout) :: rhoe (
ka)
667 real(
rp),
intent(out) :: mflx (
ka)
668 real(
rp),
intent(out) :: sflx (2)
669 real(
rp),
intent(out) :: esflx
673 real(
rp) :: rhocp(
ka)
674 real(
rp) :: rhocv(
ka)
678 real(
rp) :: vtermh(
ka)
679 real(
rp) :: dvterm(
ka)
681 real(
rp) :: rfdz2 (
ka)
682 real(
rp) :: dist (
ka)
685 integer :: k_src (
ka)
698 rhocp(
k) = cptot(
k) * dens(
k)
699 rhocv(
k) = cvtot(
k) * dens(
k)
703 cdz(
k) = 1.0_rp / rcdz(
k)
706 rfdz2(
k) = 1.0_rp / ( cdz(
k) + cdz(
k+1) )
716 vtermh(
k) = ( cdz(
k) * vterm(
k+1,iq) + cdz(
k+1) * vterm(
k,iq) ) * rfdz2(
k)
718 vtermh(
ks-1) = vterm(
ks,iq)
721 dvterm(
k) = vtermh(
k) - vtermh(
k-1)
728 dist(
k) = - vtermh(
k) * dt &
729 + vtermh(
k) * dt**2 / 2.0_rp * ( dvterm(
k+1)+dvterm(
k) ) * rfdz2(
k) &
730 - vtermh(
k)**2 * dt**3 / 4.0_rp * ( dvterm(
k+1)*rcdz(
k+1) - dvterm(
k)*rcdz(
k) ) * rfdz2(
k)
731 dist(
k) = max( dist(
k), 0.0_rp )
733 dist(
ks-1) = - vtermh(
ks-1) * dt &
734 + vtermh(
ks-1) * dt**2 / 2.0_rp * dvterm(
ks)*rcdz(
ks)
735 dist(
ks-1) = max( dist(
ks-1), 0.0_rp )
739 do k =
ke-2,
ks-1, -1
740 dist(
k) = min( dist(
k), dist(
k+1) + cdz(
k+1) )
749 do k_dst =
ks-1,
ke-1
750 z_src = fz(k_dst) + dist(k_dst)
754 if ( z_src > fz(
k ) &
755 .AND. z_src <= fz(
k+1) )
then
760 if ( z_src > fz(
ke) ) k_src(k_dst) =
ke
776 do k_dst =
ks-1,
ke-1
777 do k = k_dst, k_src(k_dst)-1
778 flx = rhoq(
k+1,iq) * cdz(
k+1) / dt
779 qflx(k_dst) = qflx(k_dst) - flx
780 eflx(k_dst) = eflx(k_dst) - flx * temp(
k+1) * cv
781 dist(k_dst) = dist(k_dst) - cdz(
k+1)
783 if ( k_src(k_dst) <
ke )
then
785 flx = rhoq(k_src(k_dst)+1,iq) * dist(k_dst) / dt
786 qflx(k_dst) = qflx(k_dst) - flx
787 eflx(k_dst) = eflx(k_dst) -flx * temp(k_src(k_dst)+1) * cv
798 rhoq(
k,iq) = rhoq(
k,iq) - dt * ( qflx(
k) - qflx(
k-1) ) * rcdz(
k)
807 if ( iq > qla + qia ) cycle
810 mflx(
k) = mflx(
k) + qflx(
k)
814 sflx(2) = sflx(2) + qflx(
ks-1)
816 sflx(1) = sflx(1) + qflx(
ks-1)
821 ddens = - ( qflx(
k) - qflx(
k-1) ) * rcdz(
k) * dt
822 rhocp(
k) = rhocp(
k) + cp * ddens
823 rhocv(
k) = rhocv(
k) + cv * ddens
824 dens(
k) = dens(
k) + ddens
829 rhoe(
k) = rhoe(
k) - ( ( eflx(
k) - eflx(
k-1) ) &
830 + qflx(
k) * fdz(
k) * grav &
833 esflx = esflx + eflx(
ks-1)
838 cptot(
k) = rhocp(
k) / dens(
k)
839 cvtot(
k) = rhocv(
k) / dens(
k)
849 DENS, MOMZ, U, V, mflx, &
851 MOMZ_t, RHOU_t, RHOV_t )
855 integer,
intent(in),
value ::
ka,
ks,
ke
856 real(
rp),
intent(in) :: dens (
ka)
857 real(
rp),
intent(in) :: momz (
ka)
858 real(
rp),
intent(in) :: u (
ka)
859 real(
rp),
intent(in) :: v (
ka)
860 real(
rp),
intent(in) :: mflx (
ka)
861 real(
rp),
intent(in) :: rcdz (
ka)
862 real(
rp),
intent(in) :: rfdz (
ka)
863 real(
rp),
intent(out) :: momz_t(
ka)
864 real(
rp),
intent(out) :: rhou_t(
ka)
865 real(
rp),
intent(out) :: rhov_t(
ka)
868 real(
rp) :: flx0, flx1
885 flx0 = ( mflx(
k ) + mflx(
k-1) ) * momz(
k ) / ( dens(
k+1) + dens(
k ) )
886 flx1 = ( mflx(
k+1) + mflx(
k ) ) * momz(
k+1) / ( dens(
k+2) + dens(
k+1) )
887 momz_t(
k) = - ( flx1 - flx0 ) * rfdz(
k)
893 flx(
k) = ( mflx(
k) + mflx(
k-1) ) * momz(
k) / ( dens(
k+1) + dens(
k) )
896 momz_t(
k) = - ( flx(
k+1) - flx(
k) ) * rfdz(
k)
903 flx0 = mflx(
k-1) * u(
k)
905 flx1 = mflx(
k) * u(
k+1)
909 rhou_t(
k) = - ( flx1 - flx0 ) * rcdz(
k)
912 flx(
k) = mflx(
k) * u(
k+1)
915 rhou_t(
k) = - ( flx(
k) - flx(
k-1) ) * rcdz(
k)
921 flx0 = mflx(
k-1) * v(
k)
923 flx1 = mflx(
k) * v(
k+1)
925 rhov_t(
k) = - ( flx1 - flx0 ) * rcdz(
k)
930 flx(
k) = mflx(
k) * v(
k+1)
933 rhov_t(
k) = - ( flx(
k) - flx(
k-1) ) * rcdz(
k)