FE-Project
Loading...
Searching...
No Matches
Functions/Subroutines
scale_atm_phy_mp_dgm_common Module Reference

module FElib / Atmosphere / Physics cloud microphysics / common More...

Functions/Subroutines

subroutine, public atm_phy_mp_dgm_common_gen_intweight (intweight, lcmesh)
 
subroutine, public atm_phy_mp_dgm_common_gen_vmap (vmapm, vmapp, lmesh, elem)
 
subroutine, public atm_phy_mp_dgm_common_precipitation (dens, rhoq, cptot, cvtot, rhoe, flx_hydro, sflx_rain, sflx_snow, esflx, temp, vterm, dt, rnstep, dz, lift, nz, vmapm, vmapp, intweight, qha, qla, qia, lcmesh, elem)
 
subroutine, public atm_phy_mp_dgm_common_precipitation_momentum (momu_t, momv_t, momz_t, dens, momu, momv, momz, mflx, dz, lift, nz, vmapm, vmapp, lcmesh, elem)
 
subroutine, public atm_phy_mp_dgm_common_negative_fixer (qtrc, ddens, pres, cvtot, cptot, rtot, dens_hyd, pres_hyd, dt, lmesh, elem, qa, qla, qia, drhot)
 

Detailed Description

module FElib / Atmosphere / Physics cloud microphysics / common

Description
cloud microphysics process common subroutines

To preserve nonnegativity in precipitation process, a limiter proposed by Light and Durran (2016, MWR) is used

Reference
  • Light and Durran 2016: Preserving Nonnegativity in Discontinuous Galerkin Approximations to Scalar Transport via Truncation and Mass Aware Rescaling (TMAR). Monthly Weather Review, 144(12), 4771–4786.
Author
Yuta Kawai, Team SCALE

Function/Subroutine Documentation

◆ atm_phy_mp_dgm_common_gen_intweight()

subroutine, public scale_atm_phy_mp_dgm_common::atm_phy_mp_dgm_common_gen_intweight ( real(rp), dimension(lcmesh%refelem3d%nfaces,lcmesh%refelem3d%nfptot), intent(out) intweight,
class(localmesh3d), target lcmesh )

Definition at line 77 of file scale_atm_phy_mp_dgm_common.F90.

81 implicit none
82 class(LocalMesh3D), target :: lcmesh
83 real(RP), intent(out) :: IntWeight(lcmesh%refElem3D%Nfaces,lcmesh%refElem3D%NfpTot)
84
85 class(ElementBase3D), pointer :: elem
86 real(RP), allocatable :: intWeight_lgl1DPts_h(:)
87 real(RP), allocatable :: intWeight_lgl1DPts_v(:)
88 real(RP), allocatable :: intWeight_h(:)
89 real(RP), allocatable :: intWeight_v(:)
90
91 integer :: f
92 integer :: i, j, k, l
93 integer :: is, ie
94 !--------------------------------------------
95
96 elem => lcmesh%refElem3D
97 intweight(:,:) = 0.0_rp
98
99 allocate( intweight_lgl1dpts_h(elem%Nnode_h1D) )
100 allocate( intweight_lgl1dpts_v(elem%Nnode_v) )
101 allocate( intweight_h(elem%Nnode_h1D*elem%Nnode_v) )
102 allocate( intweight_v(elem%Nnode_h1D**2) )
103
104 intweight_lgl1dpts_h(:) = polynominal_gengausslobattoptintweight(elem%PolyOrder_h)
105 intweight_lgl1dpts_v(:) = polynominal_gengausslobattoptintweight(elem%PolyOrder_v)
106
107 do f=1, elem%Nfaces_h
108 do k=1, elem%Nnode_v
109 do i=1, elem%Nnode_h1D
110 l = i + (k-1)*elem%Nnode_h1D
111 intweight_h(l) = intweight_lgl1dpts_h(i) * intweight_lgl1dpts_v(k)
112 end do
113 end do
114
115 is = (f-1)*elem%Nfp_h + 1
116 ie = is + elem%Nfp_h - 1
117 intweight(f,is:ie) = intweight_h(:)
118 end do
119
120 do f=1, elem%Nfaces_v
121 do j=1, elem%Nnode_h1D
122 do i=1, elem%Nnode_h1D
123 l = i + (j-1)*elem%Nnode_h1D
124 intweight_v(l) = intweight_lgl1dpts_h(i) * intweight_lgl1dpts_h(j)
125 end do
126 end do
127
128 is = elem%Nfaces_h*elem%Nfp_h + (f-1)*elem%Nfp_v + 1
129 ie = is + elem%Nfp_v - 1
130 intweight(elem%Nfaces_h+f,is:ie) = intweight_v(:)
131 end do
132
133 return
module common / Polynominal
real(rp) function, dimension(nord+1), public polynominal_gengausslobattoptintweight(nord)
A function to calcuate the Gauss-Lobbato weights.

