FE-Project
Loading...
Searching...
No Matches
scale_meshfieldcomm_base Module Reference

module FElib / Data / Communication base More...

Data Types

type  localmeshcommdata
 Derived type to manage data communication at a face between adjacent local meshes. More...
type  meshfieldcommbase
 Base derived type to manage data communication. More...
interface  meshfieldcommbase_put
type  meshfieldcontainer
 Container to save a pointer of MeshField(1D, 2D, 3D) object. More...

Functions/Subroutines

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_final (this)
 Finalize a base object to manage data communication of fields.
subroutine, public meshfieldcommbase_exchange_core (this, commdata_list, do_wait)
 Exchange halo data.
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_extract_bounddata (var, refelem, mesh, buf)
 Extract halo data from data array with MeshField object and set it to the recieving buffer.
subroutine, public meshfieldcommbase_extract_bounddata_2 (field_list, dim, varid_s, lcmesh_list, buf)
 Extract halo data from data array with MeshField object and set it to the recieving buffer.
subroutine, public meshfieldcommbase_set_bounddata (buf, refelem, mesh, var)
 Extract halo data from the recieving buffer and set it to data array with MeshField object.

Detailed Description

module FElib / Data / Communication base

Description
Base module to manage data communication for element-based methods
Author
Yuta Kawai, Team SCALE

Function/Subroutine Documentation

◆ meshfieldcommbase_init()

subroutine, public scale_meshfieldcomm_base::meshfieldcommbase_init ( class(meshfieldcommbase), intent(inout) this,
integer, intent(in) sfield_num,
integer, intent(in) hvfield_num,
integer, intent(in) htensorfield_num,
integer, intent(in) bufsize_per_field,
integer, intent(in) comm_face_num,
integer, dimension(comm_face_num,mesh%local_mesh_num), intent(in) nnode_lcmeshface,
class(meshbase), intent(in), target mesh )

Initialize a base object to manage data communication of fields.

Parameters
sfield_numNumber of scalar fields
hvfield_numNumber of horizontal vector fields
htensorfield_numNumber of horizontal tensor fields
bufsize_per_fieldBuffer size per a field
comm_face_numNumber of faces on a local mesh which perform data communication
Nnode_LCMeshFaceArray to store the number of nodes

Definition at line 161 of file scale_meshfieldcomm_base.F90.

164
165 implicit none
166
167 class(MeshFieldCommBase), intent(inout) :: this
168 class(Meshbase), intent(in), target :: mesh
169 integer, intent(in) :: sfield_num
170 integer, intent(in) :: hvfield_num
171 integer, intent(in) :: htensorfield_num
172 integer, intent(in) :: bufsize_per_field
173 integer, intent(in) :: comm_face_num
174 integer, intent(in) :: Nnode_LCMeshFace(comm_face_num,mesh%LOCAL_MESH_NUM)
175
176 integer :: n, f
177 class(LocalMeshBase), pointer :: lcmesh
178 !-----------------------------------------------------------------------------
179
180 this%mesh => mesh
181 this%sfield_num = sfield_num
182 this%hvfield_num = hvfield_num
183 this%htensorfield_num = htensorfield_num
184 this%field_num_tot = sfield_num + hvfield_num*2 + htensorfield_num*4
185 this%nfaces_comm = comm_face_num
186
187 if (this%field_num_tot > 0) then
188 allocate( this%send_buf(bufsize_per_field, this%field_num_tot, mesh%LOCAL_MESH_NUM) )
189 allocate( this%recv_buf(bufsize_per_field, this%field_num_tot, mesh%LOCAL_MESH_NUM) )
190 allocate( this%request_send(comm_face_num*mesh%LOCAL_MESH_NUM) )
191 allocate( this%request_recv(comm_face_num*mesh%LOCAL_MESH_NUM) )
192
193 allocate( this%commdata_list(comm_face_num,mesh%LOCAL_MESH_NUM) )
194 allocate( this%is_f(comm_face_num,mesh%LOCAL_MESH_NUM) )
195
196 do n=1, mesh%LOCAL_MESH_NUM
197 this%is_f(1,n) = 1
198 do f=2, this%nfaces_comm
199 this%is_f(f,n) = this%is_f(f-1,n) + nnode_lcmeshface(f-1,n)
200 end do
201
202 call mesh%GetLocalMesh(n, lcmesh)
203 do f=1, this%nfaces_comm
204 call this%commdata_list(f,n)%Init( this, lcmesh, f, nnode_lcmeshface(f,n) )
205 end do
206 end do
207 end if
208
209 this%MPI_pc_flag = .false.
210
211 obj_ind = obj_ind + 1
212 if ( obj_ind > obj_index_max ) then
213 log_error("MeshFieldCommBase_Init",*) 'obj_ind > OBJ_INDEX_MAX. Check!'
214 call prc_abort
215 end if
216 this%obj_ind = obj_ind
217
218 return

