FE-Project
Loading...
Searching...
No Matches
scale_meshfieldcomm_cubedom3d.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Data / Communication 3D cubic domain
3!!
4!! @par Description
5!! A module to manage data communication with 3D cubic 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
22 use scale_meshfieldcomm_base, only: &
32 use scale_prof
33 !-----------------------------------------------------------------------------
34 implicit none
35 private
36
37 !-----------------------------------------------------------------------------
38 !
39 !++ Public type & procedure
40 !
41
42 !> Base derived type to manage data communication with 3D cubic domain
43 type, public, extends(meshfieldcommbase) :: meshfieldcommcubedom3d
44 class(meshcubedom3d), pointer :: mesh3d !< Pointer to an object representing 3D cubic computational mesh
45
46 integer :: halosize_h1d !< Halo size for 1D horizontal direction
47 integer :: halosize_v !< Halo size for vertical direction
48 contains
49 procedure, public :: init => meshfieldcommcubedom3d_init
50 procedure, public :: put => meshfieldcommcubedom3d_put
51 procedure, public :: get => meshfieldcommcubedom3d_get
52 procedure, public :: exchange => meshfieldcommcubedom3d_exchange
53 procedure, public :: final => meshfieldcommcubedom3d_final
55
56 !-----------------------------------------------------------------------------
57 !
58 !++ Public parameters & variables
59 !
60
61 !-----------------------------------------------------------------------------
62 !
63 !++ Private procedure
64 !
65 private :: push_localsendbuf
66
67 !-----------------------------------------------------------------------------
68 !
69 !++ Private parameters & variables
70 !
71 integer, parameter :: comm_face_num = 6 !< Number of faces with data communication
72
73contains
74!> Initialize an object to manage data communication with 3D cubic domain
75 subroutine meshfieldcommcubedom3d_init( this, &
76 sfield_num, hvfield_num, htensorfield_num, mesh3d, &
77 haloSize_h1D, haloSize_v )
78
80 implicit none
81
82 class(meshfieldcommcubedom3d), intent(inout) :: this
83 integer, intent(in) :: sfield_num !< Number of scalar fields
84 integer, intent(in) :: hvfield_num !< Number of horizontal vector fields
85 integer, intent(in) :: htensorfield_num !< Number of horizontal vector fields
86 class(meshcubedom3d), intent(in), target :: mesh3d !< Object to manage a 3D cubic computational mesh
87 integer, intent(in), optional :: halosize_h1d !< Halo size for 1D horizontal direction (if not given, halo size of mesh3d is used)
88 integer, intent(in), optional :: halosize_v !< Halo size for vertical direction (if not given, halo size of mesh3d is used)
89
90 type(localmesh3d), pointer :: lcmesh
91 type(elementbase3d), pointer :: elem
92 integer :: n
93 integer :: nnode_lcmeshface(comm_face_num,mesh3d%local_mesh_num)
94 !-----------------------------------------------------------------------------
95
96 this%mesh3d => mesh3d
97 lcmesh => mesh3d%lcmesh_list(1)
98 elem => lcmesh%refElem3D
99
100
101 !-
102 if ( present(halosize_h1d) ) then
103 this%haloSize_h1D = halosize_h1d
104 else
105 this%haloSize_h1D = 1
106 end if
107 if ( present(halosize_v) ) then
108 this%haloSize_v = halosize_v
109 else
110 this%haloSize_v = 1
111 end if
112
113 !-
114 allocate( this%VMapB_size(this%mesh3d%LOCAL_MESH_NUM) )
115
116 this%bufsize_per_field = 2 * (lcmesh%NeX + lcmesh%NeY) * lcmesh%NeZ*elem%Nfp_h*this%haloSize_h1D &
117 + 2 * lcmesh%NeX*lcmesh%NeY * elem%Nfp_v*this%haloSize_v
118
119
120 do n=1, this%mesh3d%LOCAL_MESH_NUM
121 lcmesh => this%mesh3d%lcmesh_list(n)
122 nnode_lcmeshface(:,n) = &
123 (/ lcmesh%NeX, lcmesh%NeY, lcmesh%NeX, lcmesh%NeY, 0, 0 /) * lcmesh%NeZ * lcmesh%refElem3D%Nfp_h*this%haloSize_h1D &
124 + (/ 0, 0, 0, 0, 1, 1 /) * lcmesh%NeX*lcmesh%NeY * lcmesh%refElem3D%Nfp_v*this%haloSize_v
125 end do
126
127 call meshfieldcommbase_init( this, sfield_num, hvfield_num, htensorfield_num, this%bufsize_per_field, comm_face_num, nnode_lcmeshface, mesh3d )
128
129 !-
130 if ( this%haloSize_h1D > 1 .or. this%haloSize_v > 1) then
131 this%use_vmap_wide_flag = .true.
132 allocate( this%VMapB2(this%bufsize_per_field) )
133
134 lcmesh => this%mesh3d%lcmesh_list(1)
135 call meshutil3d_genpatchboundarymap_wide( this%VMapB2, &
136 lcmesh%VMapB, this%haloSize_h1D, this%haloSize_v, &
137 lcmesh%NeX, lcmesh%NeY, lcmesh%NeZ, &
138 elem%Nfp_h, elem%Nfp_v, elem%Nnode_h1D, elem%Nnode_v )
139 !$acc enter data copyin(this%VMapB2)
140 else
141 this%use_vmap_wide_flag = .false.
142 end if
143
144 do n=1, this%mesh3d%LOCAL_MESH_NUM
145 lcmesh => this%mesh3d%lcmesh_list(n)
146 if ( this%use_vmap_wide_flag ) then
147 this%VMapB_size(n) = size(this%VMapB2)
148 else
149 this%VMapB_size(n) = size(lcmesh%VMapB)
150 end if
151 end do
152 !$acc enter data copyin(this%VMapB_size)
153
154 return
155 end subroutine meshfieldcommcubedom3d_init
156
157!> Finalize an object to manage data communication with 3D cubic domain
158 subroutine meshfieldcommcubedom3d_final( this )
159 implicit none
160 class(meshfieldcommcubedom3d), intent(inout) :: this
161 !-----------------------------------------------------------------------------
162 call meshfieldcommbase_final( this )
163 return
164 end subroutine meshfieldcommcubedom3d_final
165
166!> Put field data into temporary buffers
167 subroutine meshfieldcommcubedom3d_put(this, field_list, varid_s)
168 implicit none
169 class(meshfieldcommcubedom3d), intent(inout) :: this
170 type(meshfieldcontainer), intent(in) :: field_list(:) !< Array of objects with 3D mesh field
171 integer, intent(in) :: varid_s !< Start index with variables when field_list(1) is written to buffers for data communication
172
173 integer :: i, n
174 type(localmesh3d), pointer :: lcmesh
175 integer :: field_num
176 !-----------------------------------------------------------------------------
177
178! call PROF_rapstart( 'comm_put', 2)
179! call PROF_rapstart( 'meshfiled_comm_put', 3)
180 if ( this%use_vmap_wide_flag ) then
181 call meshfieldcommbase_extract_bounddata_3( field_list, 3, varid_s, this%mesh3d%lcmesh_list, this%VMapB2, this%VMapB_size(1), & ! (in)
182 this%send_buf ) ! (out)
183 else
185 field_list, 3, varid_s, this%mesh3d%lcmesh_list, size(this%mesh3d%lcmesh_list(1)%VMapB), & !(in)
186 this%send_buf ) ! (out)
187 end if
188! call PROF_rapend( 'meshfiled_comm_put', 3)
189! call PROF_rapend( 'comm_put', 2)
190
191 return
192 end subroutine meshfieldcommcubedom3d_put
193
194!> Extract field data from temporary buffers
195 subroutine meshfieldcommcubedom3d_get(this, field_list, varid_s)
196 use scale_meshfieldcomm_base, only: &
198 implicit none
199
200 class(meshfieldcommcubedom3d), intent(inout) :: this
201 type(meshfieldcontainer), intent(inout) :: field_list(:) !< Array of objects with 3D mesh field
202 integer, intent(in) :: varid_s !< Start index with variables when field_list(1) is written to buffers for data communication
203
204 integer :: i
205 integer :: n
206 type(localmesh3d), pointer :: lcmesh
207 !-----------------------------------------------------------------------------
208! call PROF_rapstart( 'comm_get', 2)
209
210 if ( this%call_wait_flag_sub_get ) then
211 ! call PROF_rapstart( 'meshfiled_comm_wait_get', 2)
212 call meshfieldcommbase_wait_core( this, this%commdata_list, &
213 field_list, 3, varid_s, this%mesh3d%lcmesh_list )
214 ! call PROF_rapend( 'meshfiled_comm_wait_get', 2)
215 else
216 ! call PROF_rapstart( 'meshfiled_comm_get', 2)
217 do i=1, size(field_list)
218 do n=1, this%mesh3d%LOCAL_MESH_NUM
219 lcmesh => this%mesh3d%lcmesh_list(n)
220 if ( this%use_vmap_wide_flag ) then
221 call meshfieldcommbase_set_bounddata_3( this%recv_buf(:,varid_s+i-1,n), lcmesh%refElem, lcmesh, & ! (in)
222 this%VMapB2, this%VMapB_size(1), & ! (in)
223 field_list(i)%field3d%local(n)%val ) !(out)
224 else
225 call meshfieldcommbase_set_bounddata( this%recv_buf(:,varid_s+i-1,n), lcmesh%refElem, lcmesh, & !(in)
226 field_list(i)%field3d%local(n)%val ) !(out)
227 end if
228 end do
229 end do
230 !$acc wait(1)
231 ! call PROF_rapend( 'meshfiled_comm_get', 2)
232 end if
233! call PROF_rapend( 'comm_get', 2)
234
235 return
236 end subroutine meshfieldcommcubedom3d_get
237
238!> Exchange field data between neighboring MPI processes
239!!
240!! @param do_wait Flag whether MPI_waitall is called and move tmp data of LocalMeshCommData object to a recv buffer
241!OCL SERIAL
242 subroutine meshfieldcommcubedom3d_exchange( this, do_wait )
243 use scale_meshfieldcomm_base, only: &
246 use scale_prof
247 implicit none
248
249 class(meshfieldcommcubedom3d), intent(inout), target :: this
250 logical, intent(in), optional :: do_wait
251
252 integer :: n, f
253 type(localmesh3d), pointer :: lcmesh
254 type(localmeshcommdata), pointer :: commdata
255 !-----------------------------------------------------------------------------
256
257! call PROF_rapstart( 'comm_exchange_1', 2)
258
259! call PROF_rapstart( 'meshfiled_comm_ex_push_buf', 3)
260 do n=1, this%mesh%LOCAL_MESH_NUM
261 lcmesh => this%mesh3d%lcmesh_list(n)
262 do f=1, this%nfaces_comm
263 commdata => this%commdata_list(f,n)
264 call push_localsendbuf( commdata%send_buf, & ! (inout)
265 this%send_buf(:,:,n), commdata%s_faceID, this%is_f(f,n), & ! (in)
266 commdata%Nnode_LCMeshFace, this%bufsize_per_field, & ! (in)
267 this%field_num_tot, lcmesh, this%haloSize_h1D ) ! (in)
268 end do
269 end do
270 !$acc wait(1)
271! call PROF_rapend( 'meshfiled_comm_ex_push_buf', 3)
272! call PROF_rapend( 'comm_exchange_1', 2)
273
274 !-----------------------
275! call PROF_rapstart( 'comm_exchange_2', 2)
276
277 call meshfieldcommbase_exchange_core(this, this%commdata_list, do_wait )
278! call PROF_rapend( 'comm_exchange_2', 2)
279
280 return
281 end subroutine meshfieldcommcubedom3d_exchange
282
283!----------------------------
284
285!OCL SERIAL
286 subroutine push_localsendbuf( lc_send_buf, &
287 send_buf, s_faceID, is, Nnode_LCMeshFace, bufsize_per_field, var_num, &
288 lcmesh, haloSize_h1D )
289 use scale_prc, only: prc_abort
290 implicit none
291 integer, intent(in) :: nnode_lcmeshface
292 integer, intent(in) :: bufsize_per_field
293 integer, intent(in) :: var_num
294 real(rp), intent(out) :: lc_send_buf(nnode_lcmeshface,var_num)
295 real(rp), intent(in) :: send_buf(bufsize_per_field,var_num)
296 integer, intent(in) :: s_faceid, is
297 type(localmesh3d), intent(in) :: lcmesh
298 integer, intent(in) :: halosize_h1d
299
300 integer :: ie
301 integer :: vid, i
302 class(elementbase3d), pointer :: e3d
303 !-----------------------------------------------------------------------------
304
305 if ( s_faceid > 0 ) then
306 !$omp parallel do
307 !$acc parallel loop collapse(2) present(lc_send_buf, send_buf) async(1)
308 do vid=1, var_num
309 do i=1, nnode_lcmeshface
310 lc_send_buf(i,vid) = send_buf(is+i-1,vid)
311 end do
312 end do
313 else
314 log_info("MeshFieldCommCubeDom3D",'(a,i0)') "Encountered s_faceID <= 0 in push_localsendbuf. Check! s_faceID=", s_faceid
315 call prc_abort
316 end if
317 return
318 end subroutine push_localsendbuf
module FElib / Element / Base
module FElib / Mesh / Local 3D
module FElib / Mesh / Cubic 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_exchange_core(this, commdata_list, do_wait)
Exchange halo data.
module FElib / Data / Communication 3D cubic domain
integer, parameter comm_face_num
Number of faces with data communication.
module FElib / Mesh / utility for 3D mesh
subroutine, public meshutil3d_genpatchboundarymap_wide(vmapb2, vmapb, halosize_h, halosize_v, nex, ney, nez, nfp_h, nfp_v, nnode_h1d, nnode_v)
Derived type representing a 3D reference element.
Derived type representing an arbitrary finite element.
Derived type to manage a local 3D computational domain.
Derived type to manage a cubic 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 cubic domain.