FE-Project
Loading...
Searching...
No Matches
scale_meshfieldcomm_cubedspheredom3d.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Data / Communication in 3D cubed-sphere domain
3!!
4!! @par Description
5!! A module to manage data communication with 3D cubed-sphere domain for element-based methods
6!!
7!! @author Yuta Kawai, Team SCALE
8!<
9#include "scaleFElib.h"
11
12 !-----------------------------------------------------------------------------
13 !
14 !++ used modules
15 !
16 use scale_precision
17 use scale_io
18 use scale_prof
19
23 use scale_meshfieldcomm_base, only: &
33
36
37
38 !-----------------------------------------------------------------------------
39 implicit none
40 private
41
42 !-----------------------------------------------------------------------------
43 !
44 !++ Public type & procedure
45 !
46
47 !> Derived type to represent covariant vector components
48 type :: veccovariantcomp
49 type(MeshField3D), pointer :: u1 => null()
50 type(MeshField3D), pointer :: u2 => null()
51 end type
52
53 !> Base derived type to manage data communication with 3D cubed-sphere domain
55 class(meshcubedspheredom3d), pointer :: mesh3d !< Pointer to an object representing 3D cubed-sphere computational mesh
56 type(veccovariantcomp), allocatable :: vec_covariant_comp_ptrlist(:)
57
58 integer :: halosize_h1d !< Halo size for 1D horizontal direction
59 integer :: halosize_v !< Halo size for vertical direction
60 contains
61 procedure, public :: init => meshfieldcommcubedspheredom3d_init
62 procedure, public :: put => meshfieldcommcubedspheredom3d_put
63 procedure, public :: get => meshfieldcommcubedspheredom3d_get
64 procedure, public :: exchange => meshfieldcommcubedspheredom3d_exchange
65 procedure, public :: setcovariantvec => meshfieldcommcubedspheredom3d_set_covariantvec
66 procedure, public :: final => meshfieldcommcubedspheredom3d_final
68
69 !-----------------------------------------------------------------------------
70 !
71 !++ Public parameters & variables
72 !
73
74 !-----------------------------------------------------------------------------
75 !
76 !++ Private type & procedure
77 !
78 private :: post_exchange_core
79 private :: push_localsendbuf
80
81 !-----------------------------------------------------------------------------
82 !
83 !++ Private parameters & variables
84 !
85 integer, parameter :: comm_face_num = 6 !< Number of faces with data communication
86
87contains
88!> Initialize an object to manage data communication with 3D cubed-sphere computational mesh
89 subroutine meshfieldcommcubedspheredom3d_init( this, &
90 sfield_num, hvfield_num, htensorfield_num, mesh3d, &
91 haloSize_h1D, haloSize_v )
92
93 use scale_meshutil_cubedsphere3d, only: meshutilcubedsphere3d_genpatchboundarymap_wide
94 implicit none
95
96 class(meshfieldcommcubedspheredom3d), intent(inout), target :: this
97 integer, intent(in) :: sfield_num !< Number of scalar fields
98 integer, intent(in) :: hvfield_num !< Number of horizontal vector fields
99 integer, intent(in) :: htensorfield_num !< Number of horizontal vector fields
100 class(meshcubedspheredom3d), intent(in), target :: mesh3d !< Object to manage a 3D cubed-sphere computational mesh
101 integer, intent(in), optional :: halosize_h1d !< Halo size for 1D horizontal direction
102 integer, intent(in), optional :: halosize_v !< Halo size for vertical direction
103
104 type(localmesh3d), pointer :: lcmesh
105 type(elementbase3d), pointer :: elem
106 integer :: n
107 integer :: nnode_lcmeshface(comm_face_num,mesh3d%local_mesh_num)
108 !-----------------------------------------------------------------------------
109
110 this%mesh3d => mesh3d
111 lcmesh => mesh3d%lcmesh_list(1)
112 elem => lcmesh%refElem3D
113
114 !-
115 if ( present(halosize_h1d) ) then
116 this%haloSize_h1D = halosize_h1d
117 else
118 this%haloSize_h1D = 1
119 end if
120 if ( present(halosize_v) ) then
121 this%haloSize_v = halosize_v
122 else
123 this%haloSize_v = 1
124 end if
125
126 !-
127 allocate( this%VMapB_size(this%mesh3d%LOCAL_MESH_NUM) )
128
129 this%bufsize_per_field = 2*(lcmesh%NeX + lcmesh%NeY)*lcmesh%NeZ*elem%Nfp_h*this%haloSize_h1D &
130 + 2*lcmesh%NeX*lcmesh%NeY*elem%Nfp_v*this%haloSize_v
131
132 do n=1, this%mesh3d%LOCAL_MESH_NUM
133 lcmesh => this%mesh3d%lcmesh_list(n)
134 nnode_lcmeshface(:,n) = &
135 (/ lcmesh%NeX, lcmesh%NeY, lcmesh%NeX, lcmesh%NeY, 0, 0 /) * lcmesh%NeZ * lcmesh%refElem3D%Nfp_h*this%haloSize_h1D &
136 + (/ 0, 0, 0, 0, 1, 1 /) * lcmesh%NeX*lcmesh%NeY * lcmesh%refElem3D%Nfp_v*this%haloSize_v
137 end do
138
139 call meshfieldcommbase_init( this, sfield_num, hvfield_num, htensorfield_num, this%bufsize_per_field, comm_face_num, nnode_lcmeshface, mesh3d )
140
141 !-
142 if ( this%haloSize_h1D > 1 .or. this%haloSize_v > 1) then
143 this%use_vmap_wide_flag = .true.
144 allocate( this%VMapB2(this%bufsize_per_field) )
145
146 lcmesh => this%mesh3d%lcmesh_list(1)
147 call meshutilcubedsphere3d_genpatchboundarymap_wide( this%VMapB2, &
148 lcmesh%VMapB, this%haloSize_h1D, this%haloSize_v, &
149 lcmesh%NeX, lcmesh%NeY, lcmesh%NeZ, &
150 elem%Nfp_h, elem%Nfp_v, elem%Nnode_h1D, elem%Nnode_v )
151 !$acc enter data copyin(this%VMapB2)
152 else
153 this%use_vmap_wide_flag = .false.
154 end if
155
156 do n=1, this%mesh3d%LOCAL_MESH_NUM
157 lcmesh => this%mesh3d%lcmesh_list(n)
158 if ( this%use_vmap_wide_flag ) then
159 this%VMapB_size(n) = size(this%VMapB2)
160 else
161 this%VMapB_size(n) = size(lcmesh%VMapB)
162 end if
163 end do
164 !$acc enter data copyin(this%VMapB_size)
165
166 !-
167 if (hvfield_num > 0) then
168 allocate( this%vec_covariant_comp_ptrlist(hvfield_num) )
169 end if
170
171 return
172 end subroutine meshfieldcommcubedspheredom3d_init
173
174!> Finalize an object to manage data communication with 3D cubed-sphere computational mesh
175 subroutine meshfieldcommcubedspheredom3d_final( this )
176 implicit none
177 class(meshfieldcommcubedspheredom3d), intent(inout) :: this
178 !-----------------------------------------------------------------------------
179
180 if ( this%hvfield_num > 0 ) then
181 deallocate( this%vec_covariant_comp_ptrlist )
182 end if
183
184 call meshfieldcommbase_final( this )
185 return
186 end subroutine meshfieldcommcubedspheredom3d_final
187
188 !> Register objects to manage covariant vector components
189 subroutine meshfieldcommcubedspheredom3d_set_covariantvec( &
190 this, hvfield_ID, u1, u2 )
191 implicit none
192 class(meshfieldcommcubedspheredom3d), intent(inout) :: this
193 integer, intent(in) :: hvfield_id
194 type(meshfield3d), intent(in), target :: u1
195 type(meshfield3d), intent(in), target :: u2
196 !--------------------------------------------------------------
197
198 this%vec_covariant_comp_ptrlist(hvfield_id)%u1 => u1
199 this%vec_covariant_comp_ptrlist(hvfield_id)%u2 => u2
200 return
201 end subroutine meshfieldcommcubedspheredom3d_set_covariantvec
202
203!> Put field data into temporary buffers
204 subroutine meshfieldcommcubedspheredom3d_put(this, field_list, varid_s)
205 implicit none
206 class(meshfieldcommcubedspheredom3d), intent(inout) :: this
207 type(meshfieldcontainer), intent(in) :: field_list(:) !< Array of objects with 3D mesh field
208 integer, intent(in) :: varid_s !< Start index with variables when field_list(1) is written to buffers for data communication
209
210 integer :: i
211 integer :: n
212 type(localmesh3d), pointer :: lcmesh
213 !-----------------------------------------------------------------------------
214 ! call PROF_rapstart( 'comm_put', 2)
215
216 if ( this%use_vmap_wide_flag ) then
217 call meshfieldcommbase_extract_bounddata_3( field_list, 3, varid_s, this%mesh3d%lcmesh_list, this%VMapB2, this%VMapB_size(1), & ! (in)
218 this%send_buf ) ! (out)
219 else
221 field_list, 3, varid_s, this%mesh3d%lcmesh_list, size(this%mesh3d%lcmesh_list(1)%VMapB), & !(in)
222 this%send_buf ) ! (out)
223 end if
224 ! call PROF_rapend( 'comm_put', 2)
225 return
226 end subroutine meshfieldcommcubedspheredom3d_put
227
228!> Extract field data from temporary buffers
229 subroutine meshfieldcommcubedspheredom3d_get(this, field_list, varid_s)
230 use scale_meshfieldcomm_base, only: &
232 implicit none
233
234 class(meshfieldcommcubedspheredom3d), intent(inout) :: this
235 type(meshfieldcontainer), intent(inout) :: field_list(:) !< Array of objects with 3D mesh field
236 integer, intent(in) :: varid_s !< Start index with variables when field_list(1) is written to buffers for data communication
237
238 integer :: i
239 integer :: n
240 integer :: ke, ke2d
241 integer :: p
242 type(localmesh3d), pointer :: lcmesh
243 class(elementbase3d), pointer :: elem
244
245 integer :: varnum
246 integer :: varid_e
247 integer :: varid_vec_s
248
249 integer, allocatable :: indexh2dto3d(:)
250 real(rp), allocatable :: g_ij(:,:,:,:)
251
252 integer :: ke_z
253 integer, allocatable :: vmapb(:)
254 !-----------------------------------------------------------------------------
255
256 ! call PROF_rapstart( 'comm_get', 2)
257
258 varnum = size(field_list)
259
260 !--
261 if ( this%call_wait_flag_sub_get ) then
262 ! This workflow should be reconsidered in near future.
263 ! The coordinate convresions for horizontal vector/tensor fields in post_exchange_core are applied for the received data (this%recv_buf).
264 ! However, MeshFieldCommBase_wait_core does not store the communication data into this%recv_buf, but directly into the field_list.
265 call meshfieldcommbase_wait_core( this, this%commdata_list, &
266 field_list, 3, varid_s, this%mesh3d%lcmesh_list )
267 call post_exchange_core( this )
268 else
269 do i=1, varnum
270 do n=1, this%mesh3d%LOCAL_MESH_NUM
271 lcmesh => this%mesh3d%lcmesh_list(n)
272 if ( this%use_vmap_wide_flag ) then
273 call meshfieldcommbase_set_bounddata_3( this%recv_buf(:,varid_s+i-1,n), lcmesh%refElem, lcmesh, & ! (in)
274 this%VMapB2, this%VMapB_size(1), & ! (in)
275 field_list(i)%field3d%local(n)%val ) !(out)
276 else
277 call meshfieldcommbase_set_bounddata( this%recv_buf(:,varid_s+i-1,n), lcmesh%refElem, lcmesh, & !(in)
278 field_list(i)%field3d%local(n)%val ) !(out)
279 end if
280 end do
281 end do
282 end if
283
284 varid_e = varid_s + varnum - 1
285 if ( varid_e > this%sfield_num ) then
286 do i=1, this%hvfield_num
287
288 varid_vec_s = this%sfield_num + 2*i - 1
289 if ( varid_vec_s > varid_e ) exit
290
291 if ( associated(this%vec_covariant_comp_ptrlist(i)%u1 ) &
292 .and. associated(this%vec_covariant_comp_ptrlist(i)%u2 ) ) then
293
294 do n=1, this%mesh3d%LOCAL_MESH_NUM
295 lcmesh => this%mesh3d%lcmesh_list(n)
296 elem => lcmesh%refElem3D
297
298 allocate( g_ij(elem%Np,lcmesh%Ne,2,2), indexh2dto3d(elem%Np) )
299 indexh2dto3d(:) = elem%IndexH2Dto3D(:)
300
301 if ( this%use_vmap_wide_flag ) then
302 allocate(vmapb(this%VMapB_size(n)))
303 vmapb(:) = this%VMapB2(:)
304 else
305 allocate(vmapb(size(lcmesh%VMapB)))
306 vmapb(:) = lcmesh%VMapB(:)
307 end if
308 !$acc enter data create(G_ij) copyin(VMapB, IndexH2Dto3D) async(1)
309
310 !$omp parallel do private(ke2D)
311 !$acc parallel loop collapse(2) async(1)
312 do ke=lcmesh%NeS, lcmesh%NeE
313 do p=1, elem%Np
314 ke2d = lcmesh%EMap3Dto2D(ke)
315 g_ij(p,ke,1,1) = lcmesh%G_ij(indexh2dto3d(p),ke2d,1,1)
316 g_ij(p,ke,2,1) = lcmesh%G_ij(indexh2dto3d(p),ke2d,2,1)
317 g_ij(p,ke,1,2) = lcmesh%G_ij(indexh2dto3d(p),ke2d,1,2)
318 g_ij(p,ke,2,2) = lcmesh%G_ij(indexh2dto3d(p),ke2d,2,2)
319 end do
320 end do
321
322 call set_boundary_data3d_u1u2( &
323 this%recv_buf(:,varid_vec_s,n), this%recv_buf(:,varid_vec_s+1,n), & ! (in)
324 this%bufsize_per_field, lcmesh%refElem3D, lcmesh, g_ij, vmapb, & ! (in)
325 this%vec_covariant_comp_ptrlist(i)%u1%local(n)%val, & ! (out)
326 this%vec_covariant_comp_ptrlist(i)%u2%local(n)%val ) ! (out)
327 !$acc exit data delete(G_ij, VMapB, IndexH2Dto3D) async(1)
328 deallocate( g_ij, vmapb, indexh2dto3d )
329 end do
330 end if
331 end do
332 end if
333
334 !$acc wait(1)
335 ! call PROF_rapend( 'comm_get', 2)
336 return
337 end subroutine meshfieldcommcubedspheredom3d_get
338
339 !> Exchange field data between neighboring MPI processes
340 !!
341 !! @param do_wait Flag whether MPI_waitall is called and move tmp data of LocalMeshCommData object to a recv buffer
342!OCL SERIAL
343 subroutine meshfieldcommcubedspheredom3d_exchange( this, do_wait )
344 use scale_meshfieldcomm_base, only: &
347 use scale_cubedsphere_coord_cnv, only: &
350 use scale_prc, only: prc_abort
351 implicit none
352
353 class(meshfieldcommcubedspheredom3d), intent(inout), target :: this
354 logical, intent(in), optional :: do_wait
355
356 integer :: n, f
357 integer :: varid
358 integer :: i
359
360 real(rp), allocatable :: fpos3d(:,:)
361 real(rp), allocatable :: lcfpos3d(:,:)
362 real(rp), allocatable :: unity_fac(:)
363 real(rp), allocatable :: tmp_svec3d(:,:)
364 real(rp), allocatable :: tmp1_htensor3d(:,:,:)
365 real(rp), allocatable :: tmp2_htensor3d(:,:,:)
366
367 class(elementbase3d), pointer :: elem
368 type(localmesh3d), pointer :: lcmesh
369 type(localmeshcommdata), pointer :: commdata
370
371 integer, pointer :: vmapb(:)
372 !-----------------------------------------------------------------------------
373
374 ! call PROF_rapstart( 'comm_exchange_1', 2)
375
376 if ( present(do_wait) ) then
377 if ( .not. do_wait ) then
378 log_info("MeshFieldCommCubedSphereDom3D_exchange",*) "do_wait=False is not currently supported. Check!"
379 call prc_abort
380 end if
381 end if
382
383 do n=1, this%mesh%LOCAL_MESH_NUM
384 lcmesh => this%mesh3d%lcmesh_list(n)
385 elem => lcmesh%refElem3D
386
387 allocate( fpos3d(this%Nnode_LCMeshAllFace(n),2) )
388
389 if ( this%use_vmap_wide_flag ) then
390 vmapb => this%VMapB2
391 else
392 vmapb => lcmesh%VMapB
393 end if
394
395 !$acc data create(fpos3D) copyin(VmapB)
396
397 call meshfieldcommbase_extract_bounddata2( lcmesh%pos_en(:,:,1), vmapb, size(vmapb), elem%Np*lcmesh%Ne, fpos3d(:,1) )
398 call meshfieldcommbase_extract_bounddata2( lcmesh%pos_en(:,:,2), vmapb, size(vmapb), elem%Np*lcmesh%Ne, fpos3d(:,2) )
399
400 do f=1, this%nfaces_comm
401 commdata => this%commdata_list(f,n)
402 call push_localsendbuf( commdata%send_buf, & ! (inout)
403 this%send_buf(:,:,n), commdata%s_faceID, this%is_f(f,n), & ! (in)
404 commdata%Nnode_LCMeshFace, this%bufsize_per_field, & ! (in)
405 this%field_num_tot, lcmesh, this%HaloSize_h1D ) ! (in)
406
407 if ( commdata%s_panelID /= lcmesh%panelID &
408 .and. ( this%hvfield_num > 0 .or. this%htensorfield_num > 0 ) ) then
409
410 allocate( lcfpos3d(commdata%Nnode_LCMeshFace,2), unity_fac(commdata%Nnode_LCMeshFace) )
411 unity_fac(:) = 1.0_rp
412 !$acc enter data create(lcfpos3D) copyin(unity_fac) async(1)
413
414 call push_localsendbuf( lcfpos3d, &
415 fpos3d, commdata%s_faceID, this%is_f(f,n), &
416 commdata%Nnode_LCMeshFace, this%Nnode_LCMeshAllFace(n), 2, &
417 lcmesh, this%HaloSize_h1D )
418 end if
419
420 if ( commdata%s_panelID /= lcmesh%panelID ) then
421 if ( this%hvfield_num > 0 ) then
422 allocate( tmp_svec3d(commdata%Nnode_LCMeshFace,2) )
423 !$acc enter data create(tmp_svec3D) async(1)
424
425 do varid=this%sfield_num+1, this%sfield_num+2*this%hvfield_num-1, 2
426 !$acc parallel loop present(tmp_svec3D, commdata%send_buf) async(1)
427 do i=1, size(tmp_svec3d,1)
428 tmp_svec3d(i,1) = commdata%send_buf(i,varid )
429 tmp_svec3d(i,2) = commdata%send_buf(i,varid+1)
430 end do
431
433 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), & ! (in)
434 commdata%Nnode_LCMeshFace, & ! (in)
435 tmp_svec3d(:,1), tmp_svec3d(:,2), & ! (in)
436 commdata%send_buf(:,varid), commdata%send_buf(:,varid+1), & ! (out)
437 gpu_async_id=1 ) ! (in)
438
439 end do
440 !$acc exit data delete(tmp_svec3D) async(1)
441 deallocate( tmp_svec3d )
442 end if
443
444 if ( this%htensorfield_num > 0 ) then
445 allocate( tmp1_htensor3d(commdata%Nnode_LCMeshFace,2,2) )
446 allocate( tmp2_htensor3d(commdata%Nnode_LCMeshFace,2,2) )
447 !$acc enter data create(tmp1_htensor3D, tmp2_htensor3D) async(1)
448
449 do varid=this%sfield_num+2*this%hvfield_num+1, this%field_num_tot-3, 4
450 !$acc parallel loop present(tmp1_htensor3D, commdata%send_buf) async(1)
451 do i=1, size(tmp1_htensor3d,1)
452 tmp1_htensor3d(i,1,1) = commdata%send_buf(i,varid )
453 tmp1_htensor3d(i,2,1) = commdata%send_buf(i,varid+1)
454 tmp1_htensor3d(i,1,2) = commdata%send_buf(i,varid+2)
455 tmp1_htensor3d(i,2,2) = commdata%send_buf(i,varid+3)
456 end do
457
459 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), & ! (in)
460 commdata%Nnode_LCMeshFace, & ! (in)
461 tmp1_htensor3d(:,1,1), tmp1_htensor3d(:,2,1), & ! (in)
462 tmp2_htensor3d(:,1,1), tmp2_htensor3d(:,2,1), & ! (out)
463 gpu_async_id=1 ) ! (in)
465 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), & ! (in)
466 commdata%Nnode_LCMeshFace, & ! (in)
467 tmp1_htensor3d(:,1,2), tmp1_htensor3d(:,2,2), & ! (in)
468 tmp2_htensor3d(:,1,2), tmp2_htensor3d(:,2,2), & ! (out)
469 gpu_async_id=1 ) ! (in)
471 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), & ! (in)
472 commdata%Nnode_LCMeshFace, & ! (in)
473 tmp2_htensor3d(:,1,1), tmp2_htensor3d(:,1,2), & ! (in)
474 commdata%send_buf(:,varid), commdata%send_buf(:,varid+2), & ! (out)
475 gpu_async_id=1 ) ! (in)
477 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), & ! (in)
478 commdata%Nnode_LCMeshFace, & ! (in)
479 tmp2_htensor3d(:,2,1), tmp2_htensor3d(:,2,2), & ! (in)
480 commdata%send_buf(:,varid+1), commdata%send_buf(:,varid+3), & ! (out)
481 gpu_async_id=1 ) ! (in)
482 end do
483 !$acc exit data delete(tmp1_htensor3D, tmp2_htensor3D) async(1)
484 deallocate( tmp1_htensor3d, tmp2_htensor3d )
485 end if
486
487 end if
488
489 if ( allocated(lcfpos3d) ) then
490 !$acc exit data delete(lcfpos3D, unity_fac) async(1)
491 deallocate( lcfpos3d, unity_fac )
492 end if
493
494 end do
495 !$acc end data
496 deallocate( fpos3d )
497 end do
498 !$acc wait(1)
499 ! call PROF_rapend( 'comm_exchange_1', 2)
500
501 !-----------------------
502
503 ! call PROF_rapstart( 'comm_exchange_2', 2)
504 call meshfieldcommbase_exchange_core(this, this%commdata_list, do_wait )
505 ! call PROF_rapend( 'comm_exchange_2', 2)
506
507 ! call PROF_rapstart( 'comm_exchange_3', 2)
508 if ( .not. this%call_wait_flag_sub_get ) &
509 call post_exchange_core( this )
510
511 ! call PROF_rapend( 'comm_exchange_3', 2)
512
513 return
514 end subroutine meshfieldcommcubedspheredom3d_exchange
515
516!----------------------------
517
518!OCL SERIAL
519 subroutine post_exchange_core( this )
520 use scale_meshfieldcomm_base, only: &
522 use scale_cubedsphere_coord_cnv, only: &
524 implicit none
525
526 class(meshfieldcommcubedspheredom3d), intent(inout), target :: this
527
528 integer :: n, f
529 integer :: varid
530
531 real(rp), allocatable :: fpos3d(:,:)
532 real(rp), allocatable :: lcfpos3d(:,:)
533 real(rp), allocatable :: unity_fac(:)
534 real(rp), allocatable :: tmp1_htensor3d(:,:,:)
535
536 class(elementbase3d), pointer :: elem
537 type(localmesh3d), pointer :: lcmesh
538 type(localmeshcommdata), pointer :: commdata
539
540 integer :: irs, ire
541 integer, pointer :: vmapb(:)
542 !-----------------------------------------------------------------------------
543
544 do n=1, this%mesh%LOCAL_MESH_NUM
545 lcmesh => this%mesh3d%lcmesh_list(n)
546 elem => lcmesh%refElem3D
547
548 allocate( fpos3d(this%Nnode_LCMeshAllFace(n),2) )
549 if ( this%use_vmap_wide_flag ) then
550 vmapb => this%VMapB2
551 else
552 vmapb => lcmesh%VMapB
553 end if
554 !$acc data create(fpos3D) copyin(VMapB)
555
556 call meshfieldcommbase_extract_bounddata2( lcmesh%pos_en(:,:,1), vmapb, size(vmapb), elem%Np*lcmesh%Ne, fpos3d(:,1) )
557 call meshfieldcommbase_extract_bounddata2( lcmesh%pos_en(:,:,2), vmapb, size(vmapb), elem%Np*lcmesh%Ne, fpos3d(:,2) )
558
559 irs = 1
560 do f=1, this%nfaces_comm
561 commdata => this%commdata_list(f,n)
562 ire = irs + commdata%Nnode_LCMeshFace - 1
563
564 if ( commdata%s_panelID /= lcmesh%panelID &
565 .and. ( this%hvfield_num > 0 .or. this%htensorfield_num > 0 ) ) then
566
567 allocate( lcfpos3d(commdata%Nnode_LCMeshFace,2), unity_fac(commdata%Nnode_LCMeshFace) )
568 unity_fac(:) = 1.0_rp
569 !$acc enter data create(lcfpos3D) copyin(unity_fac) async(1)
570
571 call push_localsendbuf( lcfpos3d, &
572 fpos3d, f, this%is_f(f,n), &
573 commdata%Nnode_LCMeshFace, this%Nnode_LCMeshAllFace(n), 2, &
574 lcmesh, this%HaloSize_h1D )
575 end if
576
577 if ( commdata%s_panelID /= lcmesh%panelID ) then
578 if ( this%hvfield_num > 0 ) then
579 do varid=this%sfield_num+1, this%sfield_num+2*this%hvfield_num-1, 2
581 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac, & ! (in)
582 commdata%Nnode_LCMeshFace, & ! (in)
583 commdata%recv_buf(:,varid), commdata%recv_buf(:,varid+1), & ! (in)
584 this%recv_buf(irs:ire,varid,n), this%recv_buf(irs:ire,varid+1,n), & ! (out)
585 gpu_async_id=1 ) ! (in)
586 end do
587 end if
588
589 if ( this%htensorfield_num > 0 ) then
590 allocate( tmp1_htensor3d(commdata%Nnode_LCMeshFace,2,2) )
591 !$acc enter data create(tmp1_htensor3D) async(1)
592
593 do varid=this%sfield_num+2*this%hvfield_num+1, this%field_num_tot-3, 4
595 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac, & ! (in)
596 commdata%Nnode_LCMeshFace, & ! (in)
597 commdata%recv_buf(:,varid), commdata%recv_buf(:,varid+1), & ! (in)
598 tmp1_htensor3d(:,1,1), tmp1_htensor3d(:,2,1), & ! (out)
599 gpu_async_id=1 ) ! (in)
601 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac, & ! (in)
602 commdata%Nnode_LCMeshFace, & ! (in)
603 commdata%recv_buf(:,varid+2), commdata%recv_buf(:,varid+3), & ! (in)
604 tmp1_htensor3d(:,1,2), tmp1_htensor3d(:,2,2), & ! (out)
605 gpu_async_id=1 ) ! (in)
607 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac, & ! (in)
608 commdata%Nnode_LCMeshFace, & ! (in)
609 tmp1_htensor3d(:,1,1), tmp1_htensor3d(:,1,2), & ! (in)
610 this%recv_buf(irs:ire,varid,n), this%recv_buf(irs:ire,varid+2,n), & ! (out)
611 gpu_async_id=1 ) ! (in)
613 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac, & ! (in)
614 commdata%Nnode_LCMeshFace, & ! (in)
615 tmp1_htensor3d(:,2,1), tmp1_htensor3d(:,2,2), & ! (in)
616 this%recv_buf(irs:ire,varid+1,n), this%recv_buf(irs:ire,varid+3,n), & ! (out)
617 gpu_async_id=1 ) ! (in)
618 end do
619 !$acc exit data delete(tmp1_htensor3D) async(1)
620 deallocate( tmp1_htensor3d )
621 end if
622 end if
623
624 irs = ire + 1
625 if ( allocated(lcfpos3d) ) then
626 !$acc exit data delete(lcfpos3D, unity_fac) async(1)
627 deallocate( lcfpos3d, unity_fac )
628 end if
629 end do
630
631 !$acc end data
632 deallocate( fpos3d )
633 end do
634 !$acc wait(1)
635
636 return
637 end subroutine post_exchange_core
638
639 !> Push temporary buffer of the local send data to the communication buffer
640!OCL SERIAL
641 subroutine push_localsendbuf( lc_send_buf, &
642 send_buf, s_faceID, is, Nnode_LCMeshFace, bufsize_per_field, var_num, &
643 lcmesh, haloSize_h1D )
644 implicit none
645
646 integer, intent(in) :: var_num
647 integer, intent(in) :: nnode_lcmeshface
648 integer, intent(in) :: bufsize_per_field
649 real(rp), intent(inout) :: lc_send_buf(nnode_lcmeshface,var_num)
650 real(rp), intent(in) :: send_buf(bufsize_per_field,var_num)
651 integer, intent(in) :: s_faceid, is
652 type(localmesh3d), pointer :: lcmesh
653 integer, intent(in) :: halosize_h1d
654
655 integer :: vid, i
656 integer :: nnode_v, nnode_h1d, nfp_h
657 !-----------------------------------------------------------------------------
658
659 if ( s_faceid > 0 ) then
660 !$omp parallel do
661 !$acc parallel loop collapse(2) present(lc_send_buf, send_buf) async(1)
662 do vid=1, var_num
663 do i=1, nnode_lcmeshface
664 lc_send_buf(i,vid) = send_buf(is+i-1,vid)
665 end do
666 end do
667 else if ( -5 < s_faceid .and. s_faceid < 0) then
668
669 nfp_h = lcmesh%refElem3D%Nfp_h
670 nnode_h1d = lcmesh%refElem3D%Nnode_h1D
671 nnode_v = lcmesh%refElem3D%Nnode_v
672
673 call revert_hori( lc_send_buf, &
674 send_buf, is, nnode_lcmeshface/(nfp_h * halosize_h1d * lcmesh%NeZ), &
675 lcmesh%NeZ, halosize_h1d )
676 end if
677
678 return
679 contains
680 !> Revert the horizontal ordering of the local send buffer for negative s_faceID
681 subroutine revert_hori(revert, ori, is_, Ne_h1D, NeZ, haloSize_h1D_ )
682 integer, intent(in) :: is_
683 integer, intent(in) :: ne_h1d, nez
684 integer, intent(in) :: halosize_h1d_
685 real(rp), intent(out) :: revert(nnode_h1d,nnode_v,halosize_h1d_, ne_h1d,nez, var_num)
686 real(rp), intent(in) :: ori(bufsize_per_field, var_num)
687
688 integer :: p1, p3, ph, i, k, n
689 integer :: i_, p1_
690 integer :: id_src
691 !-----------------------------------------------------------------------------
692
693 !$acc parallel loop collapse(4) present(revert, ori) async(1)
694 do n=1, var_num
695 do k=1, nez
696 do i=1, ne_h1d
697 do ph=1, halosize_h1d_
698 i_ = ne_h1d - i + 1
699 do p3=1, nnode_v
700 do p1=1, nnode_h1d
701 p1_ = nnode_h1d - p1 + 1
702 ! source ordering: (p1_,p3,ph,i_,k)
703 id_src = is_ - 1 &
704 + p1_ &
705 + (p3-1) * nnode_h1d &
706 + (ph-1) * nfp_h &
707 + (i_-1) * nfp_h * halosize_h1d_ &
708 + (k -1) * nfp_h * halosize_h1d_ * ne_h1d
709
710 revert(p1,p3,ph,i,k,n) = ori(id_src,n)
711 end do
712 end do
713 end do
714 end do
715 end do
716 end do
717 return
718 end subroutine revert_hori
719 end subroutine push_localsendbuf
720
721 subroutine set_boundary_data3d_u1u2( buf_U, buf_V, &
722 bufsize_per_field, elem, mesh, G_ij, VMapB, &
723 u1, u2)
724
725 implicit none
726 integer, intent(in) :: bufsize_per_field
727 type(elementbase3d), intent(in) :: elem
728 type(localmesh3d), intent(in) :: mesh
729 real(dp), intent(in) :: buf_u(bufsize_per_field)
730 real(dp), intent(in) :: buf_v(bufsize_per_field)
731 real(dp), intent(in) :: g_ij(elem%np * mesh%ne,2,2)
732 integer, intent(in) :: vmapb(bufsize_per_field)
733 real(dp), intent(inout) :: u1(elem%np * mesh%nea)
734 real(dp), intent(inout) :: u2(elem%np * mesh%nea)
735
736 integer :: ii, iis
737 integer :: vmap_b
738 !------------------------------------------------------------
739
740#ifdef _OPENACC
741 iis = elem%Np*mesh%NeE
742 !$acc parallel loop present(buf_U, buf_V, G_ij, u1, u2, VMapB)
743 do ii=1, bufsize_per_field
744 vmap_b = vmapb(ii)
745 u1(iis+ii) = g_ij(vmap_b,1,1) * buf_u(ii) + g_ij(vmap_b,1,2) * buf_v(ii)
746 u2(iis+ii) = g_ij(vmap_b,2,1) * buf_u(ii) + g_ij(vmap_b,2,2) * buf_v(ii)
747 end do
748#else
749 u1(elem%Np*mesh%NeE+1:elem%Np*mesh%NeE+bufsize_per_field) &
750 = g_ij(vmapb,1,1) * buf_u(:) + g_ij(vmapb,1,2) * buf_v(:)
751 u2(elem%Np*mesh%NeE+1:elem%Np*mesh%NeE+bufsize_per_field) &
752 = g_ij(vmapb,2,1) * buf_u(:) + g_ij(vmapb,2,2) * buf_v(:)
753#endif
754 return
755 end subroutine set_boundary_data3d_u1u2
756
Module common / Coordinate conversion with cubed-sphere projection.
subroutine, public cubedspherecoordcnv_lonlat2csvec(panelid, alpha, beta, gam, np, veclon, veclat, vecalpha, vecbeta, lat, gpu_async_id)
Convert the components of a vector in longitude and latitude coordinates to those in local coordinate...
subroutine, public cubedspherecoordcnv_cs2lonlatvec(panelid, alpha, beta, gam, np, vecalpha, vecbeta, veclon, veclat, lat, gpu_async_id)
Convert the components of a vector in local coordinates with an equiangular gnomonic cubed-sphere pro...
module FElib / Element / Base
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Mesh / Cubed-sphere 3D domain
module FElib / Data / base
module FElib / Data / Communication base
subroutine, public meshfieldcommbase_extract_bounddata(var, refelem, mesh, buf)
Extract halo data from data array with MeshField object and set it to the receiving buffer.
subroutine, public meshfieldcommbase_extract_bounddata_3(field_list, dim, varid_s, lcmesh_list, vmapb2, vmapb2_size, buf)
Extract halo data from data array with MeshField object and set it to the recieving buffer.
subroutine, public meshfieldcommbase_final(this)
Finalize a base object to manage data communication of fields.
subroutine, public meshfieldcommbase_wait_core(this, commdata_list, field_list, dim, varid_s, lcmesh_list)
Wait data communication and move tmp data of LocalMeshCommData object to a recv buffer.
subroutine, public meshfieldcommbase_set_bounddata(buf, refelem, mesh, var)
Extract halo data from the receiving buffer and set it to data array with MeshField object.
subroutine, public meshfieldcommbase_set_bounddata_3(buf, refelem, mesh, vmapb, vmapb_size, var)
Extract halo data from the recieving buffer and set it to data array with MeshField object.
subroutine, public meshfieldcommbase_init(this, sfield_num, hvfield_num, htensorfield_num, bufsize_per_field, comm_face_num, nnode_lcmeshface, mesh)
Initialize a base object to manage data communication of fields.
subroutine, public meshfieldcommbase_extract_bounddata_2(field_list, dim, varid_s, lcmesh_list, vmapb_size, buf)
Extract halo data from data array with MeshField object and set it to the receiving buffer.
subroutine, public meshfieldcommbase_extract_bounddata2(var, vmapb, vmapb_size, npxnea, buf)
Extract halo data from data array with MeshField object and set it to the receiving buffer.
subroutine, public meshfieldcommbase_exchange_core(this, commdata_list, do_wait)
Exchange halo data.
module FElib / Data / Communication in 3D cubed-sphere domain
integer, parameter comm_face_num
Number of faces with data communication.
module FElib / Mesh / utility for 3D cubed-sphere mesh
Derived type representing a 3D reference element.
Derived type representing an arbitrary finite element.
Derived type representing a local mesh for 2D domain.
Derived type to manage a local 3D computational domain.
Derived type to manage a cubed-sphere 3D computational domain.
Derived type representing a field with 3D mesh.
Derived type to manage data communication at a face between adjacent local meshes.
Base derived type to manage data communication.
Container to save a pointer of MeshField(1D, 2D, 3D) object.
Base derived type to manage data communication with 3D cubed-sphere domain.