Referenced by scale_meshfieldcomm_base::meshfieldcommbase::prepare_pc().

◆ meshfieldcommbase_final()

subroutine, public scale_meshfieldcomm_base::meshfieldcommbase_final ( class(meshfieldcommbase), intent(inout) this)

Finalize a base object to manage data communication of fields.

Definition at line 224 of file scale_meshfieldcomm_base.F90.

225 implicit none
226
227 class(MeshFieldCommBase), intent(inout) :: this
228
229 integer :: n, f
230 integer :: ireq
231 integer :: ierr
232 !-----------------------------------------------------------------------------
233
234 if (this%field_num_tot > 0) then
235 deallocate( this%send_buf, this%recv_buf )
236 deallocate( this%request_send, this%request_recv )
237
238 do n=1, this%mesh%LOCAL_MESH_NUM
239 do f=1, this%nfaces_comm
240 call this%commdata_list(f,n)%Final()
241 end do
242 end do
243 deallocate( this%commdata_list, this%is_f )
244
245 if ( this%MPI_pc_flag ) then
246 do ireq=1, this%req_counter
247 call mpi_request_free( this%request_pc(ireq), ierr )
248 end do
249 deallocate( this%request_pc )
250 end if
251 end if
252
253 return

Referenced by scale_meshfieldcomm_base::meshfieldcommbase::prepare_pc().

◆ meshfieldcommbase_exchange_core()

subroutine, public scale_meshfieldcomm_base::meshfieldcommbase_exchange_core ( class(meshfieldcommbase), intent(inout) this,
type(localmeshcommdata), dimension(this%nfaces_comm, this%mesh%local_mesh_num), intent(inout), target commdata_list,
logical, intent(in), optional do_wait )

Exchange halo data.

Parameters
commdata_listArray of LocalMeshCommData objects which manage information and halo data
do_waitFlag whether MPI_waitall is called and move tmp data of LocalMeshCommData object to a recv buffer

Definition at line 315 of file scale_meshfieldcomm_base.F90.

316#ifdef __FUJITSU
317 use mpi_ext, only: &
318 fjmpi_prequest_startall
319#endif
320! use mpi, only: &
321! MPI_startall
322 use scale_prof
323 implicit none
324
325 class(MeshFieldCommBase), intent(inout) :: this
326 type(LocalMeshCommData), intent(inout), target :: commdata_list(this%nfaces_comm, this%mesh%LOCAL_MESH_NUM)
327 logical, intent(in), optional :: do_wait
328
329 integer :: n, f
330 integer :: ierr
331 logical :: do_wait_
332
333 integer :: i
334 type(LocalMeshCommData), pointer :: lcommdata
335 !-----------------------------------------------------------------------------
336
337 if ( present(do_wait) ) then
338 do_wait_ = do_wait
339 else
340 do_wait_ = .true.
341 end if
342
343! call PROF_rapstart( 'meshfiled_comm_ex_core', 3)
344 !
345 if ( this%MPI_pc_flag ) then
346 !$omp parallel
347 !$omp master
348 if ( this%use_mpi_pc_fujitsu_ext ) then
349#ifdef __FUJITSU
350 ! Use Fujitsu MPI extension for persistent communication
351 call fjmpi_prequest_startall( this%req_counter, this%request_pc(1:this%req_counter), ierr )
352#endif
353 else
354 call mpi_startall( this%req_counter, this%request_pc(1:this%req_counter), ierr )
355 end if
356 !$omp end master
357 !$omp do collapse(2) private(lcommdata)
358 do n=1, this%mesh%LOCAL_MESH_NUM
359 do f=1, this%nfaces_comm
360 lcommdata => commdata_list(f,n)
361 if ( lcommdata%s_rank == lcommdata%lcmesh%PRC_myrank ) then
362 commdata_list(abs(lcommdata%s_faceID), lcommdata%s_tilelocalID)%recv_buf(:,:) &
363 = lcommdata%send_buf(:,:)
364 end if
365 end do
366 end do
367 !$omp end parallel
368 else
369 this%req_counter = 0
370 do n=1, this%mesh%LOCAL_MESH_NUM
371 do f=1, this%nfaces_comm
372 call commdata_list(f,n)%SendRecv( &
373 this%req_counter, this%request_send(:), this%request_recv(:), & ! (inout)
374 commdata_list(:,:) ) ! (inout)
375 end do
376 end do
377 end if
378
379! call PROF_rapend( 'meshfiled_comm_ex_core', 3)
380
381 if ( do_wait_ ) then
382 call meshfieldcommbase_wait_core( this, commdata_list )
383 this%call_wait_flag_sub_get = .false.
384 else
385 this%call_wait_flag_sub_get = .true.
386 end if
387
388 return

