identify_elements Subroutine

private recursive subroutine identify_elements(treeID, tree, pathFirst, pathLast, levelDesc, elemPos, proc, Stencil, nesting, skip_add_additionalGhost)

Check, on which partition a given element is located add required elements to corresponding lists: if remote, add to halo if ghost, add to resp. ghost list

Arguments

Type IntentOptional Attributes Name
integer(kind=long_k), intent(in) :: treeID

treeID to identify

type(treelmesh_type), intent(in) :: tree

tree information

type(tem_path_type), intent(in) :: pathFirst(:)

first treeID path in every process

type(tem_path_type), intent(in) :: pathLast(:)

last treeID path in every process

type(tem_levelDesc_type), intent(inout) :: levelDesc(tree%global%minLevel:)

the level descriptor to be filled

integer, intent(out) :: elemPos

nTreeID element position in the levelDesc % elem list

type(tem_comm_env_type), intent(in) :: proc

Process description to use.

type(tem_stencilHeader_type), intent(in) :: Stencil

current stencil definition

integer, intent(in) :: nesting

nesting level

logical, intent(in), optional :: skip_add_additionalGhost

logical, optional, if true no ghosts are added


Calls

proc~~identify_elements~~CallsGraph proc~identify_elements identify_elements proc~identify_elements->proc~identify_elements interface~append~29 append proc~identify_elements->interface~append~29 interface~init~20 init proc~identify_elements->interface~init~20 proc~create_allparentneighbors create_allParentNeighbors proc~identify_elements->proc~create_allparentneighbors proc~identify_stencilneigh identify_stencilNeigh proc~identify_elements->proc~identify_stencilneigh proc~single_process_element single_process_element proc~identify_elements->proc~single_process_element proc~tem_directchildren tem_directChildren proc~identify_elements->proc~tem_directchildren proc~tem_find_depproc tem_find_depProc proc~identify_elements->proc~tem_find_depproc proc~tem_levelof tem_LevelOf proc~identify_elements->proc~tem_levelof proc~tem_pathof tem_PathOf proc~identify_elements->proc~tem_pathof proc~tem_tidinfo tem_tIDinfo proc~identify_elements->proc~tem_tidinfo proc~append_ga_dynlong append_ga_dynlong interface~append~29->proc~append_ga_dynlong proc~append_ga_dynlong_vec append_ga_dynlong_vec interface~append~29->proc~append_ga_dynlong_vec proc~init_ga2d_real init_ga2d_real interface~init~20->proc~init_ga2d_real proc~create_allparentneighbors->proc~identify_elements proc~create_allparentneighbors->interface~append~29 proc~create_allparentneighbors->proc~identify_stencilneigh interface~tem_parentof tem_ParentOf proc~create_allparentneighbors->interface~tem_parentof proc~identify_stencilneigh->proc~identify_elements proc~single_process_element->interface~append~29 proc~single_process_element->interface~init~20 proc~single_process_element->proc~tem_levelof proc~identify_local_element identify_local_element proc~single_process_element->proc~identify_local_element proc~tem_abort tem_abort proc~single_process_element->proc~tem_abort proc~tem_find_depproc_globsearch tem_find_depProc_globSearch proc~tem_find_depproc->proc~tem_find_depproc_globsearch proc~tem_pathcomparison tem_PathComparison proc~tem_find_depproc->proc~tem_pathcomparison proc~tem_baryofid tem_BaryOfId proc~tem_tidinfo->proc~tem_baryofid proc~tem_coordofid tem_CoordOfId proc~tem_tidinfo->proc~tem_coordofid proc~tem_elemsize tem_ElemSize proc~tem_tidinfo->proc~tem_elemsize proc~tem_directparent tem_directParent interface~tem_parentof->proc~tem_directparent proc~tem_parentatlevel tem_ParentAtLevel interface~tem_parentof->proc~tem_parentatlevel interface~expand~25 expand proc~append_ga_dynlong->interface~expand~25 proc~append_ga_dynlong_vec->interface~expand~25 proc~identify_local_element->interface~append~29 proc~identify_local_element->proc~tem_levelof proc~identify_local_element->proc~tem_pathof proc~identify_local_element->proc~tem_tidinfo interface~positionofval~5 positionofval proc~identify_local_element->interface~positionofval~5 proc~add_all_virtual_children add_all_virtual_children proc~identify_local_element->proc~add_all_virtual_children proc~add_ghostfromfiner add_ghostFromFiner proc~identify_local_element->proc~add_ghostfromfiner proc~tem_posofpath tem_PosOfPath proc~identify_local_element->proc~tem_posofpath mpi_abort mpi_abort proc~tem_abort->mpi_abort proc~tem_baryofid->proc~tem_coordofid proc~tem_elemsizelevel tem_ElemSizeLevel proc~tem_baryofid->proc~tem_elemsizelevel proc~tem_coordofid->proc~tem_levelof proc~tem_elemsize->proc~tem_levelof proc~tem_elemsize->proc~tem_elemsizelevel proc~tem_find_depproc_globsearch->proc~tem_pathcomparison

