45 real(rp),
public :: xmin_gl
46 real(rp),
public :: xmax_gl
47 real(rp),
public :: ymin_gl
48 real(rp),
public :: ymax_gl
50 integer,
allocatable :: rcdomijp2lcmeshid(:,:,:)
53 integer :: halosize_1d
56 procedure :: final => meshcubedspheredom2d_final
57 procedure :: generate => meshcubedspheredom2d_generate
58 procedure :: assigndomid => meshcubedspheredom2d_assigndomid
74 private :: meshcubedspheredom2d_calc_normal
75 private :: meshcubedspheredom2d_coord_conv
76 private :: fill_halo_metric
85 NeGX, NeGY, RPlanet, &
86 refElem, NLocalMeshPerPrc, &
89 use scale_const,
only: &
94 integer,
intent(in) :: NeGX
95 integer,
intent(in) :: NeGY
96 real(RP),
intent(in) :: RPlanet
98 integer,
intent(in) :: NLocalMeshPerPrc
99 integer,
intent(in),
optional :: nproc
100 integer,
intent(in),
optional :: myrank
106 this%xmin_gl = - 0.25_rp * pi
107 this%xmax_gl = + 0.25_rp * pi
108 this%ymin_gl = - 0.25_rp * pi
109 this%ymax_gl = + 0.25_rp * pi
110 this%RPlanet = rplanet
111 this%dom_vol = 4.0_rp * pi * rplanet**2
125 subroutine meshcubedspheredom2d_final( this )
130 if (this%isGenerated)
then
131 if (
allocated(this%rcdomIJP2LCMeshID) )
then
133 deallocate( this%rcdomIJP2LCMeshID )
140 end subroutine meshcubedspheredom2d_final
142 subroutine meshcubedspheredom2d_generate( this )
150 integer :: tileID_table(this%LOCAL_MESH_NUM, this%PRC_NUM)
151 integer :: panelID_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
152 integer :: pi_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
153 integer :: pj_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
155 integer :: NprcX_lc, NprcY_lc
161 nprcx_lc, nprcy_lc, &
162 this%PRC_NUM, this%LOCAL_MESH_NUM_global, &
167 call this%AssignDomID( &
168 nprcx_lc, nprcy_lc, &
169 tileid_table, panelid_table, &
172 do n=1, this%LOCAL_MESH_NUM
173 mesh => this%lcmesh_list(n)
174 tileid = tileid_table(n, mesh%PRC_myrank+1)
177 tileid, panelid_table(tileid), &
178 pi_table(tileid), pj_table(tileid), nprcx_lc, nprcy_lc, &
179 this%xmin_gl, this%xmax_gl, this%ymin_gl, this%ymax_gl, this%RPlanet, &
180 this%NeGX/nprcx_lc, this%NeGY/nprcy_lc )
195 this%isGenerated = .true.
198 end subroutine meshcubedspheredom2d_generate
201 NprcX_lc, NprcY_lc, &
202 PRC_NUM, LOCAL_MESH_NUM_global, &
205 use scale_prc,
only: prc_abort
208 integer,
intent(in) :: prc_num
209 integer,
intent(in) :: local_mesh_num_global
210 integer,
intent(out) :: nprcx_lc
211 integer,
intent(out) :: nprcy_lc
212 logical,
intent(in),
optional :: call_prc_abort
214 integer :: tile_num_per_panel
215 logical :: call_prc_abort_
218 if (
present(call_prc_abort))
then
219 call_prc_abort_ = call_prc_abort
221 call_prc_abort_ = .false.
224 if ( mod(local_mesh_num_global, 6) /= 0 )
then
225 log_error(
"MeshCubedSphereDom2D_division_params",*)
"The total number of local mesh must be a multiple of 6. Check!"
226 if (call_prc_abort_)
call prc_abort
229 tile_num_per_panel = local_mesh_num_global / 6
231 if ( prc_num <= 6 )
then
232 if ( ( prc_num == 1 ) .or. &
233 ( prc_num <= 6 .and. (mod(prc_num,2)==0 .or. mod(prc_num,3)==0)) )
then
234 nprcx_lc = 1; nprcy_lc = 1
236 log_error(
"MeshCubedSphereDom2D_division_params",*)
"The number of proceses is inappropriate. Check!"
237 if (call_prc_abort_)
call prc_abort
240 if ( mod(prc_num,6) == 0 )
then
241 nprcx_lc = int(sqrt(dble(tile_num_per_panel)))
242 nprcy_lc = tile_num_per_panel / nprcx_lc
243 if ( nprcx_lc /= nprcy_lc )
then
244 log_error(
"MeshCubedSphereDom2D_division_params",*)
"The number of proceses is inappropriate. Check!"
245 if (call_prc_abort_)
call prc_abort
248 log_error(
"MeshCubedSphereDom2D_division_params",*)
"The number of proceses is inappropriate. Check!"
249 if (call_prc_abort_)
call prc_abort
258 i, j, NprcX, NprcY, &
259 dom_xmin, dom_xmax, dom_ymin, dom_ymax, planet_radius, &
263 meshutilcubedsphere2d_genconnectivity, &
264 meshutilcubedsphere2d_genrectdomain, &
265 meshutilcubedsphere2d_buildinteriormap, &
266 meshutilcubedsphere2d_genpatchboundarymap
277 integer,
intent(in) :: tileid
278 integer,
intent(in) :: panelid
279 integer,
intent(in) :: i, j
280 integer,
intent(in) :: nprcx, nprcy
281 real(rp),
intent(in) :: dom_xmin, dom_xmax
282 real(rp),
intent(in) :: dom_ymin, dom_ymax
283 real(rp),
intent(in) :: planet_radius
284 integer,
intent(in) :: nex, ney
287 real(rp) :: delx, dely
290 real(rp),
allocatable :: gam(:,:)
293 elem => lcmesh%refElem2D
295 lcmesh%tileID = tileid
296 lcmesh%panelID = panelid
300 lcmesh%Ne = nex * ney
301 lcmesh%Nv = (nex + 1)*(ney + 1)
303 lcmesh%NeE = lcmesh%Ne
304 lcmesh%NeA = lcmesh%Ne + 2*(nex + ney)
312 delx = ( dom_xmax - dom_xmin ) / dble(nprcx)
313 dely = ( dom_ymax - dom_ymin ) / dble(nprcy)
315 lcmesh%xmin = dom_xmin + (i-1)*delx
316 lcmesh%xmax = dom_xmin + i *delx
317 lcmesh%ymin = dom_ymin + (j-1)*dely
318 lcmesh%ymax = dom_ymin + j *dely
322 allocate( lcmesh%pos_ev(lcmesh%Nv,2) )
323 allocate( lcmesh%EToV(lcmesh%Ne,elem%Nv) )
324 allocate( lcmesh%EToE(lcmesh%Ne,elem%Nfaces) )
325 allocate( lcmesh%EToF(lcmesh%Ne,elem%Nfaces) )
326 allocate( lcmesh%BCType(lcmesh%refElem%Nfaces,lcmesh%Ne) )
327 allocate( lcmesh%VMapM(elem%NfpTot, lcmesh%Ne) )
328 allocate( lcmesh%VMapP(elem%NfpTot, lcmesh%Ne) )
329 allocate( lcmesh%MapM(elem%NfpTot, lcmesh%Ne) )
330 allocate( lcmesh%MapP(elem%NfpTot, lcmesh%Ne) )
339 call meshutilcubedsphere2d_genrectdomain( lcmesh%pos_ev, lcmesh%EToV, &
340 lcmesh%NeX, lcmesh%xmin, lcmesh%xmax, &
341 lcmesh%NeY, lcmesh%ymin, lcmesh%ymax )
348 lcmesh%pos_en(:,:,1), lcmesh%pos_en(:,:,2), elem%Np * lcmesh%Ne, planet_radius, &
349 lcmesh%G_ij, lcmesh%GIJ, lcmesh%Gsqrt(:,lcmesh%NeS:lcmesh%NeE) )
352 allocate( gam(elem%Np,lcmesh%Ne) )
357 lcmesh%panelID, lcmesh%pos_en(:,:,1), lcmesh%pos_en(:,:,2), gam(:,:), &
358 lcmesh%Ne * lcmesh%refElem2D%Np, &
359 lcmesh%lon(:,:), lcmesh%lat(:,:) )
366 call meshutilcubedsphere2d_genconnectivity( lcmesh%EToE, lcmesh%EToF, &
367 lcmesh%EToV, lcmesh%Ne, elem%Nfaces )
371 call meshutilcubedsphere2d_buildinteriormap( &
372 lcmesh%VmapM, lcmesh%VMapP, lcmesh%MapM, lcmesh%MapP, &
373 lcmesh%pos_en, lcmesh%pos_ev, lcmesh%EToE, lcmesh%EtoF, lcmesh%EtoV, &
374 elem%Fmask, lcmesh%Ne, elem%Np, elem%Nfp, elem%Nfaces, lcmesh%Nv )
376 call meshutilcubedsphere2d_genpatchboundarymap( &
377 lcmesh%VMapB, lcmesh%MapB, lcmesh%VMapP, &
378 lcmesh%pos_en, lcmesh%xmin, lcmesh%xmax, lcmesh%ymin, lcmesh%ymax, &
379 elem%Fmask, lcmesh%Ne, elem%Np, elem%Nfp, elem%Nfaces, lcmesh%Nv )
384 call fill_halo_metric( lcmesh%Gsqrt, &
385 lcmesh%VMapM, lcmesh%VMapP, lcmesh, elem )
393 subroutine meshcubedspheredom2d_assigndomid( this, &
394 NprcX_lc, NprcY_lc, &
395 tileID_table, panelID_table, &
404 integer,
intent(in) :: nprcx_lc
405 integer,
intent(in) :: nprcy_lc
406 integer,
intent(out) :: tileid_table(this%local_mesh_num, this%prc_num)
407 integer,
intent(out) :: panelid_table(this%local_mesh_num*this%prc_num)
408 integer,
intent(out) :: pi_table(this%local_mesh_num*this%prc_num)
409 integer,
intent(out) :: pj_table(this%local_mesh_num*this%prc_num)
414 integer :: is_lc, js_lc, ps_lc
415 integer :: ilc_count, jlc_count, plc_count
416 integer :: ilc, jlc, plc
423 panelid_table, pi_table, pj_table, &
424 this%tileID_globalMap, this%tileFaceID_globalMap, this%tilePanelID_globalMap, &
425 this%LOCAL_MESH_NUM_global )
430 do prc=1, this%PRC_NUM
431 do n=1, this%LOCAL_MESH_NUM
432 tileid = n + (prc-1)*this%LOCAL_MESH_NUM
433 lcmesh => this%lcmesh_list(n)
436 tileid_table(n,prc) = tileid
437 this%tileID_global2localMap(tileid) = n
438 this%PRCRank_globalMap(tileid) = prc - 1
441 if ( this%PRCRank_globalMap(tileid) == lcmesh%PRC_myrank )
then
443 is_lc = pi_table(tileid); ilc_count = 1
444 js_lc = pj_table(tileid); jlc_count = 1
445 ps_lc = panelid_table(tileid); plc_count = 1
447 if(is_lc < pi_table(tileid)) ilc_count = ilc_count + 1
448 if(js_lc < pj_table(tileid)) jlc_count = jlc_count + 1
449 if(ps_lc < panelid_table(tileid)) plc_count = plc_count + 1
455 allocate( this%rcdomIJP2LCMeshID(ilc_count,jlc_count,plc_count) )
459 this%rcdomIJP2LCMeshID(ilc,jlc,plc) = ilc + (jlc - 1)*ilc_count + (plc-1)*ilc_count*jlc_count
466 end subroutine meshcubedspheredom2d_assigndomid
468 subroutine meshcubedspheredom2d_coord_conv( x, y, xr, xs, yr, ys, &
474 real(rp),
intent(out) :: x(elem%np), y(elem%np)
475 real(rp),
intent(out) :: xr(elem%np), xs(elem%np), yr(elem%np), ys(elem%np)
476 real(rp),
intent(in) :: vx(elem%nv), vy(elem%nv)
480 x(:) = vx(1) + 0.5_rp*(elem%x1(:) + 1.0_rp)*(vx(2) - vx(1))
481 y(:) = vy(1) + 0.5_rp*(elem%x2(:) + 1.0_rp)*(vy(3) - vy(1))
483 xr(:) = 0.5_rp*(vx(2) - vx(1))
486 ys(:) = 0.5_rp*(vy(3) - vy(1))
489 end subroutine meshcubedspheredom2d_coord_conv
491 subroutine meshcubedspheredom2d_calc_normal( normal_fn, &
492 Escale_f, fid, elem )
497 real(rp),
intent(out) :: normal_fn(elem%nfptot,2)
498 integer,
intent(in) :: fid(elem%nfp,elem%nfaces)
499 real(rp),
intent(in) :: escale_f(elem%nfptot,2,2)
505 normal_fn(fid(:,1),d) = - escale_f(fid(:,1),2,d)
506 normal_fn(fid(:,2),d) = + escale_f(fid(:,2),1,d)
507 normal_fn(fid(:,3),d) = + escale_f(fid(:,3),2,d)
508 normal_fn(fid(:,4),d) = - escale_f(fid(:,4),1,d)
512 end subroutine meshcubedspheredom2d_calc_normal
517 subroutine fill_halo_metric( Gsqrt, vmapM, vmapP, lmesh, elem )
521 integer,
intent(in) :: vmapm(elem%nfptot*lmesh%ne)
522 integer,
intent(in) :: vmapp(elem%nfptot*lmesh%ne)
523 real(rp),
intent(inout) :: gsqrt(elem%np*lmesh%nea)
529 npxne = elem%Np * lmesh%Ne
533 do i=1, elem%NfpTot*lmesh%Ne
534 im = vmapm(i); ip = vmapp(i)
535 if ( ip > npxne )
then
536 gsqrt(ip) = gsqrt(im)
540 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 / Quadrilateral
module FElib / Mesh / Local 2D
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)
integer, public meshbase2d_dimtypeid_xy
integer, public meshbase2d_dimtypeid_xyt
integer, public meshbase2d_dimtypeid_x
integer, public meshbase2d_dimtype_num
integer, public meshbase2d_dimtypeid_y
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)
subroutine meshcubedspheredom2d_init(this, negx, negy, rplanet, refelem, nlocalmeshperprc, nproc, myrank)
module FElib / Mesh / utility for 2D cubed-sphere mesh
subroutine, public meshutilcubedsphere2d_buildglobalmap(panelid_table, pi_table, pj_table, tileid_map, tilefaceid_map, tilepanelid_map, ntile)
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 to manage a cubed-sphere 2D computational domain.