References meshfieldcommbase_wait_core().

Referenced by scale_meshfieldcomm_base::meshfieldcommbase::prepare_pc().

◆ meshfieldcommbase_wait_core()

subroutine, public scale_meshfieldcomm_base::meshfieldcommbase_wait_core ( class(meshfieldcommbase), intent(inout) this,
type(localmeshcommdata), dimension(this%nfaces_comm, this%mesh%local_mesh_num), intent(inout), target commdata_list,
type(meshfieldcontainer), dimension(:), intent(inout), optional field_list,
integer, intent(in), optional dim,
integer, intent(in), optional varid_s,
class(localmeshbase), dimension(:), intent(in), optional, target lcmesh_list )

Wait data communication and move tmp data of LocalMeshCommData object to a recv buffer.

Parameters
commdata_listArray of LocalMeshCommData objects which manage information and halo data

Definition at line 395 of file scale_meshfieldcomm_base.F90.

397 use mpi, only: &
398! MPI_waitall, &
399 mpi_status_size
400 use scale_prof
401 implicit none
402
403 class(MeshFieldCommBase), intent(inout) :: this
404 type(LocalMeshCommData), intent(inout), target :: commdata_list(this%nfaces_comm, this%mesh%LOCAL_MESH_NUM)
405 type(MeshFieldContainer), intent(inout), optional :: field_list(:)
406 integer, intent(in), optional :: dim
407 integer, intent(in), optional :: varid_s
408 class(LocalMeshBase), intent(in), optional, target :: lcmesh_list(:)
409
410 integer :: ierr
411 integer :: stat_send(MPI_STATUS_SIZE, this%req_counter)
412 integer :: stat_recv(MPI_STATUS_SIZE, this%req_counter)
413 integer :: stat_pc(MPI_STATUS_SIZE, this%req_counter)
414
415 integer :: n, f
416 integer :: i, var_id
417 integer :: irs(this%nfaces_comm,this%mesh%LOCAL_MESH_NUM), ire(this%nfaces_comm,this%mesh%LOCAL_MESH_NUM)
418
419 class(LocalMeshBase), pointer :: lcmesh
420 integer :: val_size(this%mesh%LOCAL_MESH_NUM)
421 !----------------------------
422
423! call PROF_rapstart( 'meshfiled_comm_wait_core', 2)
424 if ( this%MPI_pc_flag ) then
425 if (this%req_counter > 0) then
426 call mpi_waitall( this%req_counter, this%request_pc(1:this%req_counter), stat_pc, ierr )
427 end if
428 else
429 if ( this%req_counter > 0 ) then
430 call mpi_waitall( this%req_counter, this%request_recv(1:this%req_counter), stat_recv, ierr )
431 call mpi_waitall( this%req_counter, this%request_send(1:this%req_counter), stat_send, ierr )
432 end if
433 end if
434! call PROF_rapend( 'meshfiled_comm_wait_core', 2)
435
436 !---------------------
437
438! call PROF_rapstart( 'meshfiled_comm_wait_post', 2)
439
440 if ( present(field_list) ) then
441 do n=1, this%mesh%LOCAL_MESH_NUM
442 lcmesh => lcmesh_list(n)
443 val_size(n) = lcmesh%refElem%Np * lcmesh%NeA
444 irs(1,n) = lcmesh%refElem%Np * lcmesh%Ne + 1
445 do f=1, this%nfaces_comm
446 ire(f,n) = irs(f,n) + commdata_list(f,n)%Nnode_LCMeshFace - 1
447 if (f<this%nfaces_comm) irs(f+1,n) = ire(f,n) + 1
448 end do
449 end do
450
451 !$omp parallel do private(var_id,n,i,f) collapse(3)
452 do n=1, this%mesh%LOCAL_MESH_NUM
453 do i=1, size(field_list)
454 do f=1, this%nfaces_comm
455 var_id = varid_s + i - 1
456 if (dim==1) then
457 call set_bounddata( field_list(var_id)%field1d%local(n)%val, val_size(n), irs(f,n), ire(f,n), commdata_list(f,n)%recv_buf(:,var_id) )
458 else if (dim==2) then
459 call set_bounddata( field_list(var_id)%field2d%local(n)%val, val_size(n), irs(f,n), ire(f,n), commdata_list(f,n)%recv_buf(:,var_id) )
460 else if (dim==3) then
461 call set_bounddata( field_list(var_id)%field3d%local(n)%val, val_size(n), irs(f,n), ire(f,n), commdata_list(f,n)%recv_buf(:,var_id) )
462 end if
463 end do ! end loop for face
464 end do
465 end do
466 else
467 do n=1, this%mesh%LOCAL_MESH_NUM
468 irs(1,n) = 1
469 do f=1, this%nfaces_comm
470 ire(f,n) = irs(f,n) + commdata_list(f,n)%Nnode_LCMeshFace - 1
471 if (f<this%nfaces_comm) irs(f+1,n) = ire(f,n) + 1
472 end do
473 end do
474
475 !$omp parallel do private(n,var_id,f) collapse(3)
476 do n=1, this%mesh%LOCAL_MESH_NUM
477 do var_id=1, this%field_num_tot
478 do f=1, this%nfaces_comm
479 this%recv_buf(irs(f,n):ire(f,n),var_id,n) = commdata_list(f,n)%recv_buf(:,var_id)
480 end do ! end loop for face
481 end do
482 end do
483 end if
484! call PROF_rapend( 'meshfiled_comm_wait_post', 2)
485 return
486 contains
487!OCL SERIAL
488 subroutine set_bounddata( var, IA, irs_, ire_, recv_buf )
489 implicit none
490 integer, intent(in) :: IA
491 real(RP), intent(inout) :: var(IA)
492 integer, intent(in) :: irs_, ire_
493 real(RP), intent(in) :: recv_buf(ire_-irs_+1)
494 !-----------------------------
495 var(irs_:ire_) = recv_buf(:)
496 return
497 end subroutine set_bounddata
subroutine set_bounddata(var, ia, irs_, ire_, recv_buf)

