FE-Project
Loading...
Searching...
No Matches
scale_meshutil_cubedsphere2d.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Mesh / utility for 2D cubed-sphere mesh
3!!
4!! @par Description
5!! A module useful for generating 2D cubed-sphere mesh
6!!
7!! @author Yuta Kawai, Team SCALE
8!<
9!-------------------------------------------------------------------------------
10#include "scaleFElib.h"
12 !-----------------------------------------------------------------------------
13 !
14 !++ used modules
15 !
16 use scale_const, only: &
17 pi => const_pi, &
18 eps => const_eps
19 use scale_precision
20 use scale_prc
21 use scale_io
22 use scale_prc
23
24 use scale_meshutil_2d, only: &
25 meshutilcubedsphere2d_genrectdomain => meshutil2d_genrectdomain, &
26 meshutilcubedsphere2d_genconnectivity => meshutil2d_genconnectivity, &
27 meshutilcubedsphere2d_buildinteriormap => meshutil2d_buildinteriormap, &
28 meshutilcubedsphere2d_genpatchboundarymap => meshutil2d_genpatchboundarymap, &
29 meshutilcubedsphere2d_genpatchboundarymap_wide => meshutil2d_genpatchboundarymap_wide
30
31 !-----------------------------------------------------------------------------
32 implicit none
33 private
34
35 !-----------------------------------------------------------------------------
36 !
37 !++ Public procedure
38 !
39 public :: meshutilcubedsphere2d_genrectdomain
40 public :: meshutilcubedsphere2d_genconnectivity
41 public :: meshutilcubedsphere2d_buildinteriormap
43 public :: meshutilcubedsphere2d_genpatchboundarymap
44 public :: meshutilcubedsphere2d_genpatchboundarymap_wide
48
49contains
50!OCL SERIAL
52 panelID_table, pi_table, pj_table, &
53 tileID_map, tileFaceID_map, tilePanelID_map, &
54 Ntile )
55
56 use scale_meshutil_2d, only: &
58 implicit none
59
60 integer, intent(in) :: ntile
61 integer, intent(out) :: panelid_table(ntile)
62 integer, intent(out) :: pi_table(ntile)
63 integer, intent(out) :: pj_table(ntile)
64 integer, intent(out) :: tileid_map(4,ntile)
65 integer, intent(out) :: tilefaceid_map(4,ntile)
66 integer, intent(out) :: tilepanelid_map(4,ntile)
67
68 integer :: ntileperpanel
69 integer :: nex, ney, nvx, nvy
70 integer, allocatable :: nodesid_2d(:,:,:)
71 integer, allocatable :: etov(:,:)
72 integer, allocatable :: etoe(:,:)
73 integer, allocatable :: etof(:,:)
74 integer :: i, j, k, f
75 integer :: panelid
76 integer :: tileid, tileid_r
77 integer :: counter
78 !-----------------------------------------------------------------------------
79
80 ntileperpanel = ntile / 6
81 ney = int( sqrt(dble(ntileperpanel)) )
82 nex = ntileperpanel/ney
83 nvx = nex + 1
84 nvy = ney + 1
85 allocate( nodesid_2d(nvx,nvy,6) )
86 allocate( etov(ntile,4), etoe(ntile,4), etof(ntile,4) )
87
88 counter = 0
89 do panelid = 1, 6
90 do j = 1, nvy
91 do i = 1, nvx
92 counter = counter + 1
93 nodesid_2d(i,j,panelid) = counter
94 end do
95 end do
96 end do
97
98 !----
99
100 tileid = 0
101 do panelid = 1, 6
102 do j = 1, ney
103 do i = 1, nex
104 tileid = tileid + 1
105 panelid_table(tileid) = panelid
106 pi_table(tileid) = i; pj_table(tileid) = j;
107 etov(tileid,:) = (/ nodesid_2d(i,j ,panelid), nodesid_2d(i+1,j ,panelid), &
108 nodesid_2d(i,j+1,panelid), nodesid_2d(i+1,j+1,panelid) /)
109 end do
110 end do
111 end do
112
113 call meshutil2d_genconnectivity( etoe, etof, &
114 etov, ntile, 4 )
115 tileid_map(:,:) = transpose(etoe)
116 tilefaceid_map(:,:) = transpose(etof)
117
118 do tileid=1, ntile
119 do f=1, 4
120 tileid_r = tileid_map(f,tileid)
121 tilepanelid_map(f,tileid) = panelid_table(tileid_r)
122 end do
123 end do
124
126 tilepanelid_map, tileid_map, tilefaceid_map, & ! (inout)
127 panelid_table, pi_table, pj_table, nex, ney, ntile, 4 ) ! (in)
128
129 return
131
132 !----
133 !> Modify the mesh connectivity with a cubic domain decomposition to support the cubed sphere mesh
134!OCL SERIAL
135 subroutine meshutilcubedsphere2d_modifyconnectivity( tilePanelID_map, tileID_map, tileFaceID_map, &
136 panelID_table, pi_table, pj_table, NeX, NeY, Ntile, Nface )
137
138 integer, intent(in) :: ntile
139 integer, intent(in) :: nface
140 integer, intent(inout) :: tileid_map(nface,ntile)
141 integer, intent(inout) :: tilefaceid_map(nface,ntile)
142 integer, intent(inout) :: tilepanelid_map(nface,ntile)
143 integer, intent(in) :: panelid_table(ntile)
144 integer, intent(in) :: pi_table(ntile)
145 integer, intent(in) :: pj_table(ntile)
146 integer, intent(in) :: nex, ney
147
148 integer :: panel_connectivity(4,6)
149 integer :: face_connectivity (4,6)
150
151 integer :: tileid
152 integer :: panelid
153 integer :: f
154 integer :: pi_, pj_
155 !-----------------------------------------------------------------------------
156
158 panel_connectivity, face_connectivity )
159
160
161 do tileid=1, ntile
162 panelid = panelid_table(tileid)
163
164 do f=1, 4
165 if ( tilefaceid_map(f,tileid) /= f ) cycle ! Does the face correspond the boundary of panel of cubed sphere?
166
167 pi_ = pi_table(tileid)
168 pj_ = pj_table(tileid)
169
170 select case( panelid )
171 case ( 1 )
172 if ( mod(f,2) == 0 ) then ! West / East
173 if ( pi_table(tileid) == 1 ) pi_ = nex
174 if ( pi_table(tileid) == nex ) pi_ = 1
175 else ! North / South
176 if ( pj_table(tileid) == 1 ) pj_ = ney
177 if ( pj_table(tileid) == ney ) pj_ = 1
178 end if
179 case ( 2 )
180 if ( mod(f,2) == 0 ) then ! West / East
181 if ( pi_table(tileid) == 1 ) pi_ = nex
182 if ( pi_table(tileid) == nex ) pi_ = 1
183 else ! North / South
184 if ( pj_table(tileid) == 1 ) then
185 pi_ = nex; pj_ = ney - pi_table(tileid) + 1
186 end if
187 if ( pj_table(tileid) == ney ) then
188 pi_ = nex ; pj_ = pi_table(tileid)
189 end if
190 end if
191 case ( 3 )
192 if ( mod(f,2) == 0 ) then ! West / East
193 if ( pi_table(tileid) == 1 ) pi_ = nex
194 if ( pi_table(tileid) == nex ) pi_ = 1
195 else ! North / South
196 if ( pj_table(tileid) == 1 ) then
197 pi_ = nex - pi_table(tileid) + 1; pj_ = 1
198 end if
199 if ( pj_table(tileid) == ney ) then
200 pi_ = nex - pi_table(tileid) + 1; pj_ = ney
201 end if
202 end if
203 case ( 4 )
204 if ( mod(f,2) == 0 ) then ! West / East
205 if ( pi_table(tileid) == 1 ) pi_ = nex
206 if ( pi_table(tileid) == nex ) pi_ = 1
207 else ! North / South
208 if ( pj_table(tileid) == 1 ) then
209 pi_ = 1; pj_ = pi_table(tileid)
210 end if
211 if ( pj_table(tileid) == ney ) then
212 pi_ = 1; pj_ = ney - pi_table(tileid) + 1;
213 end if
214 end if
215 case ( 5 )
216 pj_ = ney
217 if ( mod(f,2) == 0 ) then
218 if ( pi_table(tileid) == 1 ) pi_ = ney - pj_table(tileid) + 1 ! West
219 if ( pi_table(tileid) == nex ) pi_ = pj_table(tileid) ! East
220 else
221 if ( pj_table(tileid) == 1 ) pi_ = pi_table(tileid) ! South
222 if ( pj_table(tileid) == ney ) pi_ = nex - pi_table(tileid) + 1 ! North
223 end if
224 case ( 6 )
225 pj_ = 1
226 if ( mod(f,2) == 0 ) then
227 if ( pi_table(tileid) == 1 ) pi_ = pj_table(tileid) ! West
228 if ( pi_table(tileid) == nex ) pi_ = ney - pj_table(tileid) + 1 ! East
229 else
230 if ( pj_table(tileid) == 1 ) pi_ = nex - pi_table(tileid) + 1 ! South
231 if ( pj_table(tileid) == ney ) pi_ = pi_table(tileid) ! North
232 end if
233 end select
234
235 tilepanelid_map(f,tileid) = panel_connectivity(f,panelid)
236 tileid_map(f,tileid) = pi_ + (pj_ - 1) * nex + (tilepanelid_map(f,tileid) - 1) * nex * ney
237 tilefaceid_map(f,tileid) = face_connectivity(f,panelid)
238 end do ! loop for f
239 end do ! loop for tile
240
241 ! if (PRC_myrank==0) then
242 ! write(*,*) " MeshUtilCubedSphere2D_modifyConnectivity"
243 ! do tileID=1, Ntile
244 ! write(*,'(a,i3,a,2i3)') "tileID=", tileID, ":", pi_table(tileID), pj_table(tileID)
245 ! write(*,'(a,6i4)') "map_tile:", tileID_map(:,tileID)
246 ! write(*,'(a,6i4)') "map_panel:", tilePanelID_map(:,tileID)
247 ! write(*,'(a,6i4)') "mac_face:", tileFaceID_map(:,tileID)
248 ! end do
249 ! end if
250
251 return
253
254!OCL SERIAL
255 subroutine meshutilcubedsphere2d_getpanelconnectivity( panel_connectivity, face_connectivity )
256
257 implicit none
258
259 integer, intent(out) :: panel_connectivity(4,6)
260 integer, intent(out) :: face_connectivity(4,6)
261
262 integer :: n
263 integer :: zonal_panelid_list(0:5)
264
265 zonal_panelid_list(:) = (/ 4, 1, 2, 3, 4, 1/)
266 do n=1, 4
267 panel_connectivity(1,n) = 6
268 if (zonal_panelid_list(4-n) > 2) then
269 face_connectivity(1,n) = +zonal_panelid_list(4-n)
270 else
271 face_connectivity(1,n) = -zonal_panelid_list(4-n)
272 end if
273
274 panel_connectivity(2,n) = zonal_panelid_list(n+1)
275 face_connectivity(2,n) = 4
276
277 panel_connectivity(3,n) = 5
278 face_connectivity(3,n) = n
279 if (n > 2) then
280 face_connectivity(3,n) = -n
281 else
282 face_connectivity(3,n) = n
283 end if
284
285 panel_connectivity(4,n) = zonal_panelid_list(n-1)
286 face_connectivity(4,n) = 2
287 end do
288
289 panel_connectivity(:,5) = (/ 1, 2, 3, 4 /)
290 face_connectivity(:,5) = (/ 3, 3, -3, -3 /)
291 panel_connectivity(:,6) = (/ 3, 2, 1, 4 /)
292 face_connectivity(:,6) = (/ -1, -1, 1, 1 /)
293
295
296!OCL SERIAL
297 subroutine meshutilcubedsphere2d_getpanelid( panelID, lon, lat, Np )
298 use scale_cubedsphere_coord_cnv, only: &
300 implicit none
301
302 integer, intent(in) :: np
303 integer, intent(out) :: panelid(np)
304 real(rp), intent(in) :: lon(np)
305 real(rp), intent(in) :: lat(np)
306
307 integer :: p
308 integer :: pnl
309 real(rp) :: alph(np), beta(np)
310 real(rp) :: lon_(np), lat_(np)
311
312 real(rp), parameter :: eps = 1.0e-64_rp
313 !------------------------------------------
314
315 !$omp parallel do
316 do p=1, np
317 if ( abs(cos(lon(p))) < eps ) then
318 lon_(p) = lon(p) + eps
319 else
320 lon_(p) = lon(p)
321 end if
322 if ( abs( lat(p) - 0.5_rp * pi ) < eps ) then
323 lat_(p) = lat(p) - sign(eps, lat(p))
324 else
325 lat_(p) = lat(p)
326 end if
327 end do
328
329 panelid(:) = -1
330 do pnl=1, 6
331 call cubedspherecoordcnv_lonlat2cspos( pnl, lon_, lat_, np, &
332 alph, beta )
333
334 select case(pnl)
335 case (5)
336 where ( lat(:) > 0.0_rp .and. abs(alph(:)) <= 0.25_rp * pi .and. abs(beta(:)) <= 0.25_rp * pi )
337 panelid(:) = pnl
338 end where
339 case (6)
340 where ( lat(:) < 0.0_rp .and. abs(alph(:)) <= 0.25_rp * pi .and. abs(beta(:)) <= 0.25_rp * pi )
341 panelid(:) = pnl
342 end where
343 case default
344 where ( abs(alph(:)) <= 0.25_rp * pi .and. abs(beta(:)) <= 0.25_rp * pi )
345 panelid(:) = pnl
346 end where
347 end select
348 end do
349
350 do p=1, np
351 if (panelid(p) < 0) then
352 log_error("MeshUtilCubedSphere2D_getPanelID",*) 'Fail to search a panel ID of cubed sphere grid!'
353 write(*,*) "p=", p, ": (lon,lat)=", lon(p), lat(p), "(alpha,beta)=", alph(p), beta(p)
354 call prc_abort
355 end if
356 end do
357
358 return
360
Module common / Coordinate conversion with cubed-sphere projection.
subroutine, public cubedspherecoordcnv_lonlat2cspos(panelid, lon, lat, np, alpha, beta)
Calculate local coordinates using the central angles in an equiangular gnomonic cubed-sphere projecti...
module FElib / Mesh / utility for 2D mesh
subroutine, public meshutil2d_buildinteriormap(vmapm, vmapp, mapm, mapp, pos_en, pos_ev, etoe, etof, etov, fmask, ne, np, nfp, nfaces, nv)
subroutine, public meshutil2d_genconnectivity(etoe, etof, etov, ne, nfaces)
subroutine, public meshutil2d_genrectdomain(pos_v, etov, ke_x, xmin, xmax, ke_y, ymin, ymax)
subroutine, public meshutil2d_genpatchboundarymap_wide(vmapb2, vmapb, halosize, nex, ney, nfp)
subroutine, public meshutil2d_genpatchboundarymap(vmapb, mapb, vmapp, pos_en, xmin, xmax, ymin, ymax, fmask, ne, np, nfp, nfaces, nv)
module FElib / Mesh / utility for 2D cubed-sphere mesh
subroutine, public meshutilcubedsphere2d_getpanelid(panelid, lon, lat, np)
subroutine, public meshutilcubedsphere2d_modifyconnectivity(tilepanelid_map, tileid_map, tilefaceid_map, panelid_table, pi_table, pj_table, nex, ney, ntile, nface)
Modify the mesh connectivity with a cubic domain decomposition to support the cubed sphere mesh.
subroutine, public meshutilcubedsphere2d_getpanelconnectivity(panel_connectivity, face_connectivity)
subroutine, public meshutilcubedsphere2d_buildglobalmap(panelid_table, pi_table, pj_table, tileid_map, tilefaceid_map, tilepanelid_map, ntile)