53 real(rp),
public :: xmin_gl
54 real(rp),
public :: xmax_gl
55 real(rp),
public :: ymin_gl
56 real(rp),
public :: ymax_gl
57 real(rp),
public :: zmin_gl
58 real(rp),
public :: zmax_gl
60 real(rp),
allocatable :: fz(:)
62 integer,
allocatable :: rcdomijkp2lcmeshid(:,:,:,:)
69 logical :: shallow_approx
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
89 private :: meshcubedspheredom3d_calc_normal
90 private :: meshcubedspheredom3d_coord_conv
91 private :: meshcubedspheredom3d_set_metric
92 private :: fill_halo_metric
103 NeGX, NeGY, NeGZ, RPlanet, &
104 dom_zmin, dom_zmax, &
105 refElem, NLocalMeshPerPrc, &
109 use scale_const,
only: &
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
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
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 )
146 allocate( this%FZ(this%NeGZ+1) )
147 if (
present(fz) )
then
150 this%FZ(1 ) = dom_zmin
151 this%FZ(this%NeGZ+1) = dom_zmax
152 dz = (dom_zmax - dom_zmin) / dble(this%NeGZ)
154 this%FZ(k) = this%FZ(k-1) + dz
159 if (
present(shallow_approx) )
then
160 this%shallow_approx = shallow_approx
162 this%shallow_approx = .true.
170 call this%refElem2D%Init( this%refElem3D%PolyOrder_h, refelem%IsLumpedMatrix() )
171 call this%mesh2D%Init( negx, negy, rplanet, this%refElem2D, nlocalmeshperprc, &
187 subroutine meshcubedspheredom3d_final( this )
192 if (this%isGenerated)
then
193 if (
allocated(this%rcdomIJKP2LCMeshID) )
then
195 deallocate( this%rcdomIJKP2LCMeshID )
198 if (
allocated( this%FZ ) )
deallocate( this%FZ )
201 call this%mesh2D%Final()
202 call this%refElem2D%Final()
207 end subroutine meshcubedspheredom3d_final
210 subroutine meshcubedspheredom3d_getmesh2d( this, ptr_mesh2D )
213 class(
meshbase2d),
pointer,
intent(out) :: ptr_mesh2D
216 ptr_mesh2d => this%mesh2D
218 end subroutine meshcubedspheredom3d_getmesh2d
222 subroutine meshcubedspheredom3d_generate( this )
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)
238 integer :: NprcX_lc, NprcY_lc, NprcZ_lc
243 nprcx_lc, nprcy_lc, &
244 this%PRC_NUM, this%LOCAL_MESH_NUM_global, &
251 call this%AssignDomID( &
252 nprcx_lc, nprcy_lc, nprcz_lc, &
253 tileid_table, panelid_table, &
254 pi_table, pj_table, pk_table )
256 do n=1, this%LOCAL_MESH_NUM
257 mesh => this%lcmesh_list(n)
258 tileid = tileid_table(n, mesh%PRC_myrank+1)
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, &
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 )
275 call mesh%SetLocalMesh2D( this%mesh2D%lcmesh_list(n) )
291 call meshcubedspheredom3d_set_metric( this )
294 call this%mesh2D%AssignDomID( &
295 nprcx_lc, nprcy_lc, &
296 tileid_table, panelid_table, &
299 this%isGenerated = .true.
300 this%mesh2D%isGenerated = .true.
303 end subroutine meshcubedspheredom3d_generate
307 subroutine meshcubedspheredom3d_set_geometric_with_vcoord(this, lcdomID, GsqrtV_lc, zlev_lc, G13_lc, G23_lc)
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)
322 lcmesh => this%lcmesh_list(lcdomid)
323 np = lcmesh%refElem3D%Np
325 if ( this%shallow_approx )
then
328 s = 1.0_rp / this%RPlanet
335 do ke=lcmesh%NeS, lcmesh%NeE
338 lcmesh%zlev(p,ke) = zlev_lc(p,ke)
343 do ke=lcmesh%NeS, lcmesh%NeA
346 lcmesh%gam(p,ke) = 1.0_rp + s * zlev_lc(p,ke)
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)
358 end subroutine meshcubedspheredom3d_set_geometric_with_vcoord
363 subroutine meshcubedspheredom3d_setuplocaldom( lcmesh, &
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, &
371 meshutilcubedsphere3d_genconnectivity, &
372 meshutilcubedsphere3d_gencubedomain, &
373 meshutilcubedsphere3d_buildinteriormap, &
374 meshutilcubedsphere3d_genpatchboundarymap
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)
393 real(RP) :: delx, dely
394 real(RP) :: FZ_lc(NeZ+1)
396 integer :: ii, jj, kk
400 elem => lcmesh%refElem3D
402 lcmesh%tileID = tileid
403 lcmesh%panelID = panelid
407 lcmesh%Ne = nex * ney * nez
408 lcmesh%Nv = (nex + 1)*(ney + 1)*(nez + 1)
410 lcmesh%NeE = lcmesh%Ne
411 lcmesh%NeA = lcmesh%Ne + 2*(nex + ney)*nez + 2*nex*ney
419 lcmesh%Ne2D = nex * ney
420 lcmesh%Ne2DA = nex * ney + 2*(nex + ney)
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)
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) )
448 allocate( lcmesh%EMap3Dto2D(lcmesh%Ne) )
455 call meshutilcubedsphere3d_gencubedomain( lcmesh%pos_ev, lcmesh%EToV, &
456 lcmesh%NeX, lcmesh%xmin, lcmesh%xmax, &
457 lcmesh%NeY, lcmesh%ymin, lcmesh%ymax, &
458 lcmesh%NeZ, lcmesh%zmin, lcmesh%zmax, fz=fz_lc )
465 call meshutilcubedsphere3d_genconnectivity( lcmesh%EToE, lcmesh%EToF, &
466 lcmesh%EToV, lcmesh%Ne, elem%Nfaces )
470 call meshutilcubedsphere3d_buildinteriormap( lcmesh%VmapM, lcmesh%VMapP, lcmesh%MapM, lcmesh%MapP, &
471 lcmesh%pos_en, lcmesh%pos_ev, lcmesh%EToE, lcmesh%EtoF, lcmesh%EtoV, &
472 elem%Fmask_h, elem%Fmask_v, lcmesh%Ne, lcmesh%Nv, elem%Np, elem%Nfp_h, elem%Nfp_v, elem%NfpTot, &
473 elem%Nfaces_h, elem%Nfaces_v, elem%Nfaces )
475 call meshutilcubedsphere3d_genpatchboundarymap( lcmesh%VMapB, lcmesh%MapB, lcmesh%VMapP, &
476 lcmesh%pos_en, lcmesh%xmin, lcmesh%xmax, lcmesh%ymin, lcmesh%ymax, lcmesh%zmin, lcmesh%zmax, &
477 elem%Fmask_h, elem%Fmask_v, lcmesh%Ne, lcmesh%Nv, elem%Np, elem%Nfp_h, elem%Nfp_v, elem%NfpTot, &
478 elem%Nfaces_h, elem%Nfaces_v, elem%Nfaces )
487 ke = ii + (jj-1) * lcmesh%NeX + (kk-1) * lcmesh%NeX * lcmesh%NeY
488 lcmesh%EMap3Dto2D(ke) = ii + (jj-1) * lcmesh%NeX
495 end subroutine meshcubedspheredom3d_setuplocaldom
498 subroutine meshcubedspheredom3d_assigndomid( this, &
499 NprcX_lc, NprcY_lc, NprcZ_lc, &
500 tileID_table, panelID_table, &
501 pi_table, pj_table, pk_table )
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)
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
529 panelid_table, pi_table, pj_table, pk_table, &
530 this%tileID_globalMap, this%tileFaceID_globalMap, this%tilePanelID_globalMap, &
531 this%LOCAL_MESH_NUM_global, nprcz_lc )
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)
542 tileid_table(n,prc) = tileid
543 this%tileID_global2localMap(tileid) = n
544 this%PRCRank_globalMap(tileid) = prc - 1
547 if ( this%PRCRank_globalMap(tileid) == lcmesh%PRC_myrank )
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
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
563 allocate( this%rcdomIJKP2LCMeshID(ilc_count,jlc_count,klc_count,plc_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
577 end subroutine meshcubedspheredom3d_assigndomid
580 subroutine meshcubedspheredom3d_coord_conv( x, y, z, xX, xY, xZ, yX, yY, yZ, zX, zY, zZ, &
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)
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))
598 xx(:) = 0.5_rp*(vx(2) - vx(1))
602 yy(:) = 0.5_rp*(vy(3) - vy(1))
606 zz(:) = 0.5_rp*(vz(5) - vz(1))
609 end subroutine meshcubedspheredom3d_coord_conv
612 subroutine meshcubedspheredom3d_calc_normal( normal_fn, &
613 Escale_f, fid_h, fid_v, 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)
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)
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)
637 end subroutine meshcubedspheredom3d_calc_normal
642 subroutine meshcubedspheredom3d_set_metric( this )
651 integer :: ke, ke2D, p
659 real(RP),
allocatable :: gam2D(:,:)
660 integer,
allocatable :: IndexH2Dto3D(:)
664 if ( this%shallow_approx )
then
667 s = 1.0_rp / this%RPlanet
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
677 allocate( gam2d(elem2d%Np,lcmesh2d%Ne) )
678 allocate( indexh2dto3d(elem%Np) )
680 indexh2dto3d(:) = elem%IndexH2Dto3D(:)
685 lcmesh2d%panelID, lcmesh2d%pos_en(:,:,1), lcmesh2d%pos_en(:,:,2), gam2d(:,:), &
686 lcmesh2d%Ne * elem2d%Np, &
687 lcmesh%lon2D(:,:), lcmesh%lat2D(:,:) )
691 lcmesh2d%pos_en(:,:,1), lcmesh2d%pos_en(:,:,2), elem2d%Np * lcmesh2d%Ne, this%RPlanet, &
692 lcmesh%G_ij, lcmesh%GIJ, lcmesh%GsqrtH )
697 do ke=lcmesh%NeS, lcmesh%NeE
698 ke2d = lcmesh%EMap3Dto2D(ke)
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)
706 call fill_halo_metric( lcmesh%Gsqrt, lcmesh%gam, lcmesh%VMapM, lcmesh%VMapP, lcmesh, lcmesh%refElem3D )
710 deallocate( gam2d, indexh2dto3d )
715 end subroutine meshcubedspheredom3d_set_metric
718 subroutine fill_halo_metric( Gsqrt, gam, vmapM, vmapP, lmesh, 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)
731 npxne = elem%Np * lmesh%Ne
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)
743 end subroutine fill_halo_metric
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.