References set_bounddata().

Referenced by meshfieldcommbase_exchange_core(), and scale_meshfieldcomm_base::meshfieldcommbase::prepare_pc().

◆ meshfieldcommbase_extract_bounddata()

subroutine, public scale_meshfieldcomm_base::meshfieldcommbase_extract_bounddata ( real(rp), dimension(refelem%np * mesh%nea), intent(in) var,
class(elementbase), intent(in) refelem,
class(localmeshbase), intent(in) mesh,
real(rp), dimension(size(mesh%vmapb)), intent(out) buf )

Extract halo data from data array with MeshField object and set it to the recieving buffer.

Definition at line 502 of file scale_meshfieldcomm_base.F90.

503 implicit none
504
505 class(ElementBase), intent(in) :: refElem
506 class(LocalMeshBase), intent(in) :: mesh
507 real(RP), intent(in) :: var(refElem%Np * mesh%NeA)
508 real(RP), intent(out) :: buf(size(mesh%VmapB))
509
510 integer :: i
511 !-----------------------------------------------------------------------------
512 !$omp parallel do
513!OCL PREFETCH
514 do i=1, size(buf)
515 buf(i) = var(mesh%VmapB(i))
516 end do
517 return

Referenced by meshfieldcommbase_extract_bounddata_2(), and scale_meshfieldcomm_base::meshfieldcommbase::prepare_pc().

◆ meshfieldcommbase_extract_bounddata_2()

subroutine, public scale_meshfieldcomm_base::meshfieldcommbase_extract_bounddata_2 ( class(meshfieldcontainer), dimension(:), intent(in), target field_list,
integer, intent(in) dim,
integer, intent(in) varid_s,
class(localmeshbase), dimension(:), intent(in), target lcmesh_list,
real(rp), dimension(size(lcmesh_list(1)%vmapb),size(field_list),size(lcmesh_list)), intent(out) buf )

Extract halo data from data array with MeshField object and set it to the recieving buffer.

Definition at line 522 of file scale_meshfieldcomm_base.F90.

