Communicate the complete stencil
Currently, this assumes same stencils for all participating elements
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(tem_communication_type), | intent(inout) | :: | send |
send and recv communication buffers |
||
type(tem_communication_type), | intent(inout) | :: | recv |
send and recv communication buffers |
||
type(tem_element_type), | intent(inout) | :: | elem |
levelDesc element list |
||
type(tem_stencilHeader_type), | intent(in) | :: | computeStencil |
array of all stencils used in the simulation |
||
type(tem_comm_env_type), | intent(in) | :: | proc |
Process description to use. |
||
type(tem_commPattern_type), | intent(in) | :: | commPattern |
communication pattern |
||
integer, | intent(in) | :: | iStencil |
amount of values to communicate |
subroutine tem_stencil_communicate( send, recv, elem, computeStencil, & & proc, commPattern, iStencil ) ! --------------------------------------------------------------------------- !> send and recv communication buffers type( tem_communication_type ), intent(inout) :: send, recv !> communication pattern type(tem_commPattern_type), intent(in) :: commPattern !> levelDesc element list type(tem_element_type), intent(inout) :: elem !> Process description to use. type(tem_comm_env_type), intent(in) :: proc !> array of all stencils used in the simulation type(tem_stencilHeader_type), intent(in) :: computeStencil !> amount of values to communicate integer, intent(in) :: iStencil ! --------------------------------------------------------------------------- integer :: iStencilElem, iElem, nElems integer(kind=long_k), allocatable :: buffer(:) type(tem_stencilElement_type ) :: tStencil integer :: addedPos, iProc, elemPos, neighPos, stencilPos logical :: wasAdded ! --------------------------------------------------------------------------- ! Number of local elements in element list nElems = elem%tID%nVals write(dbgUnit(10),*)'in stencil communicate, nElems: ', nElems ! buffer which sends stencil neighbors to remove process allocate( buffer( nElems )) ! Set the temporary (empty) stencil call init( me = tStencil, & & QQN = computeStencil%QQN , & & headerPos = iStencil ) ! add stencil headerPos for all halo elements depends on requested stencil ! communication do iProc = 1, recv%nProcs do iElem = 1, recv%nElemsProc( iProc ) elemPos = recv%elemPos( iProc )%val( iElem ) if( elem%stencil%val( elemPos )%nVals > 0 ) then ! @todo: SZ: this does not make sense since all elements have a stencil ! elem%stencil%val( elemPos )%nVals .gt. 0 for all elements ! Find the stencil corresponding to the current one ( iStencil ) stencilPos = tem_stencil_getHeaderPos( & & me = elem%stencil%val( elemPos ), & & val = iStencil ) ! if none was found, use the most appropriate one (headerPos = 0) ! this assigns the first stencil to the halo element ! why not assign it right away to be 1? if( stencilPos <= 0 )then stencilPos = tem_stencil_getHeaderPos( & & me = elem%stencil%val( elemPos ), & & val = 0 ) elem%stencil%val( elemPos )%val( stencilPos )%headerPos = iStencil end if else ! if stencil is not initialized for this element append tStencil call append( me = elem%stencil%val( elemPos ), val = tStencil ) end if end do end do ! -------------------------------------------------------------------------- ! Do the communication for each stencil tID entry do iStencilElem = 1, computeStencil%QQN ! Fill the send buffer do iProc = 1, send%nProcs do iElem = 1, send%nElemsProc( iProc ) elemPos = send%elemPos( iProc )%val( iElem ) neighPos = elem%stencil%val( elemPos )%val( iStencil )% & & tIDpos( iStencilElem ) buffer( elemPos ) = elem%neighID%val( elemPos )%val( neighPos ) end do ! iElem send end do ! iProc send ! Do the exchange between all participating processes call commPattern%exchange_long( send = send, & & recv = recv, & & state = buffer, & & message_flag = 0, & & comm = proc%comm ) ! Read from the buffer do iProc = 1, recv%nProcs do iElem = 1, recv%nElemsProc( iProc ) elemPos = recv%elemPos( iProc )%val( iElem ) ! Find the stencil corresponding to the current one (iStencil ) stencilPos = tem_stencil_getHeaderPos( & & me = elem%stencil%val( elemPos ), & & val = iStencil ) if( stencilPos > 0 ) then ! Only append elements, if there is only one stencil for the element ! Append the treeID to the element's neighIDs call append( me = elem%neighID%val( elemPos ), & & val = buffer( elemPos), & & pos = addedPos, & & wasAdded = wasAdded ) ! ... and store the appended position to the stencil elem%stencil%val( elemPos )%val( stencilPos )% & & tIDpos( iStencilElem ) = addedPos end if end do ! iElem recv end do ! iProc recv end do ! iStencilElem end subroutine tem_stencil_communicate