| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | HTS | |||
| integer, | intent(in) | :: | GRSNR | |||
| integer, | intent(in) | :: | SBSNR | 
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
SUBROUTINE CHKSBS(HTS,GRSNR,SBSNR)
          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Legacy Code
          !       DATE WRITTEN
          !       MODIFIED       na
          !       RE-ENGINEERED  Lawrie, Oct 2000
          ! PURPOSE OF THIS SUBROUTINE:
          ! Checks that a subsurface is completely
          ! enclosed by its base surface.
          ! METHODOLOGY EMPLOYED:
          ! na
          ! REFERENCES:
          ! BLAST/IBLAST code, original author George Walton
          ! 3D Planar Polygons
          ! In 3D applications, one sometimes wants to test a point and polygon that are in the same plane.
          ! For example, one may have the intersection point of a ray with the plane of a polyhedron's face,
          ! and want to test if it is inside the face.  Or one may want to know if the base of a 3D perpendicular
          ! dropped from a point is inside a planar polygon.
          ! 3D inclusion is easily determined by projecting the point and polygon into 2D.  To do this, one simply
          ! ignores one of the 3D coordinates and uses the other two.  To optimally select the coordinate to ignore,
          ! compute a normal vector to the plane, and select the coordinate with the largest absolute value [Snyder & Barr, 1987].
          ! This gives the projection of the polygon with maximum area, and results in robust computations.
          ! John M. Snyder & Alan H. Barr, "Ray Tracing Complex Models Containing Surface Tessellations",
          ! Computer Graphics 21(4), 119-126 (1987) [also in the Proceedings of SIGGRAPH 1987]
          !--- using adapted routine from Triangulation code -- EnergyPlus.
          ! USE STATEMENTS:
          ! na
  IMPLICIT NONE    ! Enforce explicit typing of all variables in this routine
          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN) :: HTS      ! Heat transfer surface number of the general receiving surf
  INTEGER, INTENT(IN) :: GRSNR    ! Surface number of general receiving surface
  INTEGER, INTENT(IN) :: SBSNR    ! Surface number of subsurface
          ! SUBROUTINE PARAMETER DEFINITIONS:
          ! MSG - for error message
  CHARACTER(len=8), PARAMETER, DIMENSION(4) :: MSG = (/'misses  ','        ','within  ','overlaps'/)
  CHARACTER(len=*), PARAMETER :: AFormat='(1X,A)'
  CHARACTER(len=*), PARAMETER :: A4Format='(1X,A,A,A,A)'
  CHARACTER(len=*), PARAMETER :: A2I2Format='(1X,A,I5,A,I5)'
  CHARACTER(len=*), PARAMETER :: VFormat='(1X,A,I5,A,"(",2(F15.2,","),F15.2,")")'
          ! INTERFACE BLOCK SPECIFICATIONS
          ! na
          ! DERIVED TYPE DEFINITIONS
          ! na
          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  INTEGER N        ! Loop Control
  INTEGER NVT      ! Number of vertices
  REAL(r64), ALLOCATABLE, DIMENSION(:), SAVE :: XVT      ! X Vertices of
  REAL(r64), ALLOCATABLE, DIMENSION(:), SAVE :: YVT      ! Y vertices of
  REAL(r64), ALLOCATABLE, DIMENSION(:), SAVE :: ZVT      ! Z vertices of
  INTEGER NS1      ! Number of the figure being overlapped
  INTEGER NS2      ! Number of the figure doing overlapping
  INTEGER NS3      ! Location to place results of overlap
  LOGICAL, SAVE :: OneTimeFlag=.true.
  logical :: inside
  LOGICAL Out
  REAL(r64) X1,Y1,Z1,X2,Y2,Z2,BX,BY,BZ,BMAX !,SX,SY,SZ
!  INTEGER M
  IF (OneTimeFlag) THEN
    ALLOCATE(XVT(MaxVerticesPerSurface+1))
    ALLOCATE(YVT(MaxVerticesPerSurface+1))
    ALLOCATE(ZVT(MaxVerticesPerSurface+1))
    XVT=0.0d0
    YVT=0.0d0
    ZVT=0.0d0
    OneTimeFlag=.false.
  ENDIF
  NS1    = 1
  NS2    = 2
  NS3    = 3
  HCT(1) = 0.0d0
  HCT(2) = 0.0d0
          ! Put coordinates of base surface into clockwise sequence on the x'-y' plane.
  XVT=0.0d0
  YVT=0.0d0
  ZVT=0.0d0
  XVS=0.0d0
  YVS=0.0d0
  CALL CTRANS(GRSNR,HTS,NVT,XVT,YVT,ZVT)
  DO N = 1, NVT
    XVS(N) = XVT(NVT+1-N)
    YVS(N) = YVT(NVT+1-N)
  END DO
  CALL HTRANS1(NS2,NVT)
          ! Put coordinates of the subsurface into clockwise sequence.
  NVS=Surface(SBSNR)%Sides
  DO N = 1, NVS
    XVS(N) = ShadeV(SBSNR)%XV(NVS+1-N)
    YVS(N) = ShadeV(SBSNR)%YV(NVS+1-N)
  END DO
  CALL HTRANS1(NS1,NVS)
          ! Determine the overlap condition.
  CALL DeterminePolygonOverlap(NS1,NS2,NS3)
          ! Print error condition if necessary.
  IF (OverlapStatus /= FirstSurfWithinSecond) THEN
      OUT=.FALSE.