523 implicit none
524 class(MeshFieldContainer), intent(in), target :: field_list(:)
525 integer, intent(in) :: varid_s
526 integer, intent(in) :: dim
527 class(LocalMeshBase), intent(in), target :: lcmesh_list(:)
528 real(RP), intent(out) :: buf(size(lcmesh_list(1)%VmapB),size(field_list),size(lcmesh_list))
529
530 class(LocalMeshBase), pointer :: lcmesh
531 integer :: varid
532 integer :: i, n
533 !-----------------------------------------------------------------------------
534
535 do n=1, size(lcmesh_list)
536 lcmesh => lcmesh_list(n)
537 i = 1
538 do while( i <= size(field_list) )
539 varid = varid_s + i - 1
540 if ( i+1 <= n ) then
541 if (dim==1) then
542 call extract_bounddata_var2( buf(:,varid,n), buf(:,varid+1,n), field_list(varid)%field1d%local(n)%val, field_list(varid+1)%field1d%local(n)%val, lcmesh, lcmesh%refElem )
543 else if(dim==2) then
544 call extract_bounddata_var2( buf(:,varid,n), buf(:,varid+1,n), field_list(varid)%field2d%local(n)%val, field_list(varid+1)%field2d%local(n)%val, lcmesh, lcmesh%refElem )
545 else if(dim==3) then
546 call extract_bounddata_var2( buf(:,varid,n), buf(:,varid+1,n), field_list(varid)%field3d%local(n)%val, field_list(varid+1)%field3d%local(n)%val, lcmesh, lcmesh%refElem )
547 end if
548 i = i + 2
549 else
550 if (dim==1) then
551 call meshfieldcommbase_extract_bounddata( field_list(varid)%field1d%local(n)%val, lcmesh%refElem, lcmesh, buf(:,varid,n) )
552 else if(dim==2) then
553 call meshfieldcommbase_extract_bounddata( field_list(varid)%field2d%local(n)%val, lcmesh%refElem, lcmesh, buf(:,varid,n) )
554 else if(dim==3) then
555 call meshfieldcommbase_extract_bounddata( field_list(varid)%field3d%local(n)%val, lcmesh%refElem, lcmesh, buf(:,varid,n) )
556 end if
557 i = i + 1
558 end if
559 end do
560 end do
561 return
562 contains
563!OCL SERIAL
564 subroutine extract_bounddata_var2( buf1_, buf2_, var1, var2, lmesh, elem )
565 implicit none
566 class(LocalMeshBase), intent(in) :: lmesh
567 class(ElementBase), intent(in) :: elem
568 real(RP), intent(out) :: buf1_(size(lmesh%VMapB))
569 real(RP), intent(out) :: buf2_(size(lmesh%VMapB))
570 real(RP), intent(inout) :: var1(elem%Np*lmesh%NeA)
571 real(RP), intent(inout) :: var2(elem%Np*lmesh%NeA)
572
573 integer :: ii
574 !-----------------------------
575 !$omp parallel do
576!OCL PREFETCH
577 do ii=1, size(buf)
578 buf1_(ii) = var1(lmesh%vmapB(ii))
579 buf2_(ii) = var2(lmesh%vmapB(ii))
580 end do
581 return
582 end subroutine extract_bounddata_var2

References meshfieldcommbase_extract_bounddata().

Referenced by scale_meshfieldcomm_base::meshfieldcommbase::prepare_pc().

◆ meshfieldcommbase_set_bounddata()

subroutine, public scale_meshfieldcomm_base::meshfieldcommbase_set_bounddata ( real(rp), dimension(size(mesh%vmapb)), intent(in) buf,
class(elementbase), intent(in) refelem,
class(localmeshbase), intent(in) mesh,
real(rp), dimension(refelem%np * mesh%nea), intent(inout) var )

Extract halo data from the recieving buffer and set it to data array with MeshField object.

Definition at line 586 of file scale_meshfieldcomm_base.F90.

587 implicit none
588
589 class(ElementBase), intent(in) :: refElem
590 class(LocalMeshBase), intent(in) :: mesh
591 real(RP), intent(in) :: buf(size(mesh%VmapB))
592 real(RP), intent(inout) :: var(refElem%Np * mesh%NeA)
593 !-----------------------------------------------------------------------------
594
595 var(refelem%Np*mesh%NeE+1:refelem%Np*mesh%NeE+size(buf)) = buf(:)
596 return

Referenced by scale_meshfieldcomm_base::meshfieldcommbase::prepare_pc().