FE-Project
Loading...
Searching...
No Matches
mod_ocean_dyn.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module Ocean Dynamics
3!!
4!! @par Description
5!! Module for oceanic dynamical process
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_prc
19 use scale_io
20 use scale_prof
21 use scale_const, only: &
22 undef8 => const_undef8
23
24 use scale_sparsemat, only: sparsemat
26
27 use scale_mesh_base, only: meshbase
30
34 use scale_element_base, only: &
36
38 use scale_localmeshfield_base, only: &
40
41 use scale_model_mesh_manager, only: modelmeshbase
44
45! use mod_ocean_dyn_dgm_driver, only: OceanDynDGMDriver_hydro3d
46
47 use mod_ocean_mesh, only: oceanmesh
48 use mod_ocean_vars, only: &
50 use mod_ocean_dyn_vars, only: &
53
54 !-----------------------------------------------------------------------------
55 implicit none
56 private
57 !-----------------------------------------------------------------------------
58 !
59 !++ Public type & procedure
60 !
61
62 !> Derived type to manage a component of oceanic dynamics
63 !!
64 type, extends(modelcomponentproc), public :: oceandyn
65! type(OceanDynDGMDriver_hydro3d) :: dyncore_driver !< A driver object to manage a oceanic dynamical core
66
67 type(oceandynvars) :: dyn_vars !< An object to manage variables in a component of oceanic dynamics
68 integer :: eqs_type !< Type of governing equations: 0=NONE, 1=SLAB
69
70 class(meshbase3d), pointer :: mesh3d
71 real(rp) :: dtsec !< Timestep for a oceanic dynamical core
72 contains
73 procedure, public :: setup => oceandyn_setup
74 procedure, public :: calc_tendency => oceandyn_calc_tendency
75 procedure, public :: update => oceandyn_update
76 procedure, public :: finalize => oceandyn_finalize
77 end type oceandyn
78
79 !-----------------------------------------------------------------------------
80 !++ Public parameters & variables
81 !-----------------------------------------------------------------------------
82
83 !-----------------------------------------------------------------------------
84 !
85 !++ Private procedure
86 !
87 private :: setup_coriolis_parameter
88
89 !-----------------------------------------------------------------------------
90 !
91 !++ Private parameters & variables
92 !
93 !-----------------------------------------------------------------------------
94
96 integer :: ocean_dyn_eqs_slab = 1
97
98contains
99
100!> Setup an object to manage a component of oceanic dynamics
101!!
102!! @param model_mesh Object to manage computational mesh of oceanic model
103!! @param tm_parent_comp Object to mange a temporal scheme in a parent component
104!!
105!OCL SERIAL
106 subroutine oceandyn_setup( this, model_mesh, tm_parent_comp )
107 use mod_ocean_mesh, only: oceanmesh
109
110 implicit none
111
112 class(oceandyn), intent(inout) :: this
113 class(modelmeshbase), target, intent(in) :: model_mesh
114 class(time_manager_component), intent(inout) :: tm_parent_comp
115
116 character(len=H_MID) :: eqs_type = "SLAB" !< Type of governing equations: FIXED_TEMP or SLAB
117 character(len=H_SHORT) :: tinteg_type = 'ERK_SSP_3s3o' !< Type of temporal scheme for a dry dynamical core
118 character(len=H_SHORT) :: tinteg_type_tracer = 'ERK_SSP_3s3o' !< Type of temporal scheme for tracer advection equations
119 real(dp) :: time_dt = undef8 !< Timestep for a atmospheric dynamical core
120 character(len=H_SHORT) :: time_dt_unit = 'SEC' !< Unit of timestep
121
122! logical :: MODALFILTER_FLAG = .false. !< Flag to set whether a modal filtering is used
123
124 namelist / param_ocean_dyn / &
125 eqs_type, &
126 tinteg_type, &
127 tinteg_type_tracer, &
128 time_dt, &
129 time_dt_unit
130! MODALFILTER_FLAG,
131
132 class(oceanmesh), pointer :: ocean_mesh
133 class(meshbase), pointer :: ptr_mesh
134 class(localmeshbase), pointer :: ptr_lcmesh
135 class(elementbase3d), pointer :: elem3d
136 integer :: n
137 real(dp) :: dtsec
138
139 integer :: ierr
140 !--------------------------------------------------
141
142 if (.not. this%IsActivated()) return
143 log_info('OceanDyn_setup',*)
144
145 eqs_type = 'SLAB'
146
147 !--- read namelist
148 rewind(io_fid_conf)
149 read(io_fid_conf,nml=param_ocean_dyn,iostat=ierr)
150 if( ierr < 0 ) then !--- missing
151 log_info("OceanDyn_setup",*) 'Not found namelist. Default used.'
152 elseif( ierr > 0 ) then !--- fatal error
153 log_error("OceanDyn_setup",*) 'Not appropriate names in namelist PARAM_OCEAN_DYN. Check!'
154 call prc_abort
155 endif
156 log_nml(param_ocean_dyn)
157
158 !-
159 select case (trim(eqs_type))
160 case ('FIXED_INIT_TEMP')
161 this%eqs_type = ocean_dyn_eqs_fixed_init_temp
162 case ('SLAB')
163 this%eqs_type = ocean_dyn_eqs_slab
164 case default
165 log_info('OceanDyn_setup',*) 'Not appropriate EQS_TYPE. Check!'
166 call prc_abort
167 end select
168
169 !- get mesh --------------------------------------------------
170
171 call model_mesh%GetModelMesh( ptr_mesh )
172 select type(model_mesh)
173 class is (oceanmesh)
174 ocean_mesh => model_mesh
175 end select
176 this%mesh3D => ocean_mesh%ptr_mesh
177
178 !- Setup the temporal integrator
179
180 call tm_parent_comp%Regist_process( 'OCEAN_DYN', time_dt, time_dt_unit, & ! (in)
181 this%tm_process_id ) ! (out)
182
183 this%dtsec = tm_parent_comp%process_list(this%tm_process_id)%dtsec
184
185 !- initialize the variables
186 call this%dyn_vars%Init( model_mesh )
187
188 call setup_coriolis_parameter( this%dyn_vars, ocean_mesh )
189
190 !- Initialize a module for 3D dynamical core
191 ! call this%dyncore_driver%Init( EQS_TYPE, &
192 ! TINTEG_TYPE, dtsec, &
193 ! MODALFILTER_FLAG, &
194 ! atm_mesh )
195
196 return
197 end subroutine oceandyn_setup
198
199
200!> Calculate tendencies associated with oceanic dynamics
201!!
202!! Because the tendencies with oceanic dynamical cores are treated in OceanDyn_update,
203!! no calculation is performed in this subroutine.
204!!
205!! @param model_mesh Object to manage computational mesh of oceanic model
206!! @param prgvars_list Object to mange prognostic variables with oceanic dynamical core
207!! @param trcvars_list Object to mange auxiliary variables
208!! @param forcing_list Object to mange forcing terms
209!! @param is_update Flag to specify whether the tendencies are updated in this call
210!!
211!OCL SERIAL
212 subroutine oceandyn_calc_tendency( this, model_mesh, prgvars_list, trcvars_list, auxvars_list, forcing_list, is_update )
213 implicit none
214
215 class(oceandyn), intent(inout) :: this
216 class(modelmeshbase), intent(in) :: model_mesh
217 class(modelvarmanager), intent(inout) :: prgvars_list
218 class(modelvarmanager), intent(inout) :: trcvars_list
219 class(modelvarmanager), intent(inout) :: auxvars_list
220 class(modelvarmanager), intent(inout) :: forcing_list
221 logical, intent(in) :: is_update
222
223 !--------------------------------------------------
224
225 if (.not. this%IsActivated()) return
226 !LOG_INFO('OceanDyn_tendency',*)
227 return
228 end subroutine oceandyn_calc_tendency
229
230
231!> Update variables with a component of oceanic dynamics
232!! The tendencies with oceanic dynamical cores are evaluated and the prognostic variables is updated.
233!!
234!! @param model_mesh Object to manage computational mesh of oceanic model
235!! @param prgvars_list Object to mange prognostic variables with oceanic dynamical core
236!! @param trcvars_list Object to mange auxiliary variables
237!! @param forcing_list Object to mange forcing terms
238!! @param is_update Flag to speicfy whether the tendencies are updated in this call
239!!
240!OCL SERIAL
241 subroutine oceandyn_update( this, model_mesh, prgvars_list, trcvars_list, auxvars_list, forcing_list, is_update )
242 use scale_meshfield_base, only: &
244 use mod_ocean_vars, only: &
247 implicit none
248
249 class(oceandyn), intent(inout) :: this
250 class(modelmeshbase), intent(in) :: model_mesh
251 class(modelvarmanager), intent(inout) :: prgvars_list
252 class(modelvarmanager), intent(inout) :: trcvars_list
253 class(modelvarmanager), intent(inout) :: auxvars_list
254 class(modelvarmanager), intent(inout) :: forcing_list
255 logical, intent(in) :: is_update
256
257 class(meshbase), pointer :: mesh
258 class(meshbase3d), pointer :: mesh3d
259
260 integer :: idom
261 class(localmesh3d), pointer :: lmesh
262 class(localmesh2d), pointer :: lmesh2d
263
264 class(meshfield3d), pointer :: therm, rhoh
265 !--------------------------------------------------
266
267 if ( this%eqs_type == ocean_dyn_eqs_fixed_init_temp ) then
268 log_info('OceanDyn_update',*) 'No update for fixed initial temperature'
269 return
270 end if
271
272 call prof_rapstart( 'OCEAN_DYN_update', 1)
273
274 call model_mesh%GetModelMesh( mesh )
275 select type(mesh)
276 class is (meshbase3d)
277 mesh3d => mesh
278 end select
279
280
281 call prof_rapstart( 'OCEAN_DYN_core', 2)
282 call prgvars_list%Get3D( prgvar_therm_id, therm )
283 call forcing_list%Get3D( phytend_rhoh_id, rhoh )
284 do idom=1, mesh3d%LOCAL_MESH_NUM
285 lmesh => mesh3d%lcmesh_list(idom)
286 lmesh2d => lmesh%lcmesh2D
287 call ocn_dyn_update_lc( therm%local(idom)%val, &
288 rhoh%local(idom)%val, &
289 this%dtsec, lmesh, lmesh%refElem3D, lmesh2d, lmesh2d%refElem2D )
290
291 end do
292
293 call prof_rapend( 'OCEAN_DYN_core', 2)
294
295 !---------------------------
296 call prof_rapend( 'OCEAN_DYN_update', 1)
297
298 return
299 end subroutine oceandyn_update
300
301!> Finalize an object to manage a component of oceanic dynamics
302!!
303!OCL SERIAL
304 subroutine oceandyn_finalize( this )
305 implicit none
306 class(oceandyn), intent(inout) :: this
307
308 integer :: n
309 !--------------------------------------------------
310 if (.not. this%IsActivated()) return
311 log_info('OceanDyn_finalize',*)
312
313 ! call this%dyncore_driver%Final()
314 call this%dyn_vars%Final()
315
316 return
317 end subroutine oceandyn_finalize
318
319 !--- private ---------------
320
321 !> Setup Coriolis parameter
322!OCL SERIAL
323 subroutine setup_coriolis_parameter( this, ocn_mesh )
324
327 implicit none
328
329 class(oceandynvars), target, intent(inout) :: this
330 class(oceanmesh), target, intent(in) :: ocn_mesh
331
332 class(localmeshfieldbase), pointer :: coriolis
333 class(localmesh3d), pointer :: lcmesh3d
334 class(localmesh2d), pointer :: lcmesh2d
335 integer :: n
336
337 character(len=H_SHORT) :: coriolis_type !< Type of coriolis force: 'PLANE', 'SPHERE'
338 real(rp) :: coriolis_f0 = 0.0_rp
339 real(rp) :: coriolis_beta = 0.0_rp
340 real(rp) :: coriolis_y0
341
342 namelist /param_ocean_dyn_coriolis/ &
343 coriolis_type, &
344 coriolis_f0, coriolis_beta, coriolis_y0
345
346 class(meshbase3d), pointer :: mesh3d
347 class(meshcubedom3d), pointer :: meshcube
348 integer :: ierr
349 !---------------------------------------------------------------
350
351 mesh3d => ocn_mesh%ptr_mesh
352
353 coriolis_type = 'NONE'
354
355 select type(mesh3d)
356 type is (meshcubedom3d)
357 coriolis_y0 = 0.5_rp*(mesh3d%ymax_gl + mesh3d%ymin_gl)
358 end select
359
360 rewind(io_fid_conf)
361 read(io_fid_conf,nml=param_ocean_dyn_coriolis,iostat=ierr)
362 if( ierr < 0 ) then !--- missing
363 log_info("OCEAN_DYN_setup_coriolis",*) 'Not found namelist. Default used.'
364 else if( ierr > 0 ) then !--- fatal error
365 log_error("OCEAN_DYN_setup_coriolis",*) 'Not appropriate names in namelist PARAM_OCEAN_DYN_CORIOLIS. Check!'
366 call prc_abort
367 end if
368 log_nml(param_ocean_dyn_coriolis)
369
370 do n = 1, mesh3d%LOCAL_MESH_NUM
371 call oceandynauxvars_getlocalmeshfields( n, mesh3d, this%AUXVARS2D_manager, &
372 coriolis, lcmesh3d )
373 lcmesh2d => lcmesh3d%lcmesh2D
374
376 coriolis%val(:,lcmesh2d%NeS:lcmesh2d%NeE), & ! (out)
377 coriolis_type, lcmesh2d%refElem2D%Np * lcmesh2d%Ne, & ! (in)
378 lcmesh2d%pos_en(:,:,2), coriolis_f0, coriolis_beta, coriolis_y0, & ! (in)
379 lcmesh3d%lat2D ) ! (in)
380
381 !$acc update device( coriolis%val )
382 end do
383
384 return
385 end subroutine setup_coriolis_parameter
386
387!-- private
388!OCL SERIAL
389 subroutine ocn_dyn_update_lc( THERM, &
390 RHOH, dt, lmesh, elem, lmesh2D, elem2D )
391 use scale_const, only: &
392 dwatr => const_dwatr
393 use scale_atmos_hydrometeor, only: &
394 cv_water
395 implicit none
396 class(localmesh3d), intent(in) :: lmesh
397 class(elementbase3d), intent(in) :: elem
398 class(localmesh2d), intent(in) :: lmesh2d
399 class(elementbase2d), intent(in) :: elem2d
400 real(rp), intent(inout) :: therm(elem%np,lmesh%nea)
401 real(rp), intent(in) :: rhoh(elem%np,lmesh%nea)
402 real(rp), intent(in) :: dt
403
404 integer :: ke
405 real(rp) :: coef
406 !----------------------------------------------------------------------
407
408 coef = dt / ( cv_water * dwatr )
409 !$omp parallel do
410 do ke=lmesh%NeS, lmesh%NeE
411 therm(:,ke) = therm(:,ke) + rhoh(:,ke) * coef
412 end do
413 return
414 end subroutine ocn_dyn_update_lc
415end module mod_ocean_dyn
module Ocean / Dynamics
subroutine, public oceandynauxvars_getlocalmeshfields(domid, mesh, auxvars_list, coriolis, lcmesh3d)
module Ocean Dynamics
integer ocean_dyn_eqs_fixed_init_temp
module Ocean / Mesh
module Ocean / Variables
subroutine, public oceanvars_getlocalmeshprgvars(domid, mesh, prgvars_list, auxvars2d_list, u, v, w, therm, salt, sfc_temp, sfc_alb_ir_dir, sfc_alb_ir_dif, sfc_alb_nir_dir, sfc_alb_nir_dif, sfc_alb_vis_dir, sfc_alb_vis_dif, lcmesh3d)
integer, parameter, public prgvar_therm_id
integer, parameter, public phytend_rhoh_id
Module common / Coriolis parameter.
subroutine, public get_coriolis_parameter(coriolis, colioris_type, np, y, f0, beta, y0, lat)
Get Coriolis parameter.
module FElib / Element / Base
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
module FElib / Mesh / Base
module FElib / Mesh / Cubic 3D domain
module FElib / Data / base
FElib / model framework / physics process.
FElib / model framework / mesh manager.
FElib / model framework / variable manager.
Module common / sparsemat.
Module common / time.
Module common / Runge-Kutta scheme.
Derived type to manage a component of oceanic dynamics.
Derived type to manage variables with oceanic dynamics component.
Derived type to manage a computational mesh (base class)
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type representing an arbitrary finite element.
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 to manage a cubic 3D computational domain.
Derived type representing a field with 2D mesh.
Derived type representing a field with 3D mesh.
Derived type representing a field (base type)
Derived type to manage a sparse matrix.
Derived type to provide RK scheme.