FE-Project
Loading...
Searching...
No Matches
scale_mesh_cubedspheredom2d.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
9#include "scaleFElib.h"
11
12 !-----------------------------------------------------------------------------
13 !
14 !++ used modules
15 !
16 use scale_io
17 use scale_precision
18
19 use scale_mesh_base2d, only: &
25
26 use scale_localmesh_2d, only: &
30
31 !-----------------------------------------------------------------------------
32 implicit none
33 private
34
35 !-----------------------------------------------------------------------------
36 !
37 !++ Public type & procedure
38 !
39 type, extends(meshbase2d), public :: meshcubedspheredom2d
40 integer :: negx
41 integer :: negy
42
43 real(rp), public :: xmin_gl, xmax_gl
44 real(rp), public :: ymin_gl, ymax_gl
45 integer, allocatable :: rcdomijp2lcmeshid(:,:,:)
46
47 real(rp) :: rplanet
48 contains
49 procedure :: init => meshcubedspheredom2d_init
50 procedure :: final => meshcubedspheredom2d_final
51 procedure :: generate => meshcubedspheredom2d_generate
52 procedure :: assigndomid => meshcubedspheredom2d_assigndomid
54
57
58 !-----------------------------------------------------------------------------
59 !
60 !++ Public parameters & variables
61 !
62
63 !-----------------------------------------------------------------------------
64 !
65 !++ Private procedure
66 !
67
68 private :: meshcubedspheredom2d_calc_normal
69 private :: meshcubedspheredom2d_coord_conv
70 private :: fill_halo_metric
71
72 !-----------------------------------------------------------------------------
73 !
74 !++ Private parameters & variables
75 !
76
77contains
78 subroutine meshcubedspheredom2d_init(this, &
79 NeGX, NeGY, RPlanet, &
80 refElem, NLocalMeshPerPrc, &
81 nproc, myrank )
82
83 use scale_const, only: &
84 pi => const_pi
85 implicit none
86
87 class(meshcubedspheredom2d), intent(inout) :: this
88 integer, intent(in) :: NeGX
89 integer, intent(in) :: NeGY
90 real(RP), intent(in) :: RPlanet
91 type(quadrilateralelement), intent(in), target :: refElem
92 integer, intent(in) :: NLocalMeshPerPrc
93 integer, intent(in), optional :: nproc
94 integer, intent(in), optional :: myrank
95 !-----------------------------------------------------------------------------
96
97 this%NeGX = negx
98 this%NeGY = negy
99
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
106
107
108 call meshbase2d_init( this, refelem, nlocalmeshperprc, &
109 nproc, myrank )
110
111 call this%SetDimInfo( meshbase2d_dimtypeid_x, "x", "1", "X-coordinate" )
112 call this%SetDimInfo( meshbase2d_dimtypeid_y, "y", "1", "Y-coordinate" )
113 call this%SetDimInfo( meshbase2d_dimtypeid_xy, "xy", "1", "XY-coordinate" )
114 call this%SetDimInfo( meshbase2d_dimtypeid_xyt, "xyt", "1", "XY-coordinate" )
115
116 return
117 end subroutine meshcubedspheredom2d_init
118
119 subroutine meshcubedspheredom2d_final( this )
120 implicit none
121 class(meshcubedspheredom2d), intent(inout) :: this
122 !-----------------------------------------------------------------------------
123
124 if (this%isGenerated) then
125 if ( allocated(this%rcdomIJP2LCMeshID) ) then
126 deallocate( this%rcdomIJP2LCMeshID )
127 end if
128 end if
129
130 call meshbase2d_final( this )
131
132 return
133 end subroutine meshcubedspheredom2d_final
134
135 subroutine meshcubedspheredom2d_generate( this )
136 implicit none
137
138 class(meshcubedspheredom2d), intent(inout), target :: this
139
140 integer :: n
141 type(localmesh2d), pointer :: mesh
142
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)
147
148 integer :: NprcX_lc, NprcY_lc
149 integer :: tileID
150
151 !-----------------------------------------------------------------------------
152
154 nprcx_lc, nprcy_lc, &
155 this%PRC_NUM, this%LOCAL_MESH_NUM_global, &
156 .true. )
157
158 !--- Construct the connectivity of patches (only master node)
159
160 call this%AssignDomID( &
161 nprcx_lc, nprcy_lc, & ! (in)
162 tileid_table, panelid_table, & ! (out)
163 pi_table, pj_table ) ! (out)
164
165 do n=1, this%LOCAL_MESH_NUM
166 mesh => this%lcmesh_list(n)
167 tileid = tileid_table(n, mesh%PRC_myrank+1)
168
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 )
174
175 !---
176 ! write(*,*) "** my_rank=", mesh%PRC_myrank
177 ! write(*,*) " tileID:", mesh%tileID
178 ! write(*,*) " pnlID:", mesh%panelID, "-- i,j (within a panel)=", pi_table(tileID), pj_table(tileID)
179 ! write(*,*) " local mesh:", n, "( total", this%LOCAL_MESH_NUM, ")"
180 ! write(*,*) " panel_connect:", this%tilePanelID_globalMap(:,mesh%tileID)
181 ! write(*,*) " tile_connect:", this%tileID_globalMap(:,mesh%tileID)
182 ! write(*,*) " face_connect:", this%tileFaceID_globalMap(:,mesh%tileID)
183 ! write(*,*) " domain size"
184 ! write(*,*) " NeX, NeY:", mesh%NeX, mesh%NeY
185 ! write(*,*) " [X], [Y]:", mesh%xmin, mesh%xmax, ":", mesh%ymin, mesh%ymax
186 end do
187
188 this%isGenerated = .true.
189
190 return
191 end subroutine meshcubedspheredom2d_generate
192
194 NprcX_lc, NprcY_lc, &
195 PRC_NUM, LOCAL_MESH_NUM_global, &
196 call_prc_abort )
197
198 use scale_prc, only: prc_abort
199 implicit none
200
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
206
207 integer :: tile_num_per_panel
208 logical :: call_prc_abort_
209 !-----------------------------------------------------------------------------
210
211 if (present(call_prc_abort)) then
212 call_prc_abort_ = call_prc_abort
213 else
214 call_prc_abort_ = .false.
215 end if
216
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
220 end if
221
222 tile_num_per_panel = local_mesh_num_global / 6
223
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
228 else
229 log_error("MeshCubedSphereDom2D_division_params",*) "The number of proceses is inappropriate. Check!"
230 if (call_prc_abort_) call prc_abort
231 end if
232 else
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
239 end if
240 else
241 log_error("MeshCubedSphereDom2D_division_params",*) "The number of proceses is inappropriate. Check!"
242 if (call_prc_abort_) call prc_abort
243 end if
244 end if
245
246 return
248
250 tileID, panelID, &
251 i, j, NprcX, NprcY, &
252 dom_xmin, dom_xmax, dom_ymin, dom_ymax, planet_radius, &
253 NeX, NeY )
254
256 meshutilcubedsphere2d_genconnectivity, &
257 meshutilcubedsphere2d_genrectdomain, &
258 meshutilcubedsphere2d_buildinteriormap, &
259 meshutilcubedsphere2d_genpatchboundarymap
260
261 use scale_cubedsphere_coord_cnv, only: &
264
266
267 implicit none
268
269 type(localmesh2d), intent(inout) :: lcmesh
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
278
279 class(elementbase2d), pointer :: elem
280 real(rp) :: delx, dely
281 integer :: ke
282
283 real(rp), allocatable :: gam(:,:)
284 !-----------------------------------------------------------------------------
285
286 elem => lcmesh%refElem2D
287 lcmesh%tileID = tileid
288 lcmesh%panelID = panelid
289
290 !--
291 lcmesh%Ne = nex * ney
292 lcmesh%Nv = (nex + 1)*(ney + 1)
293 lcmesh%NeS = 1
294 lcmesh%NeE = lcmesh%Ne
295 lcmesh%NeA = lcmesh%Ne + 2*(nex + ney)
296
297 lcmesh%NeX = nex
298 lcmesh%NeY = ney
299
300 !--
301 delx = ( dom_xmax - dom_xmin ) / dble(nprcx)
302 dely = ( dom_ymax - dom_ymin ) / dble(nprcy)
303
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
308
309 !--
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) )
319
320 lcmesh%BCType(:,:) = bctype_interior
321
322 !----
323
324 call meshutilcubedsphere2d_genrectdomain( lcmesh%pos_ev, lcmesh%EToV, & ! (out)
325 lcmesh%NeX, lcmesh%xmin, lcmesh%xmax, & ! (in)
326 lcmesh%NeY, lcmesh%ymin, lcmesh%ymax ) ! (in)
327
328 !---
329 call meshbase2d_setgeometricinfo(lcmesh, meshcubedspheredom2d_coord_conv, meshcubedspheredom2d_calc_normal )
330
332 lcmesh%pos_en(:,:,1), lcmesh%pos_en(:,:,2), elem%Np * lcmesh%Ne, planet_radius, & ! (in)
333 lcmesh%G_ij, lcmesh%GIJ, lcmesh%Gsqrt(:,lcmesh%NeS:lcmesh%NeE) ) ! (out)
334
335
336 allocate( gam(elem%Np,lcmesh%Ne) )
337 gam(:,:) = 1.0_rp
338
340 lcmesh%panelID, lcmesh%pos_en(:,:,1), lcmesh%pos_en(:,:,2), gam(:,:), & ! (in)
341 lcmesh%Ne * lcmesh%refElem2D%Np, & ! (in)
342 lcmesh%lon(:,:), lcmesh%lat(:,:) ) ! (out)
343
344 !---
345
346 call meshutilcubedsphere2d_genconnectivity( lcmesh%EToE, lcmesh%EToF, & ! (out)
347 lcmesh%EToV, lcmesh%Ne, elem%Nfaces ) ! (in)
348
349 !---
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 )
354
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 )
359
360 !--
361 call fill_halo_metric( lcmesh%Gsqrt, &
362 lcmesh%VMapM, lcmesh%VMapP, lcmesh, elem )
363
364 return
366
367 !- private ------------------------------
368
369 subroutine meshcubedspheredom2d_assigndomid( this, &
370 NprcX_lc, NprcY_lc, &
371 tileID_table, panelID_table, &
372 pi_table, pj_table )
373
374 use scale_meshutil_cubedsphere2d, only: &
376
377 implicit none
378
379 class(meshcubedspheredom2d), target, intent(inout) :: this
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)
386
387 integer :: n
388 integer :: prc
389 integer :: tileid
390 integer :: is_lc, js_lc, ps_lc
391 integer :: ilc_count, jlc_count, plc_count
392 integer :: ilc, jlc, plc
393 integer :: npanel_lc
394
395 type(localmesh2d), pointer :: lcmesh
396 !-----------------------------------------------------------------------------
397
399 panelid_table, pi_table, pj_table, & ! (out)
400 this%tileID_globalMap, this%tileFaceID_globalMap, this%tilePanelID_globalMap, & ! (out)
401 this%LOCAL_MESH_NUM_global ) ! (in)
402
403 !----
404
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)
409
410 !-
411 tileid_table(n,prc) = tileid
412 this%tileID_global2localMap(tileid) = n
413 this%PRCRank_globalMap(tileid) = prc - 1
414
415 !-
416 if ( this%PRCRank_globalMap(tileid) == lcmesh%PRC_myrank ) then
417 if (n==1) 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
421 end if
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
425 end if
426 end do
427 end do
428
429 allocate( this%rcdomIJP2LCMeshID(ilc_count,jlc_count,plc_count) )
430 do plc=1, plc_count
431 do jlc=1, jlc_count
432 do ilc=1, ilc_count
433 this%rcdomIJP2LCMeshID(ilc,jlc,plc) = ilc + (jlc - 1)*ilc_count + (plc-1)*ilc_count*jlc_count
434 end do
435 end do
436 end do
437
438 return
439 end subroutine meshcubedspheredom2d_assigndomid
440
441 subroutine meshcubedspheredom2d_coord_conv( x, y, xr, xs, yr, ys, &
442 vx, vy, elem )
443
444 implicit none
445
446 type(elementbase2d), intent(in) :: elem
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)
450
451 !-------------------------------------------------
452
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))
455
456 xr(:) = 0.5_rp*(vx(2) - vx(1)) !matmul(refElem%Dx1,mesh%x1(:,n))
457 xs(:) = 0.0_rp !matmul(refElem%Dx2,mesh%x1(:,n))
458 yr(:) = 0.0_rp !matmul(refElem%Dx1,mesh%x2(:,n))
459 ys(:) = 0.5_rp*(vy(3) - vy(1)) !matmul(refElem%Dx2,mesh%x2(:,n))
460
461 return
462 end subroutine meshcubedspheredom2d_coord_conv
463
464 subroutine meshcubedspheredom2d_calc_normal( normal_fn, &
465 Escale_f, fid, elem )
466
467 implicit none
468
469 type(elementbase2d), intent(in) :: 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)
473
474 integer :: d
475 !-------------------------------------------------
476
477 do d=1, 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)
482 end do
483
484 return
485 end subroutine meshcubedspheredom2d_calc_normal
486
487 !--
488
489!OCL SERIAL
490 subroutine fill_halo_metric( Gsqrt, vmapM, vmapP, lmesh, elem )
491 implicit none
492 class(localmesh2d), intent(in) :: lmesh
493 class(elementbase2d), intent(in) :: 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)
497
498 integer :: i, im, ip
499 !------------------------------------------------
500
501 !$omp parallel do private(i, iM, iP)
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)
506 end if
507 end do
508 return
509 end subroutine fill_halo_metric
510
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)