References scale_polynominal::polynominal_gengausslobattoptintweight().

◆ atm_phy_mp_dgm_common_gen_vmap()

subroutine, public scale_atm_phy_mp_dgm_common::atm_phy_mp_dgm_common_gen_vmap ( integer, dimension(elem%nfptot,lmesh%nez), intent(out) vmapm,
integer, dimension(elem%nfptot,lmesh%nez), intent(out) vmapp,
class(localmesh3d), intent(in) lmesh,
class(elementbase3d), intent(in) elem )

Definition at line 137 of file scale_atm_phy_mp_dgm_common.F90.

140 implicit none
141 class(LocalMesh3D), intent(in) :: lmesh
142 class(ElementBase3D), intent(in) :: elem
143 integer, intent(out) :: vmapM(elem%NfpTot,lmesh%NeZ)
144 integer, intent(out) :: vmapP(elem%NfpTot,lmesh%NeZ)
145
146 integer :: ke_z
147 integer :: f
148 integer :: vs, ve
149 !-------------------------------------------------------
150
151 !$omp parallel private(f, vs, ve)
152 !$omp do
153 do ke_z=1, lmesh%NeZ
154 do f=1, elem%Nfaces_h
155 vs = 1 + (f-1)*elem%Nfp_h
156 ve = vs + elem%Nfp_h - 1
157 vmapm(vs:ve,ke_z) = elem%Fmask_h(:,f) + (ke_z-1)*elem%Np
158 end do
159 do f=1, elem%Nfaces_v
160 vs = elem%Nfp_h*elem%Nfaces_h + 1 + (f-1)*elem%Nfp_v
161 ve = vs + elem%Nfp_v - 1
162 vmapm(vs:ve,ke_z) = elem%Fmask_v(:,f) + (ke_z-1)*elem%Np
163 end do
164 vmapp(:,ke_z) = vmapm(:,ke_z)
165 end do
166 !$omp do
167 do ke_z=1, lmesh%NeZ
168 vs = elem%Nfp_h*elem%Nfaces_h + 1
169 ve = vs + elem%Nfp_v - 1
170 if (ke_z > 1) &
171 vmapp(vs:ve,ke_z) = elem%Fmask_v(:,2) + (ke_z-2)*elem%Np
172
173 vs = elem%Nfp_h*elem%Nfaces_h + elem%Nfp_v + 1
174 ve = vs + elem%Nfp_v - 1
175 if (ke_z < lmesh%NeZ) &
176 vmapp(vs:ve,ke_z) = elem%Fmask_v(:,1) + ke_z*elem%Np
177 end do
178 !$omp end parallel
179
180 return

◆ atm_phy_mp_dgm_common_precipitation()

subroutine, public scale_atm_phy_mp_dgm_common::atm_phy_mp_dgm_common_precipitation ( real(rp), dimension (elem%np,lcmesh%nez,lcmesh%ne2d), intent(inout) dens,
real(rp), dimension (elem%np,lcmesh%nez,lcmesh%ne2d,qha), intent(inout) rhoq,
real(rp), dimension(elem%np,lcmesh%nez,lcmesh%ne2d), intent(inout) cptot,
real(rp), dimension(elem%np,lcmesh%nez,lcmesh%ne2d), intent(inout) cvtot,
real(rp), dimension (elem%np,lcmesh%nez,lcmesh%ne2d), intent(inout) rhoe,
real(rp), dimension(elem%np,lcmesh%nez,lcmesh%ne2d), intent(inout) flx_hydro,
real(rp), dimension(elem%nfp_v,lcmesh%ne2da), intent(inout) sflx_rain,
real(rp), dimension(elem%nfp_v,lcmesh%ne2da), intent(inout) sflx_snow,
real(rp), dimension (elem%nfp_v,lcmesh%ne2da), intent(inout) esflx,
real(rp), dimension (elem%np,lcmesh%nez,lcmesh%ne2d), intent(in) temp,
real(rp), dimension(elem%np,lcmesh%nez,lcmesh%ne2d,qha), intent(in) vterm,
real(rp), intent(in) dt,
real(rp), intent(in) rnstep,
type(sparsemat), intent(in) dz,
type(sparsemat), intent(in) lift,
real(rp), dimension(elem%nfptot,lcmesh%nez,lcmesh%ne2d), intent(in) nz,
integer, dimension(elem%nfptot,lcmesh%nez), intent(in) vmapm,
integer, dimension(elem%nfptot,lcmesh%nez), intent(in) vmapp,
real(rp), dimension(elem%nfaces,elem%nfptot), intent(in) intweight,
integer, intent(in) qha,
integer, intent(in) qla,
integer, intent(in) qia,
class(localmesh3d), intent(in) lcmesh,
class(elementbase3d), intent(in) elem )
Parameters
[in]qhahydrometeor (water + ice)

