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 )
141 eng(
k) = cvtot(
k,i,j) * temp(
k,i,j)
151 call atmos_hydrometeor_lhv(
ka,
ks,
ke, temp(:,i,j), lhv(:) )
155 work = - min( qtrc(
k,i,j,iq), 0.0_rp )
156 if ( work > 0.0_rp )
then
157 eng(
k) = eng(
k) + work * lhv(
k)
158 diffq(
k) = diffq(
k) - work
162 qtrc(
k,i,j,iq) = 0.0_rp
169 call atmos_hydrometeor_lhs(
ka,
ks,
ke, temp(:,i,j), lhs(:) )
171 do iq = qla+1, qla+qia
173 work = - min( qtrc(
k,i,j,iq), 0.0_rp )
174 if ( work > 0.0_rp )
then
175 eng(
k) = eng(
k) + work * lhs(
k)
176 diffq(
k) = diffq(
k) - work
180 qtrc(
k,i,j,iq) = 0.0_rp
187 if ( abs(limit_negative) > 0.0_rp )
then
189 if ( diffq(
k) < - abs(limit_negative) )
then
190 diffq_min = min( diffq_min, diffq(
k) )
191 log_error(
"ATMOS_PHY_MP_negative_fixer",*)
'large negative is found'
192 log_error_cont(*)
'value = ', diffq(
k),
' at (',
k,
',', i,
',', j,
')'
198 if ( diffq(
k) < 0.0_rp )
then
200 qv(
k,i,j) = qv(
k,i,j) + diffq(
k)
206 rhoh(
k,i,j) = ( eng(
k) - eng0(
k) ) * dens(
k,i,j)
213 dens0(
k) = dens(
k,i,j)
218 eng0(
k) = eng(
k) * dens(
k,i,j)
224 work = - min( qv(
k,i,j), 0.0_rp )
225 if ( work > 0.0_rp )
then
227 dens(
k,i,j) = dens(
k,i,j) * ( 1.0_rp + work )
228 cvtot(
k,i,j) = ( cvtot(
k,i,j) + work *
cv_vapor ) / ( 1.0_rp + work )
229 cptot(
k,i,j) = ( cptot(
k,i,j) + work *
cp_vapor ) / ( 1.0_rp + work )
230 eng(
k) = ( eng(
k) + work *
cv_vapor * temp(
k,i,j) ) / ( 1.0_rp + work )
236 temp(
k,i,j) = eng(
k) / cvtot(
k,i,j)
241 dens_diff(
k,i,j) = dens(
k,i,j) - dens0(
k)
246 engi_diff(
k,i,j) = eng(
k) * dens(
k,i,j) - eng0(
k)
254 if ( abs(limit_negative) > 0.0_rp &
255 .AND. abs(limit_negative) < abs(diffq_min) )
then
256 log_error_cont(*)
'maximum negative hydrometeor ', diffq_min,
' < ', - abs(limit_negative)
269 KA, KS, KE, IA, IS, IE, JA, JS, JE, &
288 atmos_saturation_moist_conversion_dens_all, &
289 atmos_saturation_moist_conversion_dens_liq
292 integer,
intent(in) :: KA, KS, KE
293 integer,
intent(in) :: IA, IS, IE
294 integer,
intent(in) :: JA, JS, JE
296 real(RP),
intent(in) :: DENS(KA,IA,JA)
297 logical ,
intent(in) :: flag_liquid
299 real(RP),
intent(inout) :: TEMP (KA,IA,JA)
300 real(RP),
intent(inout) :: QV (KA,IA,JA)
301 real(RP),
intent(inout) :: QC (KA,IA,JA)
302 real(RP),
intent(inout) :: QI (KA,IA,JA)
303 real(RP),
intent(inout) :: CPtot(KA,IA,JA)
304 real(RP),
intent(inout) :: CVtot(KA,IA,JA)
306 real(RP),
intent(out) :: RHOE_d(KA,IA,JA)
315 logical :: converged, error
324 if ( flag_liquid )
then
340 emoist = temp(k,i,j) * cvtot(k,i,j) &
343 call atmos_saturation_moist_conversion_dens_liq( dens(k,i,j), emoist, &
344 temp(k,i,j), qv1, qc1, &
345 cptot(k,i,j), cvtot(k,i,j), &
348 if ( .NOT. converged )
then
349 log_error(
"ATMOS_PHY_MP_saturation_adjustment_3D",*)
'moist_conversion not converged! ', k,i,j
354 rhoe_d(k,i,j) = -
lhv * ( qv1 - qv(k,i,j) ) * dens(k,i,j)
381 emoist = temp(k,i,j) * cvtot(k,i,j) &
385 call atmos_saturation_moist_conversion_dens_all( dens(k,i,j), emoist, &
386 temp(k,i,j), qv1, qc1, qi1, &
387 cptot(k,i,j), cvtot(k,i,j), &
390 if ( .NOT. converged )
then
391 log_error(
"ATMOS_PHY_MP_saturation_adjustment_3D",*)
'moist_conversion not converged! ', k,i,j
396 rhoe_d(k,i,j) = ( -
lhv * ( qv1 - qv(k,i,j) ) &
397 +
lhf * ( qi1 - qi(k,i,j) ) ) * dens(k,i,j)
418 KA, KS, KE, QHA, QLA, QIA, &
419 TEMP, vterm, FDZ, RCDZ, dt, &
421 DENS, RHOQ, CPtot, CVtot, RHOE, &
431 integer,
intent(in) ::
ka,
ks,
ke
432 integer,
intent(in) :: qha, qla, qia
434 real(
rp),
intent(in) :: temp (
ka)
435 real(
rp),
intent(in) :: vterm(
ka,qha)
436 real(
rp),
intent(in) :: fdz (
ka)
437 real(
rp),
intent(in) :: rcdz (
ka)
438 real(
dp),
intent(in) :: dt
439 integer,
intent(in) :: i, j
441 real(
rp),
intent(inout) :: dens (
ka)
442 real(
rp),
intent(inout) :: rhoq (
ka,qha)
443 real(
rp),
intent(inout) :: cptot(
ka)
444 real(
rp),
intent(inout) :: cvtot(
ka)
445 real(
rp),
intent(inout) :: rhoe (
ka)
447 real(
rp),
intent(out) :: mflx (
ka)
448 real(
rp),
intent(out) :: sflx (2)
449 real(
rp),
intent(out) :: esflx
451 real(
rp) :: vtermh(
ka)
452 real(
rp) :: qflx (
ka)
453 real(
rp) :: eflx (
ka)
454 real(
rp) :: rhocp (
ka)
455 real(
rp) :: rhocv (
ka)
472 rhocp(
k) = cptot(
k) * dens(
k)
473 rhocv(
k) = cvtot(
k) * dens(
k)
478 vtermh(
k) = 0.5_rp * ( vterm(
k+1,iq) + vterm(
k,iq) )
480 vtermh(
ks-1) = vterm(
ks,iq)
484 qflx(
k) = vtermh(
k) * rhoq(
k+1,iq)
489 rhoq(
k,iq) = rhoq(
k,iq) - dt * ( qflx(
k) - qflx(
k-1) ) * rcdz(
k)
493 if ( iq > qla + qia ) cycle
496 mflx(
k) = mflx(
k) + qflx(
k)
502 sflx(2) = sflx(2) + qflx(
ks-1)
506 sflx(1) = sflx(1) + qflx(
ks-1)
511 ddens = - ( qflx(
k) - qflx(
k-1) ) * rcdz(
k) * dt
512 rhocp(
k) = rhocp(
k) + cp * ddens
513 rhocv(
k) = rhocv(
k) + cv * ddens
514 dens(
k) = dens(
k) + ddens
519 eflx(
k) = qflx(
k) * temp(
k+1) * cv
521 esflx = esflx + eflx(
ks-1)
525 rhoe(
k) = rhoe(
k) - ( ( eflx(
k) - eflx(
k-1) ) &
526 + qflx(
k) * fdz(
k) * grav &
533 cptot(
k) = rhocp(
k) / dens(
k)
534 cvtot(
k) = rhocv(
k) / dens(
k)
543 KA, KS, KE, QHA, QLA, QIA, &
544 TEMP, vterm, FZ, FDZ, RCDZ, dt, &
546 DENS, RHOQ, CPtot, CVtot, RHOE, &
556 integer,
intent(in) ::
ka,
ks,
ke
557 integer,
intent(in) :: qha, qla, qia
559 real(
rp),
intent(in) :: temp (
ka)
560 real(
rp),
intent(in) :: vterm(
ka,qha)
561 real(
rp),
intent(in) :: fz (
ka)
562 real(
rp),
intent(in) :: fdz (
ka)
563 real(
rp),
intent(in) :: rcdz (
ka)
564 real(
dp),
intent(in) :: dt
565 integer,
intent(in) :: i, j
567 real(
rp),
intent(inout) :: dens (
ka)
568 real(
rp),
intent(inout) :: rhoq (
ka,qha)
569 real(
rp),
intent(inout) :: cptot(
ka)
570 real(
rp),
intent(inout) :: cvtot(
ka)
571 real(
rp),
intent(inout) :: rhoe (
ka)
573 real(
rp),
intent(out) :: mflx (
ka)
574 real(
rp),
intent(out) :: sflx (2)
575 real(
rp),
intent(out) :: esflx
579 real(
rp) :: rhocp(
ka)
580 real(
rp) :: rhocv(
ka)
584 real(
rp) :: vtermh(
ka)
585 real(
rp) :: dvterm(
ka)
587 real(
rp) :: rfdz2 (
ka)
588 real(
rp) :: dist (
ka)
591 integer :: k_src (
ka)
605 rhocp(
k) = cptot(
k) * dens(
k)
606 rhocv(
k) = cvtot(
k) * dens(
k)
610 cdz(
k) = 1.0_rp / rcdz(
k)
613 rfdz2(
k) = 1.0_rp / ( cdz(
k) + cdz(
k+1) )
621 vtermh(
k) = ( cdz(
k) * vterm(
k+1,iq) + cdz(
k+1) * vterm(
k,iq) ) * rfdz2(
k)
623 vtermh(
ks-1) = vterm(
ks,iq)
626 dvterm(
k) = vtermh(
k) - vtermh(
k-1)
633 dist(
k) = - vtermh(
k) * dt &
634 + vtermh(
k) * dt**2 / 2.0_rp * ( dvterm(
k+1)+dvterm(
k) ) * rfdz2(
k) &
635 - vtermh(
k)**2 * dt**3 / 4.0_rp * ( dvterm(
k+1)*rcdz(
k+1) - dvterm(
k)*rcdz(
k) ) * rfdz2(
k)
636 dist(
k) = max( dist(
k), 0.0_rp )
638 dist(
ks-1) = - vtermh(
ks-1) * dt &
639 + vtermh(
ks-1) * dt**2 / 2.0_rp * dvterm(
ks)*rcdz(
ks)
640 dist(
ks-1) = max( dist(
ks-1), 0.0_rp )
643 do k =
ke-2,
ks-1, -1
644 dist(
k) = min( dist(
k), dist(
k+1) + cdz(
k+1) )
653 do k_dst =
ks-1,
ke-1
654 z_src = fz(k_dst) + dist(k_dst)
658 if ( z_src > fz(
k ) &
659 .AND. z_src <= fz(
k+1) )
then
664 if ( z_src > fz(
ke) ) k_src(k_dst) =
ke
680 do k_dst =
ks-1,
ke-1
681 do k = k_dst, k_src(k_dst)-1
682 flx = rhoq(
k+1,iq) * cdz(
k+1) / dt
683 qflx(k_dst) = qflx(k_dst) - flx
684 eflx(k_dst) = eflx(k_dst) - flx * temp(
k+1) * cv
685 dist(k_dst) = dist(k_dst) - cdz(
k+1)
687 if ( k_src(k_dst) <
ke )
then
689 flx = rhoq(k_src(k_dst)+1,iq) * dist(k_dst) / dt
690 qflx(k_dst) = qflx(k_dst) - flx
691 eflx(k_dst) = eflx(k_dst) -flx * temp(k_src(k_dst)+1) * cv
702 rhoq(
k,iq) = rhoq(
k,iq) - dt * ( qflx(
k) - qflx(
k-1) ) * rcdz(
k)
711 if ( iq > qla + qia ) cycle
714 mflx(
k) = mflx(
k) + qflx(
k)
718 sflx(2) = sflx(2) + qflx(
ks-1)
720 sflx(1) = sflx(1) + qflx(
ks-1)
725 ddens = - ( qflx(
k) - qflx(
k-1) ) * rcdz(
k) * dt
726 rhocp(
k) = rhocp(
k) + cp * ddens
727 rhocv(
k) = rhocv(
k) + cv * ddens
728 dens(
k) = dens(
k) + ddens
733 rhoe(
k) = rhoe(
k) - ( ( eflx(
k) - eflx(
k-1) ) &
734 + qflx(
k) * fdz(
k) * grav &
742 cptot(
k) = rhocp(
k) / dens(
k)
743 cvtot(
k) = rhocv(
k) / dens(
k)
753 DENS, MOMZ, U, V, mflx, &
755 MOMZ_t, RHOU_t, RHOV_t )
758 integer,
intent(in) ::
ka,
ks,
ke
759 real(
rp),
intent(in) :: dens (
ka)
760 real(
rp),
intent(in) :: momz (
ka)
761 real(
rp),
intent(in) :: u (
ka)
762 real(
rp),
intent(in) :: v (
ka)
763 real(
rp),
intent(in) :: mflx (
ka)
764 real(
rp),
intent(in) :: rcdz (
ka)
765 real(
rp),
intent(in) :: rfdz (
ka)
766 real(
rp),
intent(out) :: momz_t(
ka)
767 real(
rp),
intent(out) :: rhou_t(
ka)
768 real(
rp),
intent(out) :: rhov_t(
ka)
779 flx(
k) = ( mflx(
k) + mflx(
k-1) ) * momz(
k) / ( dens(
k+1) + dens(
k) )
782 momz_t(
k) = - ( flx(
k+1) - flx(
k) ) * rfdz(
k)
788 flx(
k) = mflx(
k) * u(
k+1)
791 rhou_t(
k) = - ( flx(
k) - flx(
k-1) ) * rcdz(
k)
796 flx(
k) = mflx(
k) * v(
k+1)
799 rhov_t(
k) = - ( flx(
k) - flx(
k-1) ) * rcdz(
k)