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.
Type | Intent | Optional | 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 |
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