Nodes of different colours represent the following:
Solid arrows point from a parent (sub)module to the submodule which is descended from it. Dashed arrows point from a module being used to the module or program unit using it. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer, | intent(in) | :: | ThisSurf | |||
logical, | intent(inout) | :: | ErrorsFound |
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 ProcessSurfaceVertices(ThisSurf,ErrorsFound)
! SUBROUTINE INFORMATION:
! AUTHOR Legacy Code (Walton)
! DATE WRITTEN 1976
! MODIFIED FW, Mar 2002: Add triangular windows
! FW, May 2002: modify test for 4-sided but non-rectangular subsurfaces
! FW, Sep 2002: add shape for base surfaces (walls and detached shading surfaces)
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! This subroutine processes each surface into the vertex representation used
! by the shading procedures.
! This routine depends on the surfaces coming in:
! Base Surface
! SubSurface (Window/Door)
! SubSurface
! Base Surface
! SubSurface
! SubSurface
! Thus, some attributes of the "Base Surface" must be SAVEd.
! METHODOLOGY EMPLOYED:
! Detached Shading, Base Surfaces, Attached Shading surfaces are represented in the
! same manner as original. Subsurfaces (windows, doors) are a "relative coordinate".
! REFERENCES:
! na
! USE STATEMENTS:
USE General, ONLY: TrimSigDigits
USE Vectors
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER, INTENT(IN) :: ThisSurf ! Surface Number
LOGICAL, INTENT(INOUT) :: ErrorsFound
! SUBROUTINE PARAMETER DEFINITIONS:
CHARACTER(len=*), PARAMETER :: RoutineName='ProcessSurfaceVertices: '
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
! na
! LOCAL VARIABLES
! REAL(r64) :: X00 ! Intermediate Result
! REAL(r64) :: Y00 ! Intermediate Result
! REAL(r64) :: Z00 ! Intermediate Result
! REAL(r64) :: A(3,3) ! Surface Rotation Matrix
! REAL(r64), SAVE :: B(3,3) ! Inverse Of Rotation Matrix
REAL(r64) :: X1 ! Intermediate Result
REAL(r64) :: Y1 ! Intermediate Result
REAL(r64) :: Z1 ! Intermediate Result
REAL(r64), SAVE :: XSHIFT ! Shift of X to Lower Left Corner
REAL(r64), SAVE :: YSHIFT ! Shift of Y to Lower Left Corner
REAL(r64) :: XLLC ! X-coordinate of lower left corner
REAL(r64) :: YLLC ! Y-coordinate of lower left corner
REAL(r64) :: ZLLC ! Z-coordinate of lower left corner
REAL(r64), ALLOCATABLE, DIMENSION(:), SAVE :: X
REAL(r64), ALLOCATABLE, DIMENSION(:), SAVE :: Y
REAL(r64), ALLOCATABLE, DIMENSION(:), SAVE :: Z
LOGICAL :: OneTimeFlag=.true.
! INTEGER :: I ! Loop Control
! INTEGER :: J ! Loop Control
INTEGER :: N ! Vertex Number in Loop
INTEGER ThisBaseSurface ! Current base surface
REAL(r64) Xp
REAL(r64) Yp
REAL(r64) Zp
REAL(r64), SAVE :: BaseCosAzimuth
REAL(r64), SAVE :: BaseCosTilt
REAL(r64), SAVE :: BaseSinAzimuth
REAL(r64), SAVE :: BaseSinTilt
REAL(r64), SAVE :: BaseXLLC
REAL(r64), SAVE :: BaseYLLC
REAL(r64), SAVE :: BaseZLLC
REAL(r64) SurfWorldAz ! Surface Azimuth (facing)
REAL(r64) SurfTilt ! Surface Tilt
type (planeeq) BasePlane
! type (planeeq) PlanarEQ
! type (vector), dimension(3) :: TriVect
! REAL(r64) testval
! INTEGER ploop
! INTEGER vloop
type (vector) TVect
type (vector) CoordinateTransVector
INTEGER ThisShape
LOGICAL BaseSurface ! True if a base surface or a detached shading surface
REAL(r64) ThisSurfAz
REAL(r64) ThisSurfTilt
REAL(r64) ThisReveal
REAL(r64) ThisWidth
REAL(r64) ThisHeight
INTEGER FrDivNum ! Frame/divider number
REAL(r64) FrWidth ! Frame width for exterior windows (m)
REAL(r64) FrArea ! Frame area for exterior windows(m2)
REAL(r64) DivWidth ! Divider width for exterior windows (m)
REAL(r64) DivArea ! Divider area for exterior windows (m2)
REAL(r64) DivFrac ! Fraction of divider area without overlaps
LOGICAL ErrorInSurface ! false/true, depending on pass through routine
REAL(r64) Diagonal1 ! Length of diagonal of 4-sided figure (m)
REAL(r64) Diagonal2 ! Length of diagonal of 4-sided figure (m)
LOGICAL SError
LOGICAL HeatTransSurf
LOGICAL IsCoplanar
REAL(r64) OutOfLine
INTEGER LastVertexInError
ErrorInSurface=.false.
IF (OneTimeFlag) THEN
ALLOCATE(X(MaxVerticesPerSurface))
ALLOCATE(Y(MaxVerticesPerSurface))
ALLOCATE(Z(MaxVerticesPerSurface))
X=0.0d0
Y=0.0d0
Z=0.0d0
OneTimeFlag=.false.
ENDIF
! Categorize this surface
IF (Surface(ThisSurf)%BaseSurf == 0 .or. Surface(ThisSurf)%BaseSurf == ThisSurf) THEN
BaseSurface=.true.
ELSE
BaseSurface=.false.
ENDIF
ThisBaseSurface=Surface(ThisSurf)%BaseSurf ! Dont know if this is still needed or not
HeatTransSurf = Surface(ThisSurf)%HeatTransSurf
! Kludge for daylighting shelves
IF (Surface(ThisSurf)%ShadowingSurf) THEN
ThisBaseSurface = ThisSurf
HeatTransSurf = .TRUE.
END IF
!IF (Surface(ThisSurf)%Name(1:3) /= 'Mir') THEN
IF (.NOT. Surface(ThisSurf)%MirroredSurf) THEN
CALL CalcCoPlanarNess(Surface(ThisSurf)%Vertex,Surface(ThisSurf)%Sides,IsCoplanar,OutOfLine,LastVertexInError)
IF (.not. IsCoPlanar) THEN
IF (OutOfLine > .01d0) THEN
CALL ShowSevereError(RoutineName//'Suspected non-planar surface:"'//TRIM(Surface(ThisSurf)%Name)//'",'// &
' Max "out of line"='//TRIM(TrimSigDigits(OutOfLine,5))//' at Vertex # '// &
TRIM(TrimSigDigits(LastVertexInError)))
ELSE
CALL ShowWarningError(RoutineName//'Possible non-planar surface:"'//TRIM(Surface(ThisSurf)%Name)//'",'// &
' Max "out of line"='//TRIM(TrimSigDigits(OutOfLine,5))//' at Vertex # '// &
TRIM(TrimSigDigits(LastVertexInError)))
ENDIF
! ErrorInSurface=.true.
ENDIF
ENDIF
IF (BaseSurface) THEN
SurfWorldAz=Surface(ThisSurf)%Azimuth
SurfTilt=Surface(ThisSurf)%Tilt
BaseCosAzimuth=COS(SurfWorldAz*DegToRadians)
BaseSinAzimuth=SIN(SurfWorldAz*DegToRadians)
BaseCosTilt=COS(SurfTilt*DegToRadians)
BaseSinTilt=SIN(SurfTilt*DegToRadians)
DO N=1,Surface(ThisSurf)%Sides
X(N)=Surface(ThisSurf)%Vertex(N)%X
Y(N)=Surface(ThisSurf)%Vertex(N)%Y
Z(N)=Surface(ThisSurf)%Vertex(N)%Z
ENDDO
BaseXLLC=Surface(ThisSurf)%Vertex(2)%X
BaseYLLC=Surface(ThisSurf)%Vertex(2)%Y
BaseZLLC=Surface(ThisSurf)%Vertex(2)%Z
TVect=Surface(ThisSurf)%Vertex(3)-Surface(ThisSurf)%Vertex(2)
ThisWidth=VecLength(TVect)
TVect=Surface(ThisSurf)%Vertex(2)-Surface(ThisSurf)%Vertex(1)
ThisHeight=VecLength(TVect)
Surface(ThisSurf)%Width=ThisWidth
Surface(ThisSurf)%Height=ThisHeight ! For a horizontal surface this is actually length!
IF(Surface(ThisSurf)%Sides==3) Surface(ThisSurf)%Shape = Triangle
IF(Surface(ThisSurf)%Sides==4) THEN
Diagonal1 = VecLength(Surface(ThisSurf)%Vertex(1)-Surface(ThisSurf)%Vertex(3))
Diagonal2 = VecLength(Surface(ThisSurf)%Vertex(2)-Surface(ThisSurf)%Vertex(4))
! Test for rectangularity
IF(ABS(Diagonal1-Diagonal2) < 0.020d0) THEN
Surface(ThisSurf)%Shape = Rectangle
ELSE
Surface(ThisSurf)%Shape = Quadrilateral
END IF
END IF
IF (Surface(ThisSurf)%Sides >4) THEN
Surface(ThisSurf)%Shape = Polygonal
if (abs(thisheight*thiswidth-surface(thissurf)%grossarea) > .001d0) then
surface(thissurf)%width=sqrt(surface(thissurf)%grossarea)
surface(thissurf)%height=surface(thissurf)%width
thiswidth=surface(thissurf)%width
thisheight=surface(thissurf)%height
endif
ENDIF
ELSE ! It's a subsurface to previous basesurface in this set of calls
ThisSurfAz=Surface(ThisSurf)%Azimuth
ThisSurfTilt=Surface(ThisSurf)%Tilt
IF (HeatTransSurf) then
IF(Surface(ThisSurf)%Sides == 4) THEN
ThisShape=RectangularDoorWindow
ELSE IF(Surface(ThisSurf)%Sides == 3 .AND. Surface(ThisSurf)%Class == SurfaceClass_Window) THEN
ThisShape=TriangularWindow
ELSE IF(Surface(ThisSurf)%Sides == 3 .AND. Surface(ThisSurf)%Class == SurfaceClass_Door) THEN
ThisShape=TriangularDoor
END IF
ELSE ! this is a shadowing subsurface
IF (ABS(Surface(Surface(ThisSurf)%Basesurf)%Tilt-ThisSurfTilt) <= .01d0) then
! left or right fin
IF (ThisSurfAz < 0.0d0) ThisSurfAz=ThisSurfAz+360.d0
IF (ThisSurfAz > Surface(Surface(ThisSurf)%BaseSurf)%Azimuth) then
ThisShape=RectangularLeftFin
ELSE
ThisShape=RectangularRightFin
ENDIF
ELSE
ThisShape=RectangularOverhang
ENDIF
ENDIF
! Setting relative coordinates for shadowing calculations for subsurfaces
SELECT CASE (ThisShape)
CASE (RectangularDoorWindow) ! Rectangular heat transfer subsurface
CALL PlaneEquation(Surface(Surface(ThisSurf)%BaseSurf)%Vertex,Surface(Surface(ThisSurf)%BaseSurf)%Sides,BasePlane,SError)
IF (SError) THEN
CALL ShowSevereError(RoutineName//'Degenerate surface (likely two vertices equal):"'//TRIM(Surface(ThisSurf)%Name)//'".')
ErrorInSurface=.true.
ENDIF
ThisReveal=-Pt2Plane(Surface(ThisSurf)%Vertex(2),BasePlane)
IF (ABS(ThisReveal) < .0002d0) ThisReveal=0.0d0
Surface(ThisSurf)%Reveal=ThisReveal
Xp=Surface(ThisSurf)%Vertex(2)%x-BaseXLLC
Yp=Surface(ThisSurf)%Vertex(2)%y-BaseYLLC
Zp=Surface(ThisSurf)%Vertex(2)%z-BaseZLLC
XLLC=-Xp*BaseCosAzimuth+Yp*BaseSinAzimuth
YLLC=-Xp*BaseSinAzimuth*BaseCosTilt-Yp*BaseCosAzimuth*BaseCosTilt+Zp*BaseSinTilt
ZLLC= Xp*BaseSinAzimuth*BaseSinTilt+Yp*BaseCosAzimuth*BaseSinTilt+Zp*BaseCosTilt
TVect=Surface(ThisSurf)%Vertex(3)-Surface(ThisSurf)%Vertex(2)
ThisWidth=VecLength(TVect)
TVect=Surface(ThisSurf)%Vertex(2)-Surface(ThisSurf)%Vertex(1)
ThisHeight=VecLength(TVect)
Surface(ThisSurf)%Width=ThisWidth
Surface(ThisSurf)%Height=ThisHeight
Diagonal1 = VecLength(Surface(ThisSurf)%Vertex(1)-Surface(ThisSurf)%Vertex(3))
Diagonal2 = VecLength(Surface(ThisSurf)%Vertex(2)-Surface(ThisSurf)%Vertex(4))
! Test for rectangularity
IF(ABS(Diagonal1-Diagonal2) > 0.020d0) THEN
CALL ShowSevereError(RoutineName//'Suspected 4-sided but non-rectangular Window, Door or GlassDoor:')
CALL ShowContinueError('Surface='//TRIM(Surface(ThisSurf)%Name) &
//', Diagonal1='//TRIM(TrimSigDigits(Diagonal1,3))//', Diagonal2='//TRIM(TrimSigDigits(Diagonal2,3)))
ErrorInSurface=.true.
ENDIF
X(1) = XLLC
X(2) = XLLC
X(3) = XLLC + Surface(ThisSurf)%Width
X(4) = XLLC + Surface(ThisSurf)%Width
Y(1) = YLLC + Surface(ThisSurf)%Height
Y(4) = YLLC + Surface(ThisSurf)%Height
Y(2) = YLLC
Y(3) = YLLC
Z(1) = ZLLC
Z(2) = ZLLC
Z(3) = ZLLC
Z(4) = ZLLC
IF(Surface(ThisSurf)%Class == SurfaceClass_Window .AND. &
Surface(ThisSurf)%ExtBoundCond == ExternalEnvironment .AND. &
Surface(ThisSurf)%FrameDivider > 0) THEN
FrDivNum = Surface(ThisSurf)%FrameDivider
! Set flag for calculating beam solar reflection from outside and/or inside window reveal
IF((Surface(ThisSurf)%Reveal > 0.0d0 .AND. FrameDivider(FrDivNum)%OutsideRevealSolAbs > 0.0d0) .OR. &
(FrameDivider(FrDivNum)%InsideSillDepth > 0.0d0 .AND. FrameDivider(FrDivNum)%InsideSillSolAbs > 0.0d0) .OR. &
(FrameDivider(FrDivNum)%InsideReveal > 0.0d0 .AND. FrameDivider(FrDivNum)%InsideRevealSolAbs > 0.0d0)) &
CalcWindowRevealReflection = .TRUE.
! For exterior window with frame, subtract frame area from base surface
! (only rectangular windows are allowed to have a frame and/or divider;
! Surface(ThisSurf)%FrameDivider will be 0 for triangular windows)
FrWidth = FrameDivider(FrDivNum)%FrameWidth
IF(FrWidth > 0.0d0) THEN
FrArea = (Surface(ThisSurf)%Height + 2.0d0*FrWidth)*(Surface(ThisSurf)%Width + 2.0d0*FrWidth) &
- Surface(ThisSurf)%Area/Surface(ThisSurf)%Multiplier
SurfaceWindow(ThisSurf)%FrameArea = FrArea * Surface(ThisSurf)%Multiplier
IF((Surface(Surface(ThisSurf)%BaseSurf)%Area - SurfaceWindow(ThisSurf)%FrameArea) <= 0.0d0) THEN
CALL ShowSevereError(RoutineName//'Base Surface="'//TRIM(Surface(Surface(ThisSurf)%BaseSurf)%Name)//'", ')
CALL ShowContinueError('Window Surface="'//trim(Surface(ThisSurf)%Name)// &
'" area (with frame) is too large to fit on the surface.')
CALL ShowContinueError('Base surface area (-windows and doors)=['// &
trim(TrimSigDigits(Surface(Surface(ThisSurf)%BaseSurf)%Area,2))// &
'] m2, frame area=['//trim(TrimSigDigits(SurfaceWindow(ThisSurf)%FrameArea,2))//'] m2.')
ErrorInSurface=.true.
ENDIF
Surface(Surface(ThisSurf)%BaseSurf)%Area = &
Surface(Surface(ThisSurf)%BaseSurf)%Area - SurfaceWindow(ThisSurf)%FrameArea
END IF
! If exterior window has divider, subtract divider area to get glazed area
DivWidth = FrameDivider(Surface(ThisSurf)%FrameDivider)%DividerWidth
IF(DivWidth > 0.0d0 .and. .not. ErrorInSurface) THEN
DivArea = DivWidth * &
(FrameDivider(FrDivNum)%HorDividers * Surface(ThisSurf)%Width + &
FrameDivider(FrDivNum)%VertDividers * Surface(ThisSurf)%Height - &
FrameDivider(FrDivNum)%HorDividers * FrameDivider(FrDivNum)%VertDividers * DivWidth)
SurfaceWindow(ThisSurf)%DividerArea = DivArea * Surface(ThisSurf)%Multiplier
IF((Surface(ThisSurf)%Area - SurfaceWindow(ThisSurf)%DividerArea) <= 0.0d0) THEN
CALL ShowSevereError(RoutineName//'Divider area exceeds glazed opening for window '&
//TRIM(Surface(ThisSurf)%Name))
CALL ShowContinueError('Window surface area=['// &
trim(TrimSigDigits(Surface(ThisSurf)%Area,2))// &
'] m2, divider area=['//trim(TrimSigDigits(SurfaceWindow(ThisSurf)%DividerArea,2))//'] m2.')
ErrorInSurface=.true.
ENDIF
Surface(ThisSurf)%Area = Surface(ThisSurf)%Area - SurfaceWindow(ThisSurf)%DividerArea ! Glazed area
IF (DivArea <= 0.0d0) THEN
CALL ShowWarningError(RoutineName//'Calculated Divider Area <= 0.0 for Window='// &
TRIM(Surface(ThisSurf)%Name))
IF (FrameDivider(FrDivNum)%HorDividers == 0) THEN
CALL ShowContinueError('..Number of Horizontal Dividers = 0.')
ENDIF
IF (FrameDivider(FrDivNum)%VertDividers == 0) THEN
CALL ShowContinueError('..Number of Vertical Dividers = 0.')
ENDIF
ELSE
SurfaceWindow(ThisSurf)%GlazedFrac = Surface(ThisSurf)%Area/(Surface(ThisSurf)%Area + &
SurfaceWindow(ThisSurf)%DividerArea)
! Correction factor for portion of divider subject to divider projection correction
DivFrac = (1.0d0-FrameDivider(FrDivNum)%HorDividers * &
FrameDivider(FrDivNum)%VertDividers * DivWidth**2 / DivArea)
SurfaceWindow(ThisSurf)%ProjCorrDivOut = DivFrac * &
FrameDivider(FrDivNum)%DividerProjectionOut/DivWidth
SurfaceWindow(ThisSurf)%ProjCorrDivIn = DivFrac * &
FrameDivider(FrDivNum)%DividerProjectionIn/DivWidth
! Correction factor for portion of frame subject to frame projection correction
IF(FrWidth > 0.0d0) THEN
SurfaceWindow(ThisSurf)%ProjCorrFrOut = (FrameDivider(FrDivNum)%FrameProjectionOut/FrWidth)* &
(ThisHeight+ThisWidth-(FrameDivider(FrDivNum)%HorDividers + FrameDivider(FrDivNum)%VertDividers)* &
DivWidth)/(ThisHeight+ThisWidth+2*FrWidth)
SurfaceWindow(ThisSurf)%ProjCorrFrIn = (FrameDivider(FrDivNum)%FrameProjectionIn/FrWidth)* &
(ThisHeight+ThisWidth-(FrameDivider(FrDivNum)%HorDividers + FrameDivider(FrDivNum)%VertDividers)* &
DivWidth)/(ThisHeight+ThisWidth+2*FrWidth)
END IF
END IF
END IF
END IF
CASE (TriangularWindow,TriangularDoor)
CALL PlaneEquation(Surface(Surface(ThisSurf)%BaseSurf)%Vertex,Surface(Surface(ThisSurf)%BaseSurf)%Sides,BasePlane,SError)
IF (SError) THEN
CALL ShowSevereError(RoutineName//'Degenerate surface (likely two vertices equal):"'//TRIM(Surface(ThisSurf)%Name)//'".')
ErrorInSurface=.true.
ENDIF
ThisReveal=-Pt2Plane(Surface(ThisSurf)%Vertex(2),BasePlane)
IF (ABS(ThisReveal) < .0002d0) ThisReveal=0.0d0
Surface(ThisSurf)%Reveal=ThisReveal
Xp=Surface(ThisSurf)%Vertex(2)%x-BaseXLLC
Yp=Surface(ThisSurf)%Vertex(2)%y-BaseYLLC
Zp=Surface(ThisSurf)%Vertex(2)%z-BaseZLLC
X(2)=-Xp*BaseCosAzimuth+Yp*BaseSinAzimuth
Y(2)=-Xp*BaseSinAzimuth*BaseCosTilt-Yp*BaseCosAzimuth*BaseCosTilt+Zp*BaseSinTilt
Z(2)= Xp*BaseSinAzimuth*BaseSinTilt+Yp*BaseCosAzimuth*BaseSinTilt+Zp*BaseCosTilt
TVect=Surface(ThisSurf)%Vertex(3)-Surface(ThisSurf)%Vertex(2)
ThisWidth=VecLength(TVect)
TVect=Surface(ThisSurf)%Vertex(2)-Surface(ThisSurf)%Vertex(1)
ThisHeight=VecLength(TVect)
Surface(ThisSurf)%Width=ThisWidth
Surface(ThisSurf)%Height=ThisHeight
! Effective height and width of a triangular window for use in calc of convective air flow
! in gap between glass and shading device when shading device is present
Surface(ThisSurf)%Height = 4.d0*Surface(ThisSurf)%Area/(3.d0*Surface(ThisSurf)%Width)
Surface(ThisSurf)%Width = 0.75d0*Surface(ThisSurf)%Width
Xp=Surface(ThisSurf)%Vertex(1)%x-BaseXLLC
Yp=Surface(ThisSurf)%Vertex(1)%y-BaseYLLC
Zp=Surface(ThisSurf)%Vertex(1)%z-BaseZLLC
X(1)=-Xp*BaseCosAzimuth+Yp*BaseSinAzimuth
Y(1)=-Xp*BaseSinAzimuth*BaseCosTilt-Yp*BaseCosAzimuth*BaseCosTilt+Zp*BaseSinTilt
Z(1)= Xp*BaseSinAzimuth*BaseSinTilt+Yp*BaseCosAzimuth*BaseSinTilt+Zp*BaseCosTilt
Xp=Surface(ThisSurf)%Vertex(3)%x-BaseXLLC
Yp=Surface(ThisSurf)%Vertex(3)%y-BaseYLLC
Zp=Surface(ThisSurf)%Vertex(3)%z-BaseZLLC
X(3)=-Xp*BaseCosAzimuth+Yp*BaseSinAzimuth
Y(3)=-Xp*BaseSinAzimuth*BaseCosTilt-Yp*BaseCosAzimuth*BaseCosTilt+Zp*BaseSinTilt
Z(3)= Xp*BaseSinAzimuth*BaseSinTilt+Yp*BaseCosAzimuth*BaseSinTilt+Zp*BaseCosTilt
CASE (RectangularOverhang)
Xp=Surface(ThisSurf)%Vertex(2)%x-BaseXLLC
Yp=Surface(ThisSurf)%Vertex(2)%y-BaseYLLC
Zp=Surface(ThisSurf)%Vertex(2)%z-BaseZLLC
XLLC=-Xp*BaseCosAzimuth+Yp*BaseSinAzimuth
YLLC=-Xp*BaseSinAzimuth*BaseCosTilt-Yp*BaseCosAzimuth*BaseCosTilt+Zp*BaseSinTilt
ZLLC= Xp*BaseSinAzimuth*BaseSinTilt+Yp*BaseCosAzimuth*BaseSinTilt+Zp*BaseCosTilt
TVect=Surface(ThisSurf)%Vertex(3)-Surface(ThisSurf)%Vertex(2)
ThisWidth=VecLength(TVect)
TVect=Surface(ThisSurf)%Vertex(2)-Surface(ThisSurf)%Vertex(1)
ThisHeight=VecLength(TVect)
Surface(ThisSurf)%Width=ThisWidth
Surface(ThisSurf)%Height=ThisHeight
X(1) = XLLC
X(2) = XLLC
X(3) = XLLC + Surface(ThisSurf)%Width
X(4) = XLLC + Surface(ThisSurf)%Width
Y(1) = YLLC
Y(2) = YLLC
Y(3) = YLLC
Y(4) = YLLC
Z(1) = Surface(ThisSurf)%Height
Z(4) = Surface(ThisSurf)%Height
Z(2) = 0.0d0
Z(3) = 0.0d0
CASE (RectangularLeftFin)
Xp=Surface(ThisSurf)%Vertex(2)%x-BaseXLLC
Yp=Surface(ThisSurf)%Vertex(2)%y-BaseYLLC
Zp=Surface(ThisSurf)%Vertex(2)%z-BaseZLLC
XLLC=-Xp*BaseCosAzimuth+Yp*BaseSinAzimuth
YLLC=-Xp*BaseSinAzimuth*BaseCosTilt-Yp*BaseCosAzimuth*BaseCosTilt+Zp*BaseSinTilt
ZLLC= Xp*BaseSinAzimuth*BaseSinTilt+Yp*BaseCosAzimuth*BaseSinTilt+Zp*BaseCosTilt
TVect=Surface(ThisSurf)%Vertex(3)-Surface(ThisSurf)%Vertex(2)
ThisWidth=VecLength(TVect)
TVect=Surface(ThisSurf)%Vertex(2)-Surface(ThisSurf)%Vertex(1)
ThisHeight=VecLength(TVect)
Surface(ThisSurf)%Width=ThisWidth
Surface(ThisSurf)%Height=ThisHeight
X(1) = XLLC
X(2) = XLLC
X(3) = XLLC
X(4) = XLLC
Y(1) = YLLC
Y(2) = YLLC
Y(3) = YLLC + Surface(ThisSurf)%Width
Y(4) = YLLC + Surface(ThisSurf)%Width
Z(1) = Surface(ThisSurf)%Height
Z(4) = Surface(ThisSurf)%Height
Z(2) = 0.0d0
Z(3) = 0.0d0
CASE (RectangularRightFin)
Xp=Surface(ThisSurf)%Vertex(2)%x-BaseXLLC
Yp=Surface(ThisSurf)%Vertex(2)%y-BaseYLLC
Zp=Surface(ThisSurf)%Vertex(2)%z-BaseZLLC
XLLC=-Xp*BaseCosAzimuth+Yp*BaseSinAzimuth
YLLC=-Xp*BaseSinAzimuth*BaseCosTilt-Yp*BaseCosAzimuth*BaseCosTilt+Zp*BaseSinTilt
ZLLC= Xp*BaseSinAzimuth*BaseSinTilt+Yp*BaseCosAzimuth*BaseSinTilt+Zp*BaseCosTilt
TVect=Surface(ThisSurf)%Vertex(3)-Surface(ThisSurf)%Vertex(2)
ThisWidth=VecLength(TVect)
TVect=Surface(ThisSurf)%Vertex(2)-Surface(ThisSurf)%Vertex(1)
ThisHeight=VecLength(TVect)
Surface(ThisSurf)%Width=ThisWidth
Surface(ThisSurf)%Height=ThisHeight
X(1) = XLLC
X(2) = XLLC
X(3) = XLLC
X(4) = XLLC
Y(1) = YLLC + Surface(ThisSurf)%Width
Y(2) = YLLC + Surface(ThisSurf)%Width
Y(3) = YLLC
Y(4) = YLLC
Z(1) = Surface(ThisSurf)%Height
Z(4) = Surface(ThisSurf)%Height
Z(2) = 0.0d0
Z(3) = 0.0d0
CASE DEFAULT
! Error Condition
CALL ShowSevereError(RoutineName//'Incorrect surface shape number.',OutputFileStandard)
CALL ShowContinueError('Please notify EnergyPlus support of this error and send input file.')
ErrorInSurface=.true.
END SELECT
DO N = 1, Surface(ThisSurf)%Sides
! if less than 1/10 inch
X(N)=ANINT(10000.d0*X(N),r64)/10000.d0
IF (ABS(X(N)) < .0025d0) X(N)=0.0d0
Y(N)=ANINT(10000.d0*Y(N),r64)/10000.d0
IF (ABS(Y(N)) < .0025d0) Y(N)=0.0d0
Z(N)=ANINT(10000.d0*Z(N),r64)/10000.d0
IF (ABS(Z(N)) < .0025d0) Z(N)=0.0d0
ENDDO
Surface(ThisSurf)%Shape=ThisShape
ENDIF ! End of check if ThisSurf is a base surface
IF (ErrorInSurface) THEN
ErrorsFound=.true.
RETURN
ENDIF
! Transfer to XV,YV,ZV arrays
ShadeV(ThisSurf)%NVert=Surface(ThisSurf)%Sides
ALLOCATE(ShadeV(ThisSurf)%XV(Surface(ThisSurf)%Sides))
ALLOCATE(ShadeV(ThisSurf)%YV(Surface(ThisSurf)%Sides))
ALLOCATE(ShadeV(ThisSurf)%ZV(Surface(ThisSurf)%Sides))
DO N = 1, Surface(ThisSurf)%Sides
! if less than 1/10 inch
ShadeV(ThisSurf)%XV(N) = X(N)
ShadeV(ThisSurf)%YV(N) = Y(N)
ShadeV(ThisSurf)%ZV(N) = Z(N)
END DO
! Process Surfaces According to Type of Coordinate Origin.
IF (BaseSurface) THEN
! General Surfaces:
CALL CalcCoordinateTransformation(ThisSurf,CoordinateTransVector) !X00,Y00,Z00,X,Y,Z,A) ! Compute Coordinate Transformation
! RECORD DIRECTION COSINES.
IF (HeatTransSurf) THEN ! This is a general surface but not detached shading surface
! RECORD COORDINATE TRANSFORMATION FOR BASE SURFACES.
X0(ThisBaseSurface) = CoordinateTransVector%x
Y0(ThisBaseSurface) = CoordinateTransVector%y
Z0(ThisBaseSurface) = CoordinateTransVector%z
! COMPUTE INVERSE TRANSFORMATION.
X1 = X(2) - CoordinateTransVector%x
Y1 = Y(2) - CoordinateTransVector%y
Z1 = Z(2) - CoordinateTransVector%z
XSHIFT = Surface(ThisBaseSurface)%lcsx%x*X1 + Surface(ThisBaseSurface)%lcsx%y*Y1 + Surface(ThisBaseSurface)%lcsx%z*Z1
YSHIFT = Surface(ThisBaseSurface)%lcsy%x*X1 + Surface(ThisBaseSurface)%lcsy%y*Y1 + Surface(ThisBaseSurface)%lcsy%z*Z1
ENDIF
! SUBSURFACES: (Surface(ThisSurf)%BaseSurf /= ThisSurf)
ELSE
! WINDOWS OR DOORS:
! SHIFT RELATIVE COORDINATES FROM LOWER LEFT CORNER TO ORIGIN DEFINED
! BY CTRAN AND SET DIRECTION COSINES SAME AS BASE SURFACE.
DO N = 1, Surface(ThisSurf)%Sides
ShadeV(ThisSurf)%XV(N) = ShadeV(ThisSurf)%XV(N) + XSHIFT
ShadeV(ThisSurf)%YV(N) = ShadeV(ThisSurf)%YV(N) + YSHIFT
ENDDO
ENDIF
IF (ErrorInSurface) THEN
ErrorsFound=.true.
ENDIF
RETURN
END SUBROUTINE ProcessSurfaceVertices