!C                            COMPUTE COMPONENTS OF VECTOR
!C                            NORMAL TO BASE SURFACE.
      X1 = Surface(GRSNR)%Vertex(1)%X-Surface(GRSNR)%Vertex(2)%X !XV(1,GRSNR)-XV(2,GRSNR)
      Y1 = Surface(GRSNR)%Vertex(1)%Y-Surface(GRSNR)%Vertex(2)%Y !YV(1,GRSNR)-YV(2,GRSNR)
      Z1 = Surface(GRSNR)%Vertex(1)%Z-Surface(GRSNR)%Vertex(2)%Z !ZV(1,GRSNR)-ZV(2,GRSNR)
      X2 = Surface(GRSNR)%Vertex(3)%X-Surface(GRSNR)%Vertex(2)%X !XV(3,GRSNR)-XV(2,GRSNR)
      Y2 = Surface(GRSNR)%Vertex(3)%Y-Surface(GRSNR)%Vertex(2)%Y !YV(3,GRSNR)-YV(2,GRSNR)
      Z2 = Surface(GRSNR)%Vertex(3)%Z-Surface(GRSNR)%Vertex(2)%Z !ZV(3,GRSNR)-ZV(2,GRSNR)
      BX = Y1*Z2-Y2*Z1
      BY = Z1*X2-Z2*X1
      BZ = X1*Y2-X2*Y1
!C                            FIND LARGEST COMPONENT.
      BMAX=MAX(ABS(BX),ABS(BY),ABS(BZ))
!C
      IF(ABS(BX).EQ.BMAX) THEN
!        write(outputfiledebug,*) ' looking bx-bmax',bmax
        DO N=1,Surface(SBSNR)%Sides !NV(SBSNR)
          inside=polygon_contains_point(Surface(GRSNR)%Sides,Surface(GRSNR)%Vertex,Surface(SBSNR)%Vertex(N),.true.,.false.,.false.)
          IF (.not. inside) THEN
            OUT=.true.
!            do m=1,surface(grsnr)%sides
!            write(outputfiledebug,*) 'grsnr,side=',m,surface(grsnr)%vertex
!            write(outputfiledebug,*) 'point outside=',surface(sbsnr)%vertex(n)
!            enddo
!            EXIT
          ENDIF
!          Y1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(NV(GRSNR),GRSNR)-YV(N,SBSNR)
!          Z1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(NV(GRSNR),GRSNR)-ZV(N,SBSNR)
!          DO M=1,Surface(GRSNR)%Sides !NV(GRSNR)
!            Y2 = Y1
!            Z2 = Z1
!            Y1 = Surface(GRSNR)%Vertex(M)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(M,GRSNR)-YV(N,SBSNR)
!            Z1 = Surface(GRSNR)%Vertex(M)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(M,GRSNR)-ZV(N,SBSNR)
!            SX = Y1*Z2-Y2*Z1
!            IF(SX*BX.LT.-1.0E-6) THEN
!              OUT=.TRUE.
!              write(outputfiledebug,*) 'sx*bx=',sx*bx
!              write(outputfiledebug,*) 'grsnr=',surface(grsnr)%vertex(m)
!              write(outputfiledebug,*) 'sbsnr=',surface(sbsnr)%vertex(n)
!            endif
!          ENDDO
!          IF (OUT) EXIT
        ENDDO
      ELSE IF(ABS(BY).EQ.BMAX) THEN
!        write(outputfiledebug,*) ' looking by-bmax',bmax
        DO N=1,Surface(SBSNR)%Sides !NV(SBSNR)
          inside=polygon_contains_point(Surface(GRSNR)%Sides,Surface(GRSNR)%Vertex,Surface(SBSNR)%Vertex(N),.false.,.true.,.false.)
          IF (.not. inside) THEN
            OUT=.true.
!            do m=1,surface(grsnr)%sides
!            write(outputfiledebug,*) 'grsnr,side=',m,surface(grsnr)%vertex
!            write(outputfiledebug,*) 'point outside=',surface(sbsnr)%vertex(n)
!            enddo
!            EXIT
          ENDIF
