43 real(rp),
public :: xmin_gl, xmax_gl
44 real(rp),
public :: ymin_gl, ymax_gl
45 integer,
allocatable :: rcdomijp2lcmeshid(:,:,:)
50 procedure :: final => meshcubedspheredom2d_final
51 procedure :: generate => meshcubedspheredom2d_generate
52 procedure :: assigndomid => meshcubedspheredom2d_assigndomid
68 private :: meshcubedspheredom2d_calc_normal
69 private :: meshcubedspheredom2d_coord_conv
70 private :: fill_halo_metric
79 NeGX, NeGY, RPlanet, &
80 refElem, NLocalMeshPerPrc, &
83 use scale_const,
only: &
88 integer,
intent(in) :: NeGX
89 integer,
intent(in) :: NeGY
90 real(RP),
intent(in) :: RPlanet
92 integer,
intent(in) :: NLocalMeshPerPrc
93 integer,
intent(in),
optional :: nproc
94 integer,
intent(in),
optional :: myrank
100 this%xmin_gl = - 0.25_rp * pi
101 this%xmax_gl = + 0.25_rp * pi
102 this%ymin_gl = - 0.25_rp * pi
103 this%ymax_gl = + 0.25_rp * pi
104 this%RPlanet = rplanet
105 this%dom_vol = 4.0_rp * pi * rplanet**2
119 subroutine meshcubedspheredom2d_final( this )
124 if (this%isGenerated)
then
125 if (
allocated(this%rcdomIJP2LCMeshID) )
then
126 deallocate( this%rcdomIJP2LCMeshID )
133 end subroutine meshcubedspheredom2d_final
135 subroutine meshcubedspheredom2d_generate( this )
143 integer :: tileID_table(this%LOCAL_MESH_NUM, this%PRC_NUM)
144 integer :: panelID_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
145 integer :: pi_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
146 integer :: pj_table(this%LOCAL_MESH_NUM*this%PRC_NUM)
148 integer :: NprcX_lc, NprcY_lc
154 nprcx_lc, nprcy_lc, &
155 this%PRC_NUM, this%LOCAL_MESH_NUM_global, &
160 call this%AssignDomID( &
161 nprcx_lc, nprcy_lc, &
162 tileid_table, panelid_table, &
165 do n=1, this%LOCAL_MESH_NUM
166 mesh => this%lcmesh_list(n)
167 tileid = tileid_table(n, mesh%PRC_myrank+1)
170 tileid, panelid_table(tileid), &
171 pi_table(tileid), pj_table(tileid), nprcx_lc, nprcy_lc, &
172 this%xmin_gl, this%xmax_gl, this%ymin_gl, this%ymax_gl, this%RPlanet, &
173 this%NeGX/nprcx_lc, this%NeGY/nprcy_lc )
188 this%isGenerated = .true.
191 end subroutine meshcubedspheredom2d_generate
194 NprcX_lc, NprcY_lc, &
195 PRC_NUM, LOCAL_MESH_NUM_global, &
198 use scale_prc,
only: prc_abort
201 integer,
intent(in) :: prc_num
202 integer,
intent(in) :: local_mesh_num_global
203 integer,
intent(out) :: nprcx_lc
204 integer,
intent(out) :: nprcy_lc
205 logical,
intent(in),
optional :: call_prc_abort
207 integer :: tile_num_per_panel
208 logical :: call_prc_abort_
211 if (
present(call_prc_abort))
then
212 call_prc_abort_ = call_prc_abort
214 call_prc_abort_ = .false.
217 if ( mod(local_mesh_num_global, 6) /= 0 )
then
218 log_error(
"MeshCubedSphereDom2D_division_params",*)
"The total number of local mesh must be a multiple of 6. Check!"
219 if (call_prc_abort_)
call prc_abort
222 tile_num_per_panel = local_mesh_num_global / 6
224 if ( prc_num <= 6 )
then
225 if ( ( prc_num == 1 ) .or. &
226 ( prc_num <= 6 .and. (mod(prc_num,2)==0 .or. mod(prc_num,3)==0)) )
then
227 nprcx_lc = 1; nprcy_lc = 1
229 log_error(
"MeshCubedSphereDom2D_division_params",*)
"The number of proceses is inappropriate. Check!"
230 if (call_prc_abort_)
call prc_abort
233 if ( mod(prc_num,6) == 0 )
then
234 nprcx_lc = int(sqrt(dble(tile_num_per_panel)))
235 nprcy_lc = tile_num_per_panel / nprcx_lc
236 if ( nprcx_lc /= nprcy_lc )
then
237 log_error(
"MeshCubedSphereDom2D_division_params",*)
"The number of proceses is inappropriate. Check!"
238 if (call_prc_abort_)
call prc_abort
241 log_error(
"MeshCubedSphereDom2D_division_params",*)
"The number of proceses is inappropriate. Check!"
242 if (call_prc_abort_)
call prc_abort
251 i, j, NprcX, NprcY, &
252 dom_xmin, dom_xmax, dom_ymin, dom_ymax, planet_radius, &
256 meshutilcubedsphere2d_genconnectivity, &
257 meshutilcubedsphere2d_genrectdomain, &
258 meshutilcubedsphere2d_buildinteriormap, &
259 meshutilcubedsphere2d_genpatchboundarymap
270 integer,
intent(in) :: tileid
271 integer,
intent(in) :: panelid
272 integer,
intent(in) :: i, j
273 integer,
intent(in) :: nprcx, nprcy
274 real(rp),
intent(in) :: dom_xmin, dom_xmax
275 real(rp),
intent(in) :: dom_ymin, dom_ymax
276 real(rp),
intent(in) :: planet_radius
277 integer,
intent(in) :: nex, ney
280 real(rp) :: delx, dely
283 real(rp),
allocatable :: gam(:,:)
286 elem => lcmesh%refElem2D
287 lcmesh%tileID = tileid
288 lcmesh%panelID = panelid
291 lcmesh%Ne = nex * ney
292 lcmesh%Nv = (nex + 1)*(ney + 1)
294 lcmesh%NeE = lcmesh%Ne
295 lcmesh%NeA = lcmesh%Ne + 2*(nex + ney)
301 delx = ( dom_xmax - dom_xmin ) / dble(nprcx)
302 dely = ( dom_ymax - dom_ymin ) / dble(nprcy)
304 lcmesh%xmin = dom_xmin + (i-1)*delx
305 lcmesh%xmax = dom_xmin + i *delx
306 lcmesh%ymin = dom_ymin + (j-1)*dely
307 lcmesh%ymax = dom_ymin + j *dely
310 allocate( lcmesh%pos_ev(lcmesh%Nv,2) )
311 allocate( lcmesh%EToV(lcmesh%Ne,elem%Nv) )
312 allocate( lcmesh%EToE(lcmesh%Ne,elem%Nfaces) )
313 allocate( lcmesh%EToF(lcmesh%Ne,elem%Nfaces) )
314 allocate( lcmesh%BCType(lcmesh%refElem%Nfaces,lcmesh%Ne) )
315 allocate( lcmesh%VMapM(elem%NfpTot, lcmesh%Ne) )
316 allocate( lcmesh%VMapP(elem%NfpTot, lcmesh%Ne) )
317 allocate( lcmesh%MapM(elem%NfpTot, lcmesh%Ne) )
318 allocate( lcmesh%MapP(elem%NfpTot, lcmesh%Ne) )
324 call meshutilcubedsphere2d_genrectdomain( lcmesh%pos_ev, lcmesh%EToV, &
325 lcmesh%NeX, lcmesh%xmin, lcmesh%xmax, &
326 lcmesh%NeY, lcmesh%ymin, lcmesh%ymax )
332 lcmesh%pos_en(:,:,1), lcmesh%pos_en(:,:,2), elem%Np * lcmesh%Ne, planet_radius, &
333 lcmesh%G_ij, lcmesh%GIJ, lcmesh%Gsqrt(:,lcmesh%NeS:lcmesh%NeE) )
336 allocate( gam(elem%Np,lcmesh%Ne) )
340 lcmesh%panelID, lcmesh%pos_en(:,:,1), lcmesh%pos_en(:,:,2), gam(:,:), &
341 lcmesh%Ne * lcmesh%refElem2D%Np, &
342 lcmesh%lon(:,:), lcmesh%lat(:,:) )
346 call meshutilcubedsphere2d_genconnectivity( lcmesh%EToE, lcmesh%EToF, &
347 lcmesh%EToV, lcmesh%Ne, elem%Nfaces )
350 call meshutilcubedsphere2d_buildinteriormap( &
351 lcmesh%VmapM, lcmesh%VMapP, lcmesh%MapM, lcmesh%MapP, &
352 lcmesh%pos_en, lcmesh%pos_ev, lcmesh%EToE, lcmesh%EtoF, lcmesh%EtoV, &
353 elem%Fmask, lcmesh%Ne, elem%Np, elem%Nfp, elem%Nfaces, lcmesh%Nv )
355 call meshutilcubedsphere2d_genpatchboundarymap( &
356 lcmesh%VMapB, lcmesh%MapB, lcmesh%VMapP, &
357 lcmesh%pos_en, lcmesh%xmin, lcmesh%xmax, lcmesh%ymin, lcmesh%ymax, &
358 elem%Fmask, lcmesh%Ne, elem%Np, elem%Nfp, elem%Nfaces, lcmesh%Nv )
361 call fill_halo_metric( lcmesh%Gsqrt, &
362 lcmesh%VMapM, lcmesh%VMapP, lcmesh, elem )
369 subroutine meshcubedspheredom2d_assigndomid( this, &
370 NprcX_lc, NprcY_lc, &
371 tileID_table, panelID_table, &
380 integer,
intent(in) :: nprcx_lc
381 integer,
intent(in) :: nprcy_lc
382 integer,
intent(out) :: tileid_table(this%local_mesh_num, this%prc_num)
383 integer,
intent(out) :: panelid_table(this%local_mesh_num*this%prc_num)
384 integer,
intent(out) :: pi_table(this%local_mesh_num*this%prc_num)
385 integer,
intent(out) :: pj_table(this%local_mesh_num*this%prc_num)
390 integer :: is_lc, js_lc, ps_lc
391 integer :: ilc_count, jlc_count, plc_count
392 integer :: ilc, jlc, plc
399 panelid_table, pi_table, pj_table, &
400 this%tileID_globalMap, this%tileFaceID_globalMap, this%tilePanelID_globalMap, &
401 this%LOCAL_MESH_NUM_global )
405 do prc=1, this%PRC_NUM
406 do n=1, this%LOCAL_MESH_NUM
407 tileid = n + (prc-1)*this%LOCAL_MESH_NUM
408 lcmesh => this%lcmesh_list(n)
411 tileid_table(n,prc) = tileid
412 this%tileID_global2localMap(tileid) = n
413 this%PRCRank_globalMap(tileid) = prc - 1
416 if ( this%PRCRank_globalMap(tileid) == lcmesh%PRC_myrank )
then
418 is_lc = pi_table(tileid); ilc_count = 1
419 js_lc = pj_table(tileid); jlc_count = 1
420 ps_lc = panelid_table(tileid); plc_count = 1
422 if(is_lc < pi_table(tileid)) ilc_count = ilc_count + 1
423 if(js_lc < pj_table(tileid)) jlc_count = jlc_count + 1
424 if(ps_lc < panelid_table(tileid)) plc_count = plc_count + 1
429 allocate( this%rcdomIJP2LCMeshID(ilc_count,jlc_count,plc_count) )
433 this%rcdomIJP2LCMeshID(ilc,jlc,plc) = ilc + (jlc - 1)*ilc_count + (plc-1)*ilc_count*jlc_count
439 end subroutine meshcubedspheredom2d_assigndomid
441 subroutine meshcubedspheredom2d_coord_conv( x, y, xr, xs, yr, ys, &
447 real(rp),
intent(out) :: x(elem%np), y(elem%np)
448 real(rp),
intent(out) :: xr(elem%np), xs(elem%np), yr(elem%np), ys(elem%np)
449 real(rp),
intent(in) :: vx(elem%nv), vy(elem%nv)
453 x(:) = vx(1) + 0.5_rp*(elem%x1(:) + 1.0_rp)*(vx(2) - vx(1))
454 y(:) = vy(1) + 0.5_rp*(elem%x2(:) + 1.0_rp)*(vy(3) - vy(1))
456 xr(:) = 0.5_rp*(vx(2) - vx(1))
459 ys(:) = 0.5_rp*(vy(3) - vy(1))
462 end subroutine meshcubedspheredom2d_coord_conv
464 subroutine meshcubedspheredom2d_calc_normal( normal_fn, &
465 Escale_f, fid, elem )
470 real(rp),
intent(out) :: normal_fn(elem%nfptot,2)
471 integer,
intent(in) :: fid(elem%nfp,elem%nfaces)
472 real(rp),
intent(in) :: escale_f(elem%nfptot,2,2)
478 normal_fn(fid(:,1),d) = - escale_f(fid(:,1),2,d)
479 normal_fn(fid(:,2),d) = + escale_f(fid(:,2),1,d)
480 normal_fn(fid(:,3),d) = + escale_f(fid(:,3),2,d)
481 normal_fn(fid(:,4),d) = - escale_f(fid(:,4),1,d)
485 end subroutine meshcubedspheredom2d_calc_normal
490 subroutine fill_halo_metric( Gsqrt, vmapM, vmapP, lmesh, elem )
494 integer,
intent(in) :: vmapm(elem%nfptot*lmesh%ne)
495 integer,
intent(in) :: vmapp(elem%nfptot*lmesh%ne)
496 real(rp),
intent(inout) :: gsqrt(elem%np*lmesh%nea)
502 do i=1, elem%NfpTot*lmesh%Ne
503 im = vmapm(i); ip = vmapp(i)
504 if ( ip > elem%Np * lmesh%Ne )
then
505 gsqrt(ip) = gsqrt(im)
509 end subroutine fill_halo_metric
511end module scale_mesh_cubedspheredom2d
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 / 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)
subroutine, public meshbase2d_init(this, refelem, nlocalmeshperprc, nprocs, myrank)
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)