Called by

proc~~identify_elements~~CalledByGraph proc~identify_elements identify_elements proc~identify_elements->proc~identify_elements proc~create_allparentneighbors create_allParentNeighbors proc~identify_elements->proc~create_allparentneighbors proc~identify_stencilneigh identify_stencilNeigh proc~identify_elements->proc~identify_stencilneigh proc~build_levelelements build_levelElements proc~build_levelelements->proc~identify_elements proc~identify_additionalneigh identify_additionalNeigh proc~build_levelelements->proc~identify_additionalneigh proc~create_allparentneighbors->proc~identify_elements proc~create_allparentneighbors->proc~identify_stencilneigh proc~identify_additionalneigh->proc~identify_elements proc~identify_stencilneigh->proc~identify_elements proc~request_remotehalos request_remoteHalos proc~request_remotehalos->proc~create_allparentneighbors proc~request_remotehalos->proc~identify_stencilneigh proc~tem_find_allelements tem_find_allElements proc~tem_find_allelements->proc~build_levelelements proc~tem_find_allelements->proc~identify_additionalneigh proc~communicate_elements communicate_elements proc~tem_find_allelements->proc~communicate_elements proc~communicate_elements->proc~request_remotehalos proc~tem_create_leveldesc tem_create_levelDesc proc~tem_create_leveldesc->proc~tem_find_allelements proc~tem_dimbydim_construction tem_dimByDim_construction proc~tem_dimbydim_construction->proc~tem_create_leveldesc

