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 )
140 eng(k) = cvtot(k,i,j) * temp(k,i,j)
150 call atmos_hydrometeor_lhv( ka, ks, ke, temp(:,i,j), lhv(:) )
154 work = - min( qtrc(k,i,j,iq), 0.0_rp )
155 if ( work > 0.0_rp )
then 156 eng(k) = eng(k) + work * lhv(k)
157 diffq(k) = diffq(k) - work
161 qtrc(k,i,j,iq) = 0.0_rp
168 call atmos_hydrometeor_lhs( ka, ks, ke, temp(:,i,j), lhs(:) )
170 do iq = qla+1, qla+qia
172 work = - min( qtrc(k,i,j,iq), 0.0_rp )
173 if ( work > 0.0_rp )
then 174 eng(k) = eng(k) + work * lhs(k)
175 diffq(k) = diffq(k) - work
179 qtrc(k,i,j,iq) = 0.0_rp
186 if ( abs(limit_negative) > 0.0_rp )
then 188 if ( diffq(k) < - abs(limit_negative) )
then 189 diffq_min = min( diffq_min, diffq(k) )
190 log_error(
"ATMOS_PHY_MP_negative_fixer",*)
'large negative is found' 191 log_error_cont(*)
'value = ', diffq(k),
' at (', k,
',', i,
',', j,
')' 197 if ( diffq(k) < 0.0_rp )
then 199 qv(k,i,j) = qv(k,i,j) + diffq(k)
205 rhoh(k,i,j) = ( eng(k) - eng0(k) ) * dens(k,i,j)
212 dens0(k) = dens(k,i,j)
217 eng0(k) = eng(k) * dens(k,i,j)
223 work = - min( qv(k,i,j), 0.0_rp )
224 if ( work > 0.0_rp )
then 226 dens(k,i,j) = dens(k,i,j) * ( 1.0_rp + work )
227 cvtot(k,i,j) = ( cvtot(k,i,j) + work *
cv_vapor ) / ( 1.0_rp + work )
228 cptot(k,i,j) = ( cptot(k,i,j) + work *
cp_vapor ) / ( 1.0_rp + work )
229 eng(k) = ( eng(k) + work *
cv_vapor * temp(k,i,j) ) / ( 1.0_rp + work )
235 temp(k,i,j) = eng(k) / cvtot(k,i,j)
240 dens_diff(k,i,j) = dens(k,i,j) - dens0(k)
245 engi_diff(k,i,j) = eng(k) * dens(k,i,j) - eng0(k)
253 if ( abs(limit_negative) > 0.0_rp &
254 .AND. abs(limit_negative) < abs(diffq_min) )
then 255 log_error_cont(*)
'maximum negative hydrometeor ', diffq_min,
' < ', - abs(limit_negative)
268 KA, KS, KE, IA, IS, IE, JA, JS, JE, &
287 atmos_saturation_moist_conversion_dens_all, &
288 atmos_saturation_moist_conversion_dens_liq
291 integer,
intent(in) :: KA, KS, KE
292 integer,
intent(in) :: IA, IS, IE
293 integer,
intent(in) :: JA, JS, JE
295 real(RP),
intent(in) :: DENS(ka,ia,ja)
296 logical ,
intent(in) :: flag_liquid
298 real(RP),
intent(inout) :: TEMP (ka,ia,ja)
299 real(RP),
intent(inout) :: QV (ka,ia,ja)
300 real(RP),
intent(inout) :: QC (ka,ia,ja)
301 real(RP),
intent(inout) :: QI (ka,ia,ja)
302 real(RP),
intent(inout) :: CPtot(ka,ia,ja)
303 real(RP),
intent(inout) :: CVtot(ka,ia,ja)
305 real(RP),
intent(out) :: RHOE_d(ka,ia,ja)
314 logical :: converged, error
323 if ( flag_liquid )
then 338 emoist = temp(k,i,j) * cvtot(k,i,j) &
341 call atmos_saturation_moist_conversion_dens_liq( dens(k,i,j), emoist, &
342 temp(k,i,j), qv1, qc1, &
343 cptot(k,i,j), cvtot(k,i,j), &
346 if ( .NOT. converged )
then 347 log_error(
"ATMOS_PHY_MP_saturation_adjustment_3D",*)
'moist_conversion not converged! ', k,i,j
352 rhoe_d(k,i,j) = -
lhv * ( qv1 - qv(k,i,j) ) * dens(k,i,j)
378 emoist = temp(k,i,j) * cvtot(k,i,j) &
382 call atmos_saturation_moist_conversion_dens_all( dens(k,i,j), emoist, &
383 temp(k,i,j), qv1, qc1, qi1, &
384 cptot(k,i,j), cvtot(k,i,j), &
387 if ( .NOT. converged )
then 388 log_error(
"ATMOS_PHY_MP_saturation_adjustment_3D",*)
'moist_conversion not converged! ', k,i,j
393 rhoe_d(k,i,j) = ( -
lhv * ( qv1 - qv(k,i,j) ) &
394 +
lhf * ( qi1 - qi(k,i,j) ) ) * dens(k,i,j)
415 KA, KS, KE, QHA, QLA, QIA, &
416 TEMP, vterm, FDZ, RCDZ, dt, &
418 DENS, RHOQ, CPtot, CVtot, RHOE, &
428 integer,
intent(in) :: KA, KS, KE
429 integer,
intent(in) :: QHA, QLA, QIA
431 real(RP),
intent(in) :: TEMP (ka)
432 real(RP),
intent(in) :: vterm(ka,qha)
433 real(RP),
intent(in) :: FDZ (ka)
434 real(RP),
intent(in) :: RCDZ (ka)
435 real(DP),
intent(in) :: dt
436 integer,
intent(in) :: i, j
438 real(RP),
intent(inout) :: DENS (ka)
439 real(RP),
intent(inout) :: RHOQ (ka,qha)
440 real(RP),
intent(inout) :: CPtot(ka)
441 real(RP),
intent(inout) :: CVtot(ka)
442 real(RP),
intent(inout) :: RHOE (ka)
444 real(RP),
intent(out) :: mflx (ka)
445 real(RP),
intent(out) :: sflx (2)
447 real(RP) :: vtermh(ka)
448 real(RP) :: qflx (ka)
449 real(RP) :: eflx (ka)
450 real(RP) :: RHOCP (ka)
451 real(RP) :: RHOCV (ka)
467 rhocp(k) = cptot(k) * dens(k)
468 rhocv(k) = cvtot(k) * dens(k)
473 vtermh(k) = 0.5_rp * ( vterm(k+1,iq) + vterm(k,iq) )
475 vtermh(ks-1) = vterm(ks,iq)
479 qflx(k) = vtermh(k) * rhoq(k+1,iq)
484 rhoq(k,iq) = rhoq(k,iq) - dt * ( qflx(k) - qflx(k-1) ) * rcdz(k)
488 if ( iq > qla + qia ) cycle
491 mflx(k) = mflx(k) + qflx(k)
497 sflx(2) = sflx(2) + qflx(ks-1)
501 sflx(1) = sflx(1) + qflx(ks-1)
506 ddens = - ( qflx(k) - qflx(k-1) ) * rcdz(k) * dt
507 rhocp(k) = rhocp(k) + cp * ddens
508 rhocv(k) = rhocv(k) + cv * ddens
509 dens(k) = dens(k) + ddens
514 eflx(k) = qflx(k) * temp(k+1) * cv &
515 + qflx(k) * fdz(k) * grav
519 rhoe(k) = rhoe(k) - ( eflx(k) - eflx(k-1) ) * rcdz(k) * dt
525 cptot(k) = rhocp(k) / dens(k)
526 cvtot(k) = rhocv(k) / dens(k)
535 KA, KS, KE, QHA, QLA, QIA, &
536 TEMP, vterm, FZ, FDZ, RCDZ, dt, &
538 DENS, RHOQ, CPtot, CVtot, RHOE, &
548 integer,
intent(in) :: KA, KS, KE
549 integer,
intent(in) :: QHA, QLA, QIA
551 real(RP),
intent(in) :: TEMP (ka)
552 real(RP),
intent(in) :: vterm(ka,qha)
553 real(RP),
intent(in) :: FZ (ka)
554 real(RP),
intent(in) :: FDZ (ka)
555 real(RP),
intent(in) :: RCDZ (ka)
556 real(DP),
intent(in) :: dt
557 integer,
intent(in) :: i, j
559 real(RP),
intent(inout) :: DENS (ka)
560 real(RP),
intent(inout) :: RHOQ (ka,qha)
561 real(RP),
intent(inout) :: CPtot(ka)
562 real(RP),
intent(inout) :: CVtot(ka)
563 real(RP),
intent(inout) :: RHOE (ka)
565 real(RP),
intent(out) :: mflx (ka)
566 real(RP),
intent(out) :: sflx (2)
570 real(RP) :: RHOCP(ka)
571 real(RP) :: RHOCV(ka)
575 real(RP) :: vtermh(ka)
576 real(RP) :: dvterm(ka)
578 real(RP) :: rfdz2 (ka)
579 real(RP) :: dist (ka)
582 integer :: k_src (ka)
597 rhocp(k) = cptot(k) * dens(k)
598 rhocv(k) = cvtot(k) * dens(k)
602 cdz(k) = 1.0_rp / rcdz(k)
605 rfdz2(k) = 1.0_rp / ( cdz(k) + cdz(k+1) )
610 vtermh(k) = ( cdz(k) * vterm(k+1,iq) + cdz(k+1) * vterm(k,iq) ) * rfdz2(k)
612 vtermh(ks-1) = vterm(ks,iq)
615 dvterm(k) = vtermh(k) - vtermh(k-1)
622 dist(k) = - vtermh(k) * dt &
623 + vtermh(k) * dt**2 / 2.0_rp * ( dvterm(k+1)+dvterm(k) ) * rfdz2(k) &
624 - vtermh(k)**2 * dt**3 / 4.0_rp * ( dvterm(k+1)*rcdz(k+1) - dvterm(k)*rcdz(k) ) * rfdz2(k)
625 dist(k) = max( dist(k), 0.0_rp )
627 dist(ks-1) = - vtermh(ks-1) * dt &
628 + vtermh(ks-1) * dt**2 / 2.0_rp * dvterm(ks)*rcdz(ks)
629 dist(ks-1) = max( dist(ks-1), 0.0_rp )
632 do k = ke-2, ks-1, -1
633 dist(k) = min( dist(k), dist(k+1) + cdz(k+1) )
642 do k_dst = ks-1, ke-1
643 z_src = fz(k_dst) + dist(k_dst)
647 if ( z_src > fz(k ) &
648 .AND. z_src <= fz(k+1) )
then 652 if ( z_src > fz(ke) ) k_src(k_dst) = ke
668 do k_dst = ks-1, ke-1
669 do k = k_dst, k_src(k_dst)-1
670 flx = rhoq(k+1,iq) * cdz(k+1) / dt
671 qflx(k_dst) = qflx(k_dst) - flx
672 eflx(k_dst) = eflx(k_dst) - flx * temp(k+1) * cv
673 dist(k_dst) = dist(k_dst) - cdz(k+1)
675 if ( k_src(k_dst) < ke )
then 677 flx = rhoq(k_src(k_dst)+1,iq) * dist(k_dst) / dt
678 qflx(k_dst) = qflx(k_dst) - flx
679 eflx(k_dst) = eflx(k_dst) -flx * temp(k_src(k_dst)+1) * cv
682 eflx(k_dst) = eflx(k_dst) + qflx(k) * fdz(k_dst) * grav
692 rhoq(k,iq) = rhoq(k,iq) - dt * ( qflx(k) - qflx(k-1) ) * rcdz(k)
701 if ( iq > qla + qia ) cycle
704 mflx(k) = mflx(k) + qflx(k)
708 sflx(2) = sflx(2) + qflx(ks-1)
710 sflx(1) = sflx(1) + qflx(ks-1)
715 ddens = - ( qflx(k) - qflx(k-1) ) * rcdz(k) * dt
716 rhocp(k) = rhocp(k) + cp * ddens
717 rhocv(k) = rhocv(k) + cv * ddens
718 dens(k) = dens(k) + ddens
723 rhoe(k) = rhoe(k) - ( eflx(k) - eflx(k-1) ) * rcdz(k) * dt
729 cptot(k) = rhocp(k) / dens(k)
730 cvtot(k) = rhocv(k) / dens(k)
740 DENS, MOMZ, U, V, mflx, &
742 MOMZ_t, RHOU_t, RHOV_t )
745 integer,
intent(in) :: KA, KS, KE
746 real(RP),
intent(in) :: DENS (ka)
747 real(RP),
intent(in) :: MOMZ (ka)
748 real(RP),
intent(in) :: U (ka)
749 real(RP),
intent(in) :: V (ka)
750 real(RP),
intent(in) :: mflx (ka)
751 real(RP),
intent(in) :: RCDZ (ka)
752 real(RP),
intent(in) :: RFDZ (ka)
753 real(RP),
intent(out) :: MOMZ_t(ka)
754 real(RP),
intent(out) :: RHOU_t(ka)
755 real(RP),
intent(out) :: RHOV_t(ka)
766 flx(k) = ( mflx(k) + mflx(k-1) ) * momz(k) / ( dens(k+1) + dens(k) )
769 momz_t(k) = - ( flx(k+1) - flx(k) ) * rfdz(k)
775 flx(k) = mflx(k) * u(k+1)
778 rhou_t(k) = - ( flx(k) - flx(k-1) ) * rcdz(k)
783 flx(k) = mflx(k) * v(k+1)
786 rhov_t(k) = - ( flx(k) - flx(k-1) ) * rcdz(k)
real(rp), public const_cvdry
specific heat (dry air,constant volume) [J/kg/K]
real(rp), public const_cpdry
specific heat (dry air,constant pressure) [J/kg/K]
module atmosphere / saturation
real(rp), public cv_ice
CV for ice [J/kg/K].
real(rp), public cp_ice
CP for ice [J/kg/K].
module ATMOSPHERE / Physics Cloud Microphysics - Common
real(rp), public cv_vapor
CV for vapor [J/kg/K].
module atmosphere / hydrometeor
module atmosphere / grid / cartesC index
real(rp), public const_grav
standard acceleration of gravity [m/s2]
subroutine, public atmos_phy_mp_precipitation_semilag(KA, KS, KE, QHA, QLA, QIA, TEMP, vterm, FZ, FDZ, RCDZ, dt, i, j, DENS, RHOQ, CPtot, CVtot, RHOE, mflx, sflx)
subroutine, public atmos_phy_mp_precipitation_momentum(KA, KS, KE, DENS, MOMZ, U, V, mflx, RCDZ, RFDZ, MOMZ_t, RHOU_t, RHOV_t)
subroutine atmos_phy_mp_saturation_adjustment_3d(KA, KS, KE, IA, IS, IE, JA, JS, JE, DENS, flag_liquid, TEMP, QV, QC, QI, CPtot, CVtot, RHOE_d)
Saturation adjustment.
real(rp), public lhf
latent heat of fusion for use [J/kg]
subroutine, public prc_abort
Abort Process.
real(rp), public lhv
latent heat of vaporization for use [J/kg]
subroutine, public prof_rapstart(rapname_base, level)
Start raptime.
subroutine, public atmos_phy_mp_precipitation_upwind(KA, KS, KE, QHA, QLA, QIA, TEMP, vterm, FDZ, RCDZ, dt, i, j, DENS, RHOQ, CPtot, CVtot, RHOE, mflx, sflx)
subroutine, public prof_rapend(rapname_base, level)
Save raptime.
real(rp), public cp_vapor
CP for vapor [J/kg/K].
real(rp), public cp_water
CP for water [J/kg/K].
real(rp), public cv_water
CV for water [J/kg/K].
subroutine, public atmos_phy_mp_negative_fixer(KA, KS, KE, IA, IS, IE, JA, JS, JE, QLA, QIA, limit_negative, DENS, TEMP, CVtot, CPtot, QV, QTRC, RHOH, DENS_diff, ENGI_diff)
ATMOS_PHY_MP_negative_fixer negative fixer.