51 real(rp),
public :: xmin_gl, xmax_gl
52 real(rp),
public :: ymin_gl, ymax_gl
53 real(rp),
public :: zmin_gl, zmax_gl
55 real(rp),
allocatable :: fz(:)
57 integer,
allocatable :: rcdomijkp2lcmeshid(:,:,:,:)
64 logical :: shallow_approx
67 procedure :: final => meshcubedspheredom3d_final
68 procedure :: generate => meshcubedspheredom3d_generate
69 procedure :: assigndomid => messhcubedspheredom3d_assigndomid
70 procedure :: getmesh2d => meshcubedspheredom3d_getmesh2d
71 procedure :: set_geometric_with_vcoord => meshcubedom3d_set_geometric_with_vcoord
84 private :: meshcubedspheredom3d_calc_normal
85 private :: meshcubedspheredom3d_coord_conv
86 private :: meshcubedspheredom3d_set_metric
87 private :: fill_halo_metric
97 NeGX, NeGY, NeGZ, RPlanet, &
99 refElem, NLocalMeshPerPrc, &
103 use scale_const,
only: &
108 integer,
intent(in) :: NeGX
109 integer,
intent(in) :: NeGY
110 integer,
intent(in) :: NeGZ
111 real(RP),
intent(in) :: RPlanet
112 real(RP),
intent(in) :: dom_Zmin
113 real(RP),
intent(in) :: dom_zmax
115 integer,
intent(in) :: NLocalMeshPerPrc
116 integer,
intent(in),
optional :: nproc
117 integer,
intent(in),
optional :: myrank
118 real(RP),
intent(in),
optional :: FZ(NeGZ+1)
119 logical,
intent(in),
optional :: shallow_approx
129 this%xmin_gl = - 0.25_rp * pi
130 this%xmax_gl = + 0.25_rp * pi
131 this%ymin_gl = - 0.25_rp * pi
132 this%ymax_gl = + 0.25_rp * pi
133 this%zmin_gl = dom_zmin
134 this%zmax_gl = dom_zmax
135 this%RPlanet = rplanet
136 this%dom_vol = 4.0_rp / 3.0_rp * pi * ( ( dom_zmax + rplanet )**3 - ( dom_zmin + rplanet )**3 )
140 allocate( this%FZ(this%NeGZ+1) )
141 if (
present(fz) )
then
144 this%FZ(1 ) = dom_zmin
145 this%FZ(this%NeGZ+1) = dom_zmax
146 dz = (dom_zmax - dom_zmin) / dble(this%NeGZ)
148 this%FZ(k) = this%FZ(k-1) + dz
153 if (
present(shallow_approx) )
then
154 this%shallow_approx = shallow_approx
156 this%shallow_approx = .true.
164 call this%refElem2D%Init( this%refElem3D%PolyOrder_h, refelem%IsLumpedMatrix() )
165 call this%mesh2D%Init( negx, negy, rplanet, this%refElem2D, nlocalmeshperprc, &
180 subroutine meshcubedspheredom3d_final( this )
185 if (this%isGenerated)
then
186 if (
allocated(this%rcdomIJKP2LCMeshID) )
then
187 deallocate( this%rcdomIJKP2LCMeshID )
190 if (
allocated( this%FZ ) )
deallocate( this%FZ )
193 call this%mesh2D%Final()
194 call this%refElem2D%Final()
199 end subroutine meshcubedspheredom3d_final
202 subroutine meshcubedspheredom3d_getmesh2d( this, ptr_mesh2D )
205 class(
meshbase2d),
pointer,
intent(out) :: ptr_mesh2D
208 ptr_mesh2d => this%mesh2D
210 end subroutine meshcubedspheredom3d_getmesh2d
213 subroutine meshcubedspheredom3d_generate( this )
223 integer :: tileID_table(this%LOCAL_MESH_NUM, this%PRC_NUM)
224 integer :: panelID_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
225 integer :: pi_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
226 integer :: pj_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
227 integer :: pk_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
229 integer :: NprcX_lc, NprcY_lc, NprcZ_lc
234 nprcx_lc, nprcy_lc, &
235 this%PRC_NUM, this%LOCAL_MESH_NUM_global, &
242 call this%AssignDomID( &
243 nprcx_lc, nprcy_lc, nprcz_lc, &
244 tileid_table, panelid_table, &
245 pi_table, pj_table, pk_table )
247 do n=1, this%LOCAL_MESH_NUM
248 mesh => this%lcmesh_list(n)
249 tileid = tileid_table(n, mesh%PRC_myrank+1)
251 call meshcubedspheredom3d_setuplocaldom( mesh, &
252 tileid, panelid_table(tileid), &
253 pi_table(tileid), pj_table(tileid), pk_table(tileid), &
254 nprcx_lc, nprcy_lc, nprcz_lc, &
255 this%xmin_gl, this%xmax_gl, this%ymin_gl, this%ymax_gl, &
256 this%zmin_gl, this%zmax_gl, this%RPlanet, &
257 this%NeGX/nprcx_lc, this%NeGY/nprcy_lc, this%NeGZ/nprcz_lc, &
261 tileid, panelid_table(tileid), &
262 pi_table(tileid), pj_table(tileid), nprcx_lc, nprcy_lc, &
263 this%xmin_gl, this%xmax_gl, this%ymin_gl, this%ymax_gl, &
264 this%RPlanet, this%NeGX/nprcx_lc, this%NeGY/nprcy_lc )
266 call mesh%SetLocalMesh2D( this%mesh2D%lcmesh_list(n) )
282 call meshcubedspheredom3d_set_metric( this )
285 call this%mesh2D%AssignDomID( &
286 nprcx_lc, nprcy_lc, &
287 tileid_table, panelid_table, &
290 this%isGenerated = .true.
291 this%mesh2D%isGenerated = .true.
293 deallocate( this%FZ )
296 end subroutine meshcubedspheredom3d_generate
299 subroutine meshcubedom3d_set_geometric_with_vcoord(this, lcdomID, GsqrtV_lc, zlev_lc, G13_lc, G23_lc)
302 integer,
intent(in) :: lcdomID
303 real(RP),
intent(in) :: GsqrtV_lc(this%refElem3D%Np,this%lcmesh_list(lcdomID)%NeA)
304 real(RP),
intent(in) :: zlev_lc(this%refElem3D%Np,this%lcmesh_list(lcdomID)%NeA)
305 real(RP),
intent(in) :: G13_lc(this%refElem3D%Np,this%lcmesh_list(lcdomID)%NeA)
306 real(RP),
intent(in) :: G23_lc(this%refElem3D%Np,this%lcmesh_list(lcdomID)%NeA)
312 lcmesh => this%lcmesh_list(lcdomid)
316 do ke=lcmesh%NeS, lcmesh%NeE
317 lcmesh%zlev(:,ke) = zlev_lc(:,ke)
320 do ke=lcmesh%NeS, lcmesh%NeA
321 if ( this%shallow_approx )
then
322 lcmesh%gam(:,ke) = 1.0_rp
324 lcmesh%gam(:,ke) = 1.0_rp + zlev_lc(:,ke) / this%RPlanet
327 lcmesh%Gsqrt(:,ke) = gsqrtv_lc(:,ke) * lcmesh%gam(:,ke)**2 * lcmesh%Gsqrt(:,ke)
328 lcmesh%GI3(:,ke,1) = g13_lc(:,ke)
329 lcmesh%GI3(:,ke,2) = g23_lc(:,ke)
334 end subroutine meshcubedom3d_set_geometric_with_vcoord
339 subroutine meshcubedspheredom3d_setuplocaldom( lcmesh, &
341 i, j, k, NprcX, NprcY, NprcZ, &
342 dom_xmin, dom_xmax, dom_ymin, dom_ymax, dom_zmin, dom_zmax, &
343 planet_radius, NeX, NeY, NeZ, &
347 meshutilcubedsphere3d_genconnectivity, &
348 meshutilcubedsphere3d_gencubedomain, &
349 meshutilcubedsphere3d_buildinteriormap, &
350 meshutilcubedsphere3d_genpatchboundarymap
357 integer,
intent(in) :: tileID
358 integer,
intent(in) :: panelID
359 integer,
intent(in) :: i, j, k
360 integer,
intent(in) :: NprcX, NprcY, NprcZ
361 real(RP),
intent(in) :: dom_xmin, dom_xmax
362 real(RP),
intent(in) :: dom_ymin, dom_ymax
363 real(RP),
intent(in) :: dom_zmin, dom_zmax
364 real(RP),
intent(in) :: planet_radius
365 integer,
intent(in) :: NeX, NeY, NeZ
366 real(RP),
intent(in) :: FZ(NeZ*NprcZ+1)
369 real(RP) :: delx, dely
370 real(RP) :: FZ_lc(NeZ+1)
372 integer :: ii, jj, kk
376 elem => lcmesh%refElem3D
377 lcmesh%tileID = tileid
378 lcmesh%panelID = panelid
381 lcmesh%Ne = nex * ney * nez
382 lcmesh%Nv = (nex + 1)*(ney + 1)*(nez + 1)
384 lcmesh%NeE = lcmesh%Ne
385 lcmesh%NeA = lcmesh%Ne + 2*(nex + ney)*nez + 2*nex*ney
391 lcmesh%Ne2D = nex * ney
392 lcmesh%Ne2DA = nex * ney + 2*(nex + ney)
395 delx = ( dom_xmax - dom_xmin ) / dble(nprcx)
396 dely = ( dom_ymax - dom_ymin ) / dble(nprcy)
397 fz_lc(:) = fz((k-1)*nez+1:k*nez+1)
398 lcmesh%xmin = dom_xmin + (i-1)*delx
399 lcmesh%xmax = dom_xmin + i *delx
400 lcmesh%ymin = dom_ymin + (j-1)*dely
401 lcmesh%ymax = dom_ymin + j *dely
402 lcmesh%zmin = fz_lc(1)
403 lcmesh%zmax = fz_lc(nez+1)
406 allocate( lcmesh%pos_ev(lcmesh%Nv,3) )
407 allocate( lcmesh%EToV(lcmesh%Ne,elem%Nv) )
408 allocate( lcmesh%EToE(lcmesh%Ne,elem%Nfaces) )
409 allocate( lcmesh%EToF(lcmesh%Ne,elem%Nfaces) )
410 allocate( lcmesh%BCType(lcmesh%refElem%Nfaces,lcmesh%Ne) )
411 allocate( lcmesh%VMapM(elem%NfpTot, lcmesh%Ne) )
412 allocate( lcmesh%VMapP(elem%NfpTot, lcmesh%Ne) )
413 allocate( lcmesh%MapM(elem%NfpTot, lcmesh%Ne) )
414 allocate( lcmesh%MapP(elem%NfpTot, lcmesh%Ne) )
416 allocate( lcmesh%EMap3Dto2D(lcmesh%Ne) )
421 call meshutilcubedsphere3d_gencubedomain( lcmesh%pos_ev, lcmesh%EToV, &
422 lcmesh%NeX, lcmesh%xmin, lcmesh%xmax, &
423 lcmesh%NeY, lcmesh%ymin, lcmesh%ymax, &
424 lcmesh%NeZ, lcmesh%zmin, lcmesh%zmax, fz=fz_lc )
430 call meshutilcubedsphere3d_genconnectivity( lcmesh%EToE, lcmesh%EToF, &
431 lcmesh%EToV, lcmesh%Ne, elem%Nfaces )
434 call meshutilcubedsphere3d_buildinteriormap( lcmesh%VmapM, lcmesh%VMapP, lcmesh%MapM, lcmesh%MapP, &
435 lcmesh%pos_en, lcmesh%pos_ev, lcmesh%EToE, lcmesh%EtoF, lcmesh%EtoV, &
436 elem%Fmask_h, elem%Fmask_v, lcmesh%Ne, lcmesh%Nv, elem%Np, elem%Nfp_h, elem%Nfp_v, elem%NfpTot, &
437 elem%Nfaces_h, elem%Nfaces_v, elem%Nfaces )
440 call meshutilcubedsphere3d_genpatchboundarymap( lcmesh%VMapB, lcmesh%MapB, lcmesh%VMapP, &
441 lcmesh%pos_en, lcmesh%xmin, lcmesh%xmax, lcmesh%ymin, lcmesh%ymax, lcmesh%zmin, lcmesh%zmax, &
442 elem%Fmask_h, elem%Fmask_v, lcmesh%Ne, lcmesh%Nv, elem%Np, elem%Nfp_h, elem%Nfp_v, elem%NfpTot, &
443 elem%Nfaces_h, elem%Nfaces_v, elem%Nfaces )
450 ke = ii + (jj-1) * lcmesh%NeX + (kk-1) * lcmesh%NeX * lcmesh%NeY
451 lcmesh%EMap3Dto2D(ke) = ii + (jj-1) * lcmesh%NeX
457 end subroutine meshcubedspheredom3d_setuplocaldom
460 subroutine messhcubedspheredom3d_assigndomid( this, &
461 NprcX_lc, NprcY_lc, NprcZ_lc, &
462 tileID_table, panelID_table, &
463 pi_table, pj_table, pk_table )
471 integer,
intent(in) :: NprcX_lc
472 integer,
intent(in) :: NprcY_lc
473 integer,
intent(in) :: NprcZ_lc
474 integer,
intent(out) :: tileID_table(this%LOCAL_MESH_NUM, this%PRC_NUM)
475 integer,
intent(out) :: panelID_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
476 integer,
intent(out) :: pi_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
477 integer,
intent(out) :: pj_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
478 integer,
intent(out) :: pk_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
483 integer :: is_lc, js_lc, ks_lc, ps_lc
484 integer :: ilc_count, jlc_count, klc_count, plc_count
485 integer :: ilc, jlc, klc, plc
491 panelid_table, pi_table, pj_table, pk_table, &
492 this%tileID_globalMap, this%tileFaceID_globalMap, this%tilePanelID_globalMap, &
493 this%LOCAL_MESH_NUM_global, nprcz_lc )
497 do prc=1, this%PRC_NUM
498 do n=1, this%LOCAL_MESH_NUM
499 tileid = n + (prc-1)*this%LOCAL_MESH_NUM
500 lcmesh => this%lcmesh_list(n)
503 tileid_table(n,prc) = tileid
504 this%tileID_global2localMap(tileid) = n
505 this%PRCRank_globalMap(tileid) = prc - 1
508 if ( this%PRCRank_globalMap(tileid) == lcmesh%PRC_myrank )
then
510 is_lc = pi_table(tileid); ilc_count = 1
511 js_lc = pj_table(tileid); jlc_count = 1
512 ks_lc = pk_table(tileid); klc_count = 1
513 ps_lc = panelid_table(tileid); plc_count = 1
515 if(is_lc < pi_table(tileid)) ilc_count = ilc_count + 1
516 if(js_lc < pj_table(tileid)) jlc_count = jlc_count + 1
517 if(ks_lc < pk_table(tileid)) klc_count = klc_count + 1
518 if(ps_lc < panelid_table(tileid)) plc_count = plc_count + 1
523 allocate( this%rcdomIJKP2LCMeshID(ilc_count,jlc_count,klc_count,plc_count) )
528 this%rcdomIJKP2LCMeshID(ilc,jlc,klc,plc) = ilc + (jlc - 1)*ilc_count + (klc - 1)*ilc_count*jlc_count &
529 + (plc-1)*ilc_count*jlc_count*klc_count
536 end subroutine messhcubedspheredom3d_assigndomid
539 subroutine meshcubedspheredom3d_coord_conv( x, y, z, xX, xY, xZ, yX, yY, yZ, zX, zY, zZ, &
545 real(RP),
intent(out) :: x(elem%Np), y(elem%Np), z(elem%Np)
546 real(RP),
intent(out) :: xX(elem%Np), xY(elem%Np), xZ(elem%Np)
547 real(RP),
intent(out) :: yX(elem%Np), yY(elem%Np), yZ(elem%Np)
548 real(RP),
intent(out) :: zX(elem%Np), zY(elem%Np), zZ(elem%Np)
549 real(RP),
intent(in) :: vx(elem%Nv), vy(elem%Nv), vz(elem%Nv)
553 x(:) = vx(1) + 0.5_rp*(elem%x1(:) + 1.0_rp)*(vx(2) - vx(1))
554 y(:) = vy(1) + 0.5_rp*(elem%x2(:) + 1.0_rp)*(vy(3) - vy(1))
555 z(:) = vz(1) + 0.5_rp*(elem%x3(:) + 1.0_rp)*(vz(5) - vz(1))
557 xx(:) = 0.5_rp*(vx(2) - vx(1))
561 yy(:) = 0.5_rp*(vy(3) - vy(1))
565 zz(:) = 0.5_rp*(vz(5) - vz(1))
568 end subroutine meshcubedspheredom3d_coord_conv
571 subroutine meshcubedspheredom3d_calc_normal( normal_fn, &
572 Escale_f, fid_h, fid_v, elem )
577 real(RP),
intent(out) :: normal_fn(elem%NfpTot,3)
578 integer,
intent(in) :: fid_h(elem%Nfp_h,elem%Nfaces_h)
579 integer,
intent(in) :: fid_v(elem%Nfp_v,elem%Nfaces_v)
580 real(RP),
intent(in) :: Escale_f(elem%NfpTot,3,3)
586 normal_fn(fid_h(:,1),d) = - escale_f(fid_h(:,1),2,d)
587 normal_fn(fid_h(:,2),d) = + escale_f(fid_h(:,2),1,d)
588 normal_fn(fid_h(:,3),d) = + escale_f(fid_h(:,3),2,d)
589 normal_fn(fid_h(:,4),d) = - escale_f(fid_h(:,4),1,d)
591 normal_fn(fid_v(:,1),d) = - escale_f(fid_v(:,1),3,d)
592 normal_fn(fid_v(:,2),d) = + escale_f(fid_v(:,2),3,d)
596 end subroutine meshcubedspheredom3d_calc_normal
601 subroutine meshcubedspheredom3d_set_metric( this )
616 real(RP),
allocatable :: gam2D(:,:)
619 do n=1, this%mesh2D%LOCAL_MESH_NUM
620 lcmesh => this%lcmesh_list(n)
621 lcmesh2d => this%mesh2D%lcmesh_list(n)
622 elem2d => lcmesh2d%refElem2D
624 allocate( gam2d(elem2d%Np,lcmesh2d%Ne) )
628 lcmesh2d%panelID, lcmesh2d%pos_en(:,:,1), lcmesh2d%pos_en(:,:,2), gam2d(:,:), &
629 lcmesh2d%Ne * elem2d%Np, &
630 lcmesh%lon2D(:,:), lcmesh%lat2D(:,:) )
633 lcmesh2d%pos_en(:,:,1), lcmesh2d%pos_en(:,:,2), elem2d%Np * lcmesh2d%Ne, this%RPlanet, &
634 lcmesh%G_ij, lcmesh%GIJ, lcmesh%GsqrtH )
637 do ke=lcmesh%NeS, lcmesh%NeE
638 ke2d = lcmesh%EMap3Dto2D(ke)
640 if ( this%shallow_approx )
then
641 lcmesh%gam(:,ke) = 1.0_rp
643 lcmesh%gam(:,ke) = 1.0_rp + lcmesh%pos_en(:,ke,3) / this%RPlanet
645 lcmesh%Gsqrt(:,ke) = lcmesh%GsqrtH(lcmesh%refElem3D%IndexH2Dto3D(:),ke2d)
648 call fill_halo_metric( lcmesh%Gsqrt, lcmesh%gam, lcmesh%VMapM, lcmesh%VMapP, lcmesh, lcmesh%refElem3D )
656 end subroutine meshcubedspheredom3d_set_metric
659 subroutine fill_halo_metric( Gsqrt, gam, vmapM, vmapP, lmesh, elem )
663 integer,
intent(in) :: vmapM(elem%NfpTot*lmesh%Ne)
664 integer,
intent(in) :: vmapP(elem%NfpTot*lmesh%Ne)
665 real(RP),
intent(inout) :: Gsqrt(elem%Np*lmesh%NeA)
666 real(RP),
intent(inout) :: gam(elem%Np*lmesh%NeA)
672 do i=1, elem%NfpTot*lmesh%Ne
673 im = vmapm(i); ip = vmapp(i)
674 if ( ip > elem%Np * lmesh%Ne )
then
675 gsqrt(ip) = gsqrt(im)
680 end subroutine fill_halo_metric
682end module scale_mesh_cubedspheredom3d
module common / Coordinate conversion with a cubed-sphere
subroutine, public cubedspherecoordcnv_cs2lonlatpos(panelid, alpha, beta, gam, np, lon, lat)
subroutine, public cubedspherecoordcnv_getmetric(alpha, beta, np, radius, g_ij, gij, gsqrt)
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)
subroutine, public meshbase2d_init(this, refelem, nlocalmeshperprc, nprocs, myrank)
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)
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)