27 public :: atmos_adiabat_cape
28 public :: atmos_adiabat_liftparcel
30 interface atmos_adiabat_cape
33 end interface atmos_adiabat_cape
35 interface atmos_adiabat_liftparcel
38 end interface atmos_adiabat_liftparcel
78 QV, QC, Qdry, Rtot, CPtot, &
80 CAPE, CIN, LCL, LFC, LNB, &
81 DENS_p, TEMP_p, BUOY_p, QV_p, &
86 integer,
intent(in) :: KA, KS, KE
88 integer,
intent(in) :: Kstr
89 real(RP),
intent(in) :: DENS (KA)
90 real(RP),
intent(in) :: TEMP (KA)
91 real(RP),
intent(in) :: PRES (KA)
92 real(RP),
intent(in) :: QV (KA)
93 real(RP),
intent(in) :: QC (KA)
94 real(RP),
intent(in) :: Qdry (KA)
95 real(RP),
intent(in) :: Rtot (KA)
96 real(RP),
intent(in) :: CPtot(KA)
97 real(RP),
intent(in) :: CZ ( KA)
98 real(RP),
intent(in) :: FZ (0:KA)
100 real(RP),
intent(out) :: CAPE
101 real(RP),
intent(out) :: CIN
102 real(RP),
intent(out) :: LCL
103 real(RP),
intent(out) :: LFC
104 real(RP),
intent(out) :: LNB
105 real(RP),
intent(out) :: DENS_p(KA)
106 real(RP),
intent(out) :: TEMP_p(KA)
107 real(RP),
intent(out) :: BUOY_p(KA)
108 real(RP),
intent(out) :: QV_p (KA)
109 logical,
intent(out) :: converged
111 real(RP) :: BUOY_pf(KA)
112 integer :: kLCL, kLFC, kLNB
120 dens(:), temp(:), pres(:), &
122 qdry(:), rtot(:), cptot(:), &
123 dens_p(:), temp_p(:), qv_p(:), &
126 if ( .not. converged )
return
130 buoy_p(k) = grav * ( dens(k) - dens_p(k) ) / dens_p(k)
134 buoy_pf(k) = 0.5_rp * ( buoy_p(k+1) + buoy_p(k) )
136 buoy_p(ke) = buoy_p(ke-1)
148 if ( buoy_p(k) >= 0.0_rp )
then
155 if ( buoy_p(k) >= 0.0_rp )
then
161 if ( klcl >= kstr )
then
165 if ( klfc >= kstr )
then
169 if ( klnb >= kstr )
then
173 if ( klfc >= kstr .AND. klnb > kstr )
then
175 cape = cape + buoy_pf(k-1) * ( fz(k)-fz(k-1) )
179 if ( klfc >= kstr )
then
181 cin = cin + buoy_pf(k-1) * ( fz(k)-fz(k-1) )
189 KA, KS, KE, IA, IS, IE, JA, JS, JE, &
192 QV, QC, Qdry, Rtot, CPtot, &
194 CAPE, CIN, LCL, LFC, LNB, &
195 DENS_p, TEMP_p, BUOY_p, QV_p )
201 integer,
intent(in) :: KA, KS, KE
202 integer,
intent(in) :: IA, IS, IE
203 integer,
intent(in) :: JA, JS, JE
205 integer,
intent(in) :: Kstr
206 real(RP),
intent(in) :: DENS (KA,IA,JA)
207 real(RP),
intent(in) :: TEMP (KA,IA,JA)
208 real(RP),
intent(in) :: PRES (KA,IA,JA)
209 real(RP),
intent(in) :: QV (KA,IA,JA)
210 real(RP),
intent(in) :: QC (KA,IA,JA)
211 real(RP),
intent(in) :: Qdry (KA,IA,JA)
212 real(RP),
intent(in) :: Rtot (KA,IA,JA)
213 real(RP),
intent(in) :: CPtot(KA,IA,JA)
214 real(RP),
intent(in) :: CZ ( KA,IA,JA)
215 real(RP),
intent(in) :: FZ (0:KA,IA,JA)
217 real(RP),
intent(out) :: CAPE(IA,JA)
218 real(RP),
intent(out) :: CIN (IA,JA)
219 real(RP),
intent(out) :: LCL (IA,JA)
220 real(RP),
intent(out) :: LFC (IA,JA)
221 real(RP),
intent(out) :: LNB (IA,JA)
223 real(RP),
intent(out),
optional,
target :: DENS_p(KA,IA,JA)
224 real(RP),
intent(out),
optional,
target :: TEMP_p(KA,IA,JA)
225 real(RP),
intent(out),
optional,
target :: BUOY_p(KA,IA,JA)
226 real(RP),
intent(out),
optional,
target :: QV_p (KA,IA,JA)
228 logical :: converged, error
230 real(RP),
pointer :: P_DENS(:,:,:), P_TEMP(:,:,:), P_BUOY(:,:,:), P_QV(:,:,:)
237 if (
present(dens_p) )
then
240 allocate( p_dens(ka,ia,ja) )
242 if (
present(temp_p) )
then
245 allocate( p_temp(ka,ia,ja) )
247 if (
present(buoy_p) )
then
250 allocate( p_buoy(ka,ia,ja) )
252 if (
present(qv_p) )
then
255 allocate( p_qv(ka,ia,ja) )
266 dens(:,i,j), temp(:,i,j), pres(:,i,j), &
267 qv(:,i,j), qc(:,i,j), qdry(:,i,j), &
268 rtot(:,i,j), cptot(:,i,j), &
269 cz(:,i,j), fz(:,i,j), &
270 cape(i,j), cin(i,j), &
271 lcl(i,j), lfc(i,j), lnb(i,j), &
272 p_dens(:,i,j), p_temp(:,i,j), &
273 p_buoy(:,i,j), p_qv(:,i,j), &
276 if ( .not. converged )
then
277 log_error(
"ATMOS_ADIABAT_cape_3D",*)
'[liftparcel] not converged! ', i, j
286 call file_history_in( p_dens(:,:,:),
'DENS_parcel',
'density profile in lifting parcel',
'kg/m3' )
287 call file_history_in( p_temp(:,:,:),
'TEMP_parcel',
'temperature profile in lifting parcel',
'K' )
288 call file_history_in( p_buoy(:,:,:),
'BUOY_parcel',
'buoyancy profile in lifting parcel',
'm/s2' )
289 call file_history_in( p_qv(:,:,:),
'QV_parcel',
'humidity profile in lifting parcel',
'kg/kg' )
291 if ( .not.
present(dens_p) )
deallocate( p_dens )
292 if ( .not.
present(temp_p) )
deallocate( p_temp )
293 if ( .not.
present(buoy_p) )
deallocate( p_buoy )
294 if ( .not.
present(qv_p ) )
deallocate( p_qv )
307 DENS, TEMP, PRES, QV, QC, &
309 DENS_p1D, TEMP_p1D, QV_p1D, &
312 hydrometeor_entr => atmos_hydrometeor_entr, &
315 atmos_saturation_moist_conversion_pres_liq
317 integer,
intent(in) :: KA, KS, KE
319 integer,
intent(in) :: Kstr
320 real(RP),
intent(in) :: DENS (KA)
321 real(RP),
intent(in) :: TEMP (KA)
322 real(RP),
intent(in) :: PRES (KA)
323 real(RP),
intent(in) :: QV (KA)
324 real(RP),
intent(in) :: QC (KA)
325 real(RP),
intent(in) :: QDRY (KA)
326 real(RP),
intent(in) :: Rtot (KA)
327 real(RP),
intent(in) :: CPtot(KA)
329 real(RP),
intent(out) :: DENS_p1D(KA)
330 real(RP),
intent(out) :: TEMP_p1D(KA)
331 real(RP),
intent(out) :: QV_p1D (KA)
332 integer,
intent(out) :: kLCL
333 logical,
intent(out) :: converged
336 real(RP) :: QV_p, QC_p, Qdry_p
337 real(RP) :: Rtot_p, CPtot_p
346 dens_p1d(k) = dens(k)
347 temp_p1d(k) = temp(k)
356 cptot_p = cptot(kstr)
358 call hydrometeor_entr( temp(kstr), pres(kstr), &
359 qv_p, qc_p, qdry_p, &
366 call atmos_saturation_moist_conversion_pres_liq( &
367 pres(k), entr_p, qdry_p, &
368 qv_p, qc_p, rtot_p, cptot_p, &
372 if ( .NOT. converged )
then
376 if ( qc_p > 0.0_rp .and. klcl == -1 ) klcl = k
379 fact = 1.0_rp / ( 1.0_rp - qc_p )
380 cptot_p = ( cptot_p -
cp_water * qc_p ) * fact
381 rtot_p = rtot_p * fact
382 qdry_p = qdry_p * fact
387 dens_p1d(k) = pres(k) / ( rtot_p * temp_p )
397 KA, KS, KE, IA, IS, IE, JA, JS, JE, &
399 DENS, TEMP, PRES, QV, QC, &
401 DENS_p3D, TEMP_p3D, QV_p3D, &
406 hydrometeor_entr => atmos_hydrometeor_entr
408 atmos_saturation_moist_conversion_pres_liq
411 integer,
intent(in) :: KA, KS, KE
412 integer,
intent(in) :: IA, IS, IE
413 integer,
intent(in) :: JA, JS, JE
415 integer,
intent(in) :: Kstr
416 real(RP),
intent(in) :: DENS (KA,IA,JA)
417 real(RP),
intent(in) :: TEMP (KA,IA,JA)
418 real(RP),
intent(in) :: PRES (KA,IA,JA)
419 real(RP),
intent(in) :: QV (KA,IA,JA)
420 real(RP),
intent(in) :: QC (KA,IA,JA)
421 real(RP),
intent(in) :: QDRY (KA,IA,JA)
422 real(RP),
intent(in) :: Rtot (KA,IA,JA)
423 real(RP),
intent(in) :: CPtot(KA,IA,JA)
425 real(RP),
intent(out) :: DENS_p3D(KA,IA,JA)
426 real(RP),
intent(out) :: TEMP_p3D(KA,IA,JA)
427 real(RP),
intent(out) :: QV_p3D (KA,IA,JA)
428 integer,
intent(out) :: kLCL(IA,JA)
429 logical,
intent(out) :: converged
444 dens(:,i,j), temp(:,i,j), pres(:,i,j), &
445 qv(:,i,j), qc(:,i,j), &
446 qdry(:,i,j), rtot(:,i,j), cptot(:,i,j), &
447 dens_p3d(:,i,j), temp_p3d(:,i,j), qv_p3d(:,i,j), &
448 klcl(i,j), converged )
449 if ( .not. converged )
then
450 log_error(
"ATMOS_ADIABAT_liftparcel_3D",*)
'[liftparcel] not converged! ', i, j