FE-Project
Loading...
Searching...
No Matches
mod_atmos_vars.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module Atmosphere / Variables
3!!
4!! @par Description
5!! Module to manage variables with atmospheric component
6!!
7!! @author Yuta Kawai, Team SCALE
8!!
9!<
10!-------------------------------------------------------------------------------
11#include "scaleFElib.h"
13 !-----------------------------------------------------------------------------
14 !
15 !++ Used modules
16 !
17 use scale_precision
18 use scale_io
19 use scale_prc
20 use scale_debug
21 use scale_tracer, only: qa
22
23 use scale_element_base, only: &
25 use scale_mesh_base, only: meshbase
26 use scale_mesh_base2d, only: &
28 use scale_mesh_base3d, only: &
29 meshbase3d, &
30 dimtype_xyz => meshbase3d_dimtypeid_xyz
31
35 use scale_localmeshfield_base, only: &
37 use scale_meshfield_base, only: &
39
42
44
45 use scale_model_var_manager, only: &
46 modelvarmanager, variableinfo
47
49 prgvar_num, auxvar_num, phytend_num1 => phytend_num, &
56
57 use mod_atmos_mesh, only: atmosmesh
58
59 use mod_atmos_vars_container, only: &
69
70 !-----------------------------------------------------------------------------
71 implicit none
72 private
73
74 !-----------------------------------------------------------------------------
75 !
76 !++ Public type & procedures
77 !
78 integer, parameter :: ATM_VARS_CONTAINER_LIST_MAX = 16
79
80 !> Derived type to manage variables with atmospheric component
81 type, public :: atmosvars
82 class(atmosmesh), pointer :: mesh !< Pointer to an object to manage a primary mesh for atmospheric component
83
84 type(atmosvarscontainer) :: container_list(atm_vars_container_list_max) !< Array of containers to manage variables. The first one is the primary container.
85 logical :: init_containers_item_flag(atm_vars_container_list_max) !< Flag whether the item of container_list is initialized or not.
86
87 type(atmosvarscontainer), pointer :: container !< Pointer to a primary container to manage variables
88 type(modelvarmanager), pointer :: progvars_manager !< Pointer to manage prognostic variables with primary container
89 type(modelvarmanager), pointer :: qtrcvars_manager !< Pointer to manage tracer variables with primary container
90 type(modelvarmanager), pointer :: auxvars_manager !< Pointer to manage auxiliary variables with primary container
91 type(modelvarmanager), pointer :: auxvars2d_manager !< Pointer to manage 2D auxiliary variables with primary container
92 type(modelvarmanager), pointer :: phytends_manager !< Pointer to manage tendency variables with physics
93
94 !-
95 type(modelvarmanager), pointer :: ptr_mp_auxvars2d_manager
96 type(modelvarmanager), pointer :: ptr_cp_auxvars2d_manager
97
98 logical :: moist
99 type(meshfield3d), pointer :: qv
100 type(meshfield3d) :: zero
101
102 !--
103 integer, allocatable :: diagvars2d_histid(:)
104 integer, allocatable :: diagvars3d_histid(:)
105
106 type(file_restart_meshfield_component) :: restart_file !< Object to manage restart file for atmospheric component
107
108 character(len=H_MID) :: phy_preproc_file_basename !< Basename of configuration file for preprocesses before physics
109
110 logical :: check_range
111 logical :: check_total
112
113 contains
114 procedure :: init => atmosvars_init
115 procedure :: final => atmosvars_final
116 procedure :: setup_container => atmosvars_setup_container
117 procedure :: get_container => atmosvars_get_container
118 procedure :: calc_diagnostics => atmosvars_calculatediagnostics
119 procedure :: calc_diagvar => atmosvars_calcdiagvar
120 procedure :: calc_diagvar2d => atmosvars_calcdiagvar2d
121 procedure :: preprocoperationforphys => atmosvars_preprocoperationforphys
122 procedure :: history => atmosvars_history
123 procedure :: check => atmosvars_check
124 procedure :: monitor => atmosvars_monitor
125 procedure :: read_restart_file => atmosvars_read_restart_file
126 procedure :: write_restart_file_prep => atmosvars_write_restart_file_prep
127 procedure :: write_restart_file => atmosvars_write_restart_file
128 procedure :: write_restart_file_post => atmosvars_write_restart_file_post
129 procedure :: regist_physvar_manager => atmosvars_regist_physvar_manager
130 end type atmosvars
131
132 ! Cascade
133 public :: atmosvarscontainer
144
145 !-----------------------------------------------------------------------------
146 !
147 !++ Public parameters & variables
148 !
149 real(rp), parameter :: progvars_check_min(prgvar_num) = (/ -1.0_rp, -100.0_rp, -200.0_rp, -200.0_rp, -200.0_rp /)
150 real(rp), parameter :: progvars_check_max(prgvar_num) = (/ 1.0_rp, 100.0_rp, 200.0_rp, 200.0_rp, 200.0_rp /)
151
152
153 ! Diagnostic variables
154
155 integer, public, parameter :: atmos_diagvars_dens_id = 1
156 integer, public, parameter :: atmos_diagvars_u_id = 2
157 integer, public, parameter :: atmos_diagvars_v_id = 3
158 integer, public, parameter :: atmos_diagvars_w_id = 4
159 integer, public, parameter :: atmos_diagvars_t_id = 5
160 integer, public, parameter :: atmos_diagvars_umet_id = 6
161 integer, public, parameter :: atmos_diagvars_vmet_id = 7
162 integer, public, parameter :: atmos_diagvars_qdry_id = 8
163 integer, public, parameter :: atmos_diagvars_rh_id = 9
164 integer, public, parameter :: atmos_diagvars_engt_id = 10
165 integer, public, parameter :: atmos_diagvars_engp_id = 11
166 integer, public, parameter :: atmos_diagvars_engk_id = 12
167 integer, public, parameter :: atmos_diagvars_engi_id = 13
168 integer, public, parameter :: atmos_diagvars3d_num = 13
169
170 type(variableinfo), public :: atmos_diagvars3d_vinfo(atmos_diagvars3d_num)
172 variableinfo( atmos_diagvars_dens_id, 'DENS', 'density' , 'kg/m3', 3, 'XYZ', 'air_density' ), &
173 variableinfo( atmos_diagvars_u_id , 'U' , 'velocity u' , 'm/s' , 3, 'XYZ', 'x_wind' ), &
174 variableinfo( atmos_diagvars_v_id , 'V' , 'velocity v' , 'm/s' , 3, 'XYZ', 'y_wind' ), &
175 variableinfo( atmos_diagvars_w_id , 'W' , 'velocity w' , 'm/s' , 3, 'XYZ', 'upward_air_velocity' ), &
176 variableinfo( atmos_diagvars_t_id , 'T' , 'temperature' , 'K' , 3, 'XYZ', 'air_temperature' ), &
177 variableinfo( atmos_diagvars_umet_id, 'Umet', 'eastward velocity' , 'm/s' , 3, 'XYZ', 'x_wind' ), &
178 variableinfo( atmos_diagvars_vmet_id, 'Vmet', 'northward velocity' , 'm/s' , 3, 'XYZ', 'y_wind' ), &
179 variableinfo( atmos_diagvars_qdry_id, 'QDRY', 'dry air' , 'kg/kg', 3, 'XYZ', '' ), &
180 variableinfo( atmos_diagvars_rh_id , 'RH', 'relative humidity(liq)', '%', 3, 'XYZ', 'relative_humidity' ), &
181 variableinfo( atmos_diagvars_engt_id, 'ENGT', 'total energy' , 'J/m3' , 3, 'XYZ', '' ), &
182 variableinfo( atmos_diagvars_engp_id, 'ENGP', 'potential energy' , 'J/m3' , 3, 'XYZ', '' ), &
183 variableinfo( atmos_diagvars_engk_id, 'ENGK', 'kinetic energy' , 'J/m3' , 3, 'XYZ', '' ), &
184 variableinfo( atmos_diagvars_engi_id, 'ENGI', 'internal energy' , 'J/m3' , 3, 'XYZ', '' ) /
185
186
187 integer, public, parameter :: atmos_diagvars_rain_id = 1
188 integer, public, parameter :: atmos_diagvars_snow_id = 2
189 integer, public, parameter :: atmos_diagvars2d_num = 2
190
191 type(variableinfo), public :: atmos_diagvars2d_vinfo(atmos_diagvars2d_num)
193 variableinfo( atmos_diagvars_rain_id, 'RAIN', 'surface rain flux' , 'kg/m2/s', 2, 'XY', 'rainfall_flux' ), &
194 variableinfo( atmos_diagvars_snow_id, 'SNOW', 'surface snow flux' , 'kg/m2/s', 2, 'XY', 'snowfall_flux' ) /
195
196 !-----------------------------------------------------------------------------
197 !
198 !++ Private procedures & variables
199 !
200
201 private :: vars_calc_diagnosevar2d_lc
202
203 ! for monitor
204
205 integer, private, parameter :: im_qdry = 1
206 integer, private, parameter :: im_qtot = 2
207 integer, private, parameter :: im_engt = 3
208 integer, private, parameter :: im_engp = 4
209 integer, private, parameter :: im_engk = 5
210 integer, private, parameter :: im_engi = 6
211 integer, private, parameter :: dvm_nmax = 6
212 integer, private :: dv_monit_id(dvm_nmax)
213
214contains
215
216!> Setup an object to manage variables with atmospheric component
217!!
218!! @param model_mesh Object to manage computational mesh of atmospheric model
219!!
220!OCL SERIAL
221 subroutine atmosvars_init( this, atm_mesh )
225 monitor_reg => file_monitor_meshfield_reg
226 implicit none
227
228 class(atmosvars), target, intent(inout) :: this
229 class(atmosmesh), target, intent(inout) :: atm_mesh
230
231 integer :: iv
232 logical :: reg_file_hist
233
234 type(modelvarmanager) :: diagvar_manager ! dummy
235 type(meshfield2d) :: diag_vars2d(atmos_diagvars2d_num) ! dummy
236 type(meshfield3d) :: diag_vars3d(atmos_diagvars3d_num) ! dummy
237
238 logical :: check_range = .false. !< Flag whether the range of values is checked
239 logical :: check_total = .false.
240
241 character(len=H_MID) :: phy_preproc_file_basename = 'phy_preoperation' !< Basename of configuration file for preprocesses before physics
242
243 namelist / param_atmos_vars / &
244 phy_preproc_file_basename, &
245 check_range, &
246 check_total
247
248 character(len=H_LONG) :: in_basename = '' !< Basename of the input file
249 logical :: in_postfix_timelabel = .false. !< Add timelabel to the basename of input file?
250 character(len=H_LONG) :: out_basename = '' !< Basename of the output file
251 logical :: out_postfix_timelabel = .true. !< Add timelabel to the basename of output file?
252 character(len=H_MID) :: out_title = '' !< Title of the output file
253 character(len=H_SHORT) :: out_dtype = 'DEFAULT' !< REAL4 or REAL8
254
255 namelist / param_atmos_vars_restart / &
256 in_basename, &
257 in_postfix_timelabel, &
258 out_basename, &
259 out_postfix_timelabel, &
260 out_title, &
261 out_dtype
262
263 integer :: ierr
264 logical :: is_specified
265
266 class(meshbase3d), pointer :: mesh3d
267 class(meshbase2d), pointer :: mesh2d
268 !--------------------------------------------------
269
270 log_info('AtmosVars_Init',*)
271
272 !- read namelist
273 rewind(io_fid_conf)
274 read(io_fid_conf,nml=param_atmos_vars,iostat=ierr)
275 if( ierr < 0 ) then !--- missing
276 log_info("ATMOS_vars_setup",*) 'Not found namelist. Default used.'
277 elseif( ierr > 0 ) then !--- fatal error
278 log_error("ATMOS_vars_setup",*) 'Invalid names in namelist PARAM_ATMOS_VARS. Check!'
279 call prc_abort
280 endif
281 log_nml(param_atmos_vars)
282
283 this%phy_preproc_file_basename = phy_preproc_file_basename
284
285 !- Set the pointer of mesh
286 this%mesh => atm_mesh
287 mesh3d => atm_mesh%ptr_mesh
288 call mesh3d%GetMesh2D( mesh2d )
289
290 !- Initialize variables associated with dynamical core
291 ! (prognostic variables, tracer variables, 3D auxiliary variables, and tendencies of physical processes)
292
293 this%init_containers_item_flag(:) = .false.
294 call this%Setup_container( 1, atm_mesh )
295
296 !- Initialize diagnostic variables for output
297
298 ! 3D
299 call diagvar_manager%Init()
300 allocate( this%DIAGVARS3D_HISTID(atmos_diagvars3d_num) )
301
302 reg_file_hist = .true.
303 do iv = 1, atmos_diagvars3d_num
304 call diagvar_manager%Regist( &
305 atmos_diagvars3d_vinfo(iv), atm_mesh%ptr_mesh, & ! (in)
306 diag_vars3d(iv), reg_file_hist ) ! (out)
307
308 this%DIAGVARS3D_HISTID(iv) = diag_vars3d(iv)%hist_id
309 end do
310 call diagvar_manager%Final()
311
312 ! 2D
313 call diagvar_manager%Init()
314 allocate( this%DIAGVARS2D_HISTID(atmos_diagvars2d_num) )
315
316 reg_file_hist = .true.
317 do iv = 1, atmos_diagvars2d_num
318 call diagvar_manager%Regist( &
319 atmos_diagvars2d_vinfo(iv), mesh2d, & ! (in)
320 diag_vars2d(iv), reg_file_hist ) ! (out)
321
322 this%DIAGVARS2D_HISTID(iv) = diag_vars2d(iv)%hist_id
323 end do
324 call diagvar_manager%Final()
325
326 !-- Setup information for input/output restart files.
327
328 is_specified = .true.
329 !- read namelist
330 rewind(io_fid_conf)
331 read(io_fid_conf,nml=param_atmos_vars_restart,iostat=ierr)
332 if( ierr < 0 ) then !--- missing
333 log_info("AtmosVars_Init",*) 'Not found namelist PARAM_ATMOS_VARS_RESTART. Default used.'
334 is_specified = .false.
335 elseif( ierr > 0 ) then !--- fatal error
336 log_error("AtmosVars_Init",*) 'Not appropriate names in namelist PARAM_ATMOS_VARS_RESTART. Check!'
337 call prc_abort
338 endif
339 log_nml(param_atmos_vars_restart)
340
341 if (is_specified) then
342 call atm_mesh%Setup_restartfile( this%restart_file, &
343 in_basename, in_postfix_timelabel, &
344 out_basename, out_postfix_timelabel, out_dtype, out_title, &
345 prgvar_num + auxvar_num, "" )
346 else
347 call atm_mesh%Setup_restartfile( this%restart_file, &
349 end if
350
351 !-----< monitor output setup >-----
352
353 call monitor_reg( 'QTOT', 'water mass', 'kg', & ! (in)
354 dv_monit_id(im_qtot), & ! (out)
355 dim_type='ATM3D', is_tendency=.false. ) ! (in)
356
357 call monitor_reg( 'ENGT', 'total energy', 'J', & ! (in)
358 dv_monit_id(im_engt), & ! (out)
359 dim_type='ATM3D', is_tendency=.false. ) ! (in)
360 call monitor_reg( 'ENGP', 'potential energy', 'J', & ! (in)
361 dv_monit_id(im_engp), & ! (out)
362 dim_type='ATM3D', is_tendency=.false. ) ! (in)
363 call monitor_reg( 'ENGK', 'kinetic energy', 'J', & ! (in)
364 dv_monit_id(im_engk), & ! (out)
365 dim_type='ATM3D', is_tendency=.false. ) ! (in)
366 call monitor_reg( 'ENGI', 'internal energy', 'J', & ! (in)
367 dv_monit_id(im_engi), & ! (out)
368 dim_type='ATM3D', is_tendency=.false. ) ! (in)
369
370
371 !-----< check the range of values >-----
372
373 this%check_range = check_range
374 this%check_total = check_total
375 log_info("ATMOS_vars_setup",*) 'Check value range of variables? : ', check_range
376 log_info("ATMOS_vars_setup",*) 'Check total value of variables? : ', check_total
377
378 !-- Set the pointer of 2D auxiliary variable manager with MP and CP components to output precipitation fluxes
379
380 nullify( this%ptr_MP_AUXVARS2D_manager )
381 nullify( this%ptr_CP_AUXVARS2D_manager )
382
383 return
384 end subroutine atmosvars_init
385
386 !> Setup a container to manage variables with atmospheric component
387 !!
388!OCL SERIAL
389 subroutine atmosvars_setup_container( this, container_type, atm_mesh )
390 implicit none
391 class(atmosvars), intent(inout), target :: this
392 integer, intent(in) :: container_type !< Type of container to setup. 1: primary container, >=2: other containers
393 class(atmosmesh), target, intent(inout) :: atm_mesh
394 !---------------------------------------------
395
396 if ( container_type < atm_vars_container_primary_id .or. container_type > atm_vars_container_list_max ) then
397 log_error("ATMOS_vars_setup_container",*) 'container_type is out of range. Check!', container_type
398 call prc_abort
399 end if
400
401 if ( .not. this%init_containers_item_flag(container_type) ) then
402 log_info("ATMOS_vars_setup_container",*) 'container_type: ', container_type
403
404 this%init_containers_item_flag(container_type) = .true.
405 call this%container_list(container_type)%Init( container_type, this%phy_preproc_file_basename, atm_mesh )
406
407 if ( container_type == atm_vars_container_primary_id ) then
408 this%container => this%container_list(container_type)
409 this%PROGVARS_manager => this%container%PROGVARS_manager
410 this%QTRCVARS_manager => this%container%QTRCVARS_manager
411 this%AUXVARS_manager => this%container%AUXVARS_manager
412 this%AUXVARS2D_manager => this%container%AUXVARS2D_manager
413 this%PHYTENDS_manager => this%container%PHYTENDS_manager
414 end if
415 end if
416 return
417 end subroutine atmosvars_setup_container
418
419 !> Get a container to manage variables with atmospheric component
420 !!
421!OCL SERIAL
422 subroutine atmosvars_get_container( this, container_type, &
423 container )
424 implicit none
425 class(atmosvars), intent(inout), target :: this
426 integer, intent(in) :: container_type !< Type of container to get. 1: primary container, >=2: other containers
427 class(atmosvarscontainer), pointer :: container !< Pointer to a container to manage variables with atmospheric component
428 !---------------------------------------------
429
430 if ( container_type < atm_vars_container_primary_id .or. container_type > atm_vars_container_list_max ) then
431 log_error("ATMOS_vars_get_container",*) 'container_type is out of range. Check!', container_type
432 call prc_abort
433 end if
434
435 if ( this%init_containers_item_flag(container_type) ) then
436 container => this%container_list(container_type)
437 else
438 log_error("ATMOS_vars_get_container",*) 'Not initialized container. Check!'
439 call prc_abort
440 end if
441 return
442 end subroutine atmosvars_get_container
443
444 !> Finalize an object to manage variables with atmospheric component
445 !!
446!OCL SERIAL
447 subroutine atmosvars_final( this )
448 implicit none
449 class(atmosvars), intent(inout) :: this
450
451 integer :: i
452 !--------------------------------------------------
453
454 log_info('AtmosVars_Final',*)
455
456 call this%restart_file%Final()
457
458 do i=1, atm_vars_container_list_max
459 if ( this%init_containers_item_flag(i) ) call this%container_list(i)%Final()
460 end do
461
462 deallocate( this%DIAGVARS3D_HISTID )
463
464 return
465 end subroutine atmosvars_final
466
467 !> Set the pointer of 2D ModelVarManager with cloud microphysics or cumlus parameterization
468 !! to output surface variables with precipitation fluxes
469!OCL SERIAL
470 subroutine atmosvars_regist_physvar_manager( this, &
471 mp_AUXVARS2D_manager, cp_AUXVARS2D_manager )
472 implicit none
473
474 class(atmosvars), target, intent(inout) :: this
475 type(modelvarmanager), intent(in), target, optional:: mp_auxvars2d_manager
476 type(modelvarmanager), intent(in), target, optional:: cp_auxvars2d_manager
477 !----------------------------------------------
478
479 if ( present(mp_auxvars2d_manager) ) then
480 this%ptr_MP_AUXVARS2D_manager => mp_auxvars2d_manager
481 end if
482 if ( present(cp_auxvars2d_manager) ) then
483 this%ptr_CP_AUXVARS2D_manager => cp_auxvars2d_manager
484 end if
485 return
486 end subroutine atmosvars_regist_physvar_manager
487
488 !> Put data with atmospheric variables to history file
489 !!
490!OCL SERIAL
491 subroutine atmosvars_history( this )
493 implicit none
494 class(atmosvars), intent(inout), target :: this
495
496 integer :: v
497 integer :: hst_id
498
499 type(meshfield3d) :: tmp_field3d
500 class(meshbase3d), pointer :: mesh3d
501
502 type(meshfield2d) :: tmp_field2d
503 class(meshbase2d), pointer :: mesh2d
504 !-------------------------------------------------------------------------
505
506 mesh3d => this%container%PROG_VARS(1)%mesh
507 call mesh3d%GetMesh2D(mesh2d)
508
509 !-
510 call this%container%Calc_diagnostics()
511
512 do v = 1, prgvar_num
513 hst_id = this%container%PROG_VARS(v)%hist_id
514 if ( hst_id > 0 ) call file_history_meshfield_put( hst_id, this%container%PROG_VARS(v) )
515 end do
516
517 do v = 1, qa
518 hst_id = this%container%QTRC_VARS(v)%hist_id
519 if ( hst_id > 0 ) call file_history_meshfield_put( hst_id, this%container%QTRC_VARS(v) )
520 end do
521
522 do v = 1, auxvar_num
523 hst_id = this%container%AUX_VARS(v)%hist_id
524 if ( hst_id > 0 ) call file_history_meshfield_put( hst_id, this%container%AUX_VARS(v) )
525 end do
526 do v = 1, atmos_auxvars2d_num
527 hst_id = this%container%AUX_VARS2D(v)%hist_id
528 if ( hst_id > 0 ) call file_history_meshfield_put( hst_id, this%container%AUX_VARS2D(v) )
529 end do
530
531 do v = 1, this%container%PHYTEND_NUM_TOT
532 hst_id = this%container%PHY_TEND(v)%hist_id
533 if ( hst_id > 0 ) call file_history_meshfield_put( hst_id, this%container%PHY_TEND(v) )
534 end do
535
536 !- Output diagnostic variables
537
538 ! 3D
539 call tmp_field3d%Init( "tmp_field", "", mesh3d)
540 do v = 1, atmos_diagvars3d_num
541 hst_id = this%DIAGVARS3D_HISTID(v)
542 if ( hst_id > 0 ) then
543 call atmosvars_calcdiagvar( this, atmos_diagvars3d_vinfo(v)%NAME, tmp_field3d )
544 call file_history_meshfield_put( hst_id, tmp_field3d )
545 end if
546 end do
547 call tmp_field3d%Final()
548
549 ! 2D
550 call tmp_field2d%Init( "tmp_field", "", mesh2d)
551 do v = 1, atmos_diagvars2d_num
552 hst_id = this%DIAGVARS2D_HISTID(v)
553 if ( hst_id > 0 ) then
554 call atmosvars_calcdiagvar2d( this, atmos_diagvars2d_vinfo(v)%NAME, tmp_field2d )
555 call file_history_meshfield_put( hst_id, tmp_field2d )
556 end if
557 end do
558 call tmp_field2d%Final()
559
560 return
561 end subroutine atmosvars_history
562
563!> Read data with atmospheric variables from restart file
564!!
565!OCL SERIAL
566 subroutine atmosvars_read_restart_file( this, atmos_mesh, dyncore )
571 implicit none
572
573 class(atmosvars), intent(inout), target :: this
574 class(atmosmesh), intent(in) :: atmos_mesh
575 class(atmdyndgmdriver_nonhydro3d), intent(inout) :: dyncore
576
577 integer :: iv
578
579 integer :: domid
580 integer :: ke
581 class(meshbase3d), pointer :: mesh3d
582 class(localmesh3d), pointer :: lcmesh3d
583 class(meshfield3d), pointer :: phyd_ref
584 !---------------------------------------
585
586 log_newline
587 log_info("AtmosVars_Read_restart_file",*) 'Open restart file (ATMOS) '
588
589 !- Open restart file
590 call this%restart_file%Open()
591
592 !- Read restart file
593
594 do iv=1, prgvar_num
595 call this%restart_file%Read_var( dimtype_xyz, this%container%PROG_VARS(iv)%varname, &
596 this%container%PROG_VARS(iv) )
597 end do
598 do iv=1, auxvar_denshydro_id
599 call this%restart_file%Read_var( dimtype_xyz, this%container%AUX_VARS(iv)%varname, &
600 this%container%AUX_VARS(iv) )
601 end do
602 do iv=1, qa
603 call this%restart_file%Read_var( dimtype_xyz, this%container%QTRC_VARS(iv)%varname, &
604 this%container%QTRC_VARS(iv) )
605 end do
606
607 !- Close restart file
608 log_info("AtmosVars_Read_restart_file",*) 'Close restart file (ATMOS) '
609 call this%restart_file%Close()
610
611 !-- Prepare diagnostic variables
612
613 ! Calculate specific heat
614 call this%container%Calc_SpecificHeat()
615
616 ! Set a basic state of thermodynamics variable
617 call dyncore%update_therm_hyd( this%container%AUXVARS_manager )
618
619 ! Calculate pressure
620 call dyncore%calc_pressure( this%container%AUX_VARS(auxvar_pres_id), &
621 this%container%PROGVARS_manager, this%container%AUXVARS_manager )
622
623 ! Set reference value of hydrostatic pressure
624 phyd_ref => this%container%AUX_VARS(auxvar_preshydro_ref_id)
625 mesh3d => phyd_ref%mesh
626 do domid=1, mesh3d%LOCAL_MESH_NUM
627 lcmesh3d => mesh3d%lcmesh_list(domid)
628 !$omp parallel do
629 do ke=lcmesh3d%NeS, lcmesh3d%NeE
630 phyd_ref%local(domid)%val(:,ke) = 0.0_rp
631 end do
632 !$acc update device(Phyd_ref%local(domid)%val)
633 end do
634
635 !-- Check read data
636 call this%Check( force = .true. )
637
638 !-- Calculate diagnostic variables
639 call this%Calc_diagnostics()
640
641 !-- Communicate halo data of hydrostatic & diagnostic variables
642 call this%container%AUXVARS_manager%MeshFieldComm_Exchange()
643
644 !-- Set horizontal gradient of hydrostatic pressure
645 call dyncore%update_phyd_hgrad( this%container%AUX_VARS(auxvar_preshydro_id), phyd_ref, &
646 mesh3d, atmos_mesh%element3D_operation )
647
648 return
649 end subroutine atmosvars_read_restart_file
650
651!> Write data with atmospheric variables to restart file
652!!
653!OCL SERIAL
654 subroutine atmosvars_write_restart_file_prep( this )
655 use scale_tracer, only: &
656 tracer_desc
659
660 implicit none
661 class(atmosvars), intent(inout) :: this
662
663 type(variableinfo) :: prgvar_info(prgvar_num)
664 type(variableinfo) :: auxvar_info(auxvar_num)
665
666 integer :: iv, rf_vid
667 !---------------------------------------
668
669 log_newline
670 log_info("AtmosVars_Write_restart_file",*) 'Create restart file (ATMOS) '
671
672 !- Check data which will be written to restart file
673 call this%Check( force = .true. )
674
675 !- Create restart file
676 call this%restart_file%Create()
677 call prc_mpibarrier()
678
679 !- Define variables
680
681 call atm_dyn_dgm_nonhydro3d_common_get_varinfo( prgvar_info, auxvar_info )
682
683 do iv=1, prgvar_num
684 rf_vid = iv
685 call this%restart_file%Def_var( this%container%PROG_VARS(iv), &
686 prgvar_info(iv)%DESC, rf_vid, dimtype_xyz )
687 end do
688 do iv=1, auxvar_denshydro_id
689 rf_vid = prgvar_num + iv
690 call this%restart_file%Def_var( this%container%AUX_VARS(iv), &
691 auxvar_info(iv)%DESC, rf_vid, dimtype_xyz )
692 end do
693 do iv=1, qa
694 rf_vid = rf_vid + 1
695 call this%restart_file%Def_var( this%container%QTRC_VARS(iv), &
696 tracer_desc(iv), rf_vid, dimtype_xyz )
697 end do
698 return
699 end subroutine atmosvars_write_restart_file_prep
700
701!> Write data with atmospheric variables to restart file
702!!
703!OCL SERIAL
704 subroutine atmosvars_write_restart_file( this )
705 implicit none
706 class(atmosvars), intent(inout) :: this
707
708 integer :: iv, rf_vid
709 !---------------------------------------
710
711 call this%restart_file%End_def()
712
713 !- Write restart file
714 do iv=1, prgvar_num
715 rf_vid = iv
716 call this%restart_file%Write_var(rf_vid, this%container%PROG_VARS(iv) )
717 end do
718 do iv=1, auxvar_denshydro_id
719 rf_vid = prgvar_num + iv
720 call this%restart_file%Write_var(rf_vid, this%container%AUX_VARS(iv) )
721 end do
722 do iv=1, qa
723 rf_vid = rf_vid + 1
724 call this%restart_file%Write_var(rf_vid, this%container%QTRC_VARS(iv) )
725 end do
726 return
727 end subroutine atmosvars_write_restart_file
728
729 !> Close restart file with atmospheric variables
730 !!
731!OCL SERIAL
732 subroutine atmosvars_write_restart_file_post( this )
733 implicit none
734 class(atmosvars), intent(inout) :: this
735 !---------------------------------------
736 log_info("AtmosVars_Write_restart_file_post",*) 'Close restart file (ATMOS) '
737
738 call this%restart_file%Close()
739 return
740 end subroutine atmosvars_write_restart_file_post
741
742!> Check the range of values with atmospheric variables
743!!
744!OCL SERIAL
745 subroutine atmosvars_check( this, force )
746
747 use scale_meshfield_statistics, only: &
750
751 implicit none
752 class(atmosvars), intent(inout) :: this
753 logical, intent(in), optional :: force
754
755 integer :: iv
756 integer :: iv_diag
757 integer :: n
758 logical :: check
759
760 class(meshbase3d), pointer :: mesh3d
761 class(localmeshbase), pointer :: lcmesh
762 class(localmeshfieldbase), pointer :: lcfield
763 type(elementbase), pointer :: elem
764 character(len=H_MID) :: varname
765
766 type(meshfield3d), pointer :: var
767 type(meshfield3d) :: vel_fields(3)
768 type(meshfield3d) :: work
769
770 integer :: ldomid
771 !--------------------------------------------------------------------------
772
773 if ( present(force) ) then
774 check = force
775 else
776 check = this%check_range
777 end if
778
779 if (check) then
780 mesh3d => this%container%PROG_VARS(1)%mesh
781
782 do iv=1, prgvar_num
783 if ( iv == prgvar_therm_id ) cycle
784
785 var => this%container%PROG_VARS(iv)
786 do n=1, mesh3d%LOCAL_MESH_NUM
787 lcmesh => mesh3d%lcmesh_list(n)
788 elem => lcmesh%refElem
789
790 call var%GetLocalMeshField(n, lcfield)
791
792 write(varname,'(a,i3.3,a)') var%varname//'(domID=', n, ')'
793
794 ! Note : *acc update host* is called in VALCHECK of SCALE library.
795 call valcheck( elem%Np, 1, elem%Np, lcmesh%NeA, lcmesh%NeS, lcmesh%NeE, lcfield%val, &
796 progvars_check_min(iv), progvars_check_max(iv), trim(varname), __file__, __line__ )
797 end do
798 end do
799
800 do iv=1, 3
801 iv_diag = atmos_diagvars_u_id + iv - 1
802 call vel_fields(iv)%Init( atmos_diagvars3d_vinfo(iv_diag)%NAME, "", mesh3d )
803 call atmosvars_calcdiagvar( this, vel_fields(iv)%varname, vel_fields(iv) )
804#ifdef _OPENACC
805 do ldomid=1, mesh3d%LOCAL_MESH_NUM
806 !$acc update host(vel_fields(iv)%local(ldomID)%val)
807 end do
808#endif
809 end do
810 call meshfield_statistics_detail( vel_fields )
811 do iv=1, 3
812 call vel_fields(iv)%Final()
813 end do
814
815 ! Check total
816 call work%Init("tmp", "", mesh3d)
817 call work%Final()
818 end if
819
820 return
821 end subroutine atmosvars_check
822
823!> Put the stastics with atmospheric variables
824!!
825!OCL SERIAL
826 subroutine atmosvars_monitor( this )
827 implicit none
828 class(atmosvars), intent(inout) :: this
829 !--------------------------------------------------------------------------
830 call atmosvars_monitor_core( this%container )
831 return
832 end subroutine atmosvars_monitor
833!OCL SERIAL
834 subroutine atmosvars_monitor_core( this )
837 implicit none
838 class(atmosvarscontainer), intent(inout) :: this
839
840 integer :: iv
841 class(meshbase3d), pointer :: mesh3d
842 type(meshfield3d) :: work
843
844 integer :: n
845 integer :: ke
846 class(localmesh3d), pointer :: lcmesh
847 !--------------------------------------------------------------------------
848
849 mesh3d => this%PROG_VARS(1)%mesh
850 call work%Init("tmp", "", mesh3d)
851
852 do iv=1, prgvar_num
853 call file_monitor_meshfield_put( this%PROG_VARS(iv)%monitor_id, this%PROG_VARS(iv) )
854 end do
855
856 do iv=1, qa
857 if ( this%QTRC_VARS(iv)%monitor_id > 0 ) then
858 do n=1, mesh3d%LOCAL_MESH_NUM
859 lcmesh => mesh3d%lcmesh_list(n)
860 !$omp parallel do
861 do ke=lcmesh%NeS, lcmesh%NeE
862 work%local(n)%val(:,ke) = ( this%AUX_VARS(auxvar_denshydro_id)%local(n)%val(:,ke) &
863 + this%PROG_VARS(prgvar_ddens_id )%local(n)%val(:,ke) &
864 ) * this%QTRC_VARS(iv)%local(n)%val(:,ke)
865 end do
866 end do
867 call file_monitor_meshfield_put( this%QTRC_VARS(iv)%monitor_id, work )
868 end if
869 end do
870 if ( dv_monit_id(im_qtot) > 0 ) then
871 do n=1, mesh3d%LOCAL_MESH_NUM
872 lcmesh => mesh3d%lcmesh_list(n)
873 !$omp parallel do
874 do ke=lcmesh%NeS, lcmesh%NeE
875 work%local(n)%val(:,ke) = ( this%AUX_VARS(auxvar_denshydro_id)%local(n)%val(:,ke) &
876 + this%PROG_VARS(prgvar_ddens_id )%local(n)%val(:,ke) &
877 ) * ( 1.0_rp - this%AUX_VARS(auxvar_qdry_id)%local(n)%val(:,ke) )
878 end do
879 end do
880 call file_monitor_meshfield_put( dv_monit_id(im_qtot), work )
881 end if
882
883 !##### Energy Budget #####
884
885 if ( dv_monit_id(im_engt) > 0 ) then
886 call this%Calc_diagVar( 'ENGT', work )
887 call file_monitor_meshfield_put( dv_monit_id(im_engt), work )
888 end if
889 if ( dv_monit_id(im_engp) > 0 ) then
890 call this%Calc_diagVar( 'ENGP', work )
891 call file_monitor_meshfield_put( dv_monit_id(im_engp), work )
892 end if
893 if ( dv_monit_id(im_engk) > 0 ) then
894 call this%Calc_diagVar( 'ENGK', work )
895 call file_monitor_meshfield_put( dv_monit_id(im_engk), work )
896 end if
897 if ( dv_monit_id(im_engi) > 0 ) then
898 call this%Calc_diagVar( 'ENGI', work )
899 call file_monitor_meshfield_put( dv_monit_id(im_engi), work )
900 end if
901
902 call work%Final()
903
904 return
905 end subroutine atmosvars_monitor_core
906
907 !> Preprocess operation for physical processes
908 !!
909!OCL SERIAL
910 subroutine atmosvars_preprocoperationforphys( this, dyncore )
912 implicit none
913 class(atmosvars), intent(inout) :: this
914 class(atmdyndgmdriver_nonhydro3d), intent(in) :: dyncore
915
916 integer :: ic
917 !--------------------------------------------------------------------------
918
919 do ic=atm_vars_container_primary_id+1, atm_vars_container_list_max
920 if ( this%init_containers_item_flag(ic) ) then
921 call this%container_list(ic)%Preproc_operation_for_phys( this%container, dyncore )
922 end if
923 end do
924 return
925 end subroutine atmosvars_preprocoperationforphys
926
927 !-----------------------------------------------------------------------------
928 !> Calculate diagnostic variables
929!OCL SERIAL
930 subroutine atmosvars_calculatediagnostics( this )
931 implicit none
932 class(atmosvars), intent(inout), target :: this
933 !-------------------------------------------------------
934 call this%container%Calc_diagnostics()
935 return
936 end subroutine atmosvars_calculatediagnostics
937
938!OCL SERIAL
939 subroutine atmosvars_calcdiagvar( this, field_name, field_work )
940 implicit none
941 class(atmosvars), intent(inout) :: this
942 character(*), intent(in) :: field_name
943 type(meshfield3d), intent(inout) :: field_work
944 !--------------------------------------------------
945 call this%container%Calc_diagVar( field_name, field_work )
946 return
947 end subroutine atmosvars_calcdiagvar
948
949!OCL SERIAL
950 subroutine atmosvars_calcdiagvar2d( this, field_name, field_work )
951 implicit none
952 class(atmosvars), intent(inout) :: this
953 character(*), intent(in) :: field_name
954 type(meshfield2d), intent(inout), target :: field_work
955
956 class(localmesh2d), pointer :: lcmesh2d
957
958 integer :: n
959 !--------------------------------------------------
960
961 field_work%varname = field_name
962
963 do n=1, field_work%mesh%LOCAL_MESH_NUM
964 lcmesh2d => field_work%mesh%lcmesh_list(n)
965 call vars_calc_diagnosevar2d_lc( field_name, field_work%local(n)%val, &
966 this%ptr_MP_AUXVARS2D_manager, this%ptr_CP_AUXVARS2D_manager, &
967 field_work%mesh, lcmesh2d, lcmesh2d%refElem2D )
968 end do
969 !$acc wait(1)
970 return
971 end subroutine atmosvars_calcdiagvar2d
972
973!--- private -----
974
975!OCL SERIAL
976 subroutine vars_calc_diagnosevar2d_lc( field_name, & ! (in)
977 var_out, & ! (out)
978 mp_auxvars2d, cp_auxvars2d, mesh2d, lcmesh, elem ) ! (in)
979
980 use mod_atmos_phy_mp_vars, only: &
982 use mod_atmos_phy_cp_vars, only: &
984
985 implicit none
986 class(localmesh2d), intent(in) :: lcmesh
987 class(elementbase2d), intent(in) :: elem
988 character(*), intent(in) :: field_name
989 real(rp), intent(out) :: var_out(elem%np,lcmesh%nea)
990 type(modelvarmanager), intent(inout), pointer :: mp_auxvars2d
991 type(modelvarmanager), intent(inout), pointer :: cp_auxvars2d
992 class(meshbase2d), intent(in) :: mesh2d
993
994 integer :: ke, p
995
996 logical :: sw_mp, sw_cp
997 class(localmeshfieldbase), pointer :: sflx_rain_mp, sflx_snow_mp, sflx_engi_mp
998 class(localmeshfieldbase), pointer :: sflx_rain_cp, sflx_snow_cp, sflx_engi_cp
999 !-------------------------------------------------------------------------
1000
1001 sw_mp = associated(mp_auxvars2d)
1002 sw_cp = associated(cp_auxvars2d)
1003
1004 select case(trim(field_name))
1005 case('RAIN', 'SNOW')
1006 if ( sw_mp ) then
1008 lcmesh%lcdomID, mesh2d, mp_auxvars2d, &
1009 sflx_rain_mp, sflx_snow_mp, sflx_engi_mp )
1010 end if
1011 if ( sw_cp ) then
1013 lcmesh%lcdomID, mesh2d, cp_auxvars2d, &
1014 sflx_rain_cp, sflx_snow_cp, sflx_engi_cp )
1015 end if
1016 end select
1017
1018 select case(trim(field_name))
1019 case('RAIN')
1020 !$omp parallel
1021 !$acc parallel present(var_out) async(1)
1022 !$omp do
1023 !$acc loop collapse(2)
1024 do ke=lcmesh%NeS, lcmesh%NeE
1025 do p=1, elem%Np
1026 var_out(p,ke) = 0.0_rp
1027 end do
1028 end do
1029 if ( sw_mp ) then
1030 !$omp do
1031 !$acc loop collapse(2)
1032 do ke=lcmesh%NeS, lcmesh%NeE
1033 do p=1, elem%Np
1034 var_out(p,ke) = var_out(p,ke) + sflx_rain_mp%val(p,ke)
1035 end do
1036 end do
1037 end if
1038 if ( sw_cp ) then
1039 !$omp do
1040 !$acc loop collapse(2)
1041 do ke=lcmesh%NeS, lcmesh%NeE
1042 do p=1, elem%Np
1043 var_out(p,ke) = var_out(p,ke) + sflx_rain_cp%val(p,ke)
1044 end do
1045 end do
1046 end if
1047 !$omp end parallel
1048 !$acc end parallel
1049 case('SNOW')
1050 !$omp parallel
1051 !$acc parallel present(var_out) async(1)
1052 !$omp do
1053 !$acc loop collapse(2)
1054 do ke=lcmesh%NeS, lcmesh%NeE
1055 do p=1, elem%Np
1056 var_out(p,ke) = 0.0_rp
1057 end do
1058 end do
1059 if ( sw_mp ) then
1060 !$omp do
1061 !$acc loop collapse(2)
1062 do ke=lcmesh%NeS, lcmesh%NeE
1063 do p=1, elem%Np
1064 var_out(p,ke) = var_out(p,ke) + sflx_snow_mp%val(p,ke)
1065 end do
1066 end do
1067 end if
1068 if ( sw_cp ) then
1069 !$omp do
1070 !$acc loop collapse(2)
1071 do ke=lcmesh%NeS, lcmesh%NeE
1072 do p=1, elem%Np
1073 var_out(p,ke) = var_out(p,ke) + sflx_snow_cp%val(p,ke)
1074 end do
1075 end do
1076 end if
1077 !$omp end parallel
1078 !$acc end parallel
1079 case default
1080 log_error("AtmosVars_calc_diagnoseVar2D_lc",*) 'The name of diagnostic variable is not suported. Check!', field_name
1081 call prc_abort
1082 end select
1083
1084 return
1085 end subroutine vars_calc_diagnosevar2d_lc
1086end module mod_atmos_vars
module Atmosphere / Mesh
module Atmosphere / Physics / Cumulus Parameterization
subroutine, public atmosphycpvars_getlocalmeshfields_sfcflx(domid, mesh, sfcflx_list, sflx_rain, sflx_snow, sflx_engi)
module Atmosphere / Physics / Cloud Microphysics
subroutine, public atmosphympvars_getlocalmeshfields_sfcflx(domid, mesh, sfcflx_list, sflx_rain, sflx_snow, sflx_engi)
module Atmosphere / Variables
integer, parameter, public atmos_auxvars2d_num
subroutine, public atmosvars_getlocalmeshphytends(domid, mesh, phytends_list, dens_tp, momx_tp, momy_tp, momz_tp, rhot_tp, rhoh_p, rhoq_tp, lcmesh3d)
subroutine, public atmosvars_getlocalmeshsfcvar(domid, mesh, auxvars2d_list, prec, prec_engi, lcmesh2d)
subroutine, public atmosvars_getlocalmeshqtrc_qv(domid, mesh, trcvars_list, forcing_list, var, var_tp, lcmesh3d)
integer, parameter, public atm_vars_container_primary_id
subroutine, public atmosvars_getlocalmeshphyauxvars(domid, mesh, phyauxvars_list, pres, pt, lcmesh3d)
subroutine, public atmosvars_getlocalmeshprgvars(domid, mesh, prgvars_list, auxvars_list, ddens, momx, momy, momz, therm, dens_hyd, pres_hyd, rtot, cvtot, cptot, lcmesh3d)
subroutine, public atmosvars_getlocalmeshqtrcvarlist(domid, mesh, trcvars_list, varid_s, var_list, lcmesh3d)
subroutine, public atmosvars_getlocalmeshqtrcphytend(domid, mesh, phytends_list, qtrcid, rhoq_tp)
subroutine, public atmosvars_getlocalmeshprgvar(domid, mesh, prgvars_list, auxvars_list, varid, var, dens_hyd, pres_hyd, lcmesh3d)
subroutine, public atmosvars_getlocalmeshqtrcvar(domid, mesh, trcvars_list, varid, var, lcmesh3d)
module Atmosphere / Variables
integer, parameter, public atmos_diagvars2d_num
real(rp), dimension(prgvar_num), parameter progvars_check_min
integer, parameter, public atmos_diagvars_dens_id
integer, parameter, public atmos_diagvars_w_id
type(variableinfo), dimension(atmos_diagvars3d_num), public atmos_diagvars3d_vinfo
integer, parameter, public atmos_diagvars3d_num
integer, parameter, public atmos_diagvars_vmet_id
integer, parameter, public atmos_diagvars_rh_id
integer, parameter, public atmos_diagvars_engi_id
integer, parameter, public atmos_diagvars_umet_id
integer, parameter, public atmos_diagvars_qdry_id
integer, parameter, public atmos_diagvars_engk_id
type(variableinfo), dimension(atmos_diagvars2d_num), public atmos_diagvars2d_vinfo
integer, parameter, public atmos_diagvars_v_id
integer, parameter, public atmos_diagvars_t_id
integer, parameter, public atmos_diagvars_snow_id
integer, parameter, public atmos_diagvars_engt_id
integer, parameter, public atmos_diagvars_engp_id
integer, parameter, public atmos_diagvars_rain_id
integer, parameter, public atmos_diagvars_u_id
module FElib / Fluid dyn solver / Atmosphere / driver (3D nonhydrostatic model)
module FElib / Fluid dyn solver / Atmosphere / Nonhydrostatic model / Common
subroutine, public atm_dyn_dgm_nonhydro3d_common_get_varinfo(prgvar_info, auxvar_info, phytend_info)
Get variable information for atmospheric nonhydrostatic dynamical core.
module FElib / Element / Base
type(file_restart_meshfield), public restart_file
An object to manage main restart file.
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Mesh / Local, Base
module FElib / Mesh / Base 2D
module FElib / Mesh / Base 3D
integer, public meshbase3d_dimtypeid_xyz
module FElib / Mesh / Base
module FElib / Data / base
module FElib / Data / Statistics
module FElib / Data / Communication base
FElib / model framework / variable manager.
Derived type to manage a computational mesh (base class)
Derived type to manage variables with atmospheric component.
Derived type to manage a set of variables (prognostic variables, tracer variables,...
Derived type to provide a driver of dynamical core with the atmospheric nonhydrostatic equations.
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type representing an arbitrary finite element.
Derived type to manage restart file with each component.
Derived type representing a local mesh for 2D domain.
Derived type to manage a local 3D computational domain.
Derived type to manage a local computational domain (base type)
Derived type representing a field with local mesh (base type)
Derived type to manage a computational mesh (base type for 2D domain)
Derived type to manage a computational mesh (base type for 3D domain)
Base type to manage a computational mesh.
Derived type representing a field with 2D mesh.
Derived type representing a field with 3D mesh.
Derived type representing a field (base type)
Container to save a pointer of MeshField(1D, 2D, 3D) object.