FE-Project
Loading...
Searching...
No Matches
scale_mesh_hierarchy_3d.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Mesh / 3D domain
3!!
4!! @par Description
5!! Manage mesh hierarchy of 3D domain for element-based methods
6!!
7!! @author Yuta Kawai, Team SCALE
8!<
9!-------------------------------------------------------------------------------
10#include "scaleFElib.h"
12
13 !-----------------------------------------------------------------------------
14 !
15 !++ used modules
16 !
17 !
18 use scale_precision
19 use scale_io
20 use scale_prc, only: prc_abort
21
24
28
29 use scale_mesh_hierarchy_base, only: &
39
40 !-----------------------------------------------------------------------------
41 implicit none
42 private
43
44 !-----------------------------------------------------------------------------
45 !
46 !++ Public type & procedure
47 !
48
49 !> Derived type to save a pointer to MeshBase3D
50 type :: meshptr3d
51 class(MeshBase3D), pointer :: ptr => null()
52 end type meshptr3d
53
54 !> Derived type to manage 3D local mesh data for multigrid
56 contains
57 procedure :: init => meshhierarchylocalmgdata3d_init
58 procedure :: final => meshhierarchylocalmgdata3d_final
60
61 !> Derived type to represent mesh hierarchy level in 3D domain
63 type(meshptr3d), pointer :: fine_mesh => null()
64 type(meshptr3d), pointer :: coarse_mesh => null()
65 type(meshhierarchylocalmgdata3d), allocatable :: mg_local(:)
66
67 real(rp), allocatable :: pmat1d_f2c(:,:)
68 real(rp), allocatable :: pmat1d_c2f(:,:)
69 contains
70 procedure :: init => meshhierarchylevel3d_init
71 procedure :: final => meshhierarchylevel3d_final
73
74 !> Derived type for mesh hierarchy in 3D domain
75 type, extends(meshhierarchybase), public :: meshhierarchy3d
76 type(meshhierarchylevel3d), allocatable :: p_level(:)
77 type(meshhierarchylevel3d), allocatable :: h_level(:)
78
79 type(meshptr3d), allocatable :: p_mesh_list(:)
80 type(meshptr3d), allocatable :: h_mesh_list(:)
81
82 type(hexahedralelement), allocatable :: elem3d_list(:)
83 contains
84 procedure :: init => meshhierarchy3d_init
85 procedure :: final => meshhierarchy3d_final
86 end type meshhierarchy3d
87
88 !-----------------------------------------------------------------------------
89 !
90 !++ Public parameters & variables
91 !
92
93 !-----------------------------------------------------------------------------
94 !
95 !++ Private procedure
96 !
97
98 !-----------------------------------------------------------------------------
99 !
100 !++ Private parameters & variables
101 !
102contains
103 !> Initialize an object for mesh hierarchy in 3D domain
104!OCL SERIAL
105 subroutine meshhierarchy3d_init( this, &
106 parent_mesh, &
107 porder_list, p_LEVEL_NUM, &
108 NeGX_list, NeGY_list, NeGZ_list, h_LEVEL_NUM )
109 implicit none
110 class(meshhierarchy3d), intent(inout), target :: this
111 class(meshbase3d), intent(in), target :: parent_mesh !< Pointer to the finest mesh
112 integer, intent(in) :: p_LEVEL_NUM !< Number of p-mesh levels
113 integer, intent(in) :: porder_list(p_LEVEL_NUM) !< Polynomial order list for p-mesh levels
114 integer, intent(in) :: h_LEVEL_NUM !< Number of h-mesh levels
115 integer, intent(in) :: NeGX_list(h_LEVEL_NUM) !< Number of elements in x-direction for h-mesh levels
116 integer, intent(in) :: NeGY_list(h_LEVEL_NUM) !< Number of elements in y-direction for h-mesh levels
117 integer, intent(in) :: NeGZ_list(h_LEVEL_NUM) !< Number of elements in z-direction for h-mesh levels
118
119 integer :: poly_lev
120 integer :: h_lev
121
122 integer :: ldom_id
123
124 type(meshhierarchylevel3d), pointer :: level_ptr
125 class(meshbase3d), pointer :: mesh3D_ptr
126
127 class(meshptr3d), pointer :: fine_mesh_ptr
128 class(meshptr3d), pointer :: coarse_mesh_ptr
129
130 integer :: NeGZ
131 !-------------------------------------------------------------
132
133 call meshhierarchybase_init( this, p_level_num, h_level_num )
134
135 !--
136 if ( parent_mesh%refElem3D%PolyOrder_h /= parent_mesh%refElem3D%PolyOrder_v ) then
137 log_info('MeshHierarchy3D_Init',*) 'Currently, PolyOrder_h should equal PolyOrder_v. Check!'
138 call prc_abort
139 end if
140 if ( porder_list(p_level_num) /= 1 .and. h_level_num > 0 ) then
141 log_info('MeshHierarchy3D_Init',*) 'Currently, only p=1 is supported for the coarsest p-mesh level. Check!'
142 call prc_abort
143 end if
144 if ( h_level_num > 0 ) then
145 negz = negz_list(1)
146 do h_lev=2, h_level_num
147 if ( negz_list(h_lev) /= negz ) then
148 log_info('MeshHierarchy3D_Init',*) 'Currently, the number of elements should be same in the vertical direction. Check!'
149 call prc_abort
150 end if
151 end do
152 end if
153
154 !- Setup p-mesh hierarchy
155
156 allocate( this%elem3D_list(p_level_num) )
157 do poly_lev=1, p_level_num
158 call this%elem3D_list(poly_lev)%Init( porder_list(poly_lev), porder_list(poly_lev), .false. )
159 end do
160
161 allocate( this%p_mesh_list(this%NUM_pMG_LEVEL) )
162
163 this%p_mesh_list(mesh_hierarchy_pmg_finest_level)%ptr => parent_mesh
164 do poly_lev=mesh_hierarchy_pmg_finest_level + 1, this%NUM_pMG_LEVEL
165 select type(parent_mesh)
166 type is (meshcubedom3d)
167 call construct_cubedom3d_mesh( this, this%p_mesh_list(poly_lev)%ptr, &
168 parent_mesh%NeGX, parent_mesh%NeGY, parent_mesh%NeGZ, parent_mesh%FZ, &
169 parent_mesh, this%elem3D_list(poly_lev) )
170 end select
171 end do
172
173 allocate( this%p_level(this%NUM_pMG_LEVEL) )
174
175 do poly_lev=mesh_hierarchy_pmg_finest_level, this%NUM_pMG_LEVEL
176 call this%p_level(poly_lev)%Init( poly_lev, this%p_mesh_list(poly_lev)%ptr, &
177 this%p_mesh_list, this%NUM_pMG_LEVEL, mesh_hierarchy_type_pmg )
178 end do
179
180 !- Setup h-mesh hierarchy
181
182 if ( this%NUM_hMG_LEVEL > 0 ) then
183 allocate( this%h_mesh_list(this%NUM_hMG_LEVEL) )
184
185 this%h_mesh_list(mesh_hierarchy_hmg_finest_level)%ptr => parent_mesh
186 do h_lev=mesh_hierarchy_hmg_finest_level + 1, this%NUM_hMG_LEVEL
187 select type(parent_mesh)
188 type is (meshcubedom3d)
189 call construct_cubedom3d_mesh( this, this%h_mesh_list(h_lev)%ptr, &
190 negx_list(h_lev), negy_list(h_lev), negz_list(h_lev), parent_mesh%FZ, &
191 parent_mesh, this%elem3D_list(p_level_num) )
192 end select
193 end do
194
195 allocate( this%h_level(this%NUM_hMG_LEVEL) )
196
197 do h_lev=mesh_hierarchy_hmg_finest_level, this%NUM_hMG_LEVEL
198 call this%h_level(h_lev)%Init( h_lev, this%h_mesh_list(h_lev)%ptr, &
199 this%h_mesh_list, this%NUM_hMG_LEVEL, mesh_hierarchy_type_hmg )
200 end do
201 end if
202
203 return
204 end subroutine meshhierarchy3d_init
205
206 !> Finalize an object for mesh hierarchy in 3D domain
207!OCL SERIAL
208 subroutine meshhierarchy3d_final(this)
209 implicit none
210 class(meshhierarchy3d), intent(inout) :: this
211
212 class(meshbase3d), pointer :: mesh3D_ptr
213 integer :: poly_lev
214 integer :: h_lev
215 integer :: ldom_id
216 !-------------------------------------------------------------
217
218 ! p-mesh hierarchy finalization
219 do poly_lev=mesh_hierarchy_pmg_finest_level, this%NUM_pMG_LEVEL
220 call this%p_level(poly_lev)%Final()
221 end do
222 deallocate( this%p_level )
223
224 do poly_lev=mesh_hierarchy_pmg_finest_level + 1, this%NUM_pMG_LEVEL
225 mesh3d_ptr => this%p_mesh_list(poly_lev)%ptr
226 select type(mesh3d_ptr)
227 type is (meshcubedom3d)
228 call mesh3d_ptr%Final()
229 end select
230 end do
231 deallocate( this%p_mesh_list )
232
233 ! h-mesh hierarchy finalization
234 if ( this%NUM_hMG_LEVEL > 0 ) then
235 do h_lev=mesh_hierarchy_hmg_finest_level, this%NUM_hMG_LEVEL
236 call this%h_level(h_lev)%Final()
237 end do
238 deallocate( this%h_level )
239
240 do h_lev=mesh_hierarchy_hmg_finest_level + 1, this%NUM_hMG_LEVEL
241 mesh3d_ptr => this%h_mesh_list(h_lev)%ptr
242 select type(mesh3d_ptr)
243 type is (meshcubedom3d)
244 call mesh3d_ptr%Final()
245 end select
246 end do
247 deallocate( this%h_mesh_list )
248 end if
249
250 !-
251 call meshhierarchybase_final( this )
252 return
253 end subroutine meshhierarchy3d_final
254
255!-- private --------------------------------------------------------------
256
257 !> Initialize an object for mesh hierarchy level in 3D domain
258!OCL SERIAL
259 subroutine meshhierarchylevel3d_init( this, &
260 level_id, mesh3D, mesh_list, LEVEL_NUM, &
261 hierarchy_type )
262 use scale_mesh_hierarchy_base, only: &
264 implicit none
265 class(meshhierarchylevel3d), intent(inout) :: this
266 integer, intent(in) :: level_id
267 class(meshbase3d), intent(in) :: mesh3D
268 integer, intent(in) :: LEVEL_NUM
269 class(meshptr3d), intent(in), target :: mesh_list(LEVEL_NUM)
270 integer, intent(in) :: hierarchy_type
271
272 integer :: ldom_id
273 !-------------------------------------------------------------
274
275 this%hierarchy_type = hierarchy_type
276 this%level_id = level_id
277
278 !- set mesh pointers with finer/coarser meshes
279
280 if ( level_id > 1 ) then
281 this%fine_mesh => mesh_list(level_id-1)
282 else
283 this%fine_mesh => null()
284 end if
285
286 if ( level_id < level_num ) then
287 this%coarse_mesh => mesh_list(level_id+1)
288 else
289 this%coarse_mesh => null()
290 end if
291
292 !- p-hierarchy
293 if ( hierarchy_type == mesh_hierarchy_type_pmg &
294 .and. level_id < level_num ) then
295
296 allocate( this%pMat1D_c2f(mesh3d%refElem3D%Nnode_h1D,this%coarse_mesh%ptr%refElem3D%Nnode_h1D) )
297 call meshhierarchy_construct_pmg_mat1d( this%pMat1D_c2f, &
298 this%coarse_mesh%ptr%refElem3D%Nnode_h1D, mesh3d%refElem3D%Nnode_h1D )
299
300 allocate( this%pMat1D_f2c(this%coarse_mesh%ptr%refElem3D%Nnode_h1D,mesh3d%refElem3D%Nnode_h1D) )
301 call meshhierarchy_construct_pmg_mat1d( this%pMat1D_f2c, &
302 mesh3d%refElem3D%Nnode_h1D, this%coarse_mesh%ptr%refElem3D%Nnode_h1D )
303 end if
304
305 !- h-hierarchy
306 if ( hierarchy_type == mesh_hierarchy_type_hmg &
307 .and. level_id < level_num ) then
308
309 allocate( this%mg_local( mesh3d%LOCAL_MESH_NUM ) )
310
311 do ldom_id=1, mesh3d%LOCAL_MESH_NUM
312 call this%mg_local(ldom_id)%Init( mesh_list(level_id)%ptr%lcmesh_list(ldom_id), &
313 this%coarse_mesh%ptr%lcmesh_list, mesh_list(level_id)%ptr%refElem3D )
314 end do
315 end if
316
317 return
318 end subroutine meshhierarchylevel3d_init
319
320 !> Finalize an object for mesh hierarchy level in 3D domain
321!OCL SERIAL
322 subroutine meshhierarchylevel3d_final( this )
323 implicit none
324 class(meshhierarchylevel3d), intent(inout) :: this
325
326 integer :: ldom_id
327 !-------------------------------------------------------------
328
329 if ( allocated(this%mg_local) ) then
330 do ldom_id=1, size(this%mg_local)
331 call this%mg_local(ldom_id)%Final()
332 end do
333 deallocate( this%mg_local )
334 end if
335 return
336 end subroutine meshhierarchylevel3d_final
337
338!> Initialize an object to manage 3D local mesh data for multigrid
339!OCL SERIAL
340 subroutine meshhierarchylocalmgdata3d_init( this, &
341 lcmesh3D, coarse_lcmesh_list, elem3D )
343 implicit none
344 class(meshhierarchylocalmgdata3d), intent(inout) :: this
345 class(localmesh3d), intent(in) :: lcmesh3D
346 class(localmesh3d), intent(in), target :: coarse_lcmesh_list(:)
347 class(elementbase3d), intent(in) :: elem3D
348
349 integer :: i, j, k
350 integer :: ke
351
352 integer :: i_c, j_c, k_c
353 integer :: ke_c
354
355 integer :: ke2i(lcmesh3D%Ne)
356 integer :: ke2j(lcmesh3D%Ne)
357 integer :: ke2k(lcmesh3D%Ne)
358
359 integer :: lcdomID_c
360 integer :: lcTileID_c
361 class(localmesh3d), pointer :: lcmesh_c
362
363 real(RP) :: vx_c(elem3D%Nv)
364 real(RP) :: vy_c(elem3D%Nv)
365 real(RP) :: vz_c(elem3D%Nv)
366 integer :: i_EtoV(elem3D%Nv)
367
368 integer :: p
369 real(RP) :: r_c, s_c, t_c
370
371 integer :: l
372 !-------------------------------------------------------------
373
375 lcmesh3d )
376
377 ! Current implementation assumes identical tileID & lcdomID in both coarsened meshes
378 this%CoarseLocalMesh_tileIDlist(1) = lcmesh3d%tileID
379 this%CoarseLocalMesh_lcdomIDlist(1) = 1
380
381 ! Preparation
382 do k=1, lcmesh3d%NeZ
383 do j=1, lcmesh3d%NeY
384 do i=1, lcmesh3d%NeX
385 ke = i + (j-1)*lcmesh3d%NeX + (k-1)*lcmesh3d%NeX*lcmesh3d%NeY
386 ke2i(ke) = i; ke2j(ke) = j; ke2k(ke) = k
387 end do
388 end do
389 end do
390
391 ! Set the relation between coarse and fine grid,
392 ! and construct interpolation operator
393
394 allocate( this%If2c_emap(4,lcmesh3d%Ne/4) )
395
396 do ke=lcmesh3d%NeS, lcmesh3d%NeE
397 lctileid_c = this%CoarseLocalMesh_tileIDlist(1)
398 lcdomid_c = this%CoarseLocalMesh_lcdomIDlist(1)
399
400 lcmesh_c => coarse_lcmesh_list(lcdomid_c)
401
402 i_c = (ke2i(ke)+1)/2; j_c = (ke2j(ke)+1)/2; k_c = ke2k(ke)
403 ke_c = i_c + (j_c-1)*lcmesh_c%NeX + (k_c-1)*lcmesh_c%NeX*lcmesh_c%NeY
404 this%Ic2f_emap(ke) = ke_c
405
406 i = ke2i(ke) - 2*(i_c-1)
407 j = ke2j(ke) - 2*(j_c-1)
408! k = ke2k(ke) - 2*(k_c-1)
409 this%If2c_emap(i+(j-1)*2,ke_c) = ke
410
411 i_etov(:) = lcmesh_c%EToV(ke_c,:)
412 vx_c(:) = lcmesh_c%pos_ev(i_etov(:),1)
413 vy_c(:) = lcmesh_c%pos_ev(i_etov(:),2)
414 vz_c(:) = lcmesh_c%pos_ev(i_etov(:),3)
415 do p=1, elem3d%Np
416 r_c = -1.0_rp + 2.0_rp * ( lcmesh3d%pos_en(p,ke,1) - vx_c(1) ) / ( vx_c(2) - vx_c(1) )
417 s_c = -1.0_rp + 2.0_rp * ( lcmesh3d%pos_en(p,ke,2) - vy_c(1) ) / ( vy_c(4) - vy_c(1) )
418 t_c = -1.0_rp + 2.0_rp * ( lcmesh3d%pos_en(p,ke,3) - vz_c(1) ) / ( vz_c(5) - vz_c(1) )
419
420 this%Ic2f(p,:,ke) = 0.125_rp * &
421 (/ ( 1.0_rp - r_c ) * ( 1.0_rp - s_c ) * ( 1.0_rp - t_c ), ( 1.0_rp + r_c ) * ( 1.0_rp - s_c ) * ( 1.0_rp - t_c ), &
422 ( 1.0_rp - r_c ) * ( 1.0_rp + s_c ) * ( 1.0_rp - t_c ), ( 1.0_rp + r_c ) * ( 1.0_rp + s_c ) * ( 1.0_rp - t_c ), &
423 ( 1.0_rp - r_c ) * ( 1.0_rp - s_c ) * ( 1.0_rp + t_c ), ( 1.0_rp + r_c ) * ( 1.0_rp - s_c ) * ( 1.0_rp + t_c ), &
424 ( 1.0_rp - r_c ) * ( 1.0_rp + s_c ) * ( 1.0_rp + t_c ), ( 1.0_rp + r_c ) * ( 1.0_rp + s_c ) * ( 1.0_rp + t_c ) /)
425 end do
426 end do
427 return
428 end subroutine meshhierarchylocalmgdata3d_init
429
430!> Finalize an object to manage 3D local mesh data for multigrid
431!OCL SERIAL
432 subroutine meshhierarchylocalmgdata3d_final( this )
434 implicit none
435 class(meshhierarchylocalmgdata3d), intent(inout) :: this
436 !-------------------------------------------------------------
438 return
439 end subroutine meshhierarchylocalmgdata3d_final
440
441!-
442!OCL SERIAL
443 subroutine construct_cubedom3d_mesh( this, child_mesh_base_ptr, &
444 NeGX, NeGY, NeGZ, FZ, &
445 parent_mesh, elem3D )
446 implicit none
447 class(meshhierarchy3d), intent(inout) :: this
448 class(meshbase3d), intent(out), pointer :: child_mesh_base_ptr
449 integer, intent(in) :: NeGX
450 integer, intent(in) :: NeGY
451 integer, intent(in) :: NeGZ
452 real(RP), intent(in) :: FZ(NeGZ+1)
453 type(meshcubedom3d), intent(in) :: parent_mesh
454 type(hexahedralelement), intent(in) :: elem3D
455
456 type(meshcubedom3d), pointer :: child_mesh_ptr
457 !-------------------------------------------------------------
458
459 allocate( child_mesh_ptr )
460 call child_mesh_ptr%Init( negx, negy, negz, &
461 parent_mesh%xmin_gl, parent_mesh%xmax_gl, parent_mesh%ymin_gl, parent_mesh%ymax_gl, &
462 parent_mesh%zmin_gl, parent_mesh%zmax_gl, &
463 parent_mesh%isPeriodicX, parent_mesh%isPeriodicY, parent_mesh%isPeriodicZ, &
464 elem3d, 1, parent_mesh%NprcX, parent_mesh%NprcY, &
465 fz=fz )
466
467 call child_mesh_ptr%Generate()
468
469 child_mesh_base_ptr => child_mesh_ptr
470 return
471 end subroutine construct_cubedom3d_mesh
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 / Mesh / 3D domain
subroutine meshhierarchy3d_init(this, parent_mesh, porder_list, p_level_num, negx_list, negy_list, negz_list, h_level_num)
Initialize an object for mesh hierarchy in 3D domain.
module FElib / Mesh / Hierarchy base
subroutine, public meshhierarchy_construct_pmg_mat1d(mat1d, np_i, np_o)
Construct a 1D p-multigrid matrix used for transfer between different p-levels.
integer, parameter, public mesh_hierarchy_type_pmg
Type ID of mesh hierarchy: p-MG.
integer, parameter, public mesh_hierarchy_hmg_finest_level
Finest level index in h-MG.
subroutine, public meshhierarchybase_init(this, p_level_num, h_level_num)
Initialize a base object for mesh hierarchy.
integer, parameter, public mesh_hierarchy_type_hmg
Type ID of mesh hierarchy: h-MG.
subroutine, public meshhierarchylocalmgdatabase_final(this)
Finalize a base object to manage local multigrid data for mesh hierarchy.
subroutine, public meshhierarchybase_final(this)
Finalize a base object for mesh hierarchy.
integer, parameter, public mesh_hierarchy_pmg_finest_level
Finest level index in p-MG.
subroutine, public meshhierarchylocalmgdatabase_init(this, lcmesh)
Initialize a base object to manage local multigrid data for mesh hierarchy.
Derived type representing a 3D reference element.
Derived type representing a hexahedral element.
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 for mesh hierarchy in 3D domain.
Derived type to represent mesh hierarchy level in 3D domain.
Derived type to manage 3D local mesh data for multigrid.
Base type to manage local mesh data for multigrid.