48 type :: veccovariantcomp
49 type(MeshField3D),
pointer :: u1 => null()
50 type(MeshField3D),
pointer :: u2 => null()
56 type(veccovariantcomp),
allocatable :: vec_covariant_comp_ptrlist(:)
58 integer :: halosize_h1d
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
78 private :: post_exchange_core
79 private :: push_localsendbuf
89 subroutine meshfieldcommcubedspheredom3d_init( this, &
90 sfield_num, hvfield_num, htensorfield_num, mesh3d, &
91 haloSize_h1D, haloSize_v )
97 integer,
intent(in) :: sfield_num
98 integer,
intent(in) :: hvfield_num
99 integer,
intent(in) :: htensorfield_num
101 integer,
intent(in),
optional :: halosize_h1d
102 integer,
intent(in),
optional :: halosize_v
107 integer :: nnode_lcmeshface(
comm_face_num,mesh3d%local_mesh_num)
110 this%mesh3d => mesh3d
111 lcmesh => mesh3d%lcmesh_list(1)
112 elem => lcmesh%refElem3D
115 if (
present(halosize_h1d) )
then
116 this%haloSize_h1D = halosize_h1d
118 this%haloSize_h1D = 1
120 if (
present(halosize_v) )
then
121 this%haloSize_v = halosize_v
127 allocate( this%VMapB_size(this%mesh3d%LOCAL_MESH_NUM) )
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
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
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) )
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 )
153 this%use_vmap_wide_flag = .false.
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)
161 this%VMapB_size(n) =
size(lcmesh%VMapB)
167 if (hvfield_num > 0)
then
168 allocate( this%vec_covariant_comp_ptrlist(hvfield_num) )
172 end subroutine meshfieldcommcubedspheredom3d_init
175 subroutine meshfieldcommcubedspheredom3d_final( this )
180 if ( this%hvfield_num > 0 )
then
181 deallocate( this%vec_covariant_comp_ptrlist )
186 end subroutine meshfieldcommcubedspheredom3d_final
189 subroutine meshfieldcommcubedspheredom3d_set_covariantvec( &
190 this, hvfield_ID, u1, u2 )
193 integer,
intent(in) :: hvfield_id
198 this%vec_covariant_comp_ptrlist(hvfield_id)%u1 => u1
199 this%vec_covariant_comp_ptrlist(hvfield_id)%u2 => u2
201 end subroutine meshfieldcommcubedspheredom3d_set_covariantvec
204 subroutine meshfieldcommcubedspheredom3d_put(this, field_list, varid_s)
208 integer,
intent(in) :: varid_s
216 if ( this%use_vmap_wide_flag )
then
221 field_list, 3, varid_s, this%mesh3d%lcmesh_list,
size(this%mesh3d%lcmesh_list(1)%VMapB), &
226 end subroutine meshfieldcommcubedspheredom3d_put
229 subroutine meshfieldcommcubedspheredom3d_get(this, field_list, varid_s)
236 integer,
intent(in) :: varid_s
247 integer :: varid_vec_s
249 integer,
allocatable :: indexh2dto3d(:)
250 real(rp),
allocatable :: g_ij(:,:,:,:)
253 integer,
allocatable :: vmapb(:)
258 varnum =
size(field_list)
261 if ( this%call_wait_flag_sub_get )
then
266 field_list, 3, varid_s, this%mesh3d%lcmesh_list )
267 call post_exchange_core( this )
270 do n=1, this%mesh3d%LOCAL_MESH_NUM
271 lcmesh => this%mesh3d%lcmesh_list(n)
272 if ( this%use_vmap_wide_flag )
then
274 this%VMapB2, this%VMapB_size(1), &
275 field_list(i)%field3d%local(n)%val )
278 field_list(i)%field3d%local(n)%val )
284 varid_e = varid_s + varnum - 1
285 if ( varid_e > this%sfield_num )
then
286 do i=1, this%hvfield_num
288 varid_vec_s = this%sfield_num + 2*i - 1
289 if ( varid_vec_s > varid_e )
exit
291 if (
associated(this%vec_covariant_comp_ptrlist(i)%u1 ) &
292 .and.
associated(this%vec_covariant_comp_ptrlist(i)%u2 ) )
then
294 do n=1, this%mesh3d%LOCAL_MESH_NUM
295 lcmesh => this%mesh3d%lcmesh_list(n)
296 elem => lcmesh%refElem3D
298 allocate( g_ij(elem%Np,lcmesh%Ne,2,2), indexh2dto3d(elem%Np) )
299 indexh2dto3d(:) = elem%IndexH2Dto3D(:)
301 if ( this%use_vmap_wide_flag )
then
302 allocate(vmapb(this%VMapB_size(n)))
303 vmapb(:) = this%VMapB2(:)
305 allocate(vmapb(
size(lcmesh%VMapB)))
306 vmapb(:) = lcmesh%VMapB(:)
312 do ke=lcmesh%NeS, lcmesh%NeE
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)
322 call set_boundary_data3d_u1u2( &
323 this%recv_buf(:,varid_vec_s,n), this%recv_buf(:,varid_vec_s+1,n), &
324 this%bufsize_per_field, lcmesh%refElem3D, lcmesh, g_ij, vmapb, &
325 this%vec_covariant_comp_ptrlist(i)%u1%local(n)%val, &
326 this%vec_covariant_comp_ptrlist(i)%u2%local(n)%val )
328 deallocate( g_ij, vmapb, indexh2dto3d )
337 end subroutine meshfieldcommcubedspheredom3d_get
343 subroutine meshfieldcommcubedspheredom3d_exchange( this, do_wait )
350 use scale_prc,
only: prc_abort
354 logical,
intent(in),
optional :: do_wait
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(:,:,:)
371 integer,
pointer :: vmapb(:)
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!"
383 do n=1, this%mesh%LOCAL_MESH_NUM
384 lcmesh => this%mesh3d%lcmesh_list(n)
385 elem => lcmesh%refElem3D
387 allocate( fpos3d(this%Nnode_LCMeshAllFace(n),2) )
389 if ( this%use_vmap_wide_flag )
then
392 vmapb => lcmesh%VMapB
400 do f=1, this%nfaces_comm
401 commdata => this%commdata_list(f,n)
402 call push_localsendbuf( commdata%send_buf, &
403 this%send_buf(:,:,n), commdata%s_faceID, this%is_f(f,n), &
404 commdata%Nnode_LCMeshFace, this%bufsize_per_field, &
405 this%field_num_tot, lcmesh, this%HaloSize_h1D )
407 if ( commdata%s_panelID /= lcmesh%panelID &
408 .and. ( this%hvfield_num > 0 .or. this%htensorfield_num > 0 ) )
then
410 allocate( lcfpos3d(commdata%Nnode_LCMeshFace,2), unity_fac(commdata%Nnode_LCMeshFace) )
411 unity_fac(:) = 1.0_rp
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 )
420 if ( commdata%s_panelID /= lcmesh%panelID )
then
421 if ( this%hvfield_num > 0 )
then
422 allocate( tmp_svec3d(commdata%Nnode_LCMeshFace,2) )
425 do varid=this%sfield_num+1, this%sfield_num+2*this%hvfield_num-1, 2
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)
433 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), &
434 commdata%Nnode_LCMeshFace, &
435 tmp_svec3d(:,1), tmp_svec3d(:,2), &
436 commdata%send_buf(:,varid), commdata%send_buf(:,varid+1), &
441 deallocate( tmp_svec3d )
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) )
449 do varid=this%sfield_num+2*this%hvfield_num+1, this%field_num_tot-3, 4
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)
459 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), &
460 commdata%Nnode_LCMeshFace, &
461 tmp1_htensor3d(:,1,1), tmp1_htensor3d(:,2,1), &
462 tmp2_htensor3d(:,1,1), tmp2_htensor3d(:,2,1), &
465 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), &
466 commdata%Nnode_LCMeshFace, &
467 tmp1_htensor3d(:,1,2), tmp1_htensor3d(:,2,2), &
468 tmp2_htensor3d(:,1,2), tmp2_htensor3d(:,2,2), &
471 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), &
472 commdata%Nnode_LCMeshFace, &
473 tmp2_htensor3d(:,1,1), tmp2_htensor3d(:,1,2), &
474 commdata%send_buf(:,varid), commdata%send_buf(:,varid+2), &
477 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac(:), &
478 commdata%Nnode_LCMeshFace, &
479 tmp2_htensor3d(:,2,1), tmp2_htensor3d(:,2,2), &
480 commdata%send_buf(:,varid+1), commdata%send_buf(:,varid+3), &
484 deallocate( tmp1_htensor3d, tmp2_htensor3d )
489 if (
allocated(lcfpos3d) )
then
491 deallocate( lcfpos3d, unity_fac )
508 if ( .not. this%call_wait_flag_sub_get ) &
509 call post_exchange_core( this )
514 end subroutine meshfieldcommcubedspheredom3d_exchange
519 subroutine post_exchange_core( this )
531 real(rp),
allocatable :: fpos3d(:,:)
532 real(rp),
allocatable :: lcfpos3d(:,:)
533 real(rp),
allocatable :: unity_fac(:)
534 real(rp),
allocatable :: tmp1_htensor3d(:,:,:)
541 integer,
pointer :: vmapb(:)
544 do n=1, this%mesh%LOCAL_MESH_NUM
545 lcmesh => this%mesh3d%lcmesh_list(n)
546 elem => lcmesh%refElem3D
548 allocate( fpos3d(this%Nnode_LCMeshAllFace(n),2) )
549 if ( this%use_vmap_wide_flag )
then
552 vmapb => lcmesh%VMapB
560 do f=1, this%nfaces_comm
561 commdata => this%commdata_list(f,n)
562 ire = irs + commdata%Nnode_LCMeshFace - 1
564 if ( commdata%s_panelID /= lcmesh%panelID &
565 .and. ( this%hvfield_num > 0 .or. this%htensorfield_num > 0 ) )
then
567 allocate( lcfpos3d(commdata%Nnode_LCMeshFace,2), unity_fac(commdata%Nnode_LCMeshFace) )
568 unity_fac(:) = 1.0_rp
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 )
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, &
582 commdata%Nnode_LCMeshFace, &
583 commdata%recv_buf(:,varid), commdata%recv_buf(:,varid+1), &
584 this%recv_buf(irs:ire,varid,n), this%recv_buf(irs:ire,varid+1,n), &
589 if ( this%htensorfield_num > 0 )
then
590 allocate( tmp1_htensor3d(commdata%Nnode_LCMeshFace,2,2) )
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, &
596 commdata%Nnode_LCMeshFace, &
597 commdata%recv_buf(:,varid), commdata%recv_buf(:,varid+1), &
598 tmp1_htensor3d(:,1,1), tmp1_htensor3d(:,2,1), &
601 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac, &
602 commdata%Nnode_LCMeshFace, &
603 commdata%recv_buf(:,varid+2), commdata%recv_buf(:,varid+3), &
604 tmp1_htensor3d(:,1,2), tmp1_htensor3d(:,2,2), &
607 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac, &
608 commdata%Nnode_LCMeshFace, &
609 tmp1_htensor3d(:,1,1), tmp1_htensor3d(:,1,2), &
610 this%recv_buf(irs:ire,varid,n), this%recv_buf(irs:ire,varid+2,n), &
613 lcmesh%panelID, lcfpos3d(:,1), lcfpos3d(:,2), unity_fac, &
614 commdata%Nnode_LCMeshFace, &
615 tmp1_htensor3d(:,2,1), tmp1_htensor3d(:,2,2), &
616 this%recv_buf(irs:ire,varid+1,n), this%recv_buf(irs:ire,varid+3,n), &
620 deallocate( tmp1_htensor3d )
625 if (
allocated(lcfpos3d) )
then
627 deallocate( lcfpos3d, unity_fac )
637 end subroutine post_exchange_core
641 subroutine push_localsendbuf( lc_send_buf, &
642 send_buf, s_faceID, is, Nnode_LCMeshFace, bufsize_per_field, var_num, &
643 lcmesh, haloSize_h1D )
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
653 integer,
intent(in) :: halosize_h1d
656 integer :: nnode_v, nnode_h1d, nfp_h
659 if ( s_faceid > 0 )
then
663 do i=1, nnode_lcmeshface
664 lc_send_buf(i,vid) = send_buf(is+i-1,vid)
667 else if ( -5 < s_faceid .and. s_faceid < 0)
then
669 nfp_h = lcmesh%refElem3D%Nfp_h
670 nnode_h1d = lcmesh%refElem3D%Nnode_h1D
671 nnode_v = lcmesh%refElem3D%Nnode_v
673 call revert_hori( lc_send_buf, &
674 send_buf, is, nnode_lcmeshface/(nfp_h * halosize_h1d * lcmesh%NeZ), &
675 lcmesh%NeZ, halosize_h1d )
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)
688 integer :: p1, p3, ph, i, k, n
697 do ph=1, halosize_h1d_
701 p1_ = nnode_h1d - p1 + 1
705 + (p3-1) * nnode_h1d &
707 + (i_-1) * nfp_h * halosize_h1d_ &
708 + (k -1) * nfp_h * halosize_h1d_ * ne_h1d
710 revert(p1,p3,ph,i,k,n) = ori(id_src,n)
718 end subroutine revert_hori
719 end subroutine push_localsendbuf
721 subroutine set_boundary_data3d_u1u2( buf_U, buf_V, &
722 bufsize_per_field, elem, mesh, G_ij, VMapB, &
726 integer,
intent(in) :: bufsize_per_field
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)
741 iis = elem%Np*mesh%NeE
743 do ii=1, bufsize_per_field
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)
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(:)
755 end subroutine set_boundary_data3d_u1u2
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.