Source Code

  recursive subroutine identify_elements( treeID, tree, pathFirst, pathLast,  &
    &                                     levelDesc, elemPos, proc,           &
    &                                     Stencil, nesting,                   &
    &                                     skip_add_additionalGhost )
    ! -------------------------------------------------------------------- !
    !> treeID to identify
    integer(kind=long_k), intent(in) :: treeID
    !> tree information
    type(treelmesh_type), intent(in) :: tree
    !> first treeID path in every process
    type(tem_path_type), intent(in) :: pathFirst(:)
    !> last treeID path in every process
    type(tem_path_type), intent(in) :: pathLast(:)
    !> the level descriptor to be filled
    type(tem_levelDesc_type), intent(inout) :: levelDesc(tree%global%minLevel:)
    !> Process description to use.
    type(tem_comm_env_type), intent(in) :: proc
    !> nTreeID element position in the levelDesc % elem list
    integer, intent(out) :: elemPos
    !> current stencil definition
    type(tem_stencilHeader_type), intent(in) :: Stencil
    !> nesting level
    integer, intent(in) :: nesting
    !> logical, optional, if true no ghosts are added
    logical, intent(in), optional :: skip_add_additionalGhost
    ! -------------------------------------------------------------------- !
    integer(kind=long_k) :: children(8) ! child elements
    integer :: nDepProcs ! processes that this neigh depend on
    integer :: depProc
    integer :: iChild, neighLevel
    type(tem_path_type) :: elemPath
    type(tem_stencilElement_type) :: emptyStencil(1)
    integer :: childPos   ! position of child element
    integer :: nNesting ! new nesting level
    ! Position of the current element in the hash
    integer :: hashpos, elemNesting
    logical :: cacheHit
    logical :: updated ! was the element updated during identify_local_element
    logical :: l_skip_add_additionalGhost
    ! -------------------------------------------------------------------- !
    
    if (present(skip_add_additionalGhost)) then 
      l_skip_add_additionalGhost = skip_add_additionalGhost
    else 
      l_skip_add_additionalGhost = .false.
    end if 
    
    ! Increase the nesting
    nNesting = nesting + 1
    cacheHit = .false.
    elemNesting = -999

    if (treeID > 0) then ! it is a element, otherwise it is a bcID
      neighLevel = tem_LevelOf(TreeID)
      elemPath  = tem_PathOf(TreeID)

      hashpos = int(mod(TreeID, nHashes))

      hashmatch: if (hash(hashpos) == TreeID) then

        if ( nesting == levelDesc(neighlevel)         &
          &               %elem                       &
          &               %haloNesting                &
          &               %val(hash_elemPos(hashPos)) ) then
          cacheHit = .true.
        end if
        if ( levelDesc(neighlevel)         &
          &    %elem                       &
          &    %needsUpdate                &
          &    %val(hash_elemPos(hashPos)) ) then
          cacheHit = .false.
          ! Set the needs update to false as it was now updated
          levelDesc(neighLevel)            &
            &  %elem                       &
            &  %needsUpdate                &
            &  %val(hash_elemPos(hashPos)) = .false.
        end if

      end if hashmatch

      cachemiss: if (.not. cacheHit) then
        ! Cache miss
        ! Probably did not hit this element yet, put it in the hash now,
        ! and identify it.
        ! (If this treeID is already in the hash, we definitely have
        !  already processed this treeID, and need nothing to do anymore).
        ! This leaves elements to be identified multiple times only in
        ! the case of hash collisions, which should be pretty few, for
        ! a sufficiently large hash.
        ! -----------------------------------------------
        call tem_find_depProc( depProc   = depProc,   &
          &                    nDepProcs = nDepProcs, &
          &                    tree      = tree,      &
          &                    elemPath  = elemPath,  &
          &                    PathFirst = PathFirst, &
          &                    PathLast  = PathLast   )

        ! How many processes possess a part of the requested treeID
        if (nDepProcs == 1) then
          updated = .false.
          ! Might be a local or halo of same level or a ghostFromCoarser
          ! or a ghostFromFiner. If halo and ghost it is distributed
          ! in single process.
          ! elemPos here is position of TreeID in levelDesc elem list
          call single_process_element( targetID       = TreeID,               &
            &                          levelDesc      = levelDesc,            &
            &                          tree           = tree,                 &
            &                          proc           = proc,                 &
            &                          iProc          = depProc,              &
            &                          minLevel       = tree%global%minlevel, &
            &                          elemPos        = elemPos,              &
            &                          updated        = updated,              &
            &                          stencil        = Stencil,              &
            &                          nesting        = nesting,               &
            &              skip_add_additionalGhost = l_skip_add_additionalGhost)

          if (elemPos > 0) then
          
            elemNesting = min( nesting,              &
              &                levelDesc(neighLevel) &
              &                  %elem               &
              &                  %haloNesting        &
              &                  %val(elemPos)       )

            if ( nesting < levelDesc(neighLevel)%elem%haloNesting  &
              &                                      %val(elemPos) ) then
              ! element needs updating as the current nesting is smaller than the
              ! one in the element property
              levelDesc(neighLevel)%elem%needsUpdate%val(elemPos) = .true.
              levelDesc(neighLevel)%elem%haloNesting%val(elemPos) &
                &  = elemNesting
              updated = .true.
            end if
            
          endif

          ! it is ghost from coarser element in current process proc%rank
          if (updated) then
            if ( levelDesc( neighLevel )%elem%eType%val( elemPos )   &
              &                               == eT_ghostFromCoarser ) then
              if (nesting < nestingLimit) then
                ! Create the direct neighbors of the ghostFromCoarser

                ! identify all the compute neighbors of the current element
                call identify_stencilNeigh( iElem          = elemPos,        &
                  &                         iLevel         = neighLevel,     &
                  &                         tree           = tree,           &
                  &                         iStencil       = 1,              &
                  &                         pathFirst      = pathFirst,      &
                  &                         pathLast       = pathLast,       &
                  &                         levelDesc      = levelDesc,      &
                  &                         proc           = proc,           &
                  &                         stencil        = Stencil,        &
                  &                         nesting        = elemNesting + 1 )

              end if ! nesting < 1?

              ! Create all elements required up to the actual existing fluid
              ! element these include the neighbors of the parents. In a level
              ! jump >1, these intermediate levels have to provide valid
              ! quantities over two of their computation updates to account for
              ! the recursive algorithm.
              call create_allParentNeighbors( &
                &    targetID  = levelDesc(neighLevel)%elem%tID%val(elemPos), &
                &    level     = neighLevel,     &
                &    tree      = tree,           &
                &    stencil   = Stencil, &
                &    levelDesc = levelDesc,      &
                &    pathFirst = pathFirst,      &
                &    pathLast  = pathLast,       &
                &    proc      = proc )

            end if ! ghostFromCoarser?
          end if ! updated?

        else if ( nDepProcs > 1 ) then
          ! more than one depending processes
          ! create ghost and find children (can only have finer children)
          call init( me        = emptyStencil(1),   &
            &        QQN       = Stencil%QQN,       &
            &        headerPos = 1 )
          ! Add to the level-wise ghost list
          ! append and store position of element for return
          call append( me              = levelDesc( neighLevel )%elem, &
            &          tID             = TreeID,                       &
            &          property        = 0_long_k,                     &
            &          eType           = eT_distributedGhostFromFiner, &
            &          stencilElements = emptyStencil,                 &
            &          pos             = elemPos                       )

          !... and store the position in the ghost list !
          ! Now find all children of this ghost
          ! childPos is return but not used anymore
          children = tem_directChildren( TreeID )
          do iChild = 1,8
            call identify_elements( TreeID    = children( iChild ), &
              &                     tree      = tree,               &
              &                     pathFirst = pathFirst,          &
              &                     pathLast  = pathLast,           &
              &                     levelDesc = levelDesc,          &
              &                     proc      = proc,               &
              &                     elemPos   = childPos,           &
              &                     stencil   = Stencil,            &
              &                     nesting   = nNesting,            &
              &  skip_add_additionalGhost = l_skip_add_additionalGhost)
          end do
        else ! nDepProcs < 1
          ! cell not existing. stop.
          write(logUnit(6),*) '---------- WARNING!!! -------------------------'
          write(logUnit(6),*) 'cell', TreeID ,' not existing on proc ',       &
            &        proc%rank, '. Number of dependencies', nDepProcs
          call tem_tIDinfo( me = TreeID, tree = tree, nUnit = logUnit(6) )
          write(logUnit(6),*) 'WARNING!!! This should never occur and '        &
            &                 // 'points to a bug or a buggy mesh.'
        end if

        if (elemPos > 0) then
          ! Set the encountered element position to the hash
          hash(hashpos) = TreeID
          hash_elemPos( hashpos ) = elemPos
        end if
        ! end cache miss
        ! -----------------------------------------------
      else cachemiss
        ! -----------------------------------------------
        ! Cache hit, i.e. element already in levelDesc%elem, just update nesting
        elemPos = hash_elemPos( hashpos )
        levelDesc( neighLevel )%elem%haloNesting%val( elemPos )            &
          &  = min( levelDesc( neighLevel )%elem%haloNesting%val(elemPos), &
          &         nesting                                                )
        ! -----------------------------------------------
      end if cachemiss
    else ! treeID <= 0, i.e. it is a bcID
      elemPos = int( TreeID )
    end if ! TreeID > 0

  end subroutine identify_elements