FE-Project
Loading...
Searching...
No Matches
mod_ocean_mesh_rm.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module Ocean / Mesh
3!!
4!! @par Description
5!! Module for mesh with ocean regional 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 regional ocean model
46 !!
47 type, extends(oceanmesh), public :: oceanmeshrm
48 type(meshcubedom3d) :: mesh !< Object to manage a cubic computational mesh
49 type(meshfieldcommcubedom3d) :: comm_list(ocn_mesh_max_commnuicator_num) !< Object to manage data communication on a cubic computational mesh
50 contains
51 procedure :: init => oceanmeshrm_init
52 procedure :: final => oceanmeshrm_final
53 procedure :: create_communicator => oceanmeshrm_create_communicator
54 procedure :: setup_restartfile1 => oceanmeshrm_setup_restartfile1
55 procedure :: setup_restartfile2 => oceanmeshrm_setup_restartfile2
56 procedure :: calc_uvmet => oceanmeshrm_calc_uvmet
57 procedure :: setup_vcoordinate => oceanmeshrm_setup_vcoordinate
58 end type oceanmeshrm
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 !- Ocean Mesh RM -----------------------------------------
79
80 !> Initialize an object to manage computational mesh
81 !!
82 subroutine oceanmeshrm_init( this )
83 use scale_meshutil_vcoord, only: &
85
86 implicit none
87 class(oceanmeshrm), target, intent(inout) :: this
88
89 real(RP) :: dom_xmin = 0.0_rp !< Minimum x-coordinate value of the computational domain
90 real(RP) :: dom_xmax = 100.0e3_rp !< Maximum x-coordinate value of the computational domain
91 real(RP) :: dom_ymin = 0.0_rp !< Minimum y-coordinate value of the computational domain
92 real(RP) :: dom_ymax = 100.0e3_rp !< Maximum y-coordinate value of the computational domain
93 real(RP) :: dom_zmin = 0.0_rp !< Minimum vertical coordinate value of the computational domain
94 real(RP) :: dom_zmax = 10.0e3_rp !< Maximum vertical coordinate value of the computational domain
95 logical :: isPeriodicX = .true. !< Flag whether a periodic boundary condition is applied in the x-direction
96 logical :: isPeriodicY = .true. !< Flag whether a periodic boundary condition is applied in the y-direction
97 logical :: isPeriodicZ = .false. !< Flag whether a periodic boundary condition is applied in the vertical direction
98
99 integer :: NeX = 2 !< Number of finite element in the x-direction in each MPI process
100 integer :: NeY = 2 !< Number of finite element in the y-direction in each MPI process
101 integer :: NeZ = 2 !< Number of finite element in the vertical direction in each MPI process
102 integer :: NprcX = 1 !< Number of MPI process in the x-direction
103 integer :: NprcY = 1 !< Number of MPI process in the y-direction
104 integer :: PolyOrder_h = 2 !< Polynomial order for the horizontal direction
105 integer :: PolyOrder_v = 2 !< Polynomial order for the z-direction
106 logical :: LumpedMassMatFlag = .false. !< Flag whether a mass lumping is applied
107
108 character(len=H_LONG) :: TOPO_IN_BASENAME = '' !< Basename of the input file
109 character(len=H_MID) :: TOPO_IN_VARNAME = 'topo' !< Variable name of topography in the input file
110 character(len=H_MID) :: VERTICAL_COORD_NAME = "TERRAIN_FOLLOWING" !< Type of the vertical coordinate
111
112 logical :: COMM_USE_MPI_PC = .false. !< Flag whether persistent communication is used in MPI
113 logical :: COMM_USE_MPI_PC_FUJITSU_EXT
114
115 character(len=H_SHORT) :: Element_operation_type = 'General' !< General or TensorProd3D
116 character(len=H_SHORT) :: SpMV_storage_format = 'ELL' !< Storage format of sparse matrix (CSR or ELL)
117
118 integer, parameter :: ATMOS_MESH_NLocalMeshPerPrc = 1
119
120 integer, parameter :: FZ_nmax = 1000
121 real(RP) :: FZ(FZ_nmax) !< Values of the vertically computational coordinate at the element boundaries
122
123 namelist / param_ocean_mesh / &
124 dom_xmin, dom_xmax, &
125 dom_ymin, dom_ymax, &
126 dom_zmin, dom_zmax, &
127 fz, &
128 isperiodicx, isperiodicy, isperiodicz, &
129 nex, ney, nez, &
130 polyorder_h, polyorder_v, lumpedmassmatflag, &
131 element_operation_type, &
132 spmv_storage_format, &
133 nprcx, nprcy, &
134 topo_in_basename, topo_in_varname, &
135 vertical_coord_name, &
136 comm_use_mpi_pc, &
137 comm_use_mpi_pc_fujitsu_ext
138
139 integer :: k
140 logical :: is_spec_FZ
141
142 integer :: ierr
143 !-------------------------------------------
144
145 log_newline
146 log_info("OCEAN_MESH_setup",*) 'Setup'
147
148 fz(:) = -1.0_rp
149#ifdef __FUJITSU
150 comm_use_mpi_pc_fujitsu_ext = .true.
151#else
152 comm_use_mpi_pc_fujitsu_ext = .false.
153#endif
154
155 rewind(io_fid_conf)
156 read(io_fid_conf,nml=param_ocean_mesh,iostat=ierr)
157 if( ierr < 0 ) then !--- missing
158 log_info("OCEAN_MESH_setup",*) 'Not found namelist. Default used.'
159 elseif( ierr > 0 ) then !--- fatal error
160 log_error("OCEAN_MESH_setup",*) 'Not appropriate names in namelist PARAM_OCEAN_MESH. Check!'
161 call prc_abort
162 endif
163 log_nml(param_ocean_mesh)
164
165 !----
166
167 ! Setup the element
168
169 call this%element%Init( polyorder_h, polyorder_v, lumpedmassmatflag )
170 call this%element_v1D%Init( polyorder_v, lumpedmassmatflag )
171
172 ! Setup the mesh
173
174 is_spec_fz = .true.
175 do k=1, nez+1
176 if (fz(k) < 0.0_rp) then
177 is_spec_fz = .false.
178 end if
179 end do
180 if (is_spec_fz) then
181 call this%mesh%Init( &
182 nprcx*nex, nprcy*ney, nez, &
183 dom_xmin, dom_xmax,dom_ymin, dom_ymax, dom_zmin, dom_zmax, &
184 isperiodicx, isperiodicy, isperiodicz, &
185 this%element, atmos_mesh_nlocalmeshperprc, nprcx, nprcy, &
186 fz=fz(1:nez+1) )
187 else
188 call this%mesh%Init( &
189 nprcx*nex, nprcy*ney, nez, &
190 dom_xmin, dom_xmax,dom_ymin, dom_ymax, dom_zmin, dom_zmax, &
191 isperiodicx, isperiodicy, isperiodicz, &
192 this%element, atmos_mesh_nlocalmeshperprc, nprcx, nprcy )
193 end if
194
195 call this%mesh%Generate()
196
197 !-
198 call this%OceanMesh_Init( this%mesh )
199 call this%PrepairElementOperation( element_operation_type, spmv_storage_format )
200
201 !- Set topography & vertical coordinate
202
203 call this%Read_topography_file( topo_in_basename, topo_in_varname, &
204 this%mesh%mesh2D, dom_zmin )
205
206 this%vcoord_type_id = meshutil_get_vcoord_typeid( vertical_coord_name )
207 ! We tentatively disable the setup of vertical coordinate in ocean component.
208 ! For future, we will implement a more flexible setup of vertical coordinate.
209 ! call this%Setup_vcoordinate()
210
211 !-
212 this%comm_use_mpi_pc = comm_use_mpi_pc
213 this%comm_use_mpi_pc_fujitsu_ext = comm_use_mpi_pc_fujitsu_ext
214
215 return
216 end subroutine oceanmeshrm_init
217
218 !> Finalize an object to manage computational mesh
219 !!
220 subroutine oceanmeshrm_final(this)
221 implicit none
222
223 class(oceanmeshrm), intent(inout) :: this
224 integer :: commid
225 !-------------------------------------------
226
227 do commid=1, this%communicator_num
228 call this%comm_list(commid)%Final()
229 end do
230
231 call this%mesh%Final()
232 call this%OceanMesh_Final()
233
234 return
235 end subroutine oceanmeshrm_final
236
237 !> Create a communicator for data communication on regional computational domain
238 !!
239 subroutine oceanmeshrm_create_communicator( this, sfield_num, hvfield_num, htensorfield_num, &
240 var_manager, field_list, commid, &
241 field_list_is, field_list_ie )
242 implicit none
243 class(oceanmeshrm), target, intent(inout) :: this
244 integer, intent(in) :: sfield_num !< Number of scalar fields
245 integer, intent(in) :: hvfield_num !< Number of horizontal vector fields
246 integer, intent(in) :: htensorfield_num !< Number of horizontal tensor fields
247 class(modelvarmanager), intent(inout) :: var_manager !< Object to manage variables
248 class(meshfield3d), intent(in) :: field_list(:) !< Array of 3D fields
249 integer, intent(out) :: commid !< Communicator ID
250 integer, intent(in), optional :: field_list_is !< Starting index of the field list for communication (optional)
251 integer, intent(in), optional :: field_list_ie !< Ending index of the field list for communication (optional)
252 !-----------------------------------------------------
253
254 commid = this%Get_communicatorID( ocn_mesh_max_commnuicator_num )
255 call this%comm_list(commid)%Init( sfield_num, hvfield_num, htensorfield_num, this%mesh )
256 if ( this%comm_use_mpi_pc ) then
257 call this%comm_list(commid)%Prepare_PC( this%comm_use_mpi_pc_fujitsu_ext )
258 end if
259 call var_manager%MeshFieldComm_Prepare( this%comm_list(commid), field_list, field_list_is, field_list_ie )
260
261 return
262 end subroutine oceanmeshrm_create_communicator
263
264 subroutine oceanmeshrm_setup_restartfile1( this, restart_file, var_num, dim_name_postfix )
265 implicit none
266 class(oceanmeshrm), target, intent(inout) :: this
267 class(file_restart_meshfield_component), intent(inout) :: restart_file
268 integer, intent(in) :: var_num
269 character(*), intent(in) :: dim_name_postfix
270 !------------------------------------------------
271
272 call restart_file%Init( 'OCEAN', var_num, dim_name_postfix, mesh3d=this%mesh )
273 return
274 end subroutine oceanmeshrm_setup_restartfile1
275
276 subroutine oceanmeshrm_setup_restartfile2( this, restart_file, &
277 in_basename, in_postfix_timelabel, &
278 out_basename, out_postfix_timelabel, &
279 out_dtype, out_title, var_num, dim_name_postfix )
280 implicit none
281 class(oceanmeshrm), target, intent(inout) :: this
282 class(file_restart_meshfield_component), intent(inout) :: restart_file
283 character(*), intent(in) :: in_basename
284 logical, intent(in) :: in_postfix_timelabel
285 character(*), intent(in) :: out_basename
286 logical, intent(in) :: out_postfix_timelabel
287 character(*), intent(in) :: out_title
288 character(*), intent(in) :: out_dtype
289 integer, intent(in) :: var_num
290 character(*), intent(in) :: dim_name_postfix
291 !-----------------------------------------------------------
292
293 call restart_file%Init( 'OCEAN', in_basename, in_postfix_timelabel, &
294 out_basename, out_postfix_timelabel, out_dtype, out_title, &
295 var_num, dim_name_postfix, &
296 mesh3d=this%mesh )
297
298 return
299 end subroutine oceanmeshrm_setup_restartfile2
300
301 subroutine oceanmeshrm_calc_uvmet( this, U, V, &
302 Umet, Vmet )
303 implicit none
304 class(oceanmeshrm), target, intent(in) :: this
305 type(meshfield3d), intent(in) :: U
306 type(meshfield3d), intent(in) :: V
307 type(meshfield3d), intent(inout) :: Umet
308 type(meshfield3d), intent(inout) :: Vmet
309
310 integer :: n
311 integer :: ke
312 type(localmesh3d), pointer :: lcmesh
313 !------------------------------------------
314
315 do n=1, this%mesh%LOCAL_MESH_NUM
316 lcmesh => this%mesh%lcmesh_list(n)
317 !$omp parallel do
318 do ke=lcmesh%NeS, lcmesh%NeE
319 umet%local(n)%val(:,ke) = u%local(n)%val(:,ke)
320 vmet%local(n)%val(:,ke) = v%local(n)%val(:,ke)
321 end do
322 end do
323
324 return
325 end subroutine oceanmeshrm_calc_uvmet
326
327!> Setup the vertical coordinate
328 subroutine oceanmeshrm_setup_vcoordinate( this )
330 implicit none
331 class(oceanmeshrm), TARGET, INTENT(INOUT) :: this
332
333 type(meshfieldcommcubedom3d) :: comm3D
334 type(meshfieldcommrectdom2d) :: comm2D
335 !-------------------------------------------------
336
337 call comm2d%Init( 1, 0, 0, this%mesh%mesh2D )
338 call comm3d%Init( 2, 1, 0, this%mesh )
339
340 call this%topography%SetVCoordinate( this%mesh, &
341 this%vcoord_type_id, this%mesh%zmax_gl, comm3d, comm2d )
342
343 call comm2d%Final()
344 call comm3d%Final()
345
346 return
347 end subroutine oceanmeshrm_setup_vcoordinate
348
349end module mod_ocean_mesh_rm
module Ocean / Mesh
subroutine oceanmeshrm_init(this)
Initialize an object to manage computational mesh.
module Ocean / Mesh
integer, parameter, public ocn_mesh_max_commnuicator_num
module FElib / Element / Base
module FElib / Element / hexahedron
module FElib / Mesh / Local 3D
module FElib / Mesh / Base 3D
module FElib / Mesh / Cubic 3D domain
module FElib / Data / base
module FElib / Data / Communication 3D cubic domain
module FElib / Data / Communication 2D rectangle 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 regional 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 3D domain)
Derived type to manage a cubic 3D computational domain.
Derived type representing a field with 3D mesh.
Base derived type to manage data communication with 3D cubic domain.
Base derived type to manage data communication with 2D rectangle domain.
Derived type to manage a sparse matrix.