FE-Project
Loading...
Searching...
No Matches
scale_atm_phy_mp_lscond.F90
Go to the documentation of this file.
1!> module FElib / Atmosphere / Physics cloud microphysics / Large-scale condensation
2!!
3!! @par Description
4!! A module to provide a large-scale condensation scheme
5!!
6!! @par Reference
7!!
8!! @author Yuta Kawai, Team SCALE
9!!
10!-------------------------------------------------------------------------------
11#include "scaleFElib.h"
13 !-----------------------------------------------------------------------------
14 !
15 !++ Used modules
16 !
17 use scale_precision
18 use scale_io
19 use scale_prof
20 use scale_prc, only: prc_abort
21 use scale_const, only: &
22 rdry => const_rdry, &
23 rvap => const_rvap, &
24 cpdry => const_cpdry, &
25 cvdry => const_cvdry, &
26 pres00 => const_pre00, &
27 grav => const_grav
28 use scale_atmos_hydrometeor, only: &
29 cp_vapor, &
30 cp_water, &
31 cp_ice, &
32 cv_vapor, &
33 cv_water, &
34 cv_ice, &
35 lhv
36
37 use scale_element_base, only: &
41
42 !-----------------------------------------------------------------------------
43 implicit none
44 private
45 !-----------------------------------------------------------------------------
46 !
47 !++ Public type & procedure
48 !
53
54 !-----------------------------------------------------------------------------
55 !++ Public parameters & variables
56 !
57 integer, private, parameter :: QA_MP = 2
58
59 integer, parameter, public :: atmos_phy_mp_lscond_ntracers = qa_mp
60 integer, parameter, public :: atmos_phy_mp_lscond_nwaters = 1
61 integer, parameter, public :: atmos_phy_mp_lscond_nices = 0
62 character(len=H_SHORT), parameter, public :: atmos_phy_mp_lscond_tracer_names(qa_mp) = (/ &
63 'QV', &
64 'QC' /)
65 character(len=H_MID) , parameter, public :: atmos_phy_mp_lscond_tracer_descriptions(qa_mp) = (/ &
66 'Ratio of Water Vapor mass to total mass (Specific humidity)', &
67 'Ratio of Cloud Water mass to total mass ' /)
68 character(len=H_SHORT), parameter, public :: atmos_phy_mp_lscond_tracer_units(qa_mp) = (/ &
69 'kg/kg', &
70 'kg/kg' /)
71
72 !-----------------------------------------------------------------------------
73 !
74 !++ Private procedure
75 !
76
77
78 !-----------------------------------------------------------------------------
79 !
80 !++ Private parameters & variables
81 !
82 integer, private, parameter :: i_qv = 1
83 integer, private, parameter :: i_qc = 2
84
85 integer, private, parameter :: i_hyd_qc = 1
86
87 logical, private :: flag_liquid = .true. ! warm rain
88 logical, private :: couple_aerosol = .false. ! Consider CCN effect ?
89
90 ! real(RP), private, parameter :: re_qc = 8.E-6_RP ! effective radius for cloud water
91
92contains
93
94 !-----------------------------------------------------------------------------
95 !> Setup a module for a large-scale condensation scheme
96 !!
98 use scale_prc, only: &
99 prc_abort
100 implicit none
101 !---------------------------------------------------------------------------
102
103 log_newline
104 log_info("ATMOS_PHY_MP_lscond_setup",*) 'Setup'
105 log_info("ATMOS_PHY_MP_lscond_setup",*) 'large-scale condensation'
106
107 if( couple_aerosol ) then
108 log_error("ATMOS_PHY_MP_lscond_setup",*) 'MP_aerosol_couple should be .false. for large-scale condensation type MP!'
109 call prc_abort
110 endif
111
112 return
113 end subroutine atmos_phy_mp_lscond_setup
114
115 !> Calculate a state after the saturation process
116 !!
117!OCL SERIAL
119 KA, KS, KE, IA, IS, IE, JA, JS, JE, & ! (in)
120 dens, pres, & ! (in)
121 dt, & ! (in)
122 temp, qtrc, cptot, cvtot, & ! (inout)
123 rhoe_t, evaporate ) ! (out)
124
125 use scale_atmos_saturation, only: &
126 atmos_saturation_pres2qsat_liq
127 use scale_const, only: &
128 cl => const_cl
129 implicit none
130 integer, intent(in) :: ka, ks, ke
131 integer, intent(in) :: ia, is, ie
132 integer, intent(in) :: ja, js, je
133 real(rp), intent(in) :: dens(ka,ia,ja)
134 real(rp), intent(in) :: pres(ka,ia,ja)
135 real(rp), intent(in) :: dt
136 real(rp), intent(inout) :: temp(ka,ia,ja)
137 real(rp), intent(inout) :: qtrc(ka,ia,ja,qa_mp)
138 real(rp), intent(inout) :: cptot(ka,ia,ja)
139 real(rp), intent(inout) :: cvtot(ka,ia,ja)
140 real(rp), intent(out) :: rhoe_t(ka,ia,ja)
141 real(rp), intent(out) :: evaporate(ka,ia,ja)
142
143 real(rp) :: qsat(ka,ia,ja)
144 real(rp) :: d_qc(ka)
145 real(rp) :: d_cv(ka)
146 real(rp) :: d_cp(ka)
147 real(rp) :: d_e(ka)
148 real(rp) :: cptot_(ka)
149 real(rp) :: cvtot_(ka)
150 real(rp) :: coef1(ka)
151 real(rp) :: coef2
152
153 integer :: i, j
154
155 real(rp) :: rdt
156 !----------------------------------------------
157
158 call atmos_saturation_pres2qsat_liq( &
159 ka, ks, ke, ia, is, ie, ja, js, je, & ! (in)
160 temp, pres, & ! (in)
161 qsat ) ! (out)
162
163
164 coef2 = rvap / lhv
165 rdt = 1.0_rp / dt
166
167 !$omp parallel do private(i,j, d_qc, d_cv, d_cp, d_e, cptot_, cvtot_, coef1) collapse(2)
168 do j=js, je
169 do i=is, ie
170 ! coef1 = LHV**2 / ( CVDry * Rvap )
171 coef1(:) = lhv * ( lhv + ( cv_vapor - cv_water ) * temp(:,i,j) ) / ( cvtot(:,i,j) * rvap )
172
173 d_qc(:) = max( ( qtrc(:,i,j,i_qv) - qsat(:,i,j) ) / ( 1.0_rp + coef1 / temp(:,i,j)**2 * ( 1.0_rp - coef2 * temp(:,i,j) ) * qsat(:,i,j) ), &
174 0.0_rp )
175
176 qtrc(:,i,j,i_qv) = qtrc(:,i,j,i_qv) - d_qc(:)
177 qtrc(:,i,j,i_qc) = qtrc(:,i,j,i_qc) + d_qc(:)
178
179 d_cp(:) = - cp_vapor * d_qc(:) &
180 + cp_water * d_qc(:)
181 cptot_(:) = cptot(:,i,j) + d_cp(:)
182
183 d_cv(:) = - cv_vapor * d_qc(:) &
184 + cv_water * d_qc(:)
185 cvtot_(:) = cvtot(:,i,j) + d_cv(:)
186
187 d_e(:) = lhv * d_qc(:)
188 rhoe_t(:,i,j) = dens(:,i,j) * d_e(:) * rdt
189
190
191 temp(:,i,j) = ( temp(:,i,j) * cvtot(:,i,j) + d_e(:) ) / cvtot_(:)
192 cptot(:,i,j) = cptot_(:)
193 cvtot(:,i,j) = cvtot_(:)
194 end do
195 end do
196
197 return
198 end subroutine atmos_phy_mp_lscond_adjustment
199
200 !> Calculate a state after the precipitation process
201 !!
202!OCL SERIAL
204 DENS, RHOQ, CPtot, CVtot, RHOE, & ! (inout)
205 sflx_rain, sflx_snow, esflx, & ! (inout)
206 temp, dt, & ! (in)
207 qha, qla, qia, lcmesh, elem, elem1d ) ! (in)
208
209 use scale_const, only: &
210 undef => const_undef8
211 implicit none
212
213 class(localmesh3d), intent(in) :: lcmesh
214 class(elementbase3d), intent(in) :: elem
215 integer, intent(in) :: qha !< hydrometeor (water + ice)
216 real(rp), intent(inout) :: dens (elem%np,lcmesh%nez,lcmesh%ne2d)
217 real(rp), intent(inout) :: rhoq (elem%np,lcmesh%nez,lcmesh%ne2d,qha)
218 real(rp), intent(inout) :: cptot(elem%np,lcmesh%nez,lcmesh%ne2d)
219 real(rp), intent(inout) :: cvtot(elem%np,lcmesh%nez,lcmesh%ne2d)
220 real(rp), intent(inout) :: rhoe (elem%np,lcmesh%nez,lcmesh%ne2d)
221 real(rp), intent(inout) :: sflx_rain(elem%nfp_v,lcmesh%ne2da)
222 real(rp), intent(inout) :: sflx_snow(elem%nfp_v,lcmesh%ne2da)
223 real(rp), intent(inout) :: esflx (elem%nfp_v,lcmesh%ne2da)
224 real(rp), intent(in) :: temp (elem%np,lcmesh%nez,lcmesh%ne2d)
225 real(rp), intent(in) :: dt
226 integer, intent(in) :: qla, qia
227 class(elementbase1d), intent(in) :: elem1d
228
229 real(rp) :: rhocp(elem%np,lcmesh%nez,lcmesh%ne2d)
230 real(rp) :: rhocv(elem%np,lcmesh%nez,lcmesh%ne2d)
231
232 real(rp) :: ddens(elem%np)
233 real(rp) :: dinternalen(elem%np)
234
235 real(rp) :: vint_weight(elem%nnode_v,elem%nnode_h1d**2)
236 real(rp) :: condens_vint_lc(elem%nnode_h1d**2)
237 real(rp) :: ien_vint_lc(elem%nnode_h1d**2)
238
239 real(rp) :: eflx(elem%np)
240 real(rp) :: cp(qha)
241 real(rp) :: cv(qha)
242
243 integer :: ke2d
244 integer :: p2d
245
246 integer :: ke_z
247 integer :: ke
248 integer :: iq
249
250 real(rp) :: rdt
251 !-------------------------------------------------------
252
253 do iq = 1, qha
254 if ( iq > qla + qia ) then
255 cp(iq) = undef
256 cv(iq) = undef
257 else if ( iq > qla ) then ! ice water
258 cp(iq) = cp_ice
259 cv(iq) = cv_ice
260 else ! liquid water
261 cp(iq) = cp_water
262 cv(iq) = cv_water
263 end if
264 end do
265
266 rdt = 1.0_rp / dt
267
268 !$omp parallel do collapse(2)
269 do ke2d = 1, lcmesh%Ne2D
270 do ke_z = 1, lcmesh%NeZ
271 rhocp(:,ke_z,ke2d) = cptot(:,ke_z,ke2d) * dens(:,ke_z,ke2d)
272 rhocv(:,ke_z,ke2d) = cvtot(:,ke_z,ke2d) * dens(:,ke_z,ke2d)
273 end do
274 end do
275
276 do iq = 1, qha
277 !$omp parallel do private(ke2D,ke_z,ke,p2D, &
278 !$omp dDENS, vint_weight, condens_vint_lc, dInternalEn, ien_vint_lc)
279 do ke2d = 1, lcmesh%Ne2D
280 do ke_z = 1, lcmesh%NeZ
281 ke = ke2d + (ke_z-1)*lcmesh%Ne2D
282
283 ddens(:) = - rhoq(:,ke_z,ke2d,iq)
284 rhoq(:,ke_z,ke2d,iq) = 0.0_rp
285
286 do p2d=1, elem%Nnode_h1D**2
287 vint_weight(:,p2d) = 0.5_rp * elem1d%IntWeight_lgl(:) * ( lcmesh%zlev(elem%Colmask(elem%Nnode_v,p2d),ke) - lcmesh%zlev(elem%Colmask(1,p2d),ke) )
288 end do
289
290 do p2d=1, elem%Nnode_h1D**2
291 condens_vint_lc(p2d) = sum( vint_weight(:,p2d) * ddens(elem%Colmask(:,p2d)) )
292 end do
293
294 if ( iq > qla ) then ! ice water
295 sflx_snow(:,ke2d) = sflx_snow(:,ke2d) &
296 + condens_vint_lc(:) * rdt
297 else ! liquid water
298 sflx_rain(:,ke2d) = sflx_rain(:,ke2d) &
299 + condens_vint_lc(:) * rdt
300 end if
301
302 !--- update density
303
304 rhocp(:,ke_z,ke2d) = rhocp(:,ke_z,ke2d) + cp(iq) * ddens(:)
305 rhocv(:,ke_z,ke2d) = rhocv(:,ke_z,ke2d) + cv(iq) * ddens(:)
306 dens(:,ke_z,ke2d) = dens(:,ke_z,ke2d) + ddens(:)
307
308 !--- update internal energy
309
310 dinternalen(:) = cp(iq) * ddens(:) * temp(:,ke_z,ke2d)
311
312 do p2d=1, elem%Nnode_h1D**2
313 ien_vint_lc(p2d) = sum( vint_weight(:,p2d) * dinternalen(elem%Colmask(:,p2d)) )
314 end do
315 esflx(:,ke2d) = esflx(:,ke2d) &
316 + ien_vint_lc(:) * rdt
317
318 rhoe(:,ke_z,ke2d) = rhoe(:,ke_z,ke2d) + dinternalen(:)
319 end do
320 end do
321 end do
322
323 !$omp parallel do collapse(2)
324 do ke2d = 1, lcmesh%Ne2D
325 do ke_z = 1, lcmesh%NeZ
326 cptot(:,ke_z,ke2d) = rhocp(:,ke_z,ke2d) / dens(:,ke_z,ke2d)
327 cvtot(:,ke_z,ke2d) = rhocv(:,ke_z,ke2d) / dens(:,ke_z,ke2d)
328 end do
329 end do
330
331 return
333
334 !> Calculate a tendency of momentum due to the precipitation process
335 !!
336!OCL SERIAL
338 MOMU_t, MOMV_t, MOMZ_t, & ! (out)
339 dens, momu, momv, momz, dens_new, & ! (in)
340 rdt_mp, lcmesh, elem ) ! (in)
341 implicit none
342
343 class(localmesh3d), intent(in) :: lcmesh
344 class(elementbase3d), intent(in) :: elem
345 real(rp), intent(out) :: momu_t(elem%np,lcmesh%nea)
346 real(rp), intent(out) :: momv_t(elem%np,lcmesh%nea)
347 real(rp), intent(out) :: momz_t(elem%np,lcmesh%nea)
348 real(rp), intent(in) :: dens(elem%np,lcmesh%nez,lcmesh%ne2d)
349 real(rp), intent(in) :: momu(elem%np,lcmesh%nez,lcmesh%ne2d)
350 real(rp), intent(in) :: momv(elem%np,lcmesh%nez,lcmesh%ne2d)
351 real(rp), intent(in) :: momz(elem%np,lcmesh%nez,lcmesh%ne2d)
352 real(rp), intent(in) :: dens_new(elem%np,lcmesh%nez,lcmesh%ne2d)
353 real(rp), intent(in) :: rdt_mp
354
355 integer :: ke2d
356 integer :: ke_z
357 integer :: ke
358 real(rp) :: coef(elem%np)
359 !----------------------------------------------------------
360
361 !$omp parallel do collapse(2) private( &
362 !$omp ke2D, ke_z, ke, coef )
363 do ke2d = 1, lcmesh%Ne2D
364 do ke_z = 1, lcmesh%NeZ
365 ke = ke2d + (ke_z-1)*lcmesh%Ne2D
366 coef(:) = ( dens_new(:,ke_z,ke2d) / dens(:,ke_z,ke2d) - 1.0_rp ) * rdt_mp
367
368 momu_t(:,ke) = coef(:) * momu(:,ke_z,ke2d)
369 momv_t(:,ke) = coef(:) * momv(:,ke_z,ke2d)
370 momz_t(:,ke) = coef(:) * momz(:,ke_z,ke2d)
371 end do
372 end do
373 return
375
module FElib / Atmosphere / Physics cloud microphysics / Large-scale condensation
subroutine, public atmos_phy_mp_lscond_adjustment(ka, ks, ke, ia, is, ie, ja, js, je, dens, pres, dt, temp, qtrc, cptot, cvtot, rhoe_t, evaporate)
Calculate a state after the saturation process.
integer, parameter, public atmos_phy_mp_lscond_ntracers
character(len=h_short), dimension(qa_mp), parameter, public atmos_phy_mp_lscond_tracer_units
character(len=h_mid), dimension(qa_mp), parameter, public atmos_phy_mp_lscond_tracer_descriptions
subroutine, public atmos_phy_mp_lscond_setup
Setup a module for a large-scale condensation scheme.
character(len=h_short), dimension(qa_mp), parameter, public atmos_phy_mp_lscond_tracer_names
subroutine, public atmos_phy_mp_lscond_precipitation(dens, rhoq, cptot, cvtot, rhoe, sflx_rain, sflx_snow, esflx, temp, dt, qha, qla, qia, lcmesh, elem, elem1d)
Calculate a state after the precipitation process.
integer, parameter, public atmos_phy_mp_lscond_nices
subroutine, public atmos_phy_mp_lscond_precipitation_momentum(momu_t, momv_t, momz_t, dens, momu, momv, momz, dens_new, rdt_mp, lcmesh, elem)
Calculate a tendency of momentum due to the precipitation process.
integer, parameter, public atmos_phy_mp_lscond_nwaters
module FElib / Element / Base
module FElib / Mesh / Local 3D
module FElib / Mesh / Base 3D
Derived type representing a 1D reference element.
Derived type representing a 3D reference element.
Derived type to manage a local 3D computational domain.
Derived type to manage a computational mesh (base type for 3D domain)