FE-Project
Loading...
Searching...
No Matches
scale_mesh_cubedspheredom3d.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Mesh / Cubed-sphere 3D domain
3!!
4!! @par Description
5!! Manage mesh data of cubed-sphere 3D domain for element-based methods
6!!
7!! @author Yuta Kawai, Team SCALE
8!<
9#include "scaleFElib.h"
11
12 !-----------------------------------------------------------------------------
13 !
14 !++ used modules
15 !
16 use scale_io
17 use scale_precision
18
19 use scale_mesh_base3d, only: &
27
28 use scale_mesh_base2d, only: &
35
37
38 !-----------------------------------------------------------------------------
39 implicit none
40 private
41
42 !-----------------------------------------------------------------------------
43 !
44 !++ Public type & procedure
45 !
46
47 !> Derived type to manage a cubed-sphere 3D computational domain
48 type, extends(meshbase3d), public :: meshcubedspheredom3d
49 integer :: negx !< Number of elements in X direction in a panel of the cubed-sphere mesh
50 integer :: negy !< Number of elements in Y direction in a panel of the cubed-sphere mesh
51 integer :: negz !< Number of elements in Z direction in a panel of the cubed-sphere mesh
52
53 real(rp), public :: xmin_gl !< Minimum x-coordinate in a panel of the cubed-sphere mesh
54 real(rp), public :: xmax_gl !< Maximum x-coordinate in a panel of the cubed-sphere mesh
55 real(rp), public :: ymin_gl !< Minimum y-coordinate in a panel of the cubed-sphere mesh
56 real(rp), public :: ymax_gl !< Maximum y-coordinate in a panel of the cubed-sphere mesh
57 real(rp), public :: zmin_gl !< Minimum z-coordinate of the global domain
58 real(rp), public :: zmax_gl !< Maximum z-coordinate of the global domain
59
60 real(rp), allocatable :: fz(:)
61
62 integer, allocatable :: rcdomijkp2lcmeshid(:,:,:,:) !< Mapping from (i,j,k,panel) to local mesh ID
63
64 real(rp) :: rplanet !< Radius of the planet (or sphere) for the cubed-sphere mesh
65
66 type(meshcubedspheredom2d) :: mesh2d
67 type(quadrilateralelement) :: refelem2d
68
69 logical :: shallow_approx !< Flag to indicate if the shallow water approximation is used
70 contains
71 procedure :: init => meshcubedspheredom3d_init
72 procedure :: final => meshcubedspheredom3d_final
73 procedure :: generate => meshcubedspheredom3d_generate
74 procedure :: assigndomid => meshcubedspheredom3d_assigndomid
75 procedure :: getmesh2d => meshcubedspheredom3d_getmesh2d
76 procedure :: set_geometric_with_vcoord => meshcubedspheredom3d_set_geometric_with_vcoord
78
79 !-----------------------------------------------------------------------------
80 !
81 !++ Public parameters & variables
82 !
83
84 !-----------------------------------------------------------------------------
85 !
86 !++ Private procedure
87 !
88
89 private :: meshcubedspheredom3d_calc_normal
90 private :: meshcubedspheredom3d_coord_conv
91 private :: meshcubedspheredom3d_set_metric
92 private :: fill_halo_metric
93
94 !-----------------------------------------------------------------------------
95 !
96 !++ Private parameters & variables
97 !
98
99contains
100 !> Initialize an object to manage a cubed-sphere 3D computational domain
101!OCL SERIAL
102 subroutine meshcubedspheredom3d_init( this, &
103 NeGX, NeGY, NeGZ, RPlanet, &
104 dom_zmin, dom_zmax, &
105 refElem, NLocalMeshPerPrc, &
106 nproc, myrank, &
107 FZ, shallow_approx )
108
109 use scale_const, only: &
110 pi => const_pi
111 implicit none
112
113 class(meshcubedspheredom3d), intent(inout) :: this
114 integer, intent(in) :: NeGX
115 integer, intent(in) :: NeGY
116 integer, intent(in) :: NeGZ
117 real(RP), intent(in) :: RPlanet
118 real(RP), intent(in) :: dom_Zmin
119 real(RP), intent(in) :: dom_zmax
120 type(hexahedralelement), intent(in), target :: refElem
121 integer, intent(in) :: NLocalMeshPerPrc
122 integer, intent(in), optional :: nproc
123 integer, intent(in), optional :: myrank
124 real(RP), intent(in), optional :: FZ(NeGZ+1)
125 logical, intent(in), optional :: shallow_approx
126
127 integer :: k
128 real(RP) :: dz
129 !-----------------------------------------------------------------------------
130
131 this%NeGX = negx
132 this%NeGY = negy
133 this%NeGZ = negz
134
135 this%xmin_gl = - 0.25_rp * pi
136 this%xmax_gl = + 0.25_rp * pi
137 this%ymin_gl = - 0.25_rp * pi
138 this%ymax_gl = + 0.25_rp * pi
139 this%zmin_gl = dom_zmin
140 this%zmax_gl = dom_zmax
141 this%RPlanet = rplanet
142 this%dom_vol = 4.0_rp / 3.0_rp * pi * ( ( dom_zmax + rplanet )**3 - ( dom_zmin + rplanet )**3 )
143
144
145 !- Fz
146 allocate( this%FZ(this%NeGZ+1) )
147 if ( present(fz) ) then
148 this%FZ(:) = fz(:)
149 else
150 this%FZ(1 ) = dom_zmin
151 this%FZ(this%NeGZ+1) = dom_zmax
152 dz = (dom_zmax - dom_zmin) / dble(this%NeGZ)
153 do k=2, this%NeGZ
154 this%FZ(k) = this%FZ(k-1) + dz
155 end do
156 end if
157
158 !-
159 if ( present(shallow_approx) ) then
160 this%shallow_approx = shallow_approx
161 else
162 this%shallow_approx = .true.
163 end if
164
165 !--
166 call meshbase3d_init( this, refelem, nlocalmeshperprc, 6, &
167 nproc, myrank )
168
169 !---
170 call this%refElem2D%Init( this%refElem3D%PolyOrder_h, refelem%IsLumpedMatrix() )
171 call this%mesh2D%Init( negx, negy, rplanet, this%refElem2D, nlocalmeshperprc, &
172 nproc, myrank )
173
174 !-- Modify the information of dimension for the cubed sphere mesh
175 call this%SetDimInfo( meshbase3d_dimtypeid_x, "x", "1", "X-coordinate" )
176 call this%SetDimInfo( meshbase3d_dimtypeid_y, "y", "1", "Y-coordinate" )
177 call this%SetDimInfo( meshbase3d_dimtypeid_z, "z", "m", "Z-coordinate" )
178 call this%SetDimInfo( meshbase3d_dimtypeid_xyz, "xyz", "1", "XYZ-coordinate" )
179 call this%SetDimInfo( meshbase3d_dimtypeid_zt, "zt", "1", "XYZ-coordinate" )
180 call this%SetDimInfo( meshbase3d_dimtypeid_xyzt, "xyzt", "1", "XYZ-coordinate" )
181
182 return
183 end subroutine meshcubedspheredom3d_init
184
185 !> Finalize an object managing a cubed-sphere 3D computational domain
186!OCL SERIAL
187 subroutine meshcubedspheredom3d_final( this )
188 implicit none
189 class(meshcubedspheredom3d), intent(inout) :: this
190 !-----------------------------------------------------------------------------
191
192 if (this%isGenerated) then
193 if ( allocated(this%rcdomIJKP2LCMeshID) ) then
194 !$acc exit data delete( this%rcdomIJKP2LCMeshID )
195 deallocate( this%rcdomIJKP2LCMeshID )
196 end if
197 else
198 if ( allocated( this%FZ ) ) deallocate( this%FZ )
199 end if
200
201 call this%mesh2D%Final()
202 call this%refElem2D%Final()
203
204 call meshbase3d_final( this )
205
206 return
207 end subroutine meshcubedspheredom3d_final
208
209!OCL SERIAL
210 subroutine meshcubedspheredom3d_getmesh2d( this, ptr_mesh2D )
211 implicit none
212 class(meshcubedspheredom3d), intent(in), target :: this
213 class(meshbase2d), pointer, intent(out) :: ptr_mesh2D
214 !-------------------------------------------------------
215
216 ptr_mesh2d => this%mesh2D
217 return
218 end subroutine meshcubedspheredom3d_getmesh2d
219
220 !> Generate the cubed-sphere 3D computational domain
221!OCL SERIAL
222 subroutine meshcubedspheredom3d_generate( this )
223 use scale_mesh_cubedspheredom2d, only: &
225 implicit none
226
227 class(meshcubedspheredom3d), intent(inout), target :: this
228
229 integer :: n
230 type(localmesh3d), pointer :: mesh
231
232 integer :: tileID_table(this%LOCAL_MESH_NUM, this%PRC_NUM)
233 integer :: panelID_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
234 integer :: pi_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
235 integer :: pj_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
236 integer :: pk_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
237
238 integer :: NprcX_lc, NprcY_lc, NprcZ_lc
239 integer :: tileID
240 !-----------------------------------------------------------------------------
241
243 nprcx_lc, nprcy_lc, &
244 this%PRC_NUM, this%LOCAL_MESH_NUM_global, &
245 .true. )
246
247 nprcz_lc = 1
248
249 !--- Construct the connectivity of patches (only master node)
250
251 call this%AssignDomID( &
252 nprcx_lc, nprcy_lc, nprcz_lc, & ! (in)
253 tileid_table, panelid_table, & ! (out)
254 pi_table, pj_table, pk_table ) ! (out)
255
256 do n=1, this%LOCAL_MESH_NUM
257 mesh => this%lcmesh_list(n)
258 tileid = tileid_table(n, mesh%PRC_myrank+1)
259
260 call meshcubedspheredom3d_setuplocaldom( mesh, &
261 tileid, panelid_table(tileid), &
262 pi_table(tileid), pj_table(tileid), pk_table(tileid), &
263 nprcx_lc, nprcy_lc, nprcz_lc, &
264 this%xmin_gl, this%xmax_gl, this%ymin_gl, this%ymax_gl, &
265 this%zmin_gl, this%zmax_gl, this%RPlanet, &
266 this%NeGX/nprcx_lc, this%NeGY/nprcy_lc, this%NeGZ/nprcz_lc, &
267 this%FZ(:) )
268
269 call meshcubedspheredom2d_setuplocaldom( this%mesh2D%lcmesh_list(n), &
270 tileid, panelid_table(tileid), &
271 pi_table(tileid), pj_table(tileid), nprcx_lc, nprcy_lc, &
272 this%xmin_gl, this%xmax_gl, this%ymin_gl, this%ymax_gl, &
273 this%RPlanet, this%NeGX/nprcx_lc, this%NeGY/nprcy_lc )
274
275 call mesh%SetLocalMesh2D( this%mesh2D%lcmesh_list(n) )
276
277 !---
278 ! write(*,*) "** my_rank=", mesh%PRC_myrank
279 ! write(*,*) " tileID:", mesh%tileID
280 ! write(*,*) " pnlID:", mesh%panelID, "-- i,j (within a panel)=", pi_table(tileID), pj_table(tileID)
281 ! write(*,*) " local mesh:", n, "( total", this%LOCAL_MESH_NUM, ")"
282 ! write(*,*) " panel_connect:", this%tilePanelID_globalMap(:,mesh%tileID)
283 ! write(*,*) " tile_connect:", this%tileID_globalMap(:,mesh%tileID)
284 ! write(*,*) " face_connect:", this%tileFaceID_globalMap(:,mesh%tileID)
285 ! write(*,*) " domain size"
286 ! write(*,*) " NeX, NeY:", mesh%NeX, mesh%NeY
287 ! write(*,*) " [X], [Y]:", mesh%xmin, mesh%xmax, ":", mesh%ymin, mesh%ymax
288 end do
289
290 ! Set lon&lat position and metrics with the cubed sphere mesh
291 call meshcubedspheredom3d_set_metric( this )
292
293 ! To set rcdomIJP2LCMeshID, call AssignDomID for 2D mesh
294 call this%mesh2D%AssignDomID( &
295 nprcx_lc, nprcy_lc, & ! (in)
296 tileid_table, panelid_table, & ! (out)
297 pi_table, pj_table ) ! (out)
298
299 this%isGenerated = .true.
300 this%mesh2D%isGenerated = .true.
301
302 return
303 end subroutine meshcubedspheredom3d_generate
304
305 !> Set the geometric information of the local mesh with the vertical coordinate transformation
306!OCL SERIAL
307 subroutine meshcubedspheredom3d_set_geometric_with_vcoord(this, lcdomID, GsqrtV_lc, zlev_lc, G13_lc, G23_lc)
308 implicit none
309 class(meshcubedspheredom3d), intent(inout), target :: this
310 integer, intent(in) :: lcdomID
311 real(RP), intent(in) :: GsqrtV_lc(this%refElem3D%Np,this%lcmesh_list(lcdomID)%NeA)
312 real(RP), intent(in) :: zlev_lc(this%refElem3D%Np,this%lcmesh_list(lcdomID)%NeA)
313 real(RP), intent(in) :: G13_lc(this%refElem3D%Np,this%lcmesh_list(lcdomID)%NeA)
314 real(RP), intent(in) :: G23_lc(this%refElem3D%Np,this%lcmesh_list(lcdomID)%NeA)
315
316 integer :: ke, p
317 integer :: Np
318 class(localmesh3d), pointer :: lcmesh
319 real(RP) :: s
320 !-------------------------------------------------------
321
322 lcmesh => this%lcmesh_list(lcdomid)
323 np = lcmesh%refElem3D%Np
324
325 if ( this%shallow_approx ) then
326 s = 0.0_rp
327 else
328 s = 1.0_rp / this%RPlanet
329 end if
330
331 !$omp parallel
332 !$omp do
333 !$acc parallel present(lcmesh%zlev, lcmesh%gam, lcmesh%Gsqrt, lcmesh%GI3, zlev_lc, GsqrtV_lc, G13_lc, G23_lc)
334 !$acc loop gang
335 do ke=lcmesh%NeS, lcmesh%NeE
336 !$acc loop vector
337 do p=1, np
338 lcmesh%zlev(p,ke) = zlev_lc(p,ke)
339 end do
340 end do
341 !$omp do
342 !$acc loop gang
343 do ke=lcmesh%NeS, lcmesh%NeA
344 !$acc loop vector
345 do p=1, np
346 lcmesh%gam(p,ke) = 1.0_rp + s * zlev_lc(p,ke)
347
348 lcmesh%Gsqrt(p,ke) = gsqrtv_lc(p,ke) * lcmesh%gam(p,ke)**2 * lcmesh%Gsqrt(p,ke)
349 lcmesh%GI3(p,ke,1) = g13_lc(p,ke)
350 lcmesh%GI3(p,ke,2) = g23_lc(p,ke)
351 end do
352 end do
353 !$acc end parallel
354 !$omp end parallel
355 !$acc update host(lcmesh%zlev, lcmesh%gam, lcmesh%Gsqrt, lcmesh%GI3)
356
357 return
358 end subroutine meshcubedspheredom3d_set_geometric_with_vcoord
359
360 !- private ------------------------------
361
362!OCL SERIAL
363 subroutine meshcubedspheredom3d_setuplocaldom( lcmesh, &
364 tileID, panelID, &
365 i, j, k, NprcX, NprcY, NprcZ, &
366 dom_xmin, dom_xmax, dom_ymin, dom_ymax, dom_zmin, dom_zmax, &
367 planet_radius, NeX, NeY, NeZ, &
368 FZ )
369
371 meshutilcubedsphere3d_genconnectivity, &
372 meshutilcubedsphere3d_gencubedomain, &
373 meshutilcubedsphere3d_buildinteriormap, &
374 meshutilcubedsphere3d_genpatchboundarymap
375
377
378 implicit none
379
380 type(localmesh3d), intent(inout) :: lcmesh
381 integer, intent(in) :: tileID
382 integer, intent(in) :: panelID
383 integer, intent(in) :: i, j, k
384 integer, intent(in) :: NprcX, NprcY, NprcZ
385 real(RP), intent(in) :: dom_xmin, dom_xmax
386 real(RP), intent(in) :: dom_ymin, dom_ymax
387 real(RP), intent(in) :: dom_zmin, dom_zmax
388 real(RP), intent(in) :: planet_radius
389 integer, intent(in) :: NeX, NeY, NeZ
390 real(RP), intent(in) :: FZ(NeZ*NprcZ+1)
391
392 class(elementbase3d), pointer :: elem
393 real(RP) :: delx, dely
394 real(RP) :: FZ_lc(NeZ+1)
395
396 integer :: ii, jj, kk
397 integer :: ke
398 !-----------------------------------------------------------------------------
399
400 elem => lcmesh%refElem3D
401
402 lcmesh%tileID = tileid
403 lcmesh%panelID = panelid
404 !$acc update device(lcmesh%tileID, lcmesh%panelID)
405
406 !--
407 lcmesh%Ne = nex * ney * nez
408 lcmesh%Nv = (nex + 1)*(ney + 1)*(nez + 1)
409 lcmesh%NeS = 1
410 lcmesh%NeE = lcmesh%Ne
411 lcmesh%NeA = lcmesh%Ne + 2*(nex + ney)*nez + 2*nex*ney
412 !$acc update device(lcmesh%Ne, lcmesh%Nv, lcmesh%NeS, lcmesh%NeE, lcmesh%NeA)
413
414 lcmesh%NeX = nex
415 lcmesh%NeY = ney
416 lcmesh%NeZ = nez
417 !$acc update device(lcmesh%NeX, lcmesh%NeY, lcmesh%NeZ)
418
419 lcmesh%Ne2D = nex * ney
420 lcmesh%Ne2DA = nex * ney + 2*(nex + ney)
421 !$acc update device(lcmesh%Ne2D, lcmesh%Ne2DA)
422
423 !--
424 delx = ( dom_xmax - dom_xmin ) / dble(nprcx)
425 dely = ( dom_ymax - dom_ymin ) / dble(nprcy)
426 fz_lc(:) = fz((k-1)*nez+1:k*nez+1)
427 lcmesh%xmin = dom_xmin + (i-1)*delx
428 lcmesh%xmax = dom_xmin + i *delx
429 lcmesh%ymin = dom_ymin + (j-1)*dely
430 lcmesh%ymax = dom_ymin + j *dely
431 lcmesh%zmin = fz_lc(1)
432 lcmesh%zmax = fz_lc(nez+1)
433 !$acc update device(lcmesh%xmin, lcmesh%xmax, lcmesh%ymin, lcmesh%ymax, lcmesh%zmin, lcmesh%zmax)
434
435 !--
436 allocate( lcmesh%pos_ev(lcmesh%Nv,3) )
437 allocate( lcmesh%EToV(lcmesh%Ne,elem%Nv) )
438 allocate( lcmesh%EToE(lcmesh%Ne,elem%Nfaces) )
439 allocate( lcmesh%EToF(lcmesh%Ne,elem%Nfaces) )
440 allocate( lcmesh%BCType(lcmesh%refElem%Nfaces,lcmesh%Ne) )
441 allocate( lcmesh%VMapM(elem%NfpTot, lcmesh%Ne) )
442 allocate( lcmesh%VMapP(elem%NfpTot, lcmesh%Ne) )
443 allocate( lcmesh%MapM(elem%NfpTot, lcmesh%Ne) )
444 allocate( lcmesh%MapP(elem%NfpTot, lcmesh%Ne) )
445 !$acc enter data create( lcmesh%pos_ev, lcmesh%EToV, lcmesh%EToE, lcmesh%EToF, lcmesh%BCType, &
446 !$acc lcmesh%VMapM, lcmesh%VMapP, lcmesh%MapM, lcmesh%MapP )
447
448 allocate( lcmesh%EMap3Dto2D(lcmesh%Ne) )
449 !$acc enter data create( lcmesh%EMap3Dto2D )
450
451 lcmesh%BCType(:,:) = bctype_interior
452 !$acc update device(lcmesh%BCType)
453
454 !----
455 call meshutilcubedsphere3d_gencubedomain( lcmesh%pos_ev, lcmesh%EToV, & ! (out)
456 lcmesh%NeX, lcmesh%xmin, lcmesh%xmax, & ! (in)
457 lcmesh%NeY, lcmesh%ymin, lcmesh%ymax, & ! (in)
458 lcmesh%NeZ, lcmesh%zmin, lcmesh%zmax, fz=fz_lc ) ! (in)
459 !$acc update device(lcmesh%pos_ev, lcmesh%EToV)
460
461 !---
462 call meshbase3d_setgeometricinfo(lcmesh, meshcubedspheredom3d_coord_conv, meshcubedspheredom3d_calc_normal )
463
464 !---
465 call meshutilcubedsphere3d_genconnectivity( lcmesh%EToE, lcmesh%EToF, & ! (out)
466 lcmesh%EToV, lcmesh%Ne, elem%Nfaces ) ! (in)
467 !$acc update device(lcmesh%EToE, lcmesh%EToF)
468
469 !---
470 call meshutilcubedsphere3d_buildinteriormap( lcmesh%VmapM, lcmesh%VMapP, lcmesh%MapM, lcmesh%MapP, & ! (out)
471 lcmesh%pos_en, lcmesh%pos_ev, lcmesh%EToE, lcmesh%EtoF, lcmesh%EtoV, & ! (in)
472 elem%Fmask_h, elem%Fmask_v, lcmesh%Ne, lcmesh%Nv, elem%Np, elem%Nfp_h, elem%Nfp_v, elem%NfpTot, & ! (in)
473 elem%Nfaces_h, elem%Nfaces_v, elem%Nfaces )
474
475 call meshutilcubedsphere3d_genpatchboundarymap( lcmesh%VMapB, lcmesh%MapB, lcmesh%VMapP, & !(out)
476 lcmesh%pos_en, lcmesh%xmin, lcmesh%xmax, lcmesh%ymin, lcmesh%ymax, lcmesh%zmin, lcmesh%zmax, & ! (in)
477 elem%Fmask_h, elem%Fmask_v, lcmesh%Ne, lcmesh%Nv, elem%Np, elem%Nfp_h, elem%Nfp_v, elem%NfpTot, & ! (in)
478 elem%Nfaces_h, elem%Nfaces_v, elem%Nfaces )
479 !$acc update device(lcmesh%VMapM, lcmesh%VMapP, lcmesh%MapM, lcmesh%MapP)
480 !$acc enter data copyin(lcmesh%VMapB, lcmesh%MapB)
481
482 !---
483 !$omp parallel do collapse(2) private(ii,ke)
484 do kk=1, lcmesh%NeZ
485 do jj=1, lcmesh%NeY
486 do ii=1, lcmesh%NeX
487 ke = ii + (jj-1) * lcmesh%NeX + (kk-1) * lcmesh%NeX * lcmesh%NeY
488 lcmesh%EMap3Dto2D(ke) = ii + (jj-1) * lcmesh%NeX
489 end do
490 end do
491 end do
492 !$acc update device(lcmesh%EMap3Dto2D)
493
494 return
495 end subroutine meshcubedspheredom3d_setuplocaldom
496
497!OCL SERIAL
498 subroutine meshcubedspheredom3d_assigndomid( this, &
499 NprcX_lc, NprcY_lc, NprcZ_lc, &
500 tileID_table, panelID_table, &
501 pi_table, pj_table, pk_table )
502
503 use scale_meshutil_cubedsphere3d, only: &
505
506 implicit none
507
508 class(meshcubedspheredom3d), target, intent(inout) :: this
509 integer, intent(in) :: NprcX_lc
510 integer, intent(in) :: NprcY_lc
511 integer, intent(in) :: NprcZ_lc
512 integer, intent(out) :: tileID_table(this%LOCAL_MESH_NUM, this%PRC_NUM)
513 integer, intent(out) :: panelID_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
514 integer, intent(out) :: pi_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
515 integer, intent(out) :: pj_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
516 integer, intent(out) :: pk_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
517
518 integer :: n
519 integer :: prc
520 integer :: tileID
521 integer :: is_lc, js_lc, ks_lc, ps_lc
522 integer :: ilc_count, jlc_count, klc_count, plc_count
523 integer :: ilc, jlc, klc, plc
524
525 type(localmesh3d), pointer :: lcmesh
526 !-----------------------------------------------------------------------------
527
529 panelid_table, pi_table, pj_table, pk_table, & ! (out)
530 this%tileID_globalMap, this%tileFaceID_globalMap, this%tilePanelID_globalMap, & ! (out)
531 this%LOCAL_MESH_NUM_global, nprcz_lc ) ! (in)
532 !$acc update device(this%tileID_globalMap, this%tileFaceID_globalMap, this%tilePanelID_globalMap)
533
534 !----
535
536 do prc=1, this%PRC_NUM
537 do n=1, this%LOCAL_MESH_NUM
538 tileid = n + (prc-1)*this%LOCAL_MESH_NUM
539 lcmesh => this%lcmesh_list(n)
540
541 !-
542 tileid_table(n,prc) = tileid
543 this%tileID_global2localMap(tileid) = n
544 this%PRCRank_globalMap(tileid) = prc - 1
545
546 !-
547 if ( this%PRCRank_globalMap(tileid) == lcmesh%PRC_myrank ) then
548 if (n==1) then
549 is_lc = pi_table(tileid); ilc_count = 1
550 js_lc = pj_table(tileid); jlc_count = 1
551 ks_lc = pk_table(tileid); klc_count = 1
552 ps_lc = panelid_table(tileid); plc_count = 1
553 end if
554 if(is_lc < pi_table(tileid)) ilc_count = ilc_count + 1
555 if(js_lc < pj_table(tileid)) jlc_count = jlc_count + 1
556 if(ks_lc < pk_table(tileid)) klc_count = klc_count + 1
557 if(ps_lc < panelid_table(tileid)) plc_count = plc_count + 1
558 end if
559 end do
560 end do
561 !$acc update device(this%tileID_global2localMap, this%PRCRank_globalMap)
562
563 allocate( this%rcdomIJKP2LCMeshID(ilc_count,jlc_count,klc_count,plc_count) )
564 do plc=1, plc_count
565 do klc=1, klc_count
566 do jlc=1, jlc_count
567 do ilc=1, ilc_count
568 this%rcdomIJKP2LCMeshID(ilc,jlc,klc,plc) = ilc + (jlc - 1)*ilc_count + (klc - 1)*ilc_count*jlc_count &
569 + (plc-1)*ilc_count*jlc_count*klc_count
570 end do
571 end do
572 end do
573 end do
574 !$acc enter data copyin(this%rcdomIJKP2LCMeshID)
575
576 return
577 end subroutine meshcubedspheredom3d_assigndomid
578
579!OCL SERIAL
580 subroutine meshcubedspheredom3d_coord_conv( x, y, z, xX, xY, xZ, yX, yY, yZ, zX, zY, zZ, &
581 vx, vy, vz, elem )
582
583 implicit none
584
585 type(elementbase3d), intent(in) :: elem
586 real(RP), intent(out) :: x(elem%Np), y(elem%Np), z(elem%Np)
587 real(RP), intent(out) :: xX(elem%Np), xY(elem%Np), xZ(elem%Np)
588 real(RP), intent(out) :: yX(elem%Np), yY(elem%Np), yZ(elem%Np)
589 real(RP), intent(out) :: zX(elem%Np), zY(elem%Np), zZ(elem%Np)
590 real(RP), intent(in) :: vx(elem%Nv), vy(elem%Nv), vz(elem%Nv)
591
592 !-------------------------------------------------
593
594 x(:) = vx(1) + 0.5_rp*(elem%x1(:) + 1.0_rp)*(vx(2) - vx(1))
595 y(:) = vy(1) + 0.5_rp*(elem%x2(:) + 1.0_rp)*(vy(3) - vy(1))
596 z(:) = vz(1) + 0.5_rp*(elem%x3(:) + 1.0_rp)*(vz(5) - vz(1))
597
598 xx(:) = 0.5_rp*(vx(2) - vx(1)) !matmul(refElem%Dx1,mesh%x1(:,n))
599 xy(:) = 0.0_rp !matmul(refElem%Dx2,mesh%x1(:,n))
600 xz(:) = 0.0_rp !matmul(refElem%Dx3,mesh%x1(:,n))
601 yx(:) = 0.0_rp !matmul(refElem%Dx1,mesh%x2(:,n))
602 yy(:) = 0.5_rp*(vy(3) - vy(1)) !matmul(refElem%Dx2,mesh%x2(:,n))
603 yz(:) = 0.0_rp !matmul(refElem%Dx3,mesh%x2(:,n))
604 zx(:) = 0.0_rp !matmul(refElem%Dx1,mesh%x3(:,n))
605 zy(:) = 0.0_rp !matmul(refElem%Dx2,mesh%x3(:,n))
606 zz(:) = 0.5_rp*(vz(5) - vz(1)) !matmul(refElem%Dx3,mesh%x3(:,n))
607
608 return
609 end subroutine meshcubedspheredom3d_coord_conv
610
611!OCL SERIAL
612 subroutine meshcubedspheredom3d_calc_normal( normal_fn, &
613 Escale_f, fid_h, fid_v, elem )
614
615 implicit none
616
617 type(elementbase3d), intent(in) :: elem
618 real(RP), intent(out) :: normal_fn(elem%NfpTot,3)
619 integer, intent(in) :: fid_h(elem%Nfp_h,elem%Nfaces_h)
620 integer, intent(in) :: fid_v(elem%Nfp_v,elem%Nfaces_v)
621 real(RP), intent(in) :: Escale_f(elem%NfpTot,3,3)
622
623 integer :: d
624 !-------------------------------------------------
625
626 do d=1, 3
627 normal_fn(fid_h(:,1),d) = - escale_f(fid_h(:,1),2,d)
628 normal_fn(fid_h(:,2),d) = + escale_f(fid_h(:,2),1,d)
629 normal_fn(fid_h(:,3),d) = + escale_f(fid_h(:,3),2,d)
630 normal_fn(fid_h(:,4),d) = - escale_f(fid_h(:,4),1,d)
631
632 normal_fn(fid_v(:,1),d) = - escale_f(fid_v(:,1),3,d)
633 normal_fn(fid_v(:,2),d) = + escale_f(fid_v(:,2),3,d)
634 end do
635
636 return
637 end subroutine meshcubedspheredom3d_calc_normal
638
639 !--
640
641!OCL SERIAL
642 subroutine meshcubedspheredom3d_set_metric( this )
643 use scale_cubedsphere_coord_cnv, only: &
646
647 implicit none
648 class(meshcubedspheredom3d), intent(inout), target :: this
649
650 integer :: n
651 integer :: ke, ke2D, p
652 integer :: Np
653
654 class(localmesh3d), pointer :: lcmesh
655 class(localmesh2d), pointer :: lcmesh2D
656 class(elementbase3d), pointer :: elem
657 class(elementbase2d), pointer :: elem2D
658
659 real(RP), allocatable :: gam2D(:,:)
660 integer, allocatable :: IndexH2Dto3D(:)
661 real(RP) :: s
662 !----------------------------------------------------
663
664 if ( this%shallow_approx ) then
665 s = 0.0_rp
666 else
667 s = 1.0_rp / this%RPlanet
668 end if
669
670 do n=1, this%mesh2D%LOCAL_MESH_NUM
671 lcmesh => this%lcmesh_list(n)
672 lcmesh2d => this%mesh2D%lcmesh_list(n)
673 elem => lcmesh%refElem3D
674 elem2d => lcmesh2d%refElem2D
675 np = elem%Np
676
677 allocate( gam2d(elem2d%Np,lcmesh2d%Ne) )
678 allocate( indexh2dto3d(elem%Np) )
679 gam2d(:,:) = 1.0_rp
680 indexh2dto3d(:) = elem%IndexH2Dto3D(:)
681
682 !$acc data copyin( gam2D, IndexH2Dto3D )
683
685 lcmesh2d%panelID, lcmesh2d%pos_en(:,:,1), lcmesh2d%pos_en(:,:,2), gam2d(:,:), & ! (in)
686 lcmesh2d%Ne * elem2d%Np, & ! (in)
687 lcmesh%lon2D(:,:), lcmesh%lat2D(:,:) ) ! (out)
688 !$acc update host(lcmesh%lon2D, lcmesh%lat2D)
689
691 lcmesh2d%pos_en(:,:,1), lcmesh2d%pos_en(:,:,2), elem2d%Np * lcmesh2d%Ne, this%RPlanet, & ! (in)
692 lcmesh%G_ij, lcmesh%GIJ, lcmesh%GsqrtH ) ! (out)
693 !$acc update host(lcmesh%G_ij, lcmesh%GIJ, lcmesh%GsqrtH)
694
695 !$omp parallel do private(ke2D)
696 !$acc parallel loop gang present(lcmesh%GsqrtH, lcmesh%GIJ, lcmesh%G_ij, lcmesh%pos_en, lcmesh%gam, lcmesh%EMap3Dto2D)
697 do ke=lcmesh%NeS, lcmesh%NeE
698 ke2d = lcmesh%EMap3Dto2D(ke)
699 !$acc loop vector
700 do p=1, np
701 lcmesh%gam(p,ke) = 1.0_rp + s * lcmesh%pos_en(p,ke,3)
702 lcmesh%Gsqrt(p,ke) = lcmesh%GsqrtH(indexh2dto3d(p),ke2d)
703 end do
704 end do
705
706 call fill_halo_metric( lcmesh%Gsqrt, lcmesh%gam, lcmesh%VMapM, lcmesh%VMapP, lcmesh, lcmesh%refElem3D )
707 !$acc update host(lcmesh%gam, lcmesh%Gsqrt)
708
709 !$acc end data
710 deallocate( gam2d, indexh2dto3d )
711 !--
712 end do
713
714 return
715 end subroutine meshcubedspheredom3d_set_metric
716
717!OCL SERIAL
718 subroutine fill_halo_metric( Gsqrt, gam, vmapM, vmapP, lmesh, elem )
719 implicit none
720 class(localmesh3d), intent(in) :: lmesh
721 class(elementbase3d), intent(in) :: elem
722 integer, intent(in) :: vmapM(elem%NfpTot*lmesh%Ne)
723 integer, intent(in) :: vmapP(elem%NfpTot*lmesh%Ne)
724 real(RP), intent(inout) :: Gsqrt(elem%Np*lmesh%NeA)
725 real(RP), intent(inout) :: gam(elem%Np*lmesh%NeA)
726
727 integer :: i, iM, iP
728 integer :: NpxNe
729 !------------------------------------------------
730
731 npxne = elem%Np * lmesh%Ne
732
733 !$omp parallel do private(i, iM, iP)
734 !$acc parallel loop present(Gsqrt, gam, vmapM, vmapP)
735 do i=1, elem%NfpTot*lmesh%Ne
736 im = vmapm(i); ip = vmapp(i)
737 if ( ip > npxne ) then
738 gsqrt(ip) = gsqrt(im)
739 gam(ip) = gam(im)
740 end if
741 end do
742 return
743 end subroutine fill_halo_metric
744
Module common / Coordinate conversion with cubed-sphere projection.
subroutine, public cubedspherecoordcnv_cs2lonlatpos(panelid, alpha, beta, gam, np, lon, lat)
Calculate longitude and latitude coordinates from local coordinates using the central angles in an eq...
subroutine, public cubedspherecoordcnv_getmetric(alpha, beta, np, radius, g_ij, gij, gsqrt)
Calculate the metrics associated with an equiangular gnomonic cubed-sphere projection to those in lon...
module FElib / Element / Base
module FElib / Element / hexahedron
module FElib / Element / Quadrilateral
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Mesh / Local, Base
integer, parameter, public bctype_interior
module FElib / Mesh / Base 2D
subroutine, public meshbase2d_final(this)
Finalize an object to manage a 2D computational mesh.
subroutine, public meshbase2d_init(this, refelem, nlocalmeshperprc, nprocs, myrank)
Initialize an object to manage a 2D computational mesh.
subroutine, public meshbase2d_setgeometricinfo(lcmesh, coord_conv, calc_normal)
module FElib / Mesh / Base 3D
subroutine, public meshbase3d_init(this, refelem, nlocalmeshperprc, nsidetile, nproc, myrank)
integer, public meshbase3d_dimtypeid_y
integer, public meshbase3d_dimtypeid_zt
integer, public meshbase3d_dimtypeid_z
integer, public meshbase3d_dimtype_num
subroutine, public meshbase3d_final(this)
subroutine, public meshbase3d_setgeometricinfo(lcmesh, coord_conv, calc_normal)
integer, public meshbase3d_dimtypeid_xyz
integer, public meshbase3d_dimtypeid_x
integer, public meshbase3d_dimtypeid_xyzt
module FElib / Mesh / Cubed-sphere 2D domain
subroutine, public meshcubedspheredom2d_check_division_params(nprcx_lc, nprcy_lc, prc_num, local_mesh_num_global, call_prc_abort)
subroutine, public meshcubedspheredom2d_setuplocaldom(lcmesh, tileid, panelid, i, j, nprcx, nprcy, dom_xmin, dom_xmax, dom_ymin, dom_ymax, planet_radius, nex, ney)
module FElib / Mesh / Cubed-sphere 3D domain
subroutine meshcubedspheredom3d_init(this, negx, negy, negz, rplanet, dom_zmin, dom_zmax, refelem, nlocalmeshperprc, nproc, myrank, fz, shallow_approx)
Initialize an object to manage a cubed-sphere 3D computational domain.
module FElib / Mesh / utility for 3D cubed-sphere mesh
subroutine, public meshutilcubedsphere3d_buildglobalmap(panelid_table, pi_table, pj_table, pk_table, tileid_map, tilefaceid_map, tilepanelid_map, ntile, nez)
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type representing a hexahedral element.
Derived type representing a quadrilateral element.
Derived type representing a local mesh for 2D domain.
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 2D computational domain.
Derived type to manage a cubed-sphere 3D computational domain.