15 #include "inc_openmp.h" 45 private :: moist_conversion_liq
46 private :: moist_conversion_all
72 real(RP),
intent(inout) :: dens(
ka,
ia,
ja)
73 real(RP),
intent(inout) :: rhot(
ka,
ia,
ja)
74 real(RP),
intent(inout) :: qtrc(
ka,
ia,
ja,
qa)
75 integer,
intent(in) :: i_qv
76 real(RP),
intent(in) :: limit_negative
79 real(RP) :: diffq_check(
ka,
ia,
ja)
82 integer :: k, i, j, iq
96 diffq = diffq + qtrc(k,i,j,iq)
98 qtrc(k,i,j,iq) = max( qtrc(k,i,j,iq), 0.0_rp )
103 diffq = diffq - qtrc(k,i,j,iq)
107 qtrc(k,i,j,i_qv) = qtrc(k,i,j,i_qv) + diffq
108 diffq_check(k,i,j) = diffq
113 diffq = qtrc(k,i,j,i_qv)
114 qtrc(k,i,j,i_qv) = max( qtrc(k,i,j,i_qv), 0.0_rp )
115 diffq = diffq - qtrc(k,i,j,i_qv)
119 dens(k,i,j) = dens(k,i,j) * ( 1.0_rp - diffq )
120 rhot(k,i,j) = rhot(k,i,j) * ( 1.0_rp - diffq )
128 if ( abs(limit_negative) > 0.0_rp &
129 .AND. abs(limit_negative) < abs(diffq_min) )
then 130 if(
io_l )
write(
io_fid_log,*)
'xxx [MP_negative_fixer] large negative is found.' 131 write(*,*)
'xxx [MP_negative_fixer] large negative is found. rank = ',
prc_myrank 136 if ( abs(limit_negative) < abs(diffq_check(k,i,j)) &
137 .OR. abs(qtrc(k,i,j,i_qv)) < abs(diffq_check(k,i,j)) )
then 139 'xxx k,i,j,value(QHYD,QV) = ', k, i, j, diffq_check(k,i,j), qtrc(k,i,j,i_qv)
144 if(
io_l )
write(
io_fid_log,*)
'xxx criteria: total negative hydrometeor < ', abs(limit_negative)
174 thermodyn_qd => atmos_thermodyn_qd, &
175 thermodyn_cv => atmos_thermodyn_cv, &
176 thermodyn_temp_pres_e => atmos_thermodyn_temp_pres_e
181 saturation_dens2qsat_liq => atmos_saturation_dens2qsat_liq, &
182 saturation_dens2qsat_all => atmos_saturation_dens2qsat_all
185 real(RP),
intent(inout) :: rhoe_t(
ka,
ia,
ja)
186 real(RP),
intent(inout) :: qtrc_t(
ka,
ia,
ja,
qa)
187 real(RP),
intent(inout) :: rhoe0 (
ka,
ia,
ja)
188 real(RP),
intent(inout) :: qtrc0 (
ka,
ia,
ja,
qa)
189 real(RP),
intent(in) :: dens0 (
ka,
ia,
ja)
190 integer,
intent(in) :: i_qv
191 integer,
intent(in) :: i_qc
192 integer,
intent(in) :: i_qi
193 logical,
intent(in) :: flag_liquid
196 real(RP) :: temp0 (
ka,
ia,
ja)
197 real(RP) :: pres0 (
ka,
ia,
ja)
198 real(RP) :: qdry0 (
ka,
ia,
ja)
199 real(RP) :: cvtot (
ka,
ia,
ja)
201 real(RP) :: emoist(
ka,
ia,
ja)
202 real(RP) :: qsum1 (
ka,
ia,
ja)
203 real(RP) :: temp1 (
ka,
ia,
ja)
205 real(RP) :: rhoe1 (
ka,
ia,
ja)
209 integer :: k, i, j, iq
223 qtrc1(k,i,j,iq) = qtrc0(k,i,j,iq)
229 call thermodyn_temp_pres_e( temp0(:,:,:), &
239 call thermodyn_qd( qdry0(:,:,:), &
243 call thermodyn_cv( cvtot(:,:,:), &
248 if ( i_qi <= 0 .OR. flag_liquid )
then 255 emoist(k,i,j) = temp0(k,i,j) * cvtot(k,i,j) &
256 + qtrc1(k,i,j,i_qv) *
lhv 258 qsum1(k,i,j) = qtrc1(k,i,j,i_qv) &
261 qtrc1(k,i,j,i_qv) = qsum1(k,i,j)
262 qtrc1(k,i,j,i_qc) = 0.0_rp
267 call thermodyn_cv( cvtot(:,:,:), &
277 temp1(k,i,j) = ( emoist(k,i,j) - qtrc1(k,i,j,i_qv) *
lhv ) / cvtot(k,i,j)
282 call moist_conversion_liq( temp1(:,:,:), &
299 emoist(k,i,j) = temp0(k,i,j) * cvtot(k,i,j) &
300 + qtrc1(k,i,j,i_qv) *
lhv &
301 - qtrc1(k,i,j,i_qi) *
lhf 303 qsum1(k,i,j) = qtrc1(k,i,j,i_qv) &
304 + qtrc1(k,i,j,i_qc) &
307 qtrc1(k,i,j,i_qv) = qsum1(k,i,j)
308 qtrc1(k,i,j,i_qc) = 0.0_rp
309 qtrc1(k,i,j,i_qi) = 0.0_rp
314 call thermodyn_cv( cvtot(:,:,:), &
324 temp1(k,i,j) = ( emoist(k,i,j) - qtrc1(k,i,j,i_qv) *
lhv ) / cvtot(k,i,j)
329 call moist_conversion_all( temp1(:,:,:), &
341 call thermodyn_cv( cvtot(:,:,:), &
353 qtrc_t(k,i,j,i_qv) = qtrc_t(k,i,j,i_qv) + ( qtrc1(k,i,j,i_qv) - qtrc0(k,i,j,i_qv) ) * rdt
355 qtrc0(k,i,j,i_qv) = qtrc1(k,i,j,i_qv)
364 qtrc_t(k,i,j,i_qc) = qtrc_t(k,i,j,i_qc) + ( qtrc1(k,i,j,i_qc) - qtrc0(k,i,j,i_qc) ) * rdt
366 qtrc0(k,i,j,i_qc) = qtrc1(k,i,j,i_qc)
372 if ( i_qi > 0 .AND. (.not. flag_liquid) )
then 377 qtrc_t(k,i,j,i_qi) = qtrc_t(k,i,j,i_qi) + ( qtrc1(k,i,j,i_qi) - qtrc0(k,i,j,i_qi) ) * rdt
379 qtrc0(k,i,j,i_qi) = qtrc1(k,i,j,i_qi)
391 rhoe1(k,i,j) = dens0(k,i,j) * temp1(k,i,j) * cvtot(k,i,j)
393 rhoe_t(k,i,j) = rhoe_t(k,i,j) + ( rhoe1(k,i,j) - rhoe0(k,i,j) ) * rdt
395 rhoe0(k,i,j) = rhoe1(k,i,j)
414 subroutine moist_conversion_liq( &
430 thermodyn_cv => atmos_thermodyn_cv
434 saturation_dens2qsat_liq => atmos_saturation_dens2qsat_liq, &
439 real(RP),
intent(inout) :: temp1 (
ka,
ia,
ja)
440 real(RP),
intent(inout) :: qtrc1 (
ka,
ia,
ja,
qa)
441 real(RP),
intent(in) :: dens0 (
ka,
ia,
ja)
442 real(RP),
intent(in) :: qsum1 (
ka,
ia,
ja)
443 real(RP),
intent(in) :: qdry0 (
ka,
ia,
ja)
444 real(RP),
intent(in) :: emoist(
ka,
ia,
ja)
445 integer,
intent(in) :: i_qv
446 integer,
intent(in) :: i_qc
448 real(RP) :: qsat(
ka,
ia,
ja)
454 real(RP) :: qsatl_new
455 real(RP) :: emoist_new
458 real(RP) :: dqsatl_dt
460 real(RP) :: dcvtot_dt
461 real(RP) :: demoist_dt
465 integer :: index_sat(
ka*
ia*
ja,3)
467 integer,
parameter :: itelim = 100
468 real(RP) :: dtemp_criteria
470 integer :: k, i, j, ijk, iq, ite
475 dtemp_criteria = 0.1_rp**(2+
rp/2)
477 call saturation_dens2qsat_liq( qsat(:,:,:), &
486 if ( qsum1(k,i,j) > qsat(k,i,j) )
then 488 ijk_sat = ijk_sat + 1
489 index_sat(ijk_sat,1) = k
490 index_sat(ijk_sat,2) = i
491 index_sat(ijk_sat,3) = j
506 q(iq) = qtrc1(k,i,j,iq)
512 call saturation_dens2qsat_liq( qsatl_new, &
518 q(i_qc) = qsum1(k,i,j) - qsatl_new
520 call thermodyn_cv( cvtot, &
525 emoist_new = temp * cvtot + qsatl_new *
lhv 532 dcvtot_dt = dqsatl_dt *
tracer_cv(i_qv) &
535 demoist_dt = temp * dcvtot_dt + cvtot + dqsatl_dt *
lhv 537 dtemp = ( emoist_new - emoist(k,i,j) ) / demoist_dt
540 if ( abs(dtemp) < dtemp_criteria )
then 545 if( temp*0.0_rp /= 0.0_rp)
exit 548 if ( .NOT. converged )
then 549 write(*,*)
'xxx [moist_conversion] not converged! dtemp=', dtemp,k,i,j,ite
554 qtrc1(k,i,j,i_qv) = q(i_qv)
555 qtrc1(k,i,j,i_qc) = q(i_qc)
564 end subroutine moist_conversion_liq
569 subroutine moist_conversion_all( &
586 thermodyn_cv => atmos_thermodyn_cv
591 saturation_dens2qsat_all => atmos_saturation_dens2qsat_all, &
592 saturation_dens2qsat_liq => atmos_saturation_dens2qsat_liq, &
593 saturation_dens2qsat_ice => atmos_saturation_dens2qsat_ice, &
594 saturation_alpha => atmos_saturation_alpha, &
595 saturation_dalphadt => atmos_saturation_dalphadt, &
602 real(RP),
intent(inout) :: temp1 (
ka,
ia,
ja)
603 real(RP),
intent(inout) :: qtrc1 (
ka,
ia,
ja,
qa)
604 real(RP),
intent(in) :: dens0 (
ka,
ia,
ja)
605 real(RP),
intent(in) :: qsum1 (
ka,
ia,
ja)
606 real(RP),
intent(in) :: qdry0 (
ka,
ia,
ja)
607 real(RP),
intent(in) :: emoist(
ka,
ia,
ja)
608 integer,
intent(in) :: i_qv
609 integer,
intent(in) :: i_qc
610 integer,
intent(in) :: i_qi
612 real(RP) :: qsat(
ka,
ia,
ja)
619 real(RP) :: qsat_new, qsatl_new, qsati_new
620 real(RP) :: emoist_new
623 real(RP) :: dalpha_dt
624 real(RP) :: dqsat_dt, dqsatl_dt, dqsati_dt
625 real(RP) :: dqc_dt, dqi_dt
626 real(RP) :: dcvtot_dt
627 real(RP) :: demoist_dt
631 integer :: index_sat(
ka*
ia*
ja,3)
633 integer,
parameter :: itelim = 100
634 real(RP) :: dtemp_criteria
636 integer :: k, i, j, ijk, iq, ite
640 dtemp_criteria = 0.1_rp**(2+
rp/2)
642 call saturation_dens2qsat_all( qsat(:,:,:), &
652 if ( qsum1(k,i,j) > qsat(k,i,j) )
then 654 ijk_sat = ijk_sat + 1
655 index_sat(ijk_sat,1) = k
656 index_sat(ijk_sat,2) = i
657 index_sat(ijk_sat,3) = j
672 q(iq) = qtrc1(k,i,j,iq)
679 call saturation_alpha( alpha, temp )
681 call saturation_dens2qsat_all( qsat_new, temp, dens0(k,i,j) )
682 call saturation_dens2qsat_liq( qsatl_new, temp, dens0(k,i,j) )
683 call saturation_dens2qsat_ice( qsati_new, temp, dens0(k,i,j) )
687 q(i_qc) = ( qsum1(k,i,j)-qsat_new ) * ( alpha )
688 q(i_qi) = ( qsum1(k,i,j)-qsat_new ) * ( 1.0_rp-alpha )
690 call thermodyn_cv( cvtot, &
695 emoist_new = temp * cvtot + qsat_new *
lhv - q(i_qi) *
lhf 698 call saturation_dalphadt( dalpha_dt, temp )
703 dqsat_dt = qsatl_new * dalpha_dt + dqsatl_dt * ( alpha ) &
704 - qsati_new * dalpha_dt + dqsati_dt * ( 1.0_rp-alpha )
706 dqc_dt = ( qsum1(k,i,j)-qsat_new ) * dalpha_dt - dqsat_dt * ( alpha )
707 dqi_dt = -( qsum1(k,i,j)-qsat_new ) * dalpha_dt - dqsat_dt * ( 1.0_rp-alpha )
713 demoist_dt = temp * dcvtot_dt + cvtot + dqsat_dt *
lhv - dqi_dt *
lhf 715 dtemp = ( emoist_new - emoist(k,i,j) ) / demoist_dt
718 if ( abs(dtemp) < dtemp_criteria )
then 723 if( temp*0.0_rp /= 0.0_rp)
exit 726 if ( .NOT. converged )
then 727 write(*,*) temp1(k,i,j), dens0(k,i,j),q,qtrc1(k,i,j,i_qv),qtrc1(k,i,j,i_qc),qtrc1(k,i,j,i_qi)
728 write(*,*)
'xxx [moist_conversion] not converged! dtemp=', dtemp, k,i,j,ite
733 qtrc1(k,i,j,i_qv) = q(i_qv)
734 qtrc1(k,i,j,i_qc) = q(i_qc)
735 qtrc1(k,i,j,i_qi) = q(i_qi)
744 end subroutine moist_conversion_all
775 integer,
intent(in) :: qa_mp
776 integer,
intent(in) :: qs_mp
777 real(RP),
intent(out) :: qflx (
ka,
ia,
ja,qa_mp-1)
778 real(RP),
intent(inout) :: vterm(
ka,
ia,
ja,qa_mp-1)
779 real(RP),
intent(inout) :: dens (
ka,
ia,
ja)
780 real(RP),
intent(inout) :: momz (
ka,
ia,
ja)
781 real(RP),
intent(inout) :: momx (
ka,
ia,
ja)
782 real(RP),
intent(inout) :: momy (
ka,
ia,
ja)
783 real(RP),
intent(inout) :: rhoe (
ka,
ia,
ja)
784 real(RP),
intent(inout) :: qtrc (
ka,
ia,
ja,
qa)
785 real(RP),
intent(in) :: temp (
ka,
ia,
ja)
786 real(RP),
intent(in) :: cvq (
qa)
787 real(DP),
intent(in) :: dt
788 logical,
intent(in),
optional :: vt_fixed
791 real(RP) :: eflx (
ka,
ia,
ja)
792 real(RP) :: rfdz (
ka,
ia,
ja)
793 real(RP) :: rcdz (
ka,
ia,
ja)
794 real(RP) :: rcdz_u(
ka,
ia,
ja)
795 real(RP) :: rcdz_v(
ka,
ia,
ja)
804 if (
present(vt_fixed) )
then 815 if( .NOT. vt_fixed_ )
call comm_vars8( vterm(:,:,:,iq), iq )
817 call comm_vars8( qtrc(:,:,:,iqa), qa_mp+iq )
831 rcdz_u(k,i,j) = 2.0_rp / ( (
real_fz(k,i+1,j) -
real_fz(k-1,i+1,j) ) &
833 rcdz_v(k,i,j) = 2.0_rp / ( (
real_fz(k,i,j+1) -
real_fz(k-1,i,j+1) ) &
843 if ( .not. vt_fixed_ )
then 844 call comm_wait( vterm(:,:,:,iq), iq )
846 call comm_wait( qtrc(:,:,:,iqa), qa_mp+iq )
857 qflx(k,i,j,iq) = vterm(k+1,i,j,iq) * dens(k+1,i,j) * qtrc(k+1,i,j,iqa) * j33g
859 qflx(
ke,i,j,iq) = 0.0_rp
862 eflx(
ks-1,i,j) = qflx(
ks-1,i,j,iq) * temp(
ks,i,j) * cvq(iqa)
864 eflx(k,i,j) = qflx(k,i,j,iq) * temp(k+1,i,j) * cvq(iqa)
865 rhoe(k,i,j) = rhoe(k,i,j) - dt * ( eflx(k,i,j) - eflx(k-1,i,j) ) * rcdz(k,i,j)
867 eflx(
ke,i,j) = 0.0_rp
868 rhoe(
ke,i,j) = rhoe(
ke,i,j) - dt * ( - eflx(
ke-1,i,j) ) * rcdz(
ke,i,j)
871 eflx(
ks-1,i,j) = qflx(
ks-1,i,j,iq) * grav / rfdz(
ks-1,i,j)
873 eflx(k,i,j) = qflx(k,i,j,iq) * grav / rfdz(k,i,j)
874 rhoe(k,i,j) = rhoe(k,i,j) - dt * ( eflx(k,i,j) - eflx(k-1,i,j) ) * rcdz(k,i,j)
876 rhoe(
ke,i,j) = rhoe(
ke,i,j) - dt * ( - eflx(
ke-1,i,j) ) * rcdz(
ke,i,j)
880 eflx(k,i,j) = 0.25_rp * ( vterm(k+1,i,j,iq ) + vterm(k,i,j,iq ) ) &
881 * ( qtrc(k+1,i,j,iqa) + qtrc(k,i,j,iqa) ) &
885 momz(k,i,j) = momz(k,i,j) - dt * ( eflx(k+1,i,j) - eflx(k,i,j) ) * rfdz(k,i,j)
889 eflx(
ks-1,i,j) = 0.25_rp * ( vterm(
ks,i,j,iq ) + vterm(
ks,i+1,j,iq ) ) &
890 * ( qtrc(
ks,i,j,iqa) + qtrc(
ks,i+1,j,iqa) ) &
893 eflx(k,i,j) = 0.25_rp * ( vterm(k+1,i,j,iq ) + vterm(k+1,i+1,j,iq ) ) &
894 * ( qtrc(k+1,i,j,iqa) + qtrc(k+1,i+1,j,iqa) ) &
896 momx(k,i,j) = momx(k,i,j) - dt * ( eflx(k,i,j) - eflx(k-1,i,j) ) * rcdz_u(k,i,j)
898 momx(
ke,i,j) = momx(
ke,i,j) - dt * ( - eflx(
ke-1,i,j) ) * rcdz_u(
ke,i,j)
901 eflx(
ks-1,i,j) = 0.25_rp * ( vterm(
ks,i,j,iq ) + vterm(
ks,i,j+1,iq ) ) &
902 * ( qtrc(
ks,i,j,iqa) + qtrc(
ks,i,j+1,iqa) ) &
905 eflx(k,i,j) = 0.25_rp * ( vterm(k+1,i,j,iq ) + vterm(k+1,i,j+1,iq ) ) &
906 * ( qtrc(k+1,i,j,iqa) + qtrc(k+1,i,j+1,iqa) ) &
908 momy(k,i,j) = momy(k,i,j) - dt * ( eflx(k,i,j) - eflx(k-1,i,j) ) * rcdz_v(k,i,j)
910 momy(
ke,i,j) = momy(
ke,i,j) - dt * ( - eflx(
ke-1,i,j) ) * rcdz_v(
ke,i,j)
922 rhoq(k,i,j,iqa) = qtrc(k,i,j,iqa) * dens(k,i,j)
935 qflx(k,i,j,iq) = vterm(k+1,i,j,iq) * rhoq(k+1,i,j,iqa)
937 qflx(
ke,i,j,iq) = 0.0_rp
947 dens(k,i,j) = dens(k,i,j) - dt * ( qflx(k,i,j,iq) - qflx(k-1,i,j,iq) ) * rcdz(k,i,j)
960 rhoq(k,i,j,iqa) = rhoq(k,i,j,iqa) - dt * ( qflx(k,i,j,iq) - qflx(k-1,i,j,iq) ) * rcdz(k,i,j)
971 qtrc(k,i,j,iqa) = rhoq(k,i,j,iqa) / dens(k,i,j)
integer, public is
start point of inner domain: x, local
integer, public je
end point of inner domain: y, local
module ATMOSPHERE / Saturation adjustment
subroutine, public prc_mpistop
Abort MPI.
real(rp), public cvovr_liq
subroutine, public atmos_phy_mp_negative_fixer(DENS, RHOT, QTRC, I_QV, limit_negative)
Negative fixer.
real(rp), dimension(qa_max), public tracer_r
real(dp), public time_dtsec_atmos_phy_mp
time interval of physics(microphysics) [sec]
logical, public io_l
output log or not? (this process)
real(rp), public cvovr_ice
integer, public ke
end point of inner domain: z, local
real(rp), public gtrans_j33g
(3,3) element of Jacobian matrix * {G}^1/2
real(rp), dimension(:,:,:), allocatable, public real_fz
geopotential height [m] (cell face )
real(rp), dimension(:,:,:), allocatable, public real_cz
geopotential height [m] (cell center)
real(rp), dimension(qa_max), public tracer_cv
real(rp), public const_undef
module ATMOSPHERE / Physics Cloud Microphysics - Common
integer, public ia
of whole cells: x, local, with HALO
subroutine, public atmos_phy_mp_saturation_adjustment(RHOE_t, QTRC_t, RHOE0, QTRC0, DENS0, I_QV, I_QC, I_QI, flag_liquid)
Saturation adjustment.
integer, public ka
of whole cells: z, local, with HALO
real(rp), public const_grav
standard acceleration of gravity [m/s2]
integer, public js
start point of inner domain: y, local
real(rp), public lovr_ice
real(rp), public lhf
latent heat of fusion for use [J/kg]
real(rp), public lhv
latent heat of vaporization for use [J/kg]
integer, public ks
start point of inner domain: z, local
integer, public prc_myrank
process num in local communicator
subroutine, public prof_rapstart(rapname_base, level)
Start raptime.
integer, public ie
end point of inner domain: x, local
real(rp), public lovr_liq
module ATMOSPHERE / Thermodynamics
subroutine, public atmos_phy_mp_precipitation(QA_MP, QS_MP, qflx, vterm, DENS, MOMZ, MOMX, MOMY, RHOE, QTRC, temp, CVq, dt, vt_fixed)
precipitation transport
integer, public io_fid_log
Log file ID.
subroutine, public prof_rapend(rapname_base, level)
Save raptime.
integer, parameter, public rp
real(rp), dimension(qa_max), public tracer_mass
integer, public ja
of whole cells: y, local, with HALO