FE-Project
Loading...
Searching...
No Matches
scale_atm_dyn_dgm_nonhydro3d_common.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Fluid dyn solver / Atmosphere / Nonhydrostatic model / Common
3!!
4!! @par Description
5!! A common model for atmospheric nonhydrostatic dynamical core
6!!
7!! @author Yuta Kawai, Team SCALE
8!<
9!-------------------------------------------------------------------------------
10#include "scaleFElib.h"
12 !-----------------------------------------------------------------------------
13 !
14 !++ Used modules
15 !
16 use scale_precision
17 use scale_io
18 use scale_prc
19 use scale_prof
20 use scale_const, only: &
21 grav => const_grav, &
22 rdry => const_rdry, &
23 cpdry => const_cpdry, &
24 cvdry => const_cvdry, &
25 pres00 => const_pre00
26
28 use scale_element_base, only: &
37
38 use scale_model_var_manager, only: &
39 modelvarmanager, variableinfo
40
42
43 !-----------------------------------------------------------------------------
44 implicit none
45 private
46 !-----------------------------------------------------------------------------
47 !
48 !++ Public procedures
49 !
61
62 !-----------------------------------------------------------------------------
63 !
64 !++ Public parameters & variables
65 !
66
67 !-
68 integer, public, parameter :: prgvar_ddens_id = 1
69 integer, public, parameter :: prgvar_therm_id = 2 ! Variable associated with energy equation (DRHOT or ETOT)
70 integer, public, parameter :: prgvar_drhot_id = 2
71 integer, public, parameter :: prgvar_etot_id = 2
72 integer, public, parameter :: prgvar_momz_id = 3
73 integer, public, parameter :: prgvar_momx_id = 4
74 integer, public, parameter :: prgvar_momy_id = 5
75 integer, public, parameter :: prgvar_scalar_num = 3
76 integer, public, parameter :: prgvar_hvec_num = 1
77 integer, public, parameter :: prgvar_num = 5
78
79 integer, public, parameter :: phytend_dens_id = 1
80 integer, public, parameter :: phytend_momx_id = 2
81 integer, public, parameter :: phytend_momy_id = 3
82 integer, public, parameter :: phytend_momz_id = 4
83 integer, public, parameter :: phytend_rhot_id = 5
84 integer, public, parameter :: phytend_rhoh_id = 6
85 integer, public, parameter :: phytend_num = 6
86
87 !-
88 integer, public, parameter :: auxvar_preshydro_id = 1
89 integer, public, parameter :: auxvar_denshydro_id = 2
90 integer, public, parameter :: auxvar_thermhydro_id = 3
91 integer, public, parameter :: auxvar_pres_id = 4
92 integer, public, parameter :: auxvar_pt_id = 5
93 integer, public, parameter :: auxvar_rtot_id = 6
94 integer, public, parameter :: auxvar_cvtot_id = 7
95 integer, public, parameter :: auxvar_cptot_id = 8
96 integer, public, parameter :: auxvar_qdry_id = 9
97 integer, public, parameter :: auxvar_preshydro_ref_id = 10
98 integer, public, parameter :: auxvar_num = 10
99
100
101
102 real(rp), public, allocatable :: intrpmat_vpordm1(:,:)
103
104 !-----------------------------------------------------------------------------
105 !
106 !++ Private procedures & variables
107 !
108 !-------------------
109
110contains
111 !> Initialize a common module for atmospheric nonhydrostatic dynamical core
113 implicit none
114 class(meshbase3d), intent(in) :: mesh
115
116 type(elementbase3d), pointer :: elem
117 !--------------------------------------------
118
119 elem => mesh%refElem3D
120 allocate( intrpmat_vpordm1(elem%Np,elem%Np) )
121 call mesh%refElem3D%Generate_ModalTruncationMat( elem%PolyOrder_h, elem%PolyOrder_v-1, & ! (in)
122 intrpmat_vpordm1 ) ! (out)
123 return
125
126
127 !> Finalize a common module for atmospheric nonhydrostatic dynamical core
129 implicit none
130 !--------------------------------------------
131
132 deallocate( intrpmat_vpordm1 )
133 return
135
136 !> Get variable information for atmospheric nonhydrostatic dynamical core
138 prgvar_info, auxvar_info, phytend_info )
139
140 implicit none
141 type(variableinfo), intent(out) :: prgvar_info(prgvar_num)
142 type(variableinfo), intent(out) :: auxvar_info(auxvar_num)
143 type(variableinfo), intent(out), optional :: phytend_info(phytend_num)
144
145 type(variableinfo) :: prgvar_varinfo(prgvar_num)
146 DATA prgvar_varinfo / &
147 variableinfo( prgvar_ddens_id, 'DDENS', 'deviation of density', &
148 'kg/m3', 3, 'XYZ', 'air_density' ), &
149 variableinfo( prgvar_therm_id, 'THERM', 'THERM', &
150 '-', 3, 'XYZ', '' ), &
151 variableinfo( prgvar_momz_id , 'MOMZ', 'momentum z', &
152 'kg/m2/s', 3, 'XYZ', 'northward_mass_flux_of_air' ), &
153 variableinfo( prgvar_momx_id , 'MOMX', 'momentum x', &
154 'kg/m2/s', 3, 'XYZ', 'upward_mass_flux_of_air' ), &
155 variableinfo( prgvar_momy_id , 'MOMY', 'momentum y', &
156 'kg/m2/s', 3, 'XYZ', 'eastward_mass_flux_of_air' ) /
157
158 type(variableinfo) :: auxvar_varinfo(auxvar_num)
159 DATA auxvar_varinfo / &
160 variableinfo( auxvar_preshydro_id, 'PRES_hyd', 'hydrostatic part of pressure', &
161 'Pa', 3, 'XYZ', '' ), &
162 variableinfo( auxvar_denshydro_id, 'DENS_hyd', 'hydrostatic part of density', &
163 'kg/m3', 3, 'XYZ', '' ), &
164 variableinfo( auxvar_thermhydro_id, 'THERM_hyd', 'hydrostatic part of THERM', &
165 'kg/m3', 3, 'XYZ', '' ), &
166 variableinfo( auxvar_pres_id , 'PRES', 'pressure', &
167 'Pa', 3, 'XYZ', 'air_pressure' ), &
168 variableinfo( auxvar_pt_id , 'PT', 'potential temperature', &
169 'K', 3, 'XYZ', 'potential_temperature' ), &
170 variableinfo( auxvar_rtot_id , 'RTOT', 'Total gas constant', &
171 'J/kg/K', 3, 'XYZ', '' ), &
172 variableinfo( auxvar_cvtot_id , 'CVTOT', 'Total heat capacity', &
173 'J/kg/K', 3, 'XYZ', '' ), &
174 variableinfo( auxvar_cptot_id , 'CPTOT', 'Total heat capacity', &
175 'J/kg/K', 3, 'XYZ', '' ), &
176 variableinfo( auxvar_qdry_id , 'QDRY', 'dry air', &
177 'kg/kg', 3, 'XYZ', '' ), &
178 variableinfo( auxvar_preshydro_ref_id, 'PRES_hyd_REF', 'hydrostatic reference pressure', &
179 'Pa', 3, 'XYZ', '' )/
180
181 type(variableinfo) :: phytend_varinfo(phytend_num)
182 DATA phytend_varinfo / &
183 variableinfo( phytend_dens_id, 'DENS_tp', 'DENS_tp', &
184 'kg/m3/s', 3, 'XYZ', 'tendency of physical process for DENS' ), &
185 variableinfo( phytend_momx_id, 'MOMX_tp', 'MOMX_tp', &
186 'kg/m2/s', 3, 'XYZ', 'tendency of physical process for MOMX' ), &
187 variableinfo( phytend_momy_id, 'MOMY_tp', 'MOMY_tp', &
188 'kg/m2/s', 3, 'XYZ', 'tendency of physical process for MOMY' ), &
189 variableinfo( phytend_momz_id, 'MOMZ_tp', 'MOMZ_tp', &
190 'kg/m2/s', 3, 'XYZ', 'tendency of physical process for MOMZ' ), &
191 variableinfo( phytend_rhot_id, 'RHOT_tp', 'RHOT_tp', &
192 'kg/m3.K/s', 3, 'XYZ', 'tendency of physical process for RHOT' ), &
193 variableinfo( phytend_rhoh_id, 'RHOH_p', 'RHOH_p', &
194 'kg/m3.J/s', 3, 'XYZ', 'heating of physical process for THERM' ) /
195
196 !----------------------------------------------------------
197
198 prgvar_info(:) = prgvar_varinfo
199 auxvar_info(:) = auxvar_varinfo
200 if ( present(phytend_info) ) phytend_info(:) = phytend_varinfo
201
202 return
204
205 !> Setup variable managers for atmospheric nonhydrostatic dynamical core
207 prgvars, qtrcvars, auxvars, phytends, & ! (inout)
208 prgvar_manager, qtrcvar_manager, auxvar_manager, phytend_manager, & ! (inout)
209 reg_file_hist, do_setup_phytend, phytend_num_tot, mesh3d, & ! (in)
210 prgvar_varinfo ) ! (out)
211
212 use scale_atmos_hydrometeor, only: &
213 atmos_hydrometeor_dry
214 use scale_tracer, only: &
215 qa, tracer_name, tracer_desc, tracer_unit
218 implicit none
219 integer, intent(in) :: phytend_num_tot
220 type(meshfield3d), intent(inout) :: prgvars(prgvar_num) !< Array of objects to manage prognostic variables
221 type(meshfield3d), intent(inout) :: qtrcvars(0:qa) !< Array of objects to manage tracer variables
222 type(meshfield3d), intent(inout) :: auxvars(auxvar_num) !< Array of objects to manage auxiliary variables
223 type(meshfield3d), intent(inout) :: phytends(phytend_num_tot) !< Array of objects to manage physics tendency variables
224 type(modelvarmanager), intent(inout) :: prgvar_manager !< Object to manage prognostic variables
225 type(modelvarmanager), intent(inout) :: qtrcvar_manager !< Object to manage tracer variables
226 type(modelvarmanager), intent(inout) :: auxvar_manager !< Object to manage auxiliary variables
227 type(modelvarmanager), intent(inout) :: phytend_manager !< Object to manage physics tendency variables
228 logical, intent(in) :: reg_file_hist !< Flag whether variables are registered for history file output or not
229 logical, intent(in) :: do_setup_phytend !< Flag whether to setup physics tendency variables or not
230 class(meshbase3d), intent(in) :: mesh3d !< Object to manage 3D mesh
231 type(variableinfo), intent(out) :: prgvar_varinfo(prgvar_num) !< Variable information with prognostic variables
232
233 type(variableinfo) :: auxvar_varinfo(auxvar_num)
234 type(variableinfo) :: phytend_varinfo(phytend_num)
235
236 integer :: iv
237 integer :: iq
238
239 type(variableinfo) :: qtrc_dry_vinfo_tmp
240 type(variableinfo) :: qtrc_dry_tp_vinfo_tmp
241 type(variableinfo) :: qtrc_vinfo_tmp
242 type(variableinfo) :: qtrc_tp_vinfo_tmp
243 !----------------------------------------------------------
244
245 call atm_dyn_dgm_nonhydro3d_common_get_varinfo( prgvar_varinfo, auxvar_varinfo, phytend_varinfo ) ! (out)
246
247 !- Initialize prognostic variables
248
249 do iv = 1, prgvar_num
250 call prgvar_manager%Regist( &
251 prgvar_varinfo(iv), mesh3d, & ! (in)
252 prgvars(iv), & ! (inout)
253 reg_file_hist, monitor_flag=.true., fill_zero=.true. ) ! (out)
254 !$acc update device( prgvars(iv) )
255 end do
256
257 !- Initialize tracer variables
258
259 if ( qa == 0 ) then
260 ! Dummy
261 qtrc_dry_vinfo_tmp%ndims = 3
262 qtrc_dry_vinfo_tmp%dim_type = 'XYZ'
263 qtrc_dry_vinfo_tmp%STDNAME = ''
264
265 qtrc_dry_vinfo_tmp%keyID = 0
266 qtrc_dry_vinfo_tmp%NAME = "QV"
267 qtrc_dry_vinfo_tmp%DESC = "Ratio of Water Vapor mass to total mass (Specific humidity)"
268 qtrc_dry_vinfo_tmp%UNIT = "kg/kg"
269 call qtrcvar_manager%Regist( &
270 qtrc_dry_vinfo_tmp, mesh3d, & ! (in)
271 qtrcvars(0), & ! (inout)
272 .false., monitor_flag=.false., fill_zero=.true. ) ! (in)
273 else
274 qtrc_vinfo_tmp%ndims = 3
275 qtrc_vinfo_tmp%dim_type = 'XYZ'
276 qtrc_vinfo_tmp%STDNAME = ''
277
278 do iq = 1, qa
279 qtrc_vinfo_tmp%keyID = iq
280 qtrc_vinfo_tmp%NAME = tracer_name(iq)
281 qtrc_vinfo_tmp%DESC = tracer_desc(iq)
282 qtrc_vinfo_tmp%UNIT = tracer_unit(iq)
283 call qtrcvar_manager%Regist( &
284 qtrc_vinfo_tmp, mesh3d, & ! (in)
285 qtrcvars(iq), & ! (inout)
286 reg_file_hist, monitor_flag=.true., fill_zero=.true. ) ! (in)
287 end do
288 end if
289
290 !- Initialize auxiliary variables
291
292 do iv = 1, auxvar_num
293 call auxvar_manager%Regist( &
294 auxvar_varinfo(iv), mesh3d, & ! (in)
295 auxvars(iv), & ! (inout)
296 reg_file_hist, fill_zero=.true. ) ! (in)
297 end do
298
299 !- Initialize the tendency of physical processes
300
301 if ( do_setup_phytend ) then
302
303 do iv = 1, phytend_num
304 call phytend_manager%Regist( &
305 phytend_varinfo(iv), mesh3d, & ! (in)
306 phytends(iv), & ! (inout)
307 reg_file_hist, fill_zero=.true. ) ! (in)
308 end do
309
310 if ( qa == 0 ) then
311 ! Dummy
312 qtrc_dry_tp_vinfo_tmp%ndims = 3
313 qtrc_dry_tp_vinfo_tmp%dim_type = 'XYZ'
314 qtrc_dry_tp_vinfo_tmp%STDNAME = ''
315
316 iv = phytend_num + 1
317 qtrc_dry_tp_vinfo_tmp%keyID = iv
318 qtrc_dry_tp_vinfo_tmp%NAME = "QV_tp"
319 qtrc_dry_tp_vinfo_tmp%DESC = "tendency of physical process for QV"
320 qtrc_dry_tp_vinfo_tmp%UNIT = "kg/m3/s"
321 call phytend_manager%Regist( &
322 qtrc_dry_tp_vinfo_tmp, mesh3d, & ! (in)
323 phytends(iv), & ! (inout)
324 .false., fill_zero=.true. ) ! (in)
325 else
326 qtrc_tp_vinfo_tmp%ndims = 3
327 qtrc_tp_vinfo_tmp%dim_type = 'XYZ'
328 qtrc_tp_vinfo_tmp%STDNAME = ''
329
330 do iq = 1, qa
331 iv = phytend_num + iq
332 qtrc_tp_vinfo_tmp%keyID = iv
333 qtrc_tp_vinfo_tmp%NAME = trim(tracer_name(iq))//'_tp'
334 qtrc_tp_vinfo_tmp%DESC = 'tendency of physical process for '//trim(tracer_desc(iq))
335 qtrc_tp_vinfo_tmp%UNIT = trim(tracer_unit(iq))//'/s'
336
337 call phytend_manager%Regist( &
338 qtrc_tp_vinfo_tmp, mesh3d, & ! (in)
339 phytends(iv), & ! (inout)
340 reg_file_hist, fill_zero=.true. ) ! (in)
341 end do
342 end if
343
344 end if
345
346 return
348
349!OCL SERIAL
351 PRES, DPRES, & ! (inout)
352 ddens, momx, momy, momz, therm, & ! (in)
353 pres_hyd, dens_hyd, therm_hyd, rtot, cvtot, cptot, & ! (in)
354 mesh3d, entot_conserve_scheme_flag ) ! (in)
355
356 implicit none
357 class(meshfield3d), intent(inout) :: pres
358 class(meshfield3d), intent(inout) :: dpres
359 class(meshfield3d), intent(in) :: ddens
360 class(meshfield3d), intent(in) :: momx
361 class(meshfield3d), intent(in) :: momy
362 class(meshfield3d), intent(in) :: momz
363 class(meshfield3d), intent(in) :: therm
364 class(meshfield3d), intent(in) :: pres_hyd
365 class(meshfield3d), intent(in) :: dens_hyd
366 class(meshfield3d), intent(in) :: therm_hyd
367 class(meshfield3d), intent(in) :: rtot
368 class(meshfield3d), intent(in) :: cvtot
369 class(meshfield3d), intent(in) :: cptot
370 class(meshbase3d), intent(in), target :: mesh3d
371 logical, intent(in) :: entot_conserve_scheme_flag
372
373 integer :: n
374 class(localmesh3d), pointer :: lcmesh3d
375 !---------------------------
376
377 do n=1, mesh3d%LOCAL_MESH_NUM
378 lcmesh3d => mesh3d%lcmesh_list(n)
379
380 if ( entot_conserve_scheme_flag ) then
381 call atm_dyn_dgm_nonhydro3d_common_entot2pres( pres%local(n)%val, dpres%local(n)%val, &
382 ddens%local(n)%val, momx%local(n)%val, momy%local(n)%val, momz%local(n)%val, therm%local(n)%val, &
383 pres_hyd%local(n)%val, dens_hyd%local(n)%val, rtot%local(n)%val, cvtot%local(n)%val, &
384 lcmesh3d, lcmesh3d%refElem3D )
385 else
386 call atm_dyn_dgm_nonhydro3d_common_drhot2pres( pres%local(n)%val, dpres%local(n)%val, &
387 therm%local(n)%val, pres_hyd%local(n)%val, therm_hyd%local(n)%val, rtot%local(n)%val, cvtot%local(n)%val, cptot%local(n)%val, &
388 lcmesh3d, lcmesh3d%refElem3D )
389 end if
390 end do
391
392 return
394
395!OCL SERIAL
397 THERM_hyd, & ! (inout)
398 pres_hyd, dens_hyd, & ! (in)
399 mesh3d, entot_conserve_scheme_flag ) ! (in)
400
401 implicit none
402 class(meshfield3d), intent(inout) :: therm_hyd
403 class(meshfield3d), intent(in) :: pres_hyd
404 class(meshfield3d), intent(in) :: dens_hyd
405 class(meshbase3d), intent(in), target :: mesh3d
406 logical, intent(in) :: entot_conserve_scheme_flag
407
408 integer :: n
409 class(localmesh3d), pointer :: lcmesh3d
410 !---------------------------
411
412 do n=1, mesh3d%LOCAL_MESH_NUM
413 lcmesh3d => mesh3d%lcmesh_list(n)
414
415 if ( entot_conserve_scheme_flag ) then
416 ! ToDO
417 else
418 call atm_dyn_dgm_nonhydro3d_common_calc_rhot_hyd( therm_hyd%local(n)%val, &
419 pres_hyd%local(n)%val, lcmesh3d, lcmesh3d%refElem3D )
420 end if
421 end do
422
423 return
425
426 !> Calculate pressure from the deviation of density-weighted potential temperature (DRHOT)
427!OCL SERIAL
429 DRHOT, PRES_hyd, THERM_hyd, Rtot, CVtot, CPtot, &
430 lcmesh, elem3D )
431
432 use scale_const, only: &
433 rdry => const_rdry, &
434 cpdry => const_cpdry, &
435 cvdry => const_cvdry, &
436 pres00 => const_pre00
437
438 implicit none
439 class(localmesh3d), intent(in) :: lcmesh
440 class(elementbase3d), intent(in) :: elem3d
441 real(rp), intent(out) :: pres(elem3d%np,lcmesh%nea)
442 real(rp), intent(out) :: dpres(elem3d%np,lcmesh%nea)
443 real(rp), intent(in) :: drhot(elem3d%np,lcmesh%nea)
444 real(rp), intent(in) :: pres_hyd(elem3d%np,lcmesh%nea)
445 real(rp), intent(in) :: therm_hyd(elem3d%np,lcmesh%nea)
446 real(rp), intent(in) :: rtot(elem3d%np,lcmesh%nea)
447 real(rp), intent(in) :: cvtot(elem3d%np,lcmesh%nea)
448 real(rp), intent(in) :: cptot(elem3d%np,lcmesh%nea)
449
450 integer :: ke, p
451 real(rp) :: rhot(elem3d%np)
452 real(rp) :: rhot_
453 real(rp) :: rp0
454 !---------------------------------------------------------------
455
456 rp0 = 1.0_rp / pres00
457 !$omp parallel do private( RHOT )
458 !$acc parallel loop gang present( PRES, DPRES, DRHOT, PRES_hyd, THERM_hyd, Rtot, CVtot, CPtot, lcmesh,elem3D )
459 do ke=lcmesh%NeS, lcmesh%NeE
460! RHOT(:) = PRES00 / Rdry * ( PRES_hyd(:,ke) / PRES00 )**(CvDry/CpDry) + DRHOT(:,ke)
461
462#ifdef _OPENACC
463 !$acc loop vector
464 do p=1, elem3d%Np
465 rhot_ = pres00 / rdry * ( pres_hyd(p,ke) / pres00 )**(cvdry/cpdry) + drhot(p,ke)
466
467 pres(p,ke) = pres00 * ( rtot(p,ke) * rp0 * rhot_ )**( cptot(p,ke) / cvtot(p,ke) )
468 dpres(p,ke) = pres(p,ke) - pres_hyd(p,ke)
469 end do
470#else
471 rhot(:) = therm_hyd(:,ke) + drhot(:,ke)
472
473 pres(:,ke) = pres00 * ( rtot(:,ke) * rp0 * rhot(:) )**( cptot(:,ke) / cvtot(:,ke) )
474 dpres(:,ke) = pres(:,ke) - pres_hyd(:,ke)
475#endif
476 end do
477
478 return
480
481!OCL SERIAL
483 DDENS, MOMX, MOMY, MOMZ, DRHOT, &
484 DENS_hyd, PRES_hyd, THERM_hyd, Rtot, CVtot, CPtot, &
485 lcmesh, elem3D )
486
487 use scale_const, only: &
488 grav => const_grav
489
490 implicit none
491 class(localmesh3d), intent(in) :: lcmesh
492 class(elementbase3d), intent(in) :: elem3d
493 real(rp), intent(out) :: entot(elem3d%np,lcmesh%nea)
494 real(rp), intent(in) :: ddens(elem3d%np,lcmesh%nea)
495 real(rp), intent(in) :: momx(elem3d%np,lcmesh%nea)
496 real(rp), intent(in) :: momy(elem3d%np,lcmesh%nea)
497 real(rp), intent(in) :: momz(elem3d%np,lcmesh%nea)
498 real(rp), intent(in) :: drhot(elem3d%np,lcmesh%nea)
499 real(rp), intent(in) :: dens_hyd(elem3d%np,lcmesh%nea)
500 real(rp), intent(in) :: pres_hyd(elem3d%np,lcmesh%nea)
501 real(rp), intent(in) :: therm_hyd(elem3d%np,lcmesh%nea)
502 real(rp), intent(in) :: rtot(elem3d%np,lcmesh%nea)
503 real(rp), intent(in) :: cvtot(elem3d%np,lcmesh%nea)
504 real(rp), intent(in) :: cptot(elem3d%np,lcmesh%nea)
505
506 integer :: ke, ke2d
507
508 real(rp) :: dens(elem3d%np)
509 real(rp) :: mom_u1(elem3d%np), mom_u2(elem3d%np)
510
511 real(rp) :: pres(elem3d%np,lcmesh%nea)
512 real(rp) :: dpres(elem3d%np,lcmesh%nea)
513 !---------------------------------------------------------------
514
516 drhot, pres_hyd, therm_hyd, rtot, cvtot, cptot, &
517 lcmesh, elem3d )
518
519 !$omp parallel do private( ke2D, DENS, mom_u1, mom_u2 )
520 do ke=lcmesh%NeS, lcmesh%NeE
521 ke2d = lcmesh%EMap3Dto2D(ke)
522
523 dens(:) = dens_hyd(:,ke) + ddens(:,ke)
524 mom_u1(:) = lcmesh%G_ij(lcmesh%refElem3D%IndexH2Dto3D,ke2d,1,1) * momx(:,ke) + lcmesh%G_ij(lcmesh%refElem3D%IndexH2Dto3D,ke2d,2,1) * momy(:,ke)
525 mom_u2(:) = lcmesh%G_ij(lcmesh%refElem3D%IndexH2Dto3D,ke2d,2,1) * momx(:,ke) + lcmesh%G_ij(lcmesh%refElem3D%IndexH2Dto3D,ke2d,2,2) * momy(:,ke)
526
527 entot(:,ke) = pres(:,ke) * cvtot(:,ke) / rtot(:,ke) &
528 + 0.5_rp * ( momx(:,ke) * mom_u1(:) + momy(:,ke) * mom_u2(:) + momz(:,ke)**2 ) / dens(:) &
529 + grav * dens(:) * lcmesh%zlev(:,ke)
530 end do
531
532 return
534
535!OCL SERIAL
537 DDENS, MOMX, MOMY, MOMZ, EnTot, &
538 PRES_hyd, DENS_hyd, Rtot, CVtot, &
539 lcmesh, elem3D )
540
541 use scale_const, only: &
542 grav => const_grav
543
544 implicit none
545 class(localmesh3d), intent(in) :: lcmesh
546 class(elementbase3d), intent(in) :: elem3d
547 real(rp), intent(out) :: pres(elem3d%np,lcmesh%nea)
548 real(rp), intent(out) :: dpres(elem3d%np,lcmesh%nea)
549 real(rp), intent(in) :: ddens(elem3d%np,lcmesh%nea)
550 real(rp), intent(in) :: momx(elem3d%np,lcmesh%nea)
551 real(rp), intent(in) :: momy(elem3d%np,lcmesh%nea)
552 real(rp), intent(in) :: momz(elem3d%np,lcmesh%nea)
553 real(rp), intent(in) :: entot(elem3d%np,lcmesh%nea)
554 real(rp), intent(in) :: pres_hyd(elem3d%np,lcmesh%nea)
555 real(rp), intent(in) :: dens_hyd(elem3d%np,lcmesh%nea)
556 real(rp), intent(in) :: rtot(elem3d%np,lcmesh%nea)
557 real(rp), intent(in) :: cvtot(elem3d%np,lcmesh%nea)
558
559 integer :: ke, ke2d
560
561 real(rp) :: dens(elem3d%np)
562 real(rp) :: mom_u1(elem3d%np), mom_u2(elem3d%np)
563 !---------------------------------------------------------------
564
565 !$omp parallel do private( ke2D, DENS, mom_u1, mom_u2 )
566 do ke=lcmesh%NeS, lcmesh%NeE
567 ke2d = lcmesh%EMap3Dto2D(ke)
568
569 dens(:) = dens_hyd(:,ke) + ddens(:,ke)
570 mom_u1(:) = lcmesh%G_ij(lcmesh%refElem3D%IndexH2Dto3D,ke2d,1,1) * momx(:,ke) + lcmesh%G_ij(lcmesh%refElem3D%IndexH2Dto3D,ke2d,2,1) * momy(:,ke)
571 mom_u2(:) = lcmesh%G_ij(lcmesh%refElem3D%IndexH2Dto3D,ke2d,2,1) * momx(:,ke) + lcmesh%G_ij(lcmesh%refElem3D%IndexH2Dto3D,ke2d,2,2) * momy(:,ke)
572
573 pres(:,ke) = ( entot(:,ke) - grav * dens(:) * lcmesh%zlev(:,ke) &
574 - 0.5_rp * ( momx(:,ke) * mom_u1(:) + momy(:,ke) * mom_u2(:) + momz(:,ke)**2 ) / dens(:) &
575 ) * rtot(:,ke) / cvtot(:,ke)
576
577 dpres(:,ke) = pres(:,ke) - pres_hyd(:,ke)
578 end do
579
580 return
582
583!OCL SERIAL
585 PRES_hyd, &
586 lcmesh, elem3D )
587
588 use scale_const, only: &
589 rdry => const_rdry, &
590 cpdry => const_cpdry, &
591 cvdry => const_cvdry, &
592 pres00 => const_pre00
593
594 implicit none
595 class(localmesh3d), intent(in) :: lcmesh
596 class(elementbase3d), intent(in) :: elem3d
597 real(rp), intent(out) :: rhot_hyd(elem3d%np,lcmesh%nea)
598 real(rp), intent(in) :: pres_hyd(elem3d%np,lcmesh%nea)
599
600 integer :: ke, p
601 real(rp) :: rp0
602 !---------------------------------------------------------------
603
604 rp0 = 1.0_rp / pres00
605
606 !$omp parallel do
607 !$acc parallel loop gang present( RHOT_hyd, PRES_hyd, lcmesh, elem3D )
608 do ke=lcmesh%NeS, lcmesh%NeE
609#ifdef _OPENACC
610 do p=1, elem3d%Np
611 rhot_hyd(p,ke) = pres00 / rdry * ( pres_hyd(p,ke) / pres00 )**(cvdry/cpdry)
612 end do
613#else
614 rhot_hyd(:,ke) = pres00 / rdry * ( pres_hyd(:,ke) / pres00 )**(cvdry/cpdry)
615#endif
616 end do
617
618 return
620
621!> Calculate horizontal graidient of hydrostatic pressure
622!! In this calculation, we assume that PRES_hyd_ref is continuous at element boundaries.
623!OCL SERIAL
625 PRES_hyd, PRES_hyd_ref, &
626 element3D_operation, lmesh, elem )
627 implicit none
628 class(localmesh3d), intent(in) :: lmesh
629 class(elementbase3d), intent(in) :: elem
630 real(rp), intent(out) :: dphyddx(elem%np,lmesh%nea)
631 real(rp), intent(out) :: dphyddy(elem%np,lmesh%nea)
632 real(rp), intent(in) :: pres_hyd(elem%np,lmesh%nea)
633 real(rp), intent(in) :: pres_hyd_ref(elem%np,lmesh%nea)
634 class(elementoperationbase3d), intent(in) :: element3d_operation
635
636 integer :: ke, ke2d, p
637
638 real(rp) :: flux(elem%np,3), fz(elem%np), dflux(elem%np,4,2)
639 real(rp) :: del_flux_hyd(elem%nfptot,2,lmesh%ne)
640 real(rp) :: gsqrtv, rgsqrtv(elem%np)
641
642 real(rp) :: e33
643 real(rp) :: gradphyd_x, gradphyd_y
644 !-----------------------------------------
645
646 call get_phyd_hgrad_numflux_generalhvc( del_flux_hyd, & ! (out)
647 pres_hyd, pres_hyd_ref, & ! (in)
648 lmesh%Gsqrt, lmesh%GsqrtH, lmesh%gam, lmesh%GI3(:,:,1), lmesh%GI3(:,:,2), & ! (in)
649 lmesh%normal_fn(:,:,1), lmesh%normal_fn(:,:,2), lmesh%normal_fn(:,:,3), & ! (in)
650 lmesh%vmapM, lmesh%vmapP, elem%IndexH2Dto3D_bnd, & ! (in)
651 lmesh, elem, lmesh%lcmesh2D, lmesh%lcmesh2D%refElem2D ) ! (in)
652
653 !$omp parallel do private( ke, ke2D, p, &
654 !$omp Flux, Fz, DFlux, GsqrtV, RGsqrtV, E33, &
655 !$omp GradPhyd_x, GradPhyd_y )
656 do ke = lmesh%NeS, lmesh%NeE
657 ke2d = lmesh%EMap3Dto2D(ke)
658
659 do p=1, elem%Np
660 gsqrtv = lmesh%Gsqrt(p,ke) / ( lmesh%gam(p,ke)**2 * lmesh%GsqrtH(elem%IndexH2Dto3D(p),ke2d) )
661
662 rgsqrtv(p) = 1.0_rp / gsqrtv
663 flux(p,1) = gsqrtv * ( pres_hyd(p,ke) - pres_hyd_ref(p,ke) )
664 end do
665
666 do p=1, elem%Np
667 flux(p,2) = flux(p,1)
668 flux(p,3) = lmesh%GI3(p,ke,1) * flux(p,1)
669 fz(p) = lmesh%GI3(p,ke,2) * flux(p,1)
670 end do
671
672 call element3d_operation%Div( flux, del_flux_hyd(:,1,ke), &
673 dflux(:,:,1) )
674 call element3d_operation%Dz( fz, dflux(:,3,2) )
675 call element3d_operation%Lift( del_flux_hyd(:,2,ke), dflux(:,4,2) )
676
677 do p=1, elem%Np
678 e33 = lmesh%Escale(p,ke,3,3)
679
680 gradphyd_x = lmesh%Escale(p,ke,1,1) * dflux(p,1,1) &
681 + e33 * dflux(p,3,1) &
682 + dflux(p,4,1)
683
684 gradphyd_y = lmesh%Escale(p,ke,2,2) * dflux(p,2,1) &
685 + e33 * dflux(p,3,2) &
686 + dflux(p,4,2)
687
688 dphyddx(p,ke) = gradphyd_x * rgsqrtv(p)
689 dphyddy(p,ke) = gradphyd_y * rgsqrtv(p)
690 end do
691 end do
692
693 return
695
696!-- private
697
698!OCL SERIAL
699 subroutine get_phyd_hgrad_numflux_generalhvc( &
700 del_flux_hyd, & ! (out)
701 pres_hyd, pres_hyd_ref, & ! (in)
702 gsqrt, gsqrth, gam, g13, g23, nx, ny, nz, & ! (in)
703 vmapm, vmapp, im2dto3d, lmesh, elem, lmesh2d, elem2d ) ! (in)
704
705 implicit none
706
707 class(localmesh3d), intent(in) :: lmesh
708 class(elementbase3d), intent(in) :: elem
709 class(localmesh2d), intent(in) :: lmesh2d
710 class(elementbase2d), intent(in) :: elem2d
711 real(rp), intent(out) :: del_flux_hyd(elem%nfptot,2,lmesh%ne)
712 real(rp), intent(in) :: pres_hyd(elem%np*lmesh%nea)
713 real(rp), intent(in) :: pres_hyd_ref(elem%np*lmesh%nea)
714 real(rp), intent(in) :: gsqrth(elem2d%np,lmesh2d%ne)
715 real(rp), intent(in) :: gsqrt(elem%np*lmesh%nea)
716 real(rp), intent(in) :: gam(elem%np*lmesh%nea)
717 real(rp), intent(in) :: g13(elem%np*lmesh%nea)
718 real(rp), intent(in) :: g23(elem%np*lmesh%nea)
719 real(rp), intent(in) :: nx(elem%nfptot,lmesh%ne)
720 real(rp), intent(in) :: ny(elem%nfptot,lmesh%ne)
721 real(rp), intent(in) :: nz(elem%nfptot,lmesh%ne)
722 integer, intent(in) :: vmapm(elem%nfptot,lmesh%ne)
723 integer, intent(in) :: vmapp(elem%nfptot,lmesh%ne)
724 integer, intent(in) :: im2dto3d(elem%nfptot)
725
726 integer :: ke, fp, i, ip(elem%nfptot), im(elem%nfptot)
727 integer :: ke2d
728 real(rp) :: dpres_hyd(elem%nfptot,2)
729 real(rp) :: gsqrt_(elem%nfptot,2)
730 real(rp) :: gsqrtv_(elem%nfptot,2)
731 real(rp) :: g13_(elem%nfptot,2)
732 real(rp) :: g23_(elem%nfptot,2)
733
734 integer, parameter :: in = 1
735 integer, parameter :: ex = 2
736
737 real(rp) :: tmp1, tmp2
738 !------------------------------------------------------------------------
739
740 !$omp parallel do private( &
741 !$omp ke, iM, iP, ke2D, fp, &
742 !$omp DPRES_hyd, Gsqrt_, GsqrtV_, G13_, G23_, &
743 !$omp tmp1, tmp2 )
744!OCL PREFETCH
745 do ke=lmesh%NeS, lmesh%NeE
746 im(:) = vmapm(:,ke); ip(:) = vmapp(:,ke)
747 ke2d = lmesh%EMap3Dto2D(ke)
748
749 gsqrt_(:,in) = gsqrt(im)
750 gsqrt_(:,ex) = gsqrt(ip)
751 gsqrtv_(:,in) = gsqrt_(:,in) / gam(im)**2 / gsqrth(im2dto3d(:),ke2d)
752 gsqrtv_(:,ex) = gsqrt_(:,ex) / gam(ip)**2 / gsqrth(im2dto3d(:),ke2d)
753
754 g13_(:,in) = g13(im)
755 g13_(:,ex) = g13(ip)
756 g23_(:,in) = g23(im)
757 g23_(:,ex) = g23(ip)
758
759 dpres_hyd(:,in) = pres_hyd(im) - pres_hyd_ref(im)
760 dpres_hyd(:,ex) = pres_hyd(ip) - pres_hyd_ref(ip)
761
762 do fp=1, elem%NfpTot
763 tmp1 = lmesh%Fscale(fp,ke) * 0.5_rp * gsqrtv_(fp,ex) * dpres_hyd(fp,ex)
764 tmp2 = lmesh%Fscale(fp,ke) * 0.5_rp * gsqrtv_(fp,in) * dpres_hyd(fp,in)
765
766 del_flux_hyd(fp,1,ke) = &
767 ( nx(fp,ke) + g13_(fp,ex) * nz(fp,ke) ) * tmp1 &
768 - ( nx(fp,ke) + g13_(fp,in) * nz(fp,ke) ) * tmp2
769
770 del_flux_hyd(fp,2,ke) = &
771 ( ny(fp,ke) + g23_(fp,ex) * nz(fp,ke) ) * tmp1 &
772 - ( ny(fp,ke) + g23_(fp,in) * nz(fp,ke) ) * tmp2
773 end do
774 end do
775
776 return
777 end subroutine get_phyd_hgrad_numflux_generalhvc
778
module FElib / Fluid dyn solver / Atmosphere / Nonhydrostatic model / Common
subroutine, public atm_dyn_dgm_nonhydro3d_common_drhot2entot(entot, ddens, momx, momy, momz, drhot, dens_hyd, pres_hyd, therm_hyd, rtot, cvtot, cptot, lcmesh, elem3d)
subroutine, public atm_dyn_dgm_nonhydro3d_common_drhot2pres(pres, dpres, drhot, pres_hyd, therm_hyd, rtot, cvtot, cptot, lcmesh, elem3d)
Calculate pressure from the deviation of density-weighted potential temperature (DRHOT)
subroutine, public atm_dyn_dgm_nonhydro3d_common_init(mesh)
Initialize a common module for atmospheric nonhydrostatic dynamical core.
subroutine, public atm_dyn_dgm_nonhydro3d_common_calc_phyd_hgrad_lc(dphyddx, dphyddy, pres_hyd, pres_hyd_ref, element3d_operation, lmesh, elem)
Calculate horizontal graidient of hydrostatic pressure In this calculation, we assume that PRES_hyd_r...
subroutine, public atm_dyn_dgm_nonhydro3d_common_setup_variables(prgvars, qtrcvars, auxvars, phytends, prgvar_manager, qtrcvar_manager, auxvar_manager, phytend_manager, reg_file_hist, do_setup_phytend, phytend_num_tot, mesh3d, prgvar_varinfo)
Setup variable managers for atmospheric nonhydrostatic dynamical core.
subroutine, public atm_dyn_dgm_nonhydro3d_common_get_varinfo(prgvar_info, auxvar_info, phytend_info)
Get variable information for atmospheric nonhydrostatic dynamical core.
real(rp), dimension(:,:), allocatable, public intrpmat_vpordm1
subroutine, public atm_dyn_dgm_nonhydro3d_common_calc_pressure(pres, dpres, ddens, momx, momy, momz, therm, pres_hyd, dens_hyd, therm_hyd, rtot, cvtot, cptot, mesh3d, entot_conserve_scheme_flag)
subroutine, public atm_dyn_dgm_nonhydro3d_common_calc_rhot_hyd(rhot_hyd, pres_hyd, lcmesh, elem3d)
subroutine, public atm_dyn_dgm_nonhydro3d_common_entot2pres(pres, dpres, ddens, momx, momy, momz, entot, pres_hyd, dens_hyd, rtot, cvtot, lcmesh, elem3d)
subroutine, public atm_dyn_dgm_nonhydro3d_common_final()
Finalize a common module for atmospheric nonhydrostatic dynamical core.
subroutine, public atm_dyn_dgm_nonhydro3d_common_calc_therm_phyd(therm_hyd, pres_hyd, dens_hyd, mesh3d, entot_conserve_scheme_flag)
module FElib / Element / Base
module FElib / Element / hexahedron
module FElib / Element / Operation / Base
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Mesh / Base 2D
module FElib / Mesh / Base 3D
module FElib / Data / base
FElib / model framework / variable manager.
Module common / sparsemat.
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type representing a hexahedral element.
Derived type representing a local mesh for 2D domain.
Derived type to manage a local 3D computational domain.
Derived type representing a field with 3D local mesh.
Derived type to manage a computational mesh (base type for 2D domain)
Derived type to manage a computational mesh (base type for 3D domain)
Derived type representing a field with 3D mesh.