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