Definition at line 184 of file scale_atm_phy_mp_dgm_common.F90.

190
191 use scale_atmos_hydrometeor, only: &
192 cv_water, &
193 cp_water, &
194 cv_ice, &
195 cp_ice
196
197 implicit none
198
199 class(LocalMesh3D), intent(in) :: lcmesh
200 class(ElementBase3D), intent(in) :: elem
201 integer, intent(in) :: QHA
202 real(RP), intent(inout) :: DENS (elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
203 real(RP), intent(inout) :: RHOQ (elem%Np,lcmesh%NeZ,lcmesh%Ne2D,QHA)
204 real(RP), intent(inout) :: CPtot(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
205 real(RP), intent(inout) :: CVtot(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
206 real(RP), intent(inout) :: RHOE (elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
207 real(RP), intent(inout) :: FLX_hydro(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
208 real(RP), intent(inout) :: sflx_rain(elem%Nfp_v,lcmesh%Ne2DA)
209 real(RP), intent(inout) :: sflx_snow(elem%Nfp_v,lcmesh%Ne2DA)
210 real(RP), intent(inout) :: esflx (elem%Nfp_v,lcmesh%Ne2DA)
211 real(RP), intent(in) :: TEMP (elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
212 real(RP), intent(in) :: vterm(elem%Np,lcmesh%NeZ,lcmesh%Ne2D,QHA)
213 real(RP), intent(in) :: dt
214 real(RP), intent(in) :: rnstep
215 type(SparseMat), intent(in) :: Dz
216 type(SparseMat), intent(in) :: Lift
217 real(RP), intent(in) :: nz(elem%NfpTot,lcmesh%NeZ,lcmesh%Ne2D)
218 integer, intent(in) :: vmapM(elem%NfpTot,lcmesh%NeZ)
219 integer, intent(in) :: vmapP(elem%NfpTot,lcmesh%NeZ)
220 real(RP), intent(in) :: IntWeight(elem%Nfaces,elem%NfpTot)
221 integer, intent(in) :: QLA, QIA
222
223 real(RP) :: qflx(elem%Np)
224 real(RP) :: eflx(elem%Np)
225 real(RP) :: DENS0(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
226 real(RP) :: RHOCP(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
227 real(RP) :: RHOCV(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
228 real(RP) :: NDcoefEuler(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
229 real(RP) :: DzRHOQ(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
230 real(RP) :: DzRHOE(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
231 real(RP) :: dDENS(elem%Np)
232 real(RP) :: CP(QHA)
233 real(RP) :: CV(QHA)
234
235 real(RP) :: fct_coef(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
236 real(RP) :: RHOQ0, RHOQ1, RHOQ_tmp(elem%Np)
237 real(RP) :: netOutwardFlux(lcmesh%NeZ,lcmesh%Ne2D)
238 real(RP) :: del_flux(elem%NfpTot,lcmesh%NeZ,lcmesh%Ne2D,2)
239
240 real(RP) :: Fz(elem%Np), LiftDelFlx(elem%Np)
241 real(RP) :: RHOQ_save(elem%Np)
242
243 integer :: ke2D
244 integer :: ke_z
245 integer :: ke
246 integer :: iq
247
248 real(RP) :: Q
249 real(RP) :: delz
250 !-------------------------------------------------------
251
252 do iq = 1, qha
253 if ( iq > qla + qia ) then
254 cp(iq) = undef
255 cv(iq) = undef
256 else if ( iq > qla ) then ! ice water
257 cp(iq) = cp_ice
258 cv(iq) = cv_ice
259 else ! liquid water
260 cp(iq) = cp_water
261 cv(iq) = cv_water
262 end if
263 end do
264
265 !$omp parallel do collapse(2)
266 do ke2d = 1, lcmesh%Ne2D
267 do ke_z = 1, lcmesh%NeZ
268 dens0(:,ke_z,ke2d) = dens(:,ke_z,ke2d)
269 rhocp(:,ke_z,ke2d) = cptot(:,ke_z,ke2d) * dens(:,ke_z,ke2d)
270 rhocv(:,ke_z,ke2d) = cvtot(:,ke_z,ke2d) * dens(:,ke_z,ke2d)
271 end do
272 end do
273
274 do iq = 1, qha
275 call atm_phy_mp_dgm_precipitation_get_delflux_dq( &
276 del_flux(:,:,:,:), & ! (out)
277 dens0(:,:,:), rhoq(:,:,:,iq), temp(:,:,:), cv(iq), nz(:,:,:), vmapm(:,:), vmapp(:,:), & ! (in)
278 lcmesh, elem ) ! (in)
279
280 !$omp parallel do private( &
281 !$omp ke2D, ke_z, ke, delz, Fz, LiftDelFlx )
282 do ke2d = 1, lcmesh%Ne2D
283 do ke_z = 1, lcmesh%NeZ
284 ke = ke2d + (ke_z-1)*lcmesh%Ne2D
285 delz = ( lcmesh%pos_ev(lcmesh%EToV(ke,5),3) - lcmesh%pos_ev(lcmesh%EToV(ke,1),3) ) / dble( elem%Nnode_v )
286
287 call sparsemat_matmul( dz, rhoq(:,ke_z,ke2d,iq), fz )
288 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke) * del_flux(:,ke_z,ke2d,1), liftdelflx )
289 dzrhoq(:,ke_z,ke2d) = lcmesh%Escale(:,ke,3,3) * fz(:) + liftdelflx(:)
290
291 call sparsemat_matmul( dz, rhoq(:,ke_z,ke2d,iq) * cv(iq) * temp(:,ke_z,ke2d), fz )
292 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke) * del_flux(:,ke_z,ke2d,2), liftdelflx )
293 dzrhoe(:,ke_z,ke2d) = lcmesh%Escale(:,ke,3,3) * fz(:) + liftdelflx(:)
294
295 ndcoefeuler(:,ke_z,ke2d) = 0.5_rp * delz * abs(vterm(:,ke_z,ke2d,iq))
296 end do
297 end do
298
299 call atm_phy_mp_dgm_netoutwardflux( &
300 netoutwardflux(:,:), & ! (out)
301 rhoq(:,:,:,iq), vterm(:,:,:,iq), dzrhoq(:,:,:), ndcoefeuler(:,:,:), & ! (in)
302 lcmesh%J(:,:), lcmesh%Fscale(:,:), & ! (in)
303 nz(:,:,:), vmapm(:,:), vmapp(:,:), lcmesh%VMapM(:,:), intweight(:,:), & ! (in)
304 lcmesh, elem ) ! (in)
305
306 !$omp parallel do collapse(2) private(ke, Q)
307 do ke2d = 1, lcmesh%Ne2D
308 do ke_z = 1, lcmesh%NeZ
309 ke = ke2d + (ke_z-1)*lcmesh%Ne2D
310
311 q = sum( lcmesh%J(:,ke) * elem%IntWeight_lgl(:) * rhoq(:,ke_z,ke2d,iq) ) / dt
312 fct_coef(:,ke_z,ke2d) = max( 0.0_rp, min( 1.0_rp, q / ( netoutwardflux(ke_z,ke2d) + 1.0e-10_rp ) ) )
313 end do ! end loop for ke_z
314 end do ! end loop for ke2D
315
316 call atm_phy_mp_dgm_precipitation_get_delflux( &
317 del_flux(:,:,:,:), & ! (out)
318 dens0(:,:,:), rhoq(:,:,:,iq), temp(:,:,:), vterm(:,:,:,iq), & ! (in)
319 dzrhoq(:,:,:), dzrhoe(:,:,:), ndcoefeuler(:,:,:), & ! (in)
320 fct_coef(:,:,:), & ! (in)
321 cv(iq), lcmesh%J(:,:), lcmesh%Fscale(:,:), nz(:,:,:), & ! (in)
322 vmapm(:,:), vmapp(:,:), lcmesh%vmapM(:,:), intweight(:,:), & ! (in)
323 lcmesh, elem ) ! (in)
324
325 !$omp parallel do collapse(2) private( &
326 !$omp ke2D, ke_z, ke, &
327 !$omp qflx, eflx, dDENS, RHOQ_tmp, RHOQ0, RHOQ1, &
328 !$omp RHOQ_save, &
329 !$omp Fz, LiftDelFlx )
330 do ke2d = 1, lcmesh%Ne2D
331 do ke_z = 1, lcmesh%NeZ
332 ke = ke2d + (ke_z-1)*lcmesh%Ne2D
333
334 !--- update falling tracer
335
336 rhoq_save(:) = rhoq(:,ke_z,ke2d,iq)
337 qflx(:) = vterm(:,ke_z,ke2d,iq) * rhoq(:,ke_z,ke2d,iq) &
338 - ndcoefeuler(:,ke_z,ke2d) * dzrhoq(:,ke_z,ke2d)
339
340 call sparsemat_matmul( dz, qflx(:), fz )
341 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke) * del_flux(:,ke_z,ke2d,1), liftdelflx )
342
343 ddens(:) = - dt * ( &
344 lcmesh%Escale(:,ke,3,3) * fz(:) + liftdelflx(:) )
345 rhoq_tmp(:) = max( 0.0_rp, rhoq(:,ke_z,ke2d,iq) + ddens(:) )
346! RHOQ_tmp(:) = RHOQ(:,ke_z,ke2D,iq) + dDENS(:)
347
348 !
349 rhoq0 = sum( lcmesh%Gsqrt(:,ke) * lcmesh%J(:,ke) * elem%IntWeight_lgl(:) * ( rhoq(:,ke_z,ke2d,iq) + ddens(:) ) )
350 rhoq1 = sum( lcmesh%Gsqrt(:,ke) * lcmesh%J(:,ke) * elem%IntWeight_lgl(:) * rhoq_tmp(:) )
351
352 ddens(:) = rhoq0 / ( rhoq1 + 1.0e-32_rp ) * rhoq_tmp(:) &
353 - rhoq(:,ke_z,ke2d,iq)
354 rhoq(:,ke_z,ke2d,iq) = rhoq(:,ke_z,ke2d,iq) + ddens(:)
355
356
357 ! QTRC(iq; iq>QLA+QLI) is not mass tracer, such as number density
358 if ( iq > qla + qia ) cycle
359
360 flx_hydro(:,ke_z,ke2d) = flx_hydro(:,ke_z,ke2d) &
361 + qflx(:) * rnstep
362 if ( ke_z == 1 ) then
363 if ( iq > qla ) then ! ice water
364 sflx_snow(:,ke2d) = sflx_snow(:,ke2d) &
365 + qflx(elem%Hslice(:,1)) * rnstep
366 else ! liquid water
367 sflx_rain(:,ke2d) = sflx_rain(:,ke2d) &
368 + qflx(elem%Hslice(:,1)) * rnstep
369 end if
370 end if
371
372 !--- update density
373
374 rhocp(:,ke_z,ke2d) = rhocp(:,ke_z,ke2d) + cp(iq) * ddens(:)
375 rhocv(:,ke_z,ke2d) = rhocv(:,ke_z,ke2d) + cv(iq) * ddens(:)
376 dens(:,ke_z,ke2d) = dens(:,ke_z,ke2d) + ddens(:)
377
378 !--- update internal energy
379
380 eflx(:) = vterm(:,ke_z,ke2d,iq) * rhoq_save(:) * temp(:,ke_z,ke2d) * cv(iq) &
381 - ndcoefeuler(:,ke_z,ke2d) * dzrhoe(:,ke_z,ke2d)
382
383 call sparsemat_matmul( dz, eflx(:), fz )
384 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke) * del_flux(:,ke_z,ke2d,2), liftdelflx )
385
386 rhoe(:,ke_z,ke2d) = rhoe(:,ke_z,ke2d) - dt * ( &
387 + lcmesh%Escale(:,ke,3,3) * fz(:) + liftdelflx(:) &
388 + qflx(:) * grav )
389
390 if ( ke_z == 1 ) then
391 esflx(:,ke2d) = esflx(:,ke2d) &
392 + eflx(elem%Hslice(:,1)) * rnstep
393 end if
394
395 end do ! end loop for ke_z
396 end do ! end loop for ke2D
397 end do ! end loop for iq
398
399 !$omp parallel do collapse(2)
400 do ke2d = 1, lcmesh%Ne2D
401 do ke_z = 1, lcmesh%NeZ
402 cptot(:,ke_z,ke2d) = rhocp(:,ke_z,ke2d) / dens(:,ke_z,ke2d)
403 cvtot(:,ke_z,ke2d) = rhocv(:,ke_z,ke2d) / dens(:,ke_z,ke2d)
404 end do
405 end do
406
407 return

◆ atm_phy_mp_dgm_common_precipitation_momentum()

subroutine, public scale_atm_phy_mp_dgm_common::atm_phy_mp_dgm_common_precipitation_momentum ( real(rp), dimension(elem%np,lcmesh%nea), intent(out) momu_t,
real(rp), dimension(elem%np,lcmesh%nea), intent(out) momv_t,
real(rp), dimension(elem%np,lcmesh%nea), intent(out) momz_t,
real(rp), dimension(elem%np,lcmesh%nez,lcmesh%ne2d), intent(in) dens,
real(rp), dimension(elem%np,lcmesh%nez,lcmesh%ne2d), intent(in) momu,
real(rp), dimension(elem%np,lcmesh%nez,lcmesh%ne2d), intent(in) momv,
real(rp), dimension(elem%np,lcmesh%nez,lcmesh%ne2d), intent(in) momz,
real(rp), dimension(elem%np,lcmesh%nez,lcmesh%ne2d), intent(in) mflx,
type(sparsemat), intent(in) dz,
type(sparsemat), intent(in) lift,
real(rp), dimension(elem%nfptot,lcmesh%nez,lcmesh%ne2d), intent(in) nz,
integer, dimension(elem%nfptot,lcmesh%nez), intent(in) vmapm,
integer, dimension(elem%nfptot,lcmesh%nez), intent(in) vmapp,
class(localmesh3d), intent(in) lcmesh,
class(elementbase3d), intent(in) elem )

Definition at line 411 of file scale_atm_phy_mp_dgm_common.F90.

416 implicit none
417
418 class(LocalMesh3D), intent(in) :: lcmesh
419 class(ElementBase3D), intent(in) :: elem
420 real(RP), intent(out) :: MOMU_t(elem%Np,lcmesh%NeA)
421 real(RP), intent(out) :: MOMV_t(elem%Np,lcmesh%NeA)
422 real(RP), intent(out) :: MOMZ_t(elem%Np,lcmesh%NeA)
423 real(RP), intent(in) :: DENS(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
424 real(RP), intent(in) :: MOMU(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
425 real(RP), intent(in) :: MOMV(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
426 real(RP), intent(in) :: MOMZ(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
427 real(RP), intent(in) :: mflx(elem%Np,lcmesh%NeZ,lcmesh%Ne2D)
428 type(SparseMat), intent(in) :: Dz
429 type(SparseMat), intent(in) :: Lift
430 real(RP), intent(in) :: nz(elem%NfpTot,lcmesh%NeZ,lcmesh%Ne2D)
431 integer, intent(in) :: vmapM(elem%NfpTot,lcmesh%NeZ)
432 integer, intent(in) :: vmapP(elem%NfpTot,lcmesh%NeZ)
433
434 integer :: ke2D
435 integer :: ke_z
436 integer :: ke
437
438 real(RP) :: Fz(elem%Np), LiftDelFlx(elem%Np)
439 real(RP) :: del_flux(elem%NfpTot,lcmesh%NeZ,lcmesh%Ne2D,3)
440
441 real(RP) :: RDENS(elem%Np)
442 !-------------------------------------------------------
443
444 call atm_phy_mp_dgm_precipitation_momentum_get_delflux( &
445 del_flux(:,:,:,:), & ! (out)
446 dens(:,:,:), momu(:,:,:), momv(:,:,:), momz(:,:,:), & ! (in)
447 mflx(:,:,:), & ! (in)
448 nz(:,:,:), vmapm(:,:), vmapp(:,:), & ! (in)
449 lcmesh, elem ) ! (in)
450
451 !$omp parallel do collapse(2) private( &
452 !$omp ke2D, ke_z, ke, RDENS, Fz, LiftDelFlx )
453 do ke2d = 1, lcmesh%Ne2D
454 do ke_z = 1, lcmesh%NeZ
455 ke = ke2d + (ke_z-1)*lcmesh%Ne2D
456 rdens(:) = 1.0_rp / dens(:,ke_z,ke2d)
457
458 call sparsemat_matmul( dz, mflx(:,ke_z,ke2d) * momu(:,ke_z,ke2d) * rdens(:), fz )
459 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke) * del_flux(:,ke_z,ke2d,1), liftdelflx )
460 momu_t(:,ke) = - ( lcmesh%Escale(:,ke,3,3) * fz(:) + liftdelflx(:) )
461
462 call sparsemat_matmul( dz, mflx(:,ke_z,ke2d) * momv(:,ke_z,ke2d) * rdens(:), fz )
463 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke) * del_flux(:,ke_z,ke2d,2), liftdelflx )
464 momv_t(:,ke) = - ( lcmesh%Escale(:,ke,3,3) * fz(:) + liftdelflx(:) )
465
466 call sparsemat_matmul( dz, mflx(:,ke_z,ke2d) * momz(:,ke_z,ke2d) * rdens(:), fz )
467 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke) * del_flux(:,ke_z,ke2d,3), liftdelflx )
468 momz_t(:,ke) = - ( lcmesh%Escale(:,ke,3,3) * fz(:) + liftdelflx(:) )
469 end do
470 end do
471
472 return

◆ atm_phy_mp_dgm_common_negative_fixer()

subroutine, public scale_atm_phy_mp_dgm_common::atm_phy_mp_dgm_common_negative_fixer ( type(localmeshfieldbaselist), dimension(qa), intent(inout) qtrc,
real(rp), dimension(elem%np,lmesh%nea), intent(inout) ddens,
real(rp), dimension(elem%np,lmesh%nea), intent(inout) pres,
real(rp), dimension(elem%np,lmesh%nea), intent(inout) cvtot,
real(rp), dimension(elem%np,lmesh%nea), intent(inout) cptot,
real(rp), dimension(elem%np,lmesh%nea), intent(inout) rtot,
real(rp), dimension(elem%np,lmesh%nea), intent(in) dens_hyd,
real(rp), dimension(elem%np,lmesh%nea), intent(in) pres_hyd,
real(rp), intent(in) dt,
class(localmesh3d), intent(in) lmesh,
class(elementbase3d), intent(in) elem,
integer, intent(in) qa,
integer, intent(in) qla,
integer, intent(in) qia,
real(rp), dimension(elem%np,lmesh%nea), intent(inout), optional drhot )

Definition at line 477 of file scale_atm_phy_mp_dgm_common.F90.

483
484 use scale_const, only: &
485 cvdry => const_cvdry, &
486 cpdry => const_cpdry, &
487 rdry => const_rdry
488
489 use scale_tracer, only: &
490 tracer_mass, tracer_r, tracer_cv, tracer_cp
491 use scale_atmos_thermodyn, only: &
492 atmos_thermodyn_specific_heat
494 implicit none
495
496 class(LocalMesh3D), intent(in) :: lmesh
497 class(ElementBase3D), intent(in) :: elem
498 integer, intent(in) :: QA
499 type(LocalMeshFieldBaseList), intent(inout) :: QTRC(QA)
500 real(RP), intent(inout) :: DDENS(elem%Np,lmesh%NeA)
501 real(RP), intent(inout) :: PRES(elem%Np,lmesh%NeA)
502 real(RP), intent(inout) :: CVtot(elem%Np,lmesh%NeA)
503 real(RP), intent(inout) :: CPtot(elem%Np,lmesh%NeA)
504 real(RP), intent(inout) :: Rtot(elem%Np,lmesh%NeA)
505 real(RP), intent(in) :: DENS_hyd(elem%Np,lmesh%NeA)
506 real(RP), intent(in) :: PRES_hyd(elem%Np,lmesh%NeA)
507 real(RP), intent(in) :: dt
508 integer, intent(in) :: QLA, QIA
509 real(RP), intent(inout), optional :: DRHOT(elem%Np,lmesh%NeA)
510
511 integer :: ke
512 integer :: iq
513
514 real(RP) :: int_w(elem%Np)
515
516 real(RP) :: DENS(elem%Np)
517 real(RP) :: DDENS0(elem%Np)
518
519 real(RP) :: TRCMASS0(elem%Np), TRCMASS1(elem%Np,QA)
520 real(RP) :: MASS0_elem, MASS1_elem
521 real(RP) :: IntEn0_elem, IntEn_elem
522
523 real(RP) :: QTRC_tmp(elem%Np,QA), Qdry(elem%Np)
524 real(RP) :: CVtot_old(elem%Np), CPtot_old(elem%Np), Rtot_old(elem%Np)
525 real(RP) :: InternalEn(elem%Np), InternalEn0(elem%Np), TEMP(elem%Np)
526 real(RP) :: RHOT_hyd(elem%Np)
527
528#ifdef SINGLE
529 real(RP), parameter :: TRC_EPS = 1e-32_rp
530#else
531 real(RP), parameter :: TRC_EPS = 1e-128_rp
532#endif
533 !------------------------------------------------
534
535 !$omp parallel do private( &
536 !$omp ke, iq, DENS, DDENS0, InternalEn, InternalEn0, TEMP, QTRC_tmp, &
537 !$omp TRCMASS0, TRCMASS1, MASS0_elem, MASS1_elem, IntEn0_elem, IntEn_elem, &
538 !$omp Qdry, CVtot_old, CPtot_old, Rtot_old, &
539 !$omp int_w, RHOT_hyd )
540 do ke = lmesh%NeS, lmesh%NeE
541
542 do iq = 1, qa
543 qtrc_tmp(:,iq) = qtrc(iq)%ptr%val(:,ke)
544 end do
545 call atmos_thermodyn_specific_heat( &
546 elem%Np, 1, elem%Np, qa, & ! (in)
547 qtrc_tmp, tracer_mass(:), tracer_r(:), tracer_cv(:), tracer_cp(:), & ! (in)
548 qdry, rtot_old, cvtot_old, cptot_old ) ! (out)
549
550 dens(:) = dens_hyd(:,ke) + ddens(:,ke)
551 ddens0(:) = ddens(:,ke)
552
553 ! RHOT_hyd(:) = PRES00 / Rdry * ( PRES_hyd(:,ke) / PRES00 )**( CVdry / CPdry )
554 ! ( Internal energy ) = Cvtot * RHO * T = CVtot * RHO * ( PT * EXNER )
555 ! InternalEn0(:) = CVtot_old(:) * ( RHOT_hyd(:) + DRHOT(:,ke) ) &
556 ! * ( Rtot_old(:) * ( RHOT_hyd(:) + DRHOT(:,ke) ) / PRES00 )**( Rtot_old(:) / CVtot_old(:) )
557 !InternalEn0(:) = CVtot_old(:) * PRES(:,ke) / Rtot_old(:)
558 internalen0(:) = cvtot(:,ke) * pres(:,ke) / rtot(:,ke)
559 !TEMP(:) = InternalEn0(:) / ( DENS(:) * CVtot_old(:) )
560 temp(:) = internalen0(:) / ( dens(:) * cvtot(:,ke) )
561 internalen(:) = internalen0(:)
562
563 int_w(:) = lmesh%Gsqrt(:,ke) * lmesh%J(:,ke) * elem%IntWeight_lgl(:)
564 do iq = 1, 1 + qla + qia
565 trcmass0(:) = dens(:) * qtrc_tmp(:,iq)
566 trcmass1(:,iq) = max( trc_eps, trcmass0(:) )
567
568 mass0_elem = sum( int_w(:) * trcmass0(:) )
569 mass1_elem = sum( int_w(:) * trcmass1(:,iq) )
570 trcmass1(:,iq) = max(mass0_elem, 0.0e0_rp) / mass1_elem * trcmass1(:,iq)
571! TRCMASS1(:,iq) = MASS0_elem / MASS1_elem * TRCMASS1(:,iq)
572
573 ddens(:,ke) = ddens(:,ke) + ( trcmass1(:,iq) - trcmass0(:) )
574 internalen(:) = internalen(:) + ( trcmass1(:,iq) - trcmass0(:) ) * tracer_cv(iq) * temp(:)
575 end do
576
577 !--
578
579 dens(:) = dens_hyd(:,ke) + ddens(:,ke)
580 do iq = 1, qa
581 qtrc_tmp(:,iq) = trcmass1(:,iq) / dens(:)
582 qtrc(iq)%ptr%val(:,ke) = qtrc_tmp(:,iq)
583 end do
584
585 inten0_elem = sum( int_w(:) * internalen0(:) )
586 inten_elem = sum( int_w(:) * internalen(:) )
587 internalen(:) = inten0_elem / inten_elem * internalen(:)
588
589 call atmos_thermodyn_specific_heat( &
590 elem%Np, 1, elem%Np, qa, & ! (in)
591 qtrc_tmp, tracer_mass(:), tracer_r(:), tracer_cv(:), tracer_cp(:), & ! (in)
592 qdry, rtot(:,ke), cvtot(:,ke), cptot(:,ke) ) ! (out)
593
594 internalen(:) = internalen(:) - ( ddens(:,ke) - ddens0(:) ) * grav * lmesh%zlev(:,ke)
595 pres(:,ke) = internalen(:) * rtot(:,ke) / cvtot(:,ke)
596
597 if ( present(drhot) ) then
598 drhot(:,ke) = pres00 / rtot(:,ke) * ( pres(:,ke) / pres00 )**( cvtot(:,ke) / cptot(:,ke) ) &
599 - pres00 / rdry * ( pres_hyd(:,ke) / pres00 )**( cvdry / cpdry )
600 end if
601 end do
602
603 return