!          Z1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(NV(GRSNR),GRSNR)-ZV(N,SBSNR)
!          X1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%X-Surface(SBSNR)%Vertex(N)%X !XV(NV(GRSNR),GRSNR)-XV(N,SBSNR)
!          DO M=1,Surface(GRSNR)%Sides !NV(GRSNR)
!            Z2 = Z1
!            X2 = X1
!            Z1 = Surface(GRSNR)%Vertex(M)%Z-Surface(SBSNR)%Vertex(N)%Z !ZV(M,GRSNR)-ZV(N,SBSNR)
!            X1 = Surface(GRSNR)%Vertex(M)%X-Surface(SBSNR)%Vertex(N)%X !XV(M,GRSNR)-XV(N,SBSNR)
!            SY = Z1*X2-Z2*X1
!            IF(SY*BY.LT.-1.0E-6) THEN
!              OUT=.TRUE.
!              write(outputfiledebug,*) 'sy*by=',sy*by
!              write(outputfiledebug,*) 'grsnr=',surface(grsnr)%vertex(m)
!              write(outputfiledebug,*) 'sbsnr=',surface(sbsnr)%vertex(n)
!            ENDIF
!          ENDDO
!          IF (OUT) EXIT
        ENDDO
      ELSE
!        write(outputfiledebug,*) ' looking bz-bmax',bmax
        DO N=1,Surface(SBSNR)%Sides !NV(SBSNR)
          inside=polygon_contains_point(Surface(GRSNR)%Sides,Surface(GRSNR)%Vertex,Surface(SBSNR)%Vertex(N),.false.,.false.,.true.)
          IF (.not. inside) THEN
            OUT=.true.
!            do m=1,surface(grsnr)%sides
!            write(outputfiledebug,*) 'grsnr,side=',m,surface(grsnr)%vertex
!            write(outputfiledebug,*) 'point outside=',surface(sbsnr)%vertex(n)
!            enddo
!            EXIT
          ENDIF
!          X1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%X-Surface(SBSNR)%Vertex(N)%X !XV(NV(GRSNR),GRSNR)-XV(N,SBSNR)
!          Y1 = Surface(GRSNR)%Vertex(Surface(GRSNR)%Sides)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(NV(GRSNR),GRSNR)-YV(N,SBSNR)
!          DO M=1,Surface(GRSNR)%Sides !NV(GRSNR)
!            X2 = X1
!            Y2 = Y1
!            X1 = Surface(GRSNR)%Vertex(M)%X-Surface(SBSNR)%Vertex(N)%X !XV(M,GRSNR)-XV(N,SBSNR)
!            Y1 = Surface(GRSNR)%Vertex(M)%Y-Surface(SBSNR)%Vertex(N)%Y !YV(M,GRSNR)-YV(N,SBSNR)
!            SZ = X1*Y2-X2*Y1
!            IF(SZ*BZ.LT.-1.0E-6) THEN
!              OUT=.TRUE.
!              write(outputfiledebug,*) 'sz*bz=',sz*bz
!              write(outputfiledebug,*) 'grsnr=',surface(grsnr)%vertex(m)
!              write(outputfiledebug,*) 'sbsnr=',surface(sbsnr)%vertex(n)
!            ENDIF
!          ENDDO
!          IF (OUT) EXIT
        ENDDO
      END IF
!    CALL ShowWarningError('Base surface does not surround subsurface (CHKSBS), Overlap Status='//  &
!                           TRIM(cOverLapStatus(OverLapStatus)))
!    CALL ShowContinueError('Surface "'//TRIM(Surface(GRSNR)%Name)//'" '//TRIM(MSG(OverlapStatus))//  &
!                     ' SubSurface "'//TRIM(Surface(SBSNR)%Name)//'"')
!    IF (FirstSurroundError) THEN
!      CALL ShowWarningError('Base Surface does not surround subsurface errors occuring...'//  &
!                     'Check that the SurfaceGeometry object is expressing the proper starting corner and '//  &
!                     'direction [CounterClockwise/Clockwise]')
!      FirstSurroundError=.false.
!    ENDIF
IF (Out) THEN
    NumBaseSubSurround=NumBaseSubSurround+1
    IF (NumBaseSubSurround > 1) THEN
      ALLOCATE(TempSurfErrorTracking(NumBaseSubSurround))
      TempSurfErrorTracking(1:NumBaseSubSurround-1)=TrackBaseSubSurround
      DEALLOCATE(TrackBaseSubSurround)
      ALLOCATE(TrackBaseSubSurround(NumBaseSubSurround))
      TrackBaseSubSurround=TempSurfErrorTracking
      DEALLOCATE(TempSurfErrorTracking)
    ELSE
      ALLOCATE(TrackBaseSubSurround(NumBaseSubSurround))
    ENDIF
    TrackBaseSubSurround(NumBaseSubSurround)%SurfIndex1=GRSNR
    TrackBaseSubSurround(NumBaseSubSurround)%SurfIndex2=SBSNR
    TrackBaseSubSurround(NumBaseSubSurround)%MiscIndex=OverLapStatus
!    CALL ShowRecurringWarningErrorAtEnd('Base surface does not surround subsurface (CHKSBS), Overlap Status='//  &
!                       TRIM(cOverLapStatus(OverLapStatus)), &
!                       TrackBaseSubSurround(GRSNR)%ErrIndex1)
!    CALL ShowRecurringContinueErrorAtEnd('Surface "'//TRIM(Surface(GRSNR)%Name)//'" '//TRIM(MSG(OverlapStatus))//  &
!                       ' SubSurface "'//TRIM(Surface(SBSNR)%Name)//'"',  &
!                      TrackBaseSubSurround(SBSNR)%ErrIndex2)
    write(OutputFileShading,AFormat) '==== Base does not Surround subsurface details ===='
    write(OutputFileShading,A4Format) 'Surface=',TRIM(Surface(GRSNR)%Name),' ',TRIM(cOverLapStatus(OverLapStatus))
    write(OutputFileShading,A2I2Format) 'Surface#=',GRSNR,' NSides=',Surface(GRSNR)%Sides
    DO N=1,Surface(GRSNR)%Sides
      write(OutputFileShading,VFormat) 'Vertex ',N,'=',Surface(GRSNR)%Vertex(N)
    ENDDO
    write(OutputFileShading,A4Format) 'SubSurface=',TRIM(Surface(SBSNR)%Name)
    write(OutputFileShading,A2I2Format) 'Surface#=',SBSNR,' NSides=',Surface(SBSNR)%Sides
    DO N=1,Surface(SBSNR)%Sides
      write(OutputFileShading,VFormat) 'Vertex ',N,'=',Surface(SBSNR)%Vertex(N)
    ENDDO
    write(OutputFileShading,AFormat) '================================'
  END IF
ENDIF
  RETURN
contains
function polygon_contains_point ( nsides, polygon_3d, point_3d, ignorex, ignorey, ignorez) result(inside)
          ! Function information:
          !       Author         Linda Lawrie
          !       Date written   October 2005
          !       Modified       na
          !       Re-engineered  na
          ! Purpose of this function:
          ! Determine if a point is inside a simple 2d polygon.  For a simple polygon (one whose
          ! boundary never crosses itself).  The polygon does not need to be convex.
          ! Methodology employed:
          ! <Description>
          ! References:
          ! M Shimrat, Position of Point Relative to Polygon, ACM Algorithm 112,
          ! Communications of the ACM, Volume 5, Number 8, page 434, August 1962.
          ! Use statements:
  Use DataVectorTypes
  Implicit none ! Enforce explicit typing of all variables in this routine
          ! Function argument definitions:
  integer :: nsides      ! number of sides (vertices)
  type(vector) :: polygon_3d(nsides)  ! points of polygon
  type(vector) :: point_3d  ! point to be tested
  logical :: ignorex
  logical :: ignorey
  logical :: ignorez
  logical :: inside  ! return value, true=inside, false = not inside
          ! Function parameter definitions:
  REAL(r64), parameter :: point_tolerance=.00001d0
          ! Interface block specifications:
          ! na
          ! Derived type definitions:
          ! na
          ! Function local variable declarations:
  integer i
  integer ip1
  type(vector_2d) polygon(nsides)
  type(vector_2d) point
  inside = .false.
  if (ignorex) then
    polygon%x=polygon_3d%y
    polygon%y=polygon_3d%z
    point%x=point_3d%y
    point%y=point_3d%z
  elseif (ignorey) then
    polygon%x=polygon_3d%x
    polygon%y=polygon_3d%z
    point%x=point_3d%x
    point%y=point_3d%z
  elseif (ignorez) then
    polygon%x=polygon_3d%x
    polygon%y=polygon_3d%y
    point%x=point_3d%x
    point%y=point_3d%y
  endif
  do i = 1, nsides
    if ( i < nsides ) then
      ip1 = i + 1
    else
      ip1 = 1
    end if
    if ( ( polygon(i)%y   <  point%y .and. point%y <= polygon(ip1)%y   ) .or. &
         ( point%y <= polygon(i)%y   .and. polygon(ip1)%y   < point%y ) ) then
      if ( ( point%x - polygon(i)%x ) - ( point%y - polygon(i)%y ) &
         * ( polygon(ip1)%x - polygon(i)%x ) / ( polygon(ip1)%y - polygon(i)%y ) < 0 ) then
        inside = .not. inside
      end if
    end if
  end do
  return
end function polygon_contains_point
END SUBROUTINE CHKSBS