FE-Project
Loading...
Searching...
No Matches
mod_ocean_mesh_gm.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module Ocean / Mesh
3!!
4!! @par Description
5!! Module for mesh with ocean global model
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
28 use scale_sparsemat, only: sparsemat
30
33
34 use mod_ocean_mesh, only: &
36
37 !-----------------------------------------------------------------------------
38 implicit none
39 private
40 !-----------------------------------------------------------------------------
41 !
42 !++ Public type & procedures
43 !
44
45 !> Derived type to manage a computational mesh of global ocean model
46 !!
47 type, extends(oceanmesh), public :: oceanmeshgm
48 type(meshcubedspheredom3d) :: mesh !< Object for 3D cubed-sphere mesh
50 contains
51 procedure :: init => oceanmeshgm_init
52 procedure :: final => oceanmeshgm_final
53 procedure :: create_communicator => oceanmeshgm_create_communicator
54 procedure :: setup_restartfile1 => oceanmeshgm_setup_restartfile1
55 procedure :: setup_restartfile2 => oceanmeshgm_setup_restartfile2
56 procedure :: calc_uvmet => oceanmeshgm_calc_uvmet
57 procedure :: setup_vcoordinate => oceanmeshgm_setup_vcoordinate
58 end type oceanmeshgm
59
60 !-----------------------------------------------------------------------------
61 !
62 !++ Public parameters & variables
63 !
64
65 !-----------------------------------------------------------------------------
66 !
67 !++ Private procedures
68 !
69 !-------------------
70
71 !-----------------------------------------------------------------------------
72 !
73 !++ Private parameters & variables
74 !
75
76contains
77
78 !> Initialize an object to manage computational mesh
79 !!
80!OCL SERIAL
81 subroutine oceanmeshgm_init( this )
82 use scale_const, only: &
83 rplanet => const_radius
85 use scale_meshutil_vcoord, only: &
87
88 implicit none
89 class(oceanmeshgm), target, intent(inout) :: this
90
91 real(RP) :: dom_zmin = 0.0_rp !< Minimum vertical coordinate value of the computational domain
92 real(RP) :: dom_zmax = 10.0e3_rp !< Maximum vertical coordinate value of the computational domain
93 logical :: isPeriodicZ = .false. !< Flag whether a periodic boundary condition is applied in the vertical direction
94
95 integer, parameter :: FZ_nmax = 1000
96 real(RP) :: FZ(FZ_nmax) !< Values of the vertically computational coordinate at the element boundaries
97
98 !* Global
99 logical :: SHALLOW_OCN_APPROX_FLAG = .true. !< Flag whether the shallow ocean approximation is applied
100 integer :: NeGX = 2 !< Number of finite element in the y-coordinate direction in each panel of the cubed-sphere mesh
101 integer :: NeGY = 2 !< Number of finite element in the y-coordinate direction in each panel of the cubed-sphere mesh
102 integer :: NeZ = 2 !< Number of finite element in the vertical direction in each MPI process
103 integer :: NLocalMeshPerPrc = 6 !< Number of local mesh per MPI process
104 integer :: Nprc = 1 !< Total number of MPI process
105 integer :: PolyOrder_h = 2 !< Polynomial order for the horizontal direction
106 integer :: PolyOrder_v = 2 !< Polynomial order for the z-direction
107 logical :: LumpedMassMatFlag = .false. !< Flag whether a mass lumping is applied
108
109 character(len=H_LONG) :: TOPO_IN_BASENAME = '' !< Basename of the input file
110 character(len=H_MID) :: TOPO_IN_VARNAME = 'topo' !< Variable name of topography in the input file
111 character(len=H_MID) :: VERTICAL_COORD_NAME = "TERRAIN_FOLLOWING" !< Type of the vertical coordinate
112
113 logical :: COMM_USE_MPI_PC = .false. !< Flag whether persistent communication is used in MPI
114 logical :: COMM_USE_MPI_PC_FUJITSU_EXT
115
116 character(len=H_SHORT) :: Element_operation_type = 'General' !< General or TensorProd3D
117 character(len=H_SHORT) :: SpMV_storage_format = 'ELL' !< CSR or ELL
118
119 namelist / param_ocean_mesh / &
120 shallow_ocn_approx_flag, &
121 dom_zmin, dom_zmax, &
122 fz, isperiodicz, &
123 negx, negy, nez, nlocalmeshperprc, nprc, &
124 polyorder_h, polyorder_v, lumpedmassmatflag, &
125 element_operation_type, &
126 spmv_storage_format, &
127 vertical_coord_name, &
128 topo_in_basename, topo_in_varname, &
129 comm_use_mpi_pc, &
130 comm_use_mpi_pc_fujitsu_ext
131
132 integer :: k
133 logical :: is_spec_FZ
134
135 integer :: ierr
136 !-------------------------------------------
137
138 log_newline
139 log_info("OCN_MESH_setup",*) 'Setup'
140
141 fz(:) = -1.0_rp
142#ifdef __FUJITSU
143 comm_use_mpi_pc_fujitsu_ext = .true.
144#else
145 comm_use_mpi_pc_fujitsu_ext = .false.
146#endif
147
148 rewind(io_fid_conf)
149 read(io_fid_conf,nml=param_ocean_mesh,iostat=ierr)
150 if( ierr < 0 ) then !--- missing
151 log_info("OCN_MESH_setup",*) 'Not found namelist. Default used.'
152 elseif( ierr > 0 ) then !--- fatal error
153 log_error("OCN_MESH_setup",*) 'Not appropriate names in namelist PARAM_OCEAN_MESH. Check!'
154 call prc_abort
155 endif
156 log_nml(param_ocean_mesh)
157
158 !----
159
160 !- Setup the element
161
162 call this%element%Init( polyorder_h, polyorder_v, lumpedmassmatflag )
163 call this%element_v1D%Init( polyorder_v, lumpedmassmatflag )
164
165 !- Setup the mesh
166
167 is_spec_fz = .true.
168 do k=1, nez+1
169 if (fz(k) < 0.0_rp) then
170 is_spec_fz = .false.
171 end if
172 end do
173 if (is_spec_fz) then
174 call this%mesh%Init( &
175 negx, negy, nez, rplanet, dom_zmin, dom_zmax, &
176 this%element, nlocalmeshperprc, nproc=nprc, &
177 fz=fz(1:nez+1), shallow_approx=shallow_ocn_approx_flag )
178 else
179 call this%mesh%Init( &
180 negx, negy, nez, rplanet, dom_zmin, dom_zmax, &
181 this%element, nlocalmeshperprc, nproc=nprc, &
182 shallow_approx=shallow_ocn_approx_flag )
183 end if
184
185 call this%mesh%Generate()
186
187 !-
188
189 call this%OceanMesh_Init( this%mesh )
190 call this%PrepairElementOperation( element_operation_type, spmv_storage_format )
191
192 !- Set topography & vertical coordinate
193
194 call this%Read_topography_file( topo_in_basename, topo_in_varname, &
195 this%mesh%mesh2D, dom_zmin )
196
197 this%vcoord_type_id = meshutil_get_vcoord_typeid( vertical_coord_name )
198 ! We tentatively disable the setup of vertical coordinate in ocean component.
199 ! For future, we will implement a more flexible setup of vertical coordinate.
200 ! call this%Setup_vcoordinate()
201
202 !-
203 this%comm_use_mpi_pc = comm_use_mpi_pc
204 this%comm_use_mpi_pc_fujitsu_ext = comm_use_mpi_pc_fujitsu_ext
205
206 return
207 end subroutine oceanmeshgm_init
208
209 !> Finalize an object to manage computational mesh
210 !!
211!OCL SERIAL
212 subroutine oceanmeshgm_final(this)
213 implicit none
214
215 class(oceanmeshgm), intent(inout) :: this
216 integer :: commid
217 !-------------------------------------------
218
219 do commid=1, this%communicator_num
220 call this%comm_list(commid)%Final()
221 end do
222
223 call this%mesh%Final()
224 call this%OceanMesh_Final()
225
226 return
227 end subroutine oceanmeshgm_final
228
229 !> Create a communicator for data communication on global computational domain
230 !!
231!OCL SERIAL
232 subroutine oceanmeshgm_create_communicator( this, sfield_num, hvfield_num, htensorfield_num, &
233 var_manager, field_list, commid, &
234 field_list_is, field_list_ie )
235 implicit none
236 class(oceanmeshgm), target, intent(inout) :: this
237 integer, intent(in) :: sfield_num !< Number of scalar fields
238 integer, intent(in) :: hvfield_num !< Number of horizontal vector fields
239 integer, intent(in) :: htensorfield_num !< Number of horizontal tensor fields
240 class(modelvarmanager), intent(inout) :: var_manager !< Object to manage variables
241 class(meshfield3d), intent(in) :: field_list(:) !< Array of 3D fields
242 integer, intent(out) :: commid !< Communicator ID
243 integer, intent(in), optional :: field_list_is !< Starting index of the field list for communication (optional)
244 integer, intent(in), optional :: field_list_ie !< Ending index of the field list for communication (optional)
245 !-----------------------------------------------------
246
247 commid = this%Get_communicatorID( ocn_mesh_max_commnuicator_num )
248 call this%comm_list(commid)%Init( sfield_num, hvfield_num, htensorfield_num, this%mesh )
249 if ( this%comm_use_mpi_pc ) then
250 call this%comm_list(commid)%Prepare_PC( this%comm_use_mpi_pc_fujitsu_ext )
251 end if
252 call var_manager%MeshFieldComm_Prepare( this%comm_list(commid), field_list, field_list_is, field_list_ie )
253
254 return
255 end subroutine oceanmeshgm_create_communicator
256
257!OCL SERIAL
258 subroutine oceanmeshgm_setup_restartfile1( this, restart_file, var_num, dim_name_postfix )
259 implicit none
260 class(oceanmeshgm), target, intent(inout) :: this
261 class(file_restart_meshfield_component), intent(inout) :: restart_file
262 integer, intent(in) :: var_num
263 character(*), intent(in) :: dim_name_postfix
264 !------------------------------------------------
265
266 call restart_file%Init( 'OCEAN', var_num, dim_name_postfix, meshcubedsphere3d=this%mesh )
267 return
268 end subroutine oceanmeshgm_setup_restartfile1
269
270!OCL SERIAL
271 subroutine oceanmeshgm_setup_restartfile2( this, restart_file, &
272 in_basename, in_postfix_timelabel, &
273 out_basename, out_postfix_timelabel, &
274 out_dtype, out_title, var_num, dim_name_postfix )
275 implicit none
276 class(oceanmeshgm), target, intent(inout) :: this
277 class(file_restart_meshfield_component), intent(inout) :: restart_file
278 character(*), intent(in) :: in_basename
279 logical, intent(in) :: in_postfix_timelabel
280 character(*), intent(in) :: out_basename
281 logical, intent(in) :: out_postfix_timelabel
282 character(*), intent(in) :: out_title
283 character(*), intent(in) :: out_dtype
284 integer, intent(in) :: var_num
285 character(*), intent(in) :: dim_name_postfix
286 !-----------------------------------------------------------
287
288 call restart_file%Init( 'OCEAN', in_basename, in_postfix_timelabel, &
289 out_basename, out_postfix_timelabel, out_dtype, out_title, &
290 var_num, dim_name_postfix, &
291 meshcubedsphere3d=this%mesh )
292
293 end subroutine oceanmeshgm_setup_restartfile2
294
295!> Calculate horizontal vector components in longitude-latitude coordinates
296!OCL SERIAL
297 subroutine oceanmeshgm_calc_uvmet( this, U, V, &
298 Umet, Vmet )
299
300 use scale_cubedsphere_coord_cnv, only: &
302 implicit none
303 class(oceanmeshgm), target, intent(in) :: this
304 type(meshfield3d), intent(in) :: U
305 type(meshfield3d), intent(in) :: V
306 type(meshfield3d), intent(inout) :: Umet
307 type(meshfield3d), intent(inout) :: Vmet
308
309 integer :: n
310 integer :: ke, ke2D
311 type(localmesh3d), pointer :: lcmesh
312 class(elementbase3d), pointer :: elem
313 !------------------------------------------
314
315 do n=1, this%mesh%LOCAL_MESH_NUM
316 lcmesh => this%mesh%lcmesh_list(n)
317 elem => lcmesh%refElem3D
319 lcmesh%panelID, lcmesh%pos_en(:,:,1), lcmesh%pos_en(:,:,2), & ! (in)
320 lcmesh%gam, elem%Np * lcmesh%Ne, & ! (in)
321 u%local(n)%val(:,lcmesh%NeS:lcmesh%NeE), & ! (in)
322 v%local(n)%val(:,lcmesh%NeS:lcmesh%NeE), & ! (in)
323 umet%local(n)%val(:,lcmesh%NeS:lcmesh%NeE), & ! (out)
324 vmet%local(n)%val(:,lcmesh%NeS:lcmesh%NeE) ) ! (out)
325 end do
326
327 return
328 end subroutine oceanmeshgm_calc_uvmet
329
330!> Setup the vertical coordinate
331!OCL SERIAL
332 subroutine oceanmeshgm_setup_vcoordinate( this )
334 implicit none
335 class(oceanmeshgm), TARGET, INTENT(INOUT) :: this
336
337 type(meshfieldcommcubedspheredom3d) :: comm3D
338 type(meshfieldcommcubedspheredom2d) :: comm2D
339 !-------------------------------------------------
340
341 call comm2d%Init( 1, 0, 0, this%mesh%mesh2D )
342 call comm3d%Init( 2, 1, 0, this%mesh )
343
344 call this%topography%SetVCoordinate( this%ptr_mesh, &
345 this%vcoord_type_id, this%mesh%zmax_gl, comm3d, comm2d )
346
347 call comm2d%Final()
348 call comm3d%Final()
349
350 return
351 end subroutine oceanmeshgm_setup_vcoordinate
352
353end module mod_ocean_mesh_gm
module Ocean / Mesh
subroutine oceanmeshgm_init(this)
Initialize an object to manage computational mesh.
module Ocean / Mesh
integer, parameter, public ocn_mesh_max_commnuicator_num
Module common / Coordinate conversion with cubed-sphere projection.
subroutine, public cubedspherecoordcnv_cs2lonlatvec(panelid, alpha, beta, gam, np, vecalpha, vecbeta, veclon, veclat, lat, gpu_async_id)
Convert the components of a vector in local coordinates with an equiangular gnomonic cubed-sphere pro...
module FElib / Element / Base
module FElib / Element / hexahedron
module FElib / Mesh / Local 3D
module FElib / Mesh / Base 2D
module FElib / Mesh / Base 3D
module FElib / Mesh / Cubed-sphere 3D domain
module FElib / Data / base
module FElib / Data / Communication in 2D cubed-sphere domain
module FElib / Data / Communication in 3D cubed-sphere domain
module FElib / Mesh / utility for general vertical coordinate
integer function, public meshutil_get_vcoord_typeid(vcoord_type)
Get a type ID of vertical coordinate.
FElib / model framework / mesh manager.
FElib / model framework / variable manager.
Module common / sparsemat.
Derived type to manage a computational mesh (base class)
Derived type to manage a computational mesh of global ocean model.
Derived type representing a 3D reference element.
Derived type representing a hexahedral element.
Derived type to manage restart file with each component.
Derived type to manage a local 3D computational domain.
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 to manage a cubed-sphere 3D computational domain.
Derived type representing a field with 3D mesh.
Base derived type to manage data communication with 2D cubed-sphere domain.
Base derived type to manage data communication with 3D cubed-sphere domain.
Derived type to manage a sparse matrix.