A routine to calculate the update to the fields DD>Could improve performance by using a "smart" routine which only operates on local/not empty data
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(fieldmat_type), | intent(inout) | :: | self | |||
complex, | intent(inout), | dimension(:,:,:) | :: | phi | ||
complex, | intent(inout), | dimension(:,:,:) | :: | apar | ||
complex, | intent(inout), | dimension(:,:,:) | :: | bpar | ||
class(pc_type), | intent(in) | :: | pc |
subroutine fm_get_field_update(self, phi, apar, bpar, pc)
use dist_fn, only: getfieldeq, getfieldeq_nogath
use dist_fn_arrays, only: fieldeq, fieldeqa, fieldeqp
implicit none
class(fieldmat_type), intent(inout) :: self
complex, dimension(:,:,:), intent(inout) :: phi,apar,bpar
class(pc_type), intent(in) :: pc
integer :: ik
!First get the field eq
if(pc%has_to_gather)then
call getfieldeq(phi,apar,bpar,fieldeq,fieldeqa,fieldeqp)
else
!<DD>Could improve performance by using a "smart" routine which only operates on local/not empty data
call self%getfieldeq_nogath(phi,apar,bpar,fieldeq,fieldeqa,fieldeqp)
endif
! Now get the field update for each ik. Note that we don't OpenMP
! here as at scale the majority of kyb will not be local so it is
! expected to be better to OpenMP at the supercell level when
! iterating over cells.
do ik=1,self%naky
!Skip non-local ky
if(.not.self%kyb(ik)%is_local) cycle
!Trigger the supercell field updates
!AJ Non-blocking can be done here
call self%kyb(ik)%get_field_update(fieldeq(:,:,ik),fieldeqa(:,:,ik),fieldeqp(:,:,ik))
enddo
!AJ Wait for collective comms here (these are setup in get_field_update
if(field_local_nonblocking_collectives) then
!$OMP PARALLEL DO DEFAULT(none) &
!$OMP PRIVATE(ik) &
!$OMP SHARED(self) &
!$OMP SCHEDULE(static)
do ik=1,self%naky
!Skip non-local ky
if(.not.self%kyb(ik)%is_local) cycle
call self%kyb(ik)%wait_for_nonblocking_collectives()
enddo
!$OMP END PARALLEL DO
end if
end subroutine fm_get_field_update