tem_polygon_material_value Function

public function tem_polygon_material_value(me, nComponents, inVal, outVal, point) result(res)

Return the material value for point, based on the position in relation to the polygon.

The point containment is decided with the help of the Gauss-Bonnet theorem, which is highly robust, but requires the polygon vertices to follow an ordering along the polygon lines.

The returned value will be polygon%inval, if the point is inside and polygon%outside otherwise.

Arguments

Type IntentOptional Attributes Name
type(tem_polygon_vertex_type), intent(in) :: me

Polygon to describe the material shape.

integer, intent(in) :: nComponents
real(kind=rk), intent(in) :: inVal(nComponents)
real(kind=rk), intent(in) :: outVal(nComponents)
real(kind=rk), intent(in) :: point(:)

Point to check against the polygon.

Return Value real(kind=rk), (nComponents)

Material value at point, as defined by the polygon.


Calls

proc~~tem_polygon_material_value~~CallsGraph proc~tem_polygon_material_value tem_polygon_material_value proc~angle_between angle_between proc~tem_polygon_material_value->proc~angle_between

Called by

proc~~tem_polygon_material_value~~CalledByGraph proc~tem_polygon_material_value tem_polygon_material_value proc~tem_eval_polygon_material tem_eval_polygon_material proc~tem_eval_polygon_material->proc~tem_polygon_material_value proc~tem_eval_polygon_material_3d tem_eval_polygon_material_3d proc~tem_eval_polygon_material_3d->proc~tem_polygon_material_value proc~tem_eval_polygon_material_scal tem_eval_polygon_material_scal proc~tem_eval_polygon_material_scal->proc~tem_polygon_material_value proc~tem_eval_polygon_material_scal_3d tem_eval_polygon_material_scal_3d proc~tem_eval_polygon_material_scal_3d->proc~tem_polygon_material_value proc~tem_polygon_material_movement_multi tem_polygon_material_movement_multi proc~tem_polygon_material_movement_multi->proc~tem_polygon_material_value proc~tem_polygon_material_movement_single tem_polygon_material_movement_single proc~tem_polygon_material_movement_single->proc~tem_polygon_material_value proc~tem_polygon_material_test_value tem_polygon_material_test_value proc~tem_polygon_material_test_value->proc~tem_polygon_material_value proc~tem_spacetime_for_coord tem_spacetime_for_coord proc~tem_spacetime_for_coord->proc~tem_polygon_material_movement_multi proc~tem_spacetime_for_coord->proc~tem_polygon_material_movement_single proc~tem_spatial_for_coord tem_spatial_for_coord proc~tem_spatial_for_coord->proc~tem_eval_polygon_material_scal proc~tem_spatial_for_coord->proc~tem_eval_polygon_material_scal_3d proc~tem_spatial_vector_for_coord tem_spatial_vector_for_coord proc~tem_spatial_vector_for_coord->proc~tem_eval_polygon_material proc~tem_spatial_vector_for_coord->proc~tem_eval_polygon_material_3d interface~tem_spacetime_for tem_spacetime_for interface~tem_spacetime_for->proc~tem_spacetime_for_coord interface~tem_spatial_for tem_spatial_for interface~tem_spatial_for->proc~tem_spatial_for_coord interface~tem_spatial_for->proc~tem_spatial_vector_for_coord proc~tem_spacetime_for_stcoord tem_spacetime_for_stcoord proc~tem_spacetime_for_stcoord->proc~tem_spacetime_for_coord proc~tem_spacetime_scalar_for_index tem_spacetime_scalar_for_index proc~tem_spacetime_scalar_for_index->proc~tem_spacetime_for_coord proc~tem_spatial_scalar_for_index tem_spatial_scalar_for_index proc~tem_spatial_scalar_for_index->proc~tem_spatial_for_coord proc~tem_spatial_vector_for_index tem_spatial_vector_for_index proc~tem_spatial_vector_for_index->proc~tem_spatial_vector_for_coord

Source Code

  function tem_polygon_material_value(me, nComponents, inVal, outVal, point) &
    & result(res)
    ! ----------------------------------------------------------------------
    !> Polygon to describe the material shape.
    type(tem_polygon_vertex_type), intent(in) :: me
    integer, intent(in) :: nComponents
    real(kind=rk), intent(in) :: inVal(nComponents)
    real(kind=rk), intent(in) :: outVal(nComponents)

    !> Point to check against the polygon.
    real(kind=rk), intent(in) :: point(:)
    ! ----------------------------------------------------------------------
    !> Material value at point, as defined by the polygon.
    real(kind=rk) :: res(nComponents)
    real(kind=rk) :: diffa(me%nVertices,2)
    real(kind=rk) :: diffb(me%nVertices,2)
    real(kind=rk) :: anglesum
    integer :: iDir
    ! ----------------------------------------------------------------------

    ! Compute difference between all vertices of the polygon and the given
    ! point.
    diffa(:,1) = me%vertex(:,1) - point(1)
    diffa(:,2) = me%vertex(:,2) - point(2)
    ! Copy the differences to a shifted array, to allow the simultaneous
    ! computation of all the angles for polygon segments.
    ! After the last point, we jump back to the first index to close the
    ! polygon again.
    do iDir=1,2
      diffb(:me%nVertices-1,iDir) = diffa(2:,iDir)
      diffb(me%nVertices,iDir) = diffa(1,iDir)
    end do

    ! With the Gauss-Bonnet theorem, we can decide the containment of the
    ! point within the polygon, based on the sum of all angles under which
    ! the polygon segments are seen from the point.
    anglesum = sum( angle_between(va_x = diffa(:,1), va_y = diffa(:,2), &
      &                           vb_x = diffb(:,1), vb_y = diffb(:,2)) )

    if (abs(anglesum) > 3.0_rk) then
      ! The point is inside, if the sum of angles is 2 Pi actually, but to
      ! allow for numerical inaccuracies and points on the polygon segments
      ! we just check for greater 3 here.
      res = inval
    else
      ! Points with a smaller value are deemed to be outside the polygon.
      ! They might actually be located on a vertex, but the angle at the
      ! vertex would be greater for the outside part than the inside, so it
      ! should definitely be ok to assume this point as outside.
      res = outval
    end if

  end function tem_polygon_material_value