tem_shape_findElemByBCLabels Subroutine

private subroutine tem_shape_findElemByBCLabels(bcLabels, cutOffQVal, bc_prop, foundAny, map2global, inTree, countPoints, grwPnts, storePnts, bcIDs, stencil)

This routine identifies elements that belong to certain bounaries. Labels of required boundaries are given by bcLabels. bc_prop contains boudnary_ID of all local elements. Firstly, bcLabels are converted into bcIDs. Then all elements in bc_prop are looped over to check if it matches one of the required bcID. If match, its position is save in map2global. Number of elements found on each level is saved in countElems.

Arguments

Type IntentOptional Attributes Name
character(len=labelLen), intent(in) :: bcLabels(:)

bcLabels

real(kind=rk), intent(in) :: cutOffQVal

Cut off qValue

type(tem_BC_prop_type), intent(in) :: bc_prop

bc property

logical, intent(out) :: foundAny

if any element be identified

type(dyn_intarray_type), intent(inout) :: map2global

dynamic array. Elements positions in bc_prop%property%elemID

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

Global tree

integer, intent(inout) :: countPoints

How many points there will be

type(tem_grwPoints_type), intent(inout) :: grwPnts

growing array to store tracking points

logical, intent(in) :: storePnts

to Store points in grwPnts

integer, intent(out), allocatable :: bcIDs(:)

id of boundary condition to be tracked

type(tem_stencilHeader_type), intent(in), optional :: stencil

stencil required to get useful links


Calls

proc~~tem_shape_findelembybclabels~~CallsGraph proc~tem_shape_findelembybclabels tem_shape_findElemByBCLabels interface~append~29 append proc~tem_shape_findelembybclabels->interface~append~29 proc~tem_baryofid tem_BaryOfId proc~tem_shape_findelembybclabels->proc~tem_baryofid proc~tem_elemsize tem_ElemSize proc~tem_shape_findelembybclabels->proc~tem_elemsize proc~append_da_label append_da_label interface~append~29->proc~append_da_label proc~append_da_veclabel append_da_veclabel interface~append~29->proc~append_da_veclabel proc~tem_coordofid tem_CoordOfId proc~tem_baryofid->proc~tem_coordofid proc~tem_elemsizelevel tem_ElemSizeLevel proc~tem_baryofid->proc~tem_elemsizelevel proc~tem_elemsize->proc~tem_elemsizelevel proc~tem_levelof tem_LevelOf proc~tem_elemsize->proc~tem_levelof interface~expand~27 expand proc~append_da_label->interface~expand~27 interface~sortedposofval~5 sortedposofval proc~append_da_label->interface~sortedposofval~5 proc~append_da_veclabel->interface~expand~27 proc~tem_coordofid->proc~tem_levelof proc~expand_da_label expand_da_label interface~expand~27->proc~expand_da_label proc~sortposofval_label sortposofval_label interface~sortedposofval~5->proc~sortposofval_label

Called by

proc~~tem_shape_findelembybclabels~~CalledByGraph proc~tem_shape_findelembybclabels tem_shape_findElemByBCLabels proc~tem_shape2subtree tem_shape2subTree proc~tem_shape2subtree->proc~tem_shape_findelembybclabels proc~tem_create_subtree_of tem_create_subTree_of proc~tem_create_subtree_of->proc~tem_shape2subtree proc~tem_create_subtree_of_st_funlist tem_create_subTree_of_st_funList proc~tem_create_subtree_of_st_funlist->proc~tem_create_subtree_of proc~tem_init_convergence tem_init_convergence proc~tem_init_convergence->proc~tem_create_subtree_of proc~tem_init_tracker_subtree tem_init_tracker_subTree proc~tem_init_tracker_subtree->proc~tem_create_subtree_of proc~tem_write_debugmesh tem_write_debugMesh proc~tem_write_debugmesh->proc~tem_create_subtree_of

Source Code

  subroutine tem_shape_findElemByBCLabels( bcLabels, cutOffQVal, bc_prop,     &
    &                                      foundAny, map2global, inTree,      &
    &                                      countPoints, grwPnts, storePnts,   &
    &                                      bcIDs, stencil )
    ! --------------------------------------------------------------------------
    !> bcLabels
    character(len=labelLen), intent(in) :: bcLabels(:)
    !> Cut off qValue
    real(kind=rk), intent(in) :: cutOffQVal
    !> bc property
    type(tem_bc_prop_type), intent(in) :: bc_prop
    !> if any element be identified
    logical,                 intent(out) :: foundAny
    !> dynamic array. Elements positions in bc_prop%property%elemID
    type(dyn_intArray_type), intent(inout) :: map2global
    !> Global tree
    type(treelmesh_type), intent(in) :: inTree
    !> How many points there will be
    integer, intent( inout ) :: countPoints
    !> growing array to store tracking points
    type(tem_grwPoints_type), intent(inout) :: grwPnts
    !> to Store points in grwPnts
    logical, intent(in) :: storePnts
    !> id of boundary condition to be tracked
    integer, allocatable, intent(out) :: bcIDs(:)
    !> stencil required to get useful links
    type( tem_stencilHeader_type ), optional, intent(in) :: stencil
    ! --------------------------------------------------------------------------
    integer :: dPos, iElem, iBC, nBCs, iBCtype, posInTree, QQN
    logical :: wasAdded, found
    integer, allocatable :: map(:)
    real(kind=rk), allocatable :: qValWeight(:), weightedQVal(:)
    real(kind=rk) :: dx, bary(3), point(3), minQVal
    integer :: iDir, length, iElem_qVal, minQValiDir
    ! --------------------------------------------------------------------------

    if( present( stencil ) ) then
      allocate( map( size(stencil%map) ) )
      map = stencil%map
      qqn = stencil%QQN
    else
      allocate( map(qQQQ) )
      map = qDir
      qqn = qQQQ
    end if

    ! calculate weights on qValue for each direction. 
    ! It depends on the link length.
    allocate(weightedQVal(qqn))
    allocate(qValWeight(qqn))
    do iDir = 1, qqn
      length   = qOffset( map(iDir), 1 )**2 &
        &      + qOffset( map(iDir), 2 )**2 &
        &      + qOffset( map(iDir), 3 )**2

      qValWeight(iDir) = sqrt(real(length, kind=rk))
    end do

    foundAny = .false.
    ! convert bcLabels to bcIDs
    nBCs = size(bcLabels)
    allocate( bcIDs( nBCs ) )

    ! loop over all required bcLabels
    do iBC = 1, nBCs

      found = .false.

      ! loop over all BCs in the mesh
      do iBCtype = 1, bc_prop%nBCtypes
        if ( trim(bcLabels(iBC)) == bc_prop%bc_label( iBCtype ) ) then
          bcIDs( iBC ) = iBCtype
          found = .true.
          exit
        end if
      end do

      if ( .not. found ) then
        write(logUnit(1),*) 'Required BC label: '//trim(bcLabels(iBC))
        write(logUnit(1),*) 'can not be found in given mesh!'
        stop
      end if
    end do ! iBC

    iElem_qVal = 0
    ! Loop over all element with boundary property
    do iElem = 1, bc_prop%property%nElems
      posInTree = bc_prop%property%elemID(iElem)
      ! Count the elem with qVal property to access the qVal from
      ! bc_prop%qVal
      if ( btest( inTree%elemPropertyBits( posInTree ), prp_hasQVal) ) then
        iElem_qVal = iElem_qVal + 1
      end if

      do iBC = 1, nBCs
        if ( any(int(bc_prop%boundary_ID( map(:qqn), iElem )) == bcIDs(iBC) ) ) then

          ! If element has qValues then consider element which satisfy
          ! cutOffQVal
          if (btest(inTree%ElemPropertyBits(posInTree), prp_hasQVal)) then
            do iDir = 1, qqn
              weightedQVal(iDir) = qValWeight(iDir)                  &
                &                * bc_prop%qVal(map(iDir), iElem_qVal)
            end do
            minQValiDir = minloc(weightedQVal, DIM=1, MASK=(weightedQVal>0))
            minQVal = bc_prop%qVal(map(minQValiDir), iElem_qVal)
          else
            minQVal = cutOffQVal
          end if

          if (minQVal <= cutOffQVal) then

            ! Append to treeID list (note that already existing ones are
            ! omitted)
            call append( me       = map2global,   &
              &          pos      = dPos,         &
              &          val      = posInTree,    &
              &          wasAdded = wasAdded )

            ! Count up if it was added
            if( wasAdded ) then
              ! tLevel = tem_levelOf( inTree%treeID(posInTree) )
              ! countElems( tLevel ) = countElems( tLevel ) + 1
              foundAny = .true.

              if (storePnts) then
                ! Create growing array of points for boundary elements with 
                ! qValues.
                ! Point is created along minimum qValue direction.
                bary = tem_BaryOfId( inTree, inTree%treeID(posInTree) )
                if (btest(inTree%ElemPropertyBits(posInTree), prp_hasQVal)) then
                  dx = tem_ElemSize( inTree, inTree%treeID(posInTree) ) 
                  point = bary + dx * qOffset(map(minQValiDir), :)
                  ! append the physical points to the growing array of points
                  call append( me  = grwPnts, &
                    &          val = point    )
                else
                  call append( me  = grwPnts, &
                    &          val = bary     )
                end if
                countPoints = countPoints + 1
              end if
            end if !storePnts

            exit ! continue with next element
          end if ! wasAdded

        end if ! boundary_ID == bcIDs
      end do

    end do ! iElem

  end subroutine tem_shape_findElemByBCLabels