FE-Project
Loading...
Searching...
No Matches
scale_mesh_hierarchy_2d.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Mesh / 2D domain
3!!
4!! @par Description
5!! Manage mesh hierarchy of 2D 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 MeshBase2D
50 type :: meshptr2d
51 class(MeshBase2D), pointer :: ptr => null()
52 end type meshptr2d
53
54 !> Derived type to manage 2D local mesh data for multigrid
56 contains
57 procedure :: init => meshhierarchylocalmgdata2d_init
58 procedure :: final => meshhierarchylocalmgdata2d_final
60
61 !> Derived type to represent mesh hierarchy level in 2D domain
63 type(meshptr2d), pointer :: fine_mesh => null()
64 type(meshptr2d), pointer :: coarse_mesh => null()
65 type(meshhierarchylocalmgdata2d), allocatable :: mg_local(:)
66
67 real(rp), allocatable :: pmat1d_f2c(:,:)
68 real(rp), allocatable :: pmat1d_c2f(:,:)
69 contains
70 procedure :: init => meshhierarchylevel2d_init
71 procedure :: final => meshhierarchylevel2d_final
73
74 !> Derived type for mesh hierarchy in 2D domain
75 type, extends(meshhierarchybase), public :: meshhierarchy2d
76 type(meshhierarchylevel2d), allocatable :: p_level(:)
77 type(meshhierarchylevel2d), allocatable :: h_level(:)
78
79 type(meshptr2d), allocatable :: p_mesh_list(:)
80 type(meshptr2d), allocatable :: h_mesh_list(:)
81
82 type(quadrilateralelement), allocatable :: elem2d_list(:)
83 contains
84 procedure :: init => meshhierarchy2d_init
85 procedure :: final => meshhierarchy2d_final
86 end type meshhierarchy2d
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 2D domain
104!OCL SERIAL
105 subroutine meshhierarchy2d_init( this, &
106 parent_mesh, &
107 porder_list, p_LEVEL_NUM, &
108 NeGX_list, NeGY_list, h_LEVEL_NUM )
109 implicit none
110 class(meshhierarchy2d), intent(inout), target :: this
111 class(meshbase2d), 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
118 integer :: poly_lev
119 integer :: h_lev
120
121 integer :: ldom_id
122
123 type(meshhierarchylevel2d), pointer :: level_ptr
124 class(meshbase2d), pointer :: mesh2D_ptr
125
126 class(meshptr2d), pointer :: fine_mesh_ptr
127 class(meshptr2d), pointer :: coarse_mesh_ptr
128 !-------------------------------------------------------------
129
130 call meshhierarchybase_init( this, p_level_num, h_level_num )
131
132 !- Setup p-mesh hierarchy
133
134 if ( porder_list(p_level_num) /= 1 .and. h_level_num > 0 ) then
135 log_info('MeshHierarchy2D_Init',*) 'Currently, only p=1 is supported for the coarsest p-mesh level when h_LEVEL_NUM > 0. Check!'
136 call prc_abort
137 end if
138
139 !- Setup p-mesh hierarchy
140
141 allocate( this%elem2D_list(p_level_num) )
142 do poly_lev=1, p_level_num
143 call this%elem2D_list(poly_lev)%Init( porder_list(poly_lev), .false. )
144 end do
145
146 allocate( this%p_mesh_list(this%NUM_pMG_LEVEL) )
147
148 this%p_mesh_list(mesh_hierarchy_pmg_finest_level)%ptr => parent_mesh
149 do poly_lev=mesh_hierarchy_pmg_finest_level + 1, this%NUM_pMG_LEVEL
150 select type(parent_mesh)
151 type is (meshrectdom2d)
152 call construct_rectdom2d_mesh( this, this%p_mesh_list(poly_lev)%ptr, &
153 parent_mesh%NeGX, parent_mesh%NeGY, &
154 parent_mesh, this%elem2D_list(poly_lev) )
155 end select
156 end do
157
158 allocate( this%p_level(this%NUM_pMG_LEVEL) )
159
160 do poly_lev=mesh_hierarchy_pmg_finest_level, this%NUM_pMG_LEVEL
161 call this%p_level(poly_lev)%Init( poly_lev, this%p_mesh_list(poly_lev)%ptr, &
162 this%p_mesh_list, this%NUM_pMG_LEVEL, mesh_hierarchy_type_pmg )
163 end do
164
165 !- Setup h-mesh hierarchy
166
167 allocate( this%h_mesh_list(this%NUM_hMG_LEVEL) )
168
169 this%h_mesh_list(mesh_hierarchy_hmg_finest_level)%ptr => this%p_mesh_list(this%NUM_pMG_LEVEL)%ptr
170 do h_lev=mesh_hierarchy_hmg_finest_level + 1, this%NUM_hMG_LEVEL
171 select type(parent_mesh)
172 type is (meshrectdom2d)
173 call construct_rectdom2d_mesh( this, this%h_mesh_list(h_lev)%ptr, &
174 negx_list(h_lev), negy_list(h_lev), &
175 parent_mesh, this%elem2D_list(p_level_num) )
176 end select
177 end do
178
179 allocate( this%h_level(this%NUM_hMG_LEVEL) )
180
181 do h_lev=mesh_hierarchy_hmg_finest_level, this%NUM_hMG_LEVEL
182 call this%h_level(h_lev)%Init( h_lev, this%h_mesh_list(h_lev)%ptr, &
183 this%h_mesh_list, this%NUM_hMG_LEVEL, mesh_hierarchy_type_hmg )
184 end do
185
186 return
187 end subroutine meshhierarchy2d_init
188
189 !> Finalize an object for mesh hierarchy in 2D domain
190!OCL SERIAL
191 subroutine meshhierarchy2d_final(this)
192 implicit none
193 class(meshhierarchy2d), intent(inout) :: this
194
195 class(meshbase2d), pointer :: mesh2D_ptr
196 integer :: poly_lev
197 integer :: h_lev
198 integer :: ldom_id
199 !-------------------------------------------------------------
200
201 ! p-mesh hierarchy finalization
202 do poly_lev=mesh_hierarchy_pmg_finest_level, this%NUM_pMG_LEVEL
203 call this%p_level(poly_lev)%Final()
204 end do
205 deallocate( this%p_level )
206
207 do poly_lev=mesh_hierarchy_pmg_finest_level + 1, this%NUM_pMG_LEVEL
208 mesh2d_ptr => this%p_mesh_list(poly_lev)%ptr
209 select type(mesh2d_ptr)
210 type is (meshrectdom2d)
211 call mesh2d_ptr%Final()
212 end select
213 end do
214 deallocate( this%p_mesh_list )
215
216 ! h-mesh hierarchy finalization
217 do h_lev=mesh_hierarchy_hmg_finest_level, this%NUM_hMG_LEVEL
218 call this%h_level(h_lev)%Final()
219 end do
220 deallocate( this%h_level )
221
222 do h_lev=mesh_hierarchy_hmg_finest_level + 1, this%NUM_hMG_LEVEL
223 mesh2d_ptr => this%h_mesh_list(h_lev)%ptr
224 select type(mesh2d_ptr)
225 type is (meshrectdom2d)
226 call mesh2d_ptr%Final()
227 end select
228 end do
229 deallocate( this%h_mesh_list )
230
231 !-
232 call meshhierarchybase_final( this )
233 return
234 end subroutine meshhierarchy2d_final
235
236!-- private --------------------------------------------------------------
237
238 !> Initialize an object for mesh hierarchy level in 2D domain
239!OCL SERIAL
240 subroutine meshhierarchylevel2d_init( this, &
241 level_id, mesh2D, mesh_list, LEVEL_NUM, &
242 hierarchy_type )
243 use scale_mesh_hierarchy_base, only: &
245 implicit none
246 class(meshhierarchylevel2d), intent(inout) :: this
247 integer, intent(in) :: level_id
248 class(meshbase2d), intent(in) :: mesh2D
249 integer, intent(in) :: LEVEL_NUM
250 class(meshptr2d), intent(in), target :: mesh_list(LEVEL_NUM)
251 integer, intent(in) :: hierarchy_type
252
253 integer :: ldom_id
254 !-------------------------------------------------------------
255
256 this%hierarchy_type = hierarchy_type
257 this%level_id = level_id
258
259 !- set mesh pointers with finer/coarser meshes
260
261 if ( level_id > 1 ) then
262 this%fine_mesh => mesh_list(level_id-1)
263 else
264 this%fine_mesh => null()
265 end if
266
267 if ( level_id < level_num ) then
268 this%coarse_mesh => mesh_list(level_id+1)
269 else
270 this%coarse_mesh => null()
271 end if
272
273 !- p-hierarchy
274 if ( hierarchy_type == mesh_hierarchy_type_pmg &
275 .and. level_id < level_num ) then
276
277 allocate( this%pMat1D_c2f(mesh2d%refElem2D%Nfp,this%coarse_mesh%ptr%refElem2D%Nfp) )
278 call meshhierarchy_construct_pmg_mat1d( this%pMat1D_c2f, &
279 this%coarse_mesh%ptr%refElem2D%Nfp, mesh2d%refElem2D%Nfp )
280
281 allocate( this%pMat1D_f2c(this%coarse_mesh%ptr%refElem2D%Nfp,mesh2d%refElem2D%Nfp) )
282 call meshhierarchy_construct_pmg_mat1d( this%pMat1D_f2c, &
283 mesh2d%refElem2D%Nfp, this%coarse_mesh%ptr%refElem2D%Nfp )
284 end if
285
286 !- h-hierarchy
287 if ( hierarchy_type == mesh_hierarchy_type_hmg &
288 .and. level_id < level_num ) then
289
290 allocate( this%mg_local( mesh2d%LOCAL_MESH_NUM ) )
291
292 do ldom_id=1, mesh2d%LOCAL_MESH_NUM
293 call this%mg_local(ldom_id)%Init( mesh_list(level_id)%ptr%lcmesh_list(ldom_id), &
294 this%coarse_mesh%ptr%lcmesh_list, mesh_list(level_id)%ptr%refElem2D )
295 end do
296 end if
297
298 return
299 end subroutine meshhierarchylevel2d_init
300
301 !> Finalize an object for mesh hierarchy level in 2D domain
302!OCL SERIAL
303 subroutine meshhierarchylevel2d_final( this )
304 implicit none
305 class(meshhierarchylevel2d), intent(inout) :: this
306
307 integer :: ldom_id
308 !-------------------------------------------------------------
309
310 !-
311 if ( allocated(this%pMat1D_c2f) ) deallocate(this%pMat1D_c2f)
312 if ( allocated(this%pMat1D_f2c) ) deallocate(this%pMat1D_f2c)
313
314 !-
315 if ( allocated(this%mg_local) ) then
316 do ldom_id=1, size(this%mg_local)
317 call this%mg_local(ldom_id)%Final()
318 end do
319 deallocate( this%mg_local )
320 end if
321
322 return
323 end subroutine meshhierarchylevel2d_final
324
325 !> Initialize an object for 2D local mesh data for multigrid
326!OCL SERIAL
327 subroutine meshhierarchylocalmgdata2d_init( this, &
328 lcmesh2D, coarse_lcmesh_list, elem2D )
330 implicit none
331 class(meshhierarchylocalmgdata2d), intent(inout) :: this
332 class(localmesh2d), intent(in) :: lcmesh2D
333 class(localmesh2d), intent(in), target :: coarse_lcmesh_list(:)
334 class(elementbase2d), intent(in) :: elem2D
335
336 integer :: i, j
337 integer :: ke
338
339 integer :: i_c, j_c
340 integer :: ke_c
341
342 integer :: ke2i(lcmesh2D%Ne)
343 integer :: ke2j(lcmesh2D%Ne)
344
345 integer :: lcdomID_c
346 integer :: lcTileID_c
347 class(localmesh2d), pointer :: lcmesh_c
348
349 real(RP) :: vx_c(elem2D%Nv)
350 real(RP) :: vy_c(elem2D%Nv)
351 integer :: i_EtoV(elem2D%Nv)
352
353 integer :: p
354 real(RP) :: r_c, s_c
355 !-------------------------------------------------------------
356
358 lcmesh2d )
359
360
361 ! Current implementation assumes identical tileID & lcdomID in both coarsened meshes
362 this%CoarseLocalMesh_tileIDlist(1) = lcmesh2d%tileID
363 this%CoarseLocalMesh_lcdomIDlist(1) = 1
364
365 ! Preparation
366 do j=1, lcmesh2d%NeY
367 do i=1, lcmesh2d%NeX
368 ke = i + (j-1)*lcmesh2d%NeX
369 ke2i(ke) = i; ke2j(ke) = j
370 end do
371 end do
372
373 ! Set the relation between coarse and fine grid,
374 ! and construct interpolation operator
375
376! write(*,*) " Constructing local MG data for h-mesh..."
377
378 allocate( this%If2c_emap(4,lcmesh2d%Ne/4) )
379
380 do ke=lcmesh2d%NeS, lcmesh2d%NeE
381 lctileid_c = this%CoarseLocalMesh_tileIDlist(1)
382 lcdomid_c = this%CoarseLocalMesh_lcdomIDlist(1)
383
384 lcmesh_c => coarse_lcmesh_list(lcdomid_c)
385
386 i_c = (ke2i(ke)+1)/2; j_c = (ke2j(ke)+1)/2
387 ke_c = i_c + (j_c-1)*lcmesh2d%NeX/2
388 this%Ic2f_emap(ke) = ke_c
389
390 i = ke2i(ke) - 2*(i_c-1)
391 j = ke2j(ke) - 2*(j_c-1)
392 this%If2c_emap(i+(j-1)*2,ke_c) = ke
393
394 i_etov(:) = lcmesh_c%EToV(ke_c,:)
395 vx_c(:) = lcmesh_c%pos_ev(i_etov(:),1)
396 vy_c(:) = lcmesh_c%pos_ev(i_etov(:),2)
397
398 do p=1, elem2d%Np
399 r_c = -1.0_rp + 2.0_rp * ( lcmesh2d%pos_en(p,ke,1) - vx_c(1) ) / ( vx_c(2) - vx_c(1) )
400 s_c = -1.0_rp + 2.0_rp * ( lcmesh2d%pos_en(p,ke,2) - vy_c(1) ) / ( vy_c(3) - vy_c(1) )
401
402 this%Ic2f(p,1:4,ke) = 0.25_rp * &
403 (/ ( 1.0_rp - r_c ) * ( 1.0_rp - s_c ), ( 1.0_rp + r_c ) * ( 1.0_rp - s_c ), &
404 ( 1.0_rp - r_c ) * ( 1.0_rp + s_c ), ( 1.0_rp + r_c ) * ( 1.0_rp + s_c ) /)
405 end do
406 end do
407 return
408 end subroutine meshhierarchylocalmgdata2d_init
409
410 !> Finalize an object for 2D local mesh data for multigrid
411!OCL SERIAL
412 subroutine meshhierarchylocalmgdata2d_final( this )
414 implicit none
415 class(meshhierarchylocalmgdata2d), intent(inout) :: this
416 !-------------------------------------------------------------
418 return
419 end subroutine meshhierarchylocalmgdata2d_final
420
421!-
422!OCL SERIAL
423 subroutine construct_rectdom2d_mesh( this, child_mesh_base_ptr, &
424 NeGX, NeGY, &
425 parent_mesh, elem2D )
426 implicit none
427 class(meshhierarchy2d), intent(inout) :: this
428 class(meshbase2d), intent(out), pointer :: child_mesh_base_ptr
429 integer, intent(in) :: NeGX
430 integer, intent(in) :: NeGY
431 type(meshrectdom2d), intent(in) :: parent_mesh
432 type(quadrilateralelement), intent(in) :: elem2D
433
434 type(meshrectdom2d), pointer :: child_mesh_ptr
435 !-------------------------------------------------------------
436
437 allocate( child_mesh_ptr )
438 call child_mesh_ptr%Init( negx, negy, &
439 parent_mesh%xmin_gl, parent_mesh%xmax_gl, parent_mesh%ymin_gl, parent_mesh%ymax_gl, &
440 parent_mesh%isPeriodicX, parent_mesh%isPeriodicY, &
441 elem2d, 1, parent_mesh%NprcX, parent_mesh%NprcY )
442
443 call child_mesh_ptr%Generate()
444
445 child_mesh_base_ptr => child_mesh_ptr
446 return
447 end subroutine construct_rectdom2d_mesh
module FElib / Element / Base
module FElib / Element / Quadrilateral
module FElib / Mesh / Local 2D
module FElib / Mesh / Base 2D
module FElib / Mesh / 2D domain
subroutine meshhierarchy2d_init(this, parent_mesh, porder_list, p_level_num, negx_list, negy_list, h_level_num)
Initialize an object for mesh hierarchy in 2D 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.
module FElib / Mesh / Rectangle 2D domain
Derived type representing a 2D reference element.
Derived type representing a quadrilateral element.
Derived type representing a local mesh for 2D domain.
Derived type to manage a computational mesh (base type for 2D domain)
Derived type for mesh hierarchy in 2D domain.
Derived type to represent mesh hierarchy level in 2D domain.
Derived type to manage 2D local mesh data for multigrid.
Base type to manage local mesh data for multigrid.
Derived type to manage a rectangular 2D computational domain.