FE-Project
Loading...
Searching...
No Matches
scale_meshfieldcomm_rectdom2d.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Data / Communication 2D rectangle domain
3!!
4!! @par Description
5!! A module to manage data communication with 2D rectangle 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
20 use scale_element_base, only: &
24 use scale_meshfieldcomm_base, only: &
34
35 !-----------------------------------------------------------------------------
36 implicit none
37 private
38
39 !-----------------------------------------------------------------------------
40 !
41 !++ Public type & procedure
42 !
43
44 !> Base derived type to manage data communication with 2D rectangle domain
45 type, public, extends(meshfieldcommbase) :: meshfieldcommrectdom2d
46 class(meshrectdom2d), pointer :: mesh2d !< Pointer to an object representing 2D rectangular computational mesh
47
48 integer :: halosize_1d !< Halo size in 1D direction
49 contains
50 procedure, public :: init => meshfieldcommrectdom2d_init
51 procedure, public :: put => meshfieldcommrectdom2d_put
52 procedure, public :: get => meshfieldcommrectdom2d_get
53 procedure, public :: exchange => meshfieldcommrectdom2d_exchange
54 procedure, public :: final => meshfieldcommrectdom2d_final
56
57 !-----------------------------------------------------------------------------
58 !
59 !++ Public parameters & variables
60 !
61
62 !-----------------------------------------------------------------------------
63 !
64 !++ Private procedure
65 !
66 private :: push_localsendbuf
67
68 !-----------------------------------------------------------------------------
69 !
70 !++ Private parameters & variables
71 !
72 integer, parameter :: comm_face_num = 4 !< Number of faces with data communication
73
74
75contains
76!> Initialize an object to manage data communication with 2D rectangle domain
77 subroutine meshfieldcommrectdom2d_init( this, &
78 sfield_num, hvfield_num, htensorfield_num, mesh2d, &
79 haloSize_1D )
80
82 implicit none
83
84 class(meshfieldcommrectdom2d), intent(inout) :: this
85 integer, intent(in) :: sfield_num !< Number of scalar fields
86 integer, intent(in) :: hvfield_num !< Number of horizontal vector fields
87 integer, intent(in) :: htensorfield_num !< Number of horizontal vector fields
88 class(meshrectdom2d), intent(in), target :: mesh2d !< Object to manage a 2D rectangular computational mesh
89 integer, intent(in), optional :: halosize_1d !< Halo size in 1D direction (default: 1)
90
91 type(localmesh2d), pointer :: lcmesh
92 type(elementbase2d), pointer :: elem
93 integer :: n
94 integer :: nnode_lcmeshface(comm_face_num,mesh2d%local_mesh_num)
95 !-----------------------------------------------------------------------------
96
97 this%mesh2d => mesh2d
98 lcmesh => mesh2d%lcmesh_list(1)
99 elem => lcmesh%refElem2D
100
101 !-
102 if ( present(halosize_1d) ) then
103 this%haloSize_1D = halosize_1d
104 else
105 this%haloSize_1D = 1
106 end if
107
108 !-
109 allocate( this%VMapB_size(this%mesh2d%LOCAL_MESH_NUM) )
110
111 this%bufsize_per_field = 2 * (lcmesh%NeX + lcmesh%NeY) * elem%Nfp*this%haloSize_1D
112
113 do n=1, this%mesh2d%LOCAL_MESH_NUM
114 lcmesh => this%mesh2d%lcmesh_list(n)
115 nnode_lcmeshface(:,n) = (/ lcmesh%NeX, lcmesh%NeY, lcmesh%NeX, lcmesh%NeY /) * lcmesh%refElem2D%Nfp*this%haloSize_1D
116 end do
117
118 call meshfieldcommbase_init( this, sfield_num, hvfield_num, htensorfield_num, this%bufsize_per_field, comm_face_num, nnode_lcmeshface, mesh2d)
119
120 !-
121 if ( this%haloSize_1D > 1 ) then
122 this%use_vmap_wide_flag = .true.
123 allocate( this%VMapB2(this%bufsize_per_field) )
124
125 lcmesh => this%mesh2d%lcmesh_list(1)
126 call meshutil2d_genpatchboundarymap_wide( this%VMapB2, &
127 lcmesh%VMapB, this%haloSize_1D, &
128 lcmesh%NeX, lcmesh%NeY, &
129 elem%Nfp )
130 else
131 this%use_vmap_wide_flag = .false.
132 end if
133
134 do n=1, this%mesh2d%LOCAL_MESH_NUM
135 lcmesh => this%mesh2d%lcmesh_list(n)
136 if ( this%use_vmap_wide_flag ) then
137 this%VMapB_size(n) = size(this%VMapB2)
138 else
139 this%VMapB_size(n) = size(lcmesh%VMapB)
140 end if
141 end do
142
143 return
144 end subroutine meshfieldcommrectdom2d_init
145
146!> Finalize an object to manage data communication with 2D rectangle domain
147 subroutine meshfieldcommrectdom2d_final( this )
148 implicit none
149 class(meshfieldcommrectdom2d), intent(inout) :: this
150 !-----------------------------------------------------------------------------
151
152 call meshfieldcommbase_final( this )
153 return
154 end subroutine meshfieldcommrectdom2d_final
155
156!> Put field data into temporary buffers
157 subroutine meshfieldcommrectdom2d_put(this, field_list, varid_s)
158 implicit none
159 class(meshfieldcommrectdom2d), intent(inout) :: this
160 type(meshfieldcontainer), intent(in) :: field_list(:)
161 integer, intent(in) :: varid_s
162 !-----------------------------------------------------------------------------
163
164 call prof_rapstart( 'comm_put', 1)
165 if ( this%use_vmap_wide_flag ) then
166 call meshfieldcommbase_extract_bounddata_3( field_list, 2, varid_s, this%mesh2d%lcmesh_list, this%VMapB2, this%VMapB_size(1), this%send_buf )
167 else
169 field_list, 2, varid_s, this%mesh2d%lcmesh_list, size(this%mesh2d%lcmesh_list(1)%VMapB), & !(in)
170 this%send_buf ) ! (out)
171 end if
172 call prof_rapend( 'comm_put', 1)
173 return
174 end subroutine meshfieldcommrectdom2d_put
175
176 !> Extract field data from temporary buffers
177 subroutine meshfieldcommrectdom2d_get(this, field_list, varid_s)
178 use scale_meshfieldcomm_base, only: &
180 implicit none
181
182 class(meshfieldcommrectdom2d), intent(inout) :: this
183 type(meshfieldcontainer), intent(inout) :: field_list(:)
184 integer, intent(in) :: varid_s
185
186 integer :: i
187 integer :: n
188 type(localmesh2d), pointer :: lcmesh
189 !-----------------------------------------------------------------------------
190 call prof_rapstart( 'comm_get', 1)
191
192 !--
193 if ( this%call_wait_flag_sub_get ) then
194 call meshfieldcommbase_wait_core( this, this%commdata_list, &
195 field_list, 2, varid_s, this%mesh2d%lcmesh_list )
196 else
197 do i=1, size(field_list)
198 do n=1, this%mesh2d%LOCAL_MESH_NUM
199 lcmesh => this%mesh2d%lcmesh_list(n)
200 if ( this%use_vmap_wide_flag ) then
201 call meshfieldcommbase_set_bounddata_3( this%recv_buf(:,varid_s+i-1,n), lcmesh%refElem, lcmesh, & ! (in)
202 this%VMapB2, this%VMapB_size(1), & ! (in)
203 field_list(i)%field2d%local(n)%val ) ! (inout)
204 else
205 call meshfieldcommbase_set_bounddata( this%recv_buf(:,varid_s+i-1,n), lcmesh%refElem, lcmesh, & !(in)
206 field_list(i)%field2d%local(n)%val ) !(out)
207 end if
208 end do
209 end do
210 !$acc wait(1)
211 end if
212 call prof_rapend( 'comm_get', 1)
213
214 return
215 end subroutine meshfieldcommrectdom2d_get
216
217!> Exchange field data between neighboring MPI processes
218!!
219!OCL SERIAL
220 subroutine meshfieldcommrectdom2d_exchange( this, do_wait )
221 use scale_meshfieldcomm_base, only: &
224
225 implicit none
226
227 class(meshfieldcommrectdom2d), intent(inout), target :: this
228 logical, intent(in), optional :: do_wait
229
230 integer :: n, f
231 type(localmesh2d), pointer :: lcmesh
232 type(localmeshcommdata), pointer :: commdata
233 !-----------------------------------------------------------------------------
234
235 call prof_rapstart( 'comm_exchange_1', 1)
236
237 do n=1, this%mesh%LOCAL_MESH_NUM
238 lcmesh => this%mesh2d%lcmesh_list(n)
239 do f=1, this%nfaces_comm
240 commdata => this%commdata_list(f,n)
241 call push_localsendbuf( commdata%send_buf, & ! (inout)
242 this%send_buf(:,:,n), commdata%s_faceID, this%is_f(f,n), & ! (in)
243 commdata%Nnode_LCMeshFace, this%bufsize_per_field, & ! (in)
244 this%field_num_tot, lcmesh, this%HaloSize_1D ) ! (in)
245 end do
246 end do
247 !$acc wait(1)
248
249 call prof_rapend( 'comm_exchange_1', 1)
250 !-----------------------
251
252 call prof_rapstart( 'comm_exchange_2', 1)
253
254 call meshfieldcommbase_exchange_core( this, this%commdata_list, do_wait )
255
256 !---------------------
257 call prof_rapend( 'comm_exchange_2', 1)
258
259 return
260 end subroutine meshfieldcommrectdom2d_exchange
261
262!----------------------------
263
264 !> Push temporary buffer of the local send data to the communication buffer
265!OCL SERIAL
266 subroutine push_localsendbuf( lc_send_buf, &
267 send_buf, s_faceID, is, Nnode_LCMeshFace, bufsize_per_field, var_num, &
268 lcmesh, haloSize_1D )
269 use scale_prc, only: prc_abort
270 implicit none
271
272 integer, intent(in) :: var_num
273 integer, intent(in) :: nnode_lcmeshface
274 integer, intent(in) :: bufsize_per_field
275 real(rp), intent(inout) :: lc_send_buf(nnode_lcmeshface,var_num)
276 real(rp), intent(in) :: send_buf(bufsize_per_field,var_num)
277 integer, intent(in) :: s_faceid, is
278 type(localmesh2d), intent(in) :: lcmesh
279 integer, intent(in) :: halosize_1d
280
281 integer :: i, v
282 integer :: ne_h1d
283 integer :: nfp
284 !-----------------------------------------------------------------------------
285
286 if ( s_faceid > 0 ) then
287 !$omp parallel do
288 !$acc parallel loop collapse(2) present(lc_send_buf, send_buf) async(1)
289 do v=1, var_num
290 do i=1, nnode_lcmeshface
291 lc_send_buf(i,v) = send_buf((is-1)*halosize_1d+i,v)
292 end do
293 end do
294 else if ( s_faceid < 0 ) then
295 log_info("MeshFieldCommRectDom2D",'(a,i0)') "Encountered s_faceID <= 0 in push_localsendbuf. Check! s_faceID=", s_faceid
296 call prc_abort
297 end if
298 return
299 end subroutine push_localsendbuf
300
module FElib / Element / Base
module FElib / Mesh / Local 2D
module FElib / Mesh / Rectangle 2D 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_exchange_core(this, commdata_list, do_wait)
Exchange halo data.
module FElib / Data / Communication 2D rectangle domain
integer, parameter comm_face_num
Number of faces with data communication.
module FElib / Mesh / utility for 2D mesh
subroutine, public meshutil2d_genpatchboundarymap_wide(vmapb2, vmapb, halosize, nex, ney, nfp)
Derived type representing a 2D reference element.
Derived type representing an arbitrary finite element.
Derived type representing a local mesh for 2D domain.
Derived type to manage a rectangular 2D computational domain.
Derived type representing a field with 2D 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 2D rectangle domain.