DaylightingDevices.f90 Source File

This File Depends On

sourcefile~~daylightingdevices.f90~~EfferentGraph sourcefile~daylightingdevices.f90 DaylightingDevices.f90 sourcefile~fluidproperties.f90 FluidProperties.f90 sourcefile~fluidproperties.f90->sourcefile~daylightingdevices.f90 sourcefile~vectorutilities.f90 VectorUtilities.f90 sourcefile~vectorutilities.f90->sourcefile~daylightingdevices.f90 sourcefile~general.f90 General.f90 sourcefile~general.f90->sourcefile~daylightingdevices.f90 sourcefile~general.f90->sourcefile~fluidproperties.f90 sourcefile~general.f90->sourcefile~vectorutilities.f90 sourcefile~dataheatbalance.f90 DataHeatBalance.f90 sourcefile~general.f90->sourcefile~dataheatbalance.f90 sourcefile~dataenvironment.f90 DataEnvironment.f90 sourcefile~general.f90->sourcefile~dataenvironment.f90 sourcefile~datasurfaces.f90 DataSurfaces.f90 sourcefile~datasurfaces.f90->sourcefile~daylightingdevices.f90 sourcefile~datasurfaces.f90->sourcefile~vectorutilities.f90 sourcefile~datasurfaces.f90->sourcefile~general.f90 sourcefile~datasurfaces.f90->sourcefile~dataheatbalance.f90 sourcefile~dataprecisionglobals.f90 DataPrecisionGlobals.f90 sourcefile~dataprecisionglobals.f90->sourcefile~daylightingdevices.f90 sourcefile~dataprecisionglobals.f90->sourcefile~fluidproperties.f90 sourcefile~dataprecisionglobals.f90->sourcefile~vectorutilities.f90 sourcefile~dataprecisionglobals.f90->sourcefile~general.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datasurfaces.f90 sourcefile~dataglobals.f90 DataGlobals.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataglobals.f90 sourcefile~dataipshortcuts.f90 DataIPShortCuts.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataipshortcuts.f90 sourcefile~datasystemvariables.f90 DataSystemVariables.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datasystemvariables.f90 sourcefile~datadaylightingdevices.f90 DataDaylightingDevices.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datadaylightingdevices.f90 sourcefile~datainterfaces.f90 DataInterfaces.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datainterfaces.f90 sourcefile~datadaylighting.f90 DataDaylighting.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datadaylighting.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataheatbalance.f90 sourcefile~inputprocessor.f90 InputProcessor.f90 sourcefile~dataprecisionglobals.f90->sourcefile~inputprocessor.f90 sourcefile~datavectortypes.f90 DataVectorTypes.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datavectortypes.f90 sourcefile~datahvacglobals.f90 DataHVACGlobals.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datahvacglobals.f90 sourcefile~dataruntimelanguage.f90 DataRuntimeLanguage.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataruntimelanguage.f90 sourcefile~databsdfwindow.f90 DataBSDFWindow.f90 sourcefile~dataprecisionglobals.f90->sourcefile~databsdfwindow.f90 sourcefile~datacomplexfenestration.f90 DataComplexFenestration.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datacomplexfenestration.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataenvironment.f90 sourcefile~dataequivalentlayerwindow.f90 DataEquivalentLayerWindow.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataequivalentlayerwindow.f90 sourcefile~datasizing.f90 DataSizing.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datasizing.f90 sourcefile~dataglobals.f90->sourcefile~daylightingdevices.f90 sourcefile~dataglobals.f90->sourcefile~fluidproperties.f90 sourcefile~dataglobals.f90->sourcefile~vectorutilities.f90 sourcefile~dataglobals.f90->sourcefile~general.f90 sourcefile~dataglobals.f90->sourcefile~datasurfaces.f90 sourcefile~dataglobals.f90->sourcefile~dataipshortcuts.f90 sourcefile~dataglobals.f90->sourcefile~datadaylightingdevices.f90 sourcefile~dataglobals.f90->sourcefile~datadaylighting.f90 sourcefile~dataglobals.f90->sourcefile~dataheatbalance.f90 sourcefile~dataglobals.f90->sourcefile~inputprocessor.f90 sourcefile~dataglobals.f90->sourcefile~datahvacglobals.f90 sourcefile~dataglobals.f90->sourcefile~dataruntimelanguage.f90 sourcefile~dataglobals.f90->sourcefile~databsdfwindow.f90 sourcefile~dataglobals.f90->sourcefile~datacomplexfenestration.f90 sourcefile~dataglobals.f90->sourcefile~dataenvironment.f90 sourcefile~dataglobals.f90->sourcefile~dataequivalentlayerwindow.f90 sourcefile~sortandstringutilities.f90 SortAndStringUtilities.f90 sourcefile~dataglobals.f90->sourcefile~sortandstringutilities.f90 sourcefile~dataoutputs.f90 DataOutputs.f90 sourcefile~dataglobals.f90->sourcefile~dataoutputs.f90 sourcefile~dataglobals.f90->sourcefile~datasizing.f90 sourcefile~dataipshortcuts.f90->sourcefile~daylightingdevices.f90 sourcefile~dataipshortcuts.f90->sourcefile~general.f90 sourcefile~dataipshortcuts.f90->sourcefile~inputprocessor.f90 sourcefile~datasystemvariables.f90->sourcefile~daylightingdevices.f90 sourcefile~datasystemvariables.f90->sourcefile~inputprocessor.f90 sourcefile~datadaylightingdevices.f90->sourcefile~daylightingdevices.f90 sourcefile~datainterfaces.f90->sourcefile~daylightingdevices.f90 sourcefile~datainterfaces.f90->sourcefile~fluidproperties.f90 sourcefile~datainterfaces.f90->sourcefile~vectorutilities.f90 sourcefile~datainterfaces.f90->sourcefile~general.f90 sourcefile~datainterfaces.f90->sourcefile~dataheatbalance.f90 sourcefile~datainterfaces.f90->sourcefile~inputprocessor.f90 sourcefile~datainterfaces.f90->sourcefile~dataruntimelanguage.f90 sourcefile~datainterfaces.f90->sourcefile~dataenvironment.f90 sourcefile~datadaylighting.f90->sourcefile~daylightingdevices.f90 sourcefile~dataheatbalance.f90->sourcefile~daylightingdevices.f90 sourcefile~inputprocessor.f90->sourcefile~daylightingdevices.f90 sourcefile~inputprocessor.f90->sourcefile~fluidproperties.f90 sourcefile~inputprocessor.f90->sourcefile~general.f90 sourcefile~inputprocessor.f90->sourcefile~dataheatbalance.f90 sourcefile~datavectortypes.f90->sourcefile~vectorutilities.f90 sourcefile~datavectortypes.f90->sourcefile~datasurfaces.f90 sourcefile~datavectortypes.f90->sourcefile~dataheatbalance.f90 sourcefile~datavectortypes.f90->sourcefile~databsdfwindow.f90 sourcefile~datahvacglobals.f90->sourcefile~general.f90 sourcefile~dataruntimelanguage.f90->sourcefile~general.f90 sourcefile~datastringglobals.f90 DataStringGlobals.f90 sourcefile~datastringglobals.f90->sourcefile~general.f90 sourcefile~datastringglobals.f90->sourcefile~datasystemvariables.f90 sourcefile~datastringglobals.f90->sourcefile~inputprocessor.f90 sourcefile~databsdfwindow.f90->sourcefile~datasurfaces.f90 sourcefile~databsdfwindow.f90->sourcefile~dataheatbalance.f90 sourcefile~datacomplexfenestration.f90->sourcefile~dataheatbalance.f90 sourcefile~dataenvironment.f90->sourcefile~dataheatbalance.f90 sourcefile~dataequivalentlayerwindow.f90->sourcefile~dataheatbalance.f90 sourcefile~sortandstringutilities.f90->sourcefile~inputprocessor.f90 sourcefile~dataoutputs.f90->sourcefile~inputprocessor.f90 sourcefile~datasizing.f90->sourcefile~inputprocessor.f90
Help

Files Dependent On This One

sourcefile~~daylightingdevices.f90~~AfferentGraph sourcefile~daylightingdevices.f90 DaylightingDevices.f90 sourcefile~daylightingmanager.f90 DaylightingManager.f90 sourcefile~daylightingdevices.f90->sourcefile~daylightingmanager.f90 sourcefile~heatbalanceinternalheatgains.f90 HeatBalanceInternalHeatGains.f90 sourcefile~daylightingdevices.f90->sourcefile~heatbalanceinternalheatgains.f90 sourcefile~solarshading.f90 SolarShading.f90 sourcefile~daylightingdevices.f90->sourcefile~solarshading.f90 sourcefile~heatbalancemanager.f90 HeatBalanceManager.f90 sourcefile~daylightingdevices.f90->sourcefile~heatbalancemanager.f90 sourcefile~heatbalancesurfacemanager.f90 HeatBalanceSurfaceManager.f90 sourcefile~daylightingdevices.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~daylightingmanager.f90->sourcefile~solarshading.f90 sourcefile~daylightingmanager.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~utilityroutines.f90 UtilityRoutines.f90 sourcefile~daylightingmanager.f90->sourcefile~utilityroutines.f90 sourcefile~windowequivalentlayer.f90 WindowEquivalentLayer.f90 sourcefile~daylightingmanager.f90->sourcefile~windowequivalentlayer.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~daylightingmanager.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~heatbalancemanager.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~zoneequipmentmanager.f90 Zoneequipmentmanager.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~zoneequipmentmanager.f90 sourcefile~roomairmodelcrossvent.f90 RoomAirModelCrossVent.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~roomairmodelcrossvent.f90 sourcefile~zonecontaminantpredictorcorrector.f90 ZoneContaminantPredictorCorrector.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~zonecontaminantpredictorcorrector.f90 sourcefile~roomairmodelusertemppattern.f90 RoomAirModelUserTempPattern.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~roomairmodelusertemppattern.f90 sourcefile~hvacmanager.f90 HVACManager.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~hvacmanager.f90 sourcefile~delightmanagerf.f90 DElightManagerF.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~delightmanagerf.f90 sourcefile~roomairmodelufad.f90 RoomAirModelUFAD.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~roomairmodelufad.f90 sourcefile~roomairmodeldisplacementvent.f90 RoomAirModelDisplacementVent.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~roomairmodeldisplacementvent.f90 sourcefile~zonetemppredictorcorrector.f90 ZoneTempPredictorCorrector.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~zonetemppredictorcorrector.f90 sourcefile~roomairmodelmundt.f90 RoomAirModelMundt.f90 sourcefile~heatbalanceinternalheatgains.f90->sourcefile~roomairmodelmundt.f90 sourcefile~solarshading.f90->sourcefile~heatbalancemanager.f90 sourcefile~solarshading.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~solarshading.f90->sourcefile~utilityroutines.f90 sourcefile~simulationmanager.f90 SimulationManager.f90 sourcefile~solarshading.f90->sourcefile~simulationmanager.f90 sourcefile~sizingmanager.f90 SizingManager.f90 sourcefile~heatbalancemanager.f90->sourcefile~sizingmanager.f90 sourcefile~heatbalancemanager.f90->sourcefile~simulationmanager.f90 sourcefile~heatbalancesurfacemanager.f90->sourcefile~heatbalancemanager.f90 sourcefile~heatbalancesurfacemanager.f90->sourcefile~simulationmanager.f90 sourcefile~windowequivalentlayer.f90->sourcefile~solarshading.f90 sourcefile~windowequivalentlayer.f90->sourcefile~heatbalancemanager.f90 sourcefile~windowequivalentlayer.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~windowmanager.f90 WindowManager.f90 sourcefile~windowequivalentlayer.f90->sourcefile~windowmanager.f90 sourcefile~heatbalanceintradexchange.f90 HeatBalanceIntRadExchange.f90 sourcefile~windowequivalentlayer.f90->sourcefile~heatbalanceintradexchange.f90 sourcefile~windowmanager.f90->sourcefile~heatbalancemanager.f90 sourcefile~windowmanager.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~heatbalanceintradexchange.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~zoneequipmentmanager.f90->sourcefile~hvacmanager.f90 sourcefile~zoneequipmentmanager.f90->sourcefile~sizingmanager.f90 sourcefile~roomairmanager.f90 RoomAirManager.f90 sourcefile~roomairmodelcrossvent.f90->sourcefile~roomairmanager.f90 sourcefile~zonecontaminantpredictorcorrector.f90->sourcefile~hvacmanager.f90 sourcefile~zonecontaminantpredictorcorrector.f90->sourcefile~simulationmanager.f90 sourcefile~roomairmodelusertemppattern.f90->sourcefile~roomairmanager.f90 sourcefile~hvacmanager.f90->sourcefile~simulationmanager.f90 sourcefile~heatbalanceairmanager.f90 HeatBalanceAirManager.f90 sourcefile~hvacmanager.f90->sourcefile~heatbalanceairmanager.f90 sourcefile~delightmanagerf.f90->sourcefile~daylightingmanager.f90 sourcefile~delightmanagerf.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~roomairmodelufad.f90->sourcefile~roomairmanager.f90 sourcefile~roomairmodeldisplacementvent.f90->sourcefile~roomairmanager.f90 sourcefile~zonetemppredictorcorrector.f90->sourcefile~zoneequipmentmanager.f90 sourcefile~zonetemppredictorcorrector.f90->sourcefile~zonecontaminantpredictorcorrector.f90 sourcefile~zonetemppredictorcorrector.f90->sourcefile~hvacmanager.f90 sourcefile~zonetemppredictorcorrector.f90->sourcefile~simulationmanager.f90 sourcefile~roomairmodelmundt.f90->sourcefile~roomairmanager.f90 sourcefile~sizingmanager.f90->sourcefile~simulationmanager.f90 sourcefile~simulationmanager.f90->sourcefile~utilityroutines.f90 sourcefile~energyplus.f90 EnergyPlus.f90 sourcefile~simulationmanager.f90->sourcefile~energyplus.f90 sourcefile~roomairmanager.f90->sourcefile~zonetemppredictorcorrector.f90 sourcefile~heatbalanceairmanager.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~heatbalanceairmanager.f90->sourcefile~simulationmanager.f90
Help


Source Code

MODULE DaylightingDevices

          ! MODULE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   May 2003
          !       MODIFIED       PGE, Aug 2003:  Added daylighting shelves.
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS MODULE:
          ! Simulates daylighting devices, namely tubular daylighting devices (a.k.a. light pipes, sun pipes, or
          ! tubular skylights) and daylighting shelves (a.k.a. light shelves).

          ! METHODOLOGY EMPLOYED:
          !
          ! TUBULAR DAYLIGHTING DEVICE
          ! A tubular daylighting device (TDD) is constructed of three components:  a dome, a pipe, and a diffuser.
          ! The dome and diffuser are treated as special window surfaces to take advantage of many of the already
          ! existing daylighting and heat transfer routines.  Together the dome and diffuser become "receiver"
          ! and "transmitter", i.e. radiation entering the dome ends up exiting the diffuser.  The geometry and
          ! construction of the pipe and the constructions of the window surfaces determine the transmittance of
          ! the TDD.
          !
          ! The main task of the module is to determine the total transmittance of the TDD for several
          ! types of radiation, including visible beam, solar beam, solar isotropic, and solar anisotropic sky.
          ! The fundamental building block for each type of radiation is the transmittance of a beam or ray of
          ! radiation (visible or solar) at a given incident angle.  This transmittance is calculated and
          ! tabulated for each TDD during initialization using a numerical integral based on the analytical
          ! solution derived by Swift and Smith.  Diffuse transmittances are subsequently calculated by integrating
          ! discrete rays over the viewable area.
          !
          ! There are three parts to the TDD model:
          !   1. Daylighting
          !   2. Solar gain
          !   3. Thermal conductive/convective gain
          !
          ! The daylighting simulation uses the visible beam transmittance to find the amount of direct beam
          ! solar illuminance that enters the zone.  The visible beam transmittance is also used for calculating
          ! the contribution of each discrete ray from a differential area during a comprehensive sky/ground
          ! integration.
          !
          ! The heat balance simulation handles both the solar gain and thermal conductive/convective gain.
          ! Although visible and solar radiation are similar, solar gain is simulated very differently from the
          ! daylighting illuminance calculations.  The gain from direct beam solar is found using the
          ! solar beam transmittance.  The diffuse solar, however, is more complicated.  A sky/ground integration
          ! is NOT performed.  Instead anisotropic sky view factor multipliers (AnisoSkyMult) are calculated for
          ! each surface.  The diffuse sky/ground transmittance of the TDD is solved using a modification of the
          ! AnisoSkyMult.  The ground radiation transmittance and anisotropic sky transmittance are found separately.
          ! See CalcTDDTransSolIso, CalcTDDTransSolHorizon, CalcTDDTransSolAniso below.
          !
          ! For thermal conductive/convective gain, TDDs are treated as one big object with an effective R value.
          ! The outside face temperature of the dome and the inside face temperature of the diffuser are calculated
          ! with the outside and inside heat balances respectively.  The temperatures are then copied to the inside
          ! face of the dome and the outside face of the diffuser.  Normal exterior and interior convection and IR
          ! radiation exchange occurs for both surfaces.
          !
          ! Solar radiation that is not transmitted through the pipe is absorbed and distributed among the transition
          ! zones that the pipe passes through between dome and diffuser.  The heat is distributed proportionate to
          ! the length of the zone.  Any exterior length of pipe also receives a proportionate amount of heat, but
          ! this is lost to the outside.
          !
          ! REFERENCES:
          ! Ellis, P. G., and Strand, R. K.  Paper to be published.
          ! Swift, P. D., and Smith, G. B.  "Cylindrical Mirror Light Pipes",
          !   Solar Energy Materials and Solar Cells 36 (1995), pp. 159-168.
          !
          !
          ! DAYLIGHTING SHELVES
          ! A daylighting shelf is constructed of up to three components: a window, an inside shelf, and an outside
          ! shelf.  Both inside shelf and outside shelf are optional, but if neither is specified, nothing happens.
          ! The window must be divided into two window surfaces: an upper window and a lower window.  The upper
          ! window interacts with the daylighting shelf but the lower window does not, except to receive shading from
          ! the outside shelf.  The inside shelf, if specified, acts to reflect all transmitted light from the
          ! upper window onto the ceiling of the zone as diffuse light.  The outside shelf, if specified, changes
          ! the total amount of light incident on the window.  All light reflected from the outside shelf also goes
          ! onto the zone ceiling.
          !
          ! Most of the work for daylighting shelves is actually done in DaylightingManager.f90, SolarShading.f90,
          ! and HeatBalanceSurfaceManager.f90.  The main task of the module is to get the input and initialize the
          ! shelf.  The biggest part of initialization is calculating the window view factor to the outside shelf.
          ! It is up to the user to reduce the window view factor to ground accordingly.
          !
          ! The inside shelf is modeled in both daylighting and heat balance simulations by converting all light
          ! transmitted by the upper window into diffuse upgoing flux.  No beam or downgoing flux can pass the end
          ! of the shelf regardless of the shelf's position or orientation.  Since it is defined as a partition,
          ! the inside shelf is essentially the same as an internal mass surface.  The initialization doubles the
          ! surface area so that both sides are exposed to the zone air.  All beam solar transmitted by the window
          ! is absorbed in one side of the shelf, i.e. half of the doubled area.
          !
          ! The outside shelf is modeled in the daylighting simulation after the detailed sky/ground integration has
          ! been completed.  Since exterior surfaces currently do not reflect or have a luminance in the Daylighting
          ! Manager, the shelf just serves to block part of the ground luminance.  The luminance of the shelf itself
          ! is added as a lump sum based on the view factor to the shelf, the sunlit fraction, the reflectance of the
          ! shelf construction, and the sun and sky illuminance on the shelf.  All the luminance is added to the
          ! diffuse upgoing flux.  The shelf view factor to sky is assumed to be 1.0 for lack of better information.
          !
          ! The outside shelf is treated similarly in the heat balance simulation, but here the shelf view factor to
          ! sky is conveniently given by AnisoSkyMult.  NOTE:  The solar shading code was modified to allow sunlit
          ! fraction, sunlit area, AnisoSkyMult, etc. to be calculated for attached shading surfaces.
          !
          ! Future shelf model improvements:
          ! 1. Allow beam and downgoing flux to pass the end of the inside shelf depending on actual shelf goemetry.
          ! 2. Reduce outside shelf view factor to sky (for daylighting) by taking into account anisotropic sky
          !    distribution and shading, i.e. the daylighting equivalent of AnisoSkyMult.
          ! 3. Expand view factor to shelf calculation to handle more complicated geometry.
          !
          ! REFERENCES:
          ! Mills, A. F.  Heat and Mass Transfer, 1995, p. 499.  (Shape factor for adjacent rectangles.)

          ! USE STATEMENTS:
USE DataPrecisionGlobals
USE DataGlobals,     ONLY: NumOfZones, MaxNameLength, DegToRadians, Pi, PiOvr2, OutputFileInits
USE DataInterfaces,  ONLY: SetupOutputVariable, ShowWarningError, ShowFatalError, ShowSevereError, ShowContinueError
USE DataHeatBalance, ONLY: Zone, Construct, TotConstructs, SolarDistribution, MinimalShadowing
USE DataSurfaces,    ONLY: Surface, TotSurfaces, SurfaceWindow, ExternalEnvironment, CalcSolRefl, SurfaceClass_Window,  &
                           SurfaceClass_Shading,SurfaceClass_TDD_Dome,SurfaceClass_TDD_Diffuser, ShadingTransmittanceVaries
USE DataDaylightingDevices

IMPLICIT NONE ! Enforce explicit typing of all variables

PRIVATE ! Everything private unless explicitly made public

          ! MODULE PARAMETER DEFINITIONS: na
          ! DERIVED TYPE DEFINITIONS: na
          ! MODULE VARIABLE TYPE DECLARATIONS: na

          ! MODULE VARIABLE DECLARATIONS:
REAL(r64), DIMENSION(NumOfAngles) :: COSAngle ! List of cosines of incident angle

          ! SUBROUTINE SPECIFICATIONS:
PUBLIC InitDaylightingDevices
PUBLIC FindTDDPipe
PUBLIC TransTDD
PUBLIC DistributeTDDAbsorbedSolar
PRIVATE GetTDDInput
PRIVATE GetShelfInput
PRIVATE CalcPipeTransBeam
PRIVATE CalcTDDTransSolIso
PRIVATE CalcTDDTransSolHorizon
PRIVATE CalcTDDTransSolAniso
PRIVATE InterpolatePipeTransBeam
PRIVATE CalcViewFactorToShelf
PUBLIC  FigureTDDZoneGains

CONTAINS

          ! MODULE SUBROUTINES:
SUBROUTINE InitDaylightingDevices

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   May 2003
          !       MODIFIED       PGE, Aug 2003:  Added daylighting shelves.
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! This subroutine initializes all daylighting device:  TDD pipes and daylighting shelves.
          ! This is only called once at the beginning of the simulation under the BeginSimFlag.

          ! METHODOLOGY EMPLOYED:
          ! Daylighting and thermal variables are calculated.  BeamTrans/COSAngle table is calculated.

          ! REFERENCES: na

          ! USE STATEMENTS:
  USE General, ONLY: RoundSigDigits
  USE DataHeatBalance, ONLY : IntGainTypeOf_DaylightingDeviceTubular
  USE DataInterfaces

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS: na

          ! DERIVED TYPE DEFINITIONS:
  TYPE TDDPipeStoredData
    REAL(r64)                    :: AspectRatio = 0.0d0 ! Aspect ratio, length / diameter
    REAL(r64)                    :: Reflectance = 0.0d0 ! Reflectance of surface
    REAL(r64), DIMENSION(NumOfAngles) :: TransBeam = 0.0d0   ! Table of beam transmittance vs. cosine angle
  END TYPE TDDPipeStoredData

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  INTEGER          :: PipeNum            ! TDD pipe object number
  INTEGER          :: StoredNum          ! Stored TDD pipe object number
  INTEGER          :: AngleNum
  INTEGER          :: TZoneNum
  INTEGER          :: Loop
  REAL(r64)        :: Theta              ! Angle of entry in degrees, 0 is parallel to pipe axis
  REAL(r64)        :: dTheta             ! Angle increment
  REAL(r64)        :: Reflectance        ! Visible or solar reflectance of surface
  REAL(r64)        :: SumTZoneLengths
  LOGICAL          :: Found
  TYPE (TDDPipeStoredData), ALLOCATABLE, DIMENSION(:) :: TDDPipeStored
  INTEGER          :: ShelfNum           ! Daylighting shelf object number
  INTEGER          :: ShelfSurf          ! Daylighting shelf surface number
  INTEGER          :: WinSurf            ! Window surface number

  INTEGER          :: NumStored = 0      ! Counter for number of pipes stored as they are calculated
  LOGICAL          :: ShelfReported=.false.

          ! FLOW:
  ! Initialize tubular daylighting devices (TDDs)
  CALL GetTDDInput

  IF (NumOfTDDPipes > 0) THEN
    CALL DisplayString('Initializing Tubular Daylighting Devices')
    ! Setup COSAngle list for all TDDs
    COSAngle(1) = 0.0d0
    COSAngle(NumOfAngles) = 1.0d0

    dTheta = 90.0d0 * DegToRadians / (NumOfAngles - 1.0d0)
    Theta = 90.0d0 * DegToRadians
    DO AngleNum = 2, NumOfAngles - 1
      Theta = Theta - dTheta
      COSAngle(AngleNum) = COS(Theta)
    END DO ! AngleNum

    ALLOCATE(TDDPipeStored(NumOfTDDPipes * 2))

    DO PipeNum = 1, NumOfTDDPipes
      ! Initialize optical properties
      TDDPipe(PipeNum)%AspectRatio = TDDPipe(PipeNum)%TotLength/TDDPipe(PipeNum)%Diameter
      TDDPipe(PipeNum)%ReflectVis = 1.0d0 - Construct(TDDPipe(PipeNum)%Construction)%InsideAbsorpVis
      TDDPipe(PipeNum)%ReflectSol = 1.0d0 - Construct(TDDPipe(PipeNum)%Construction)%InsideAbsorpSolar

      ! Calculate the beam transmittance table for visible and solar spectrum
      ! First time thru use the visible reflectance
      Reflectance = TDDPipe(PipeNum)%ReflectVis
      DO Loop = 1, 2
        ! For computational efficiency, search stored pipes to see if an identical pipe has already been calculated
        Found = .FALSE.
        DO StoredNum = 1, NumStored
          IF (TDDPipeStored(StoredNum)%AspectRatio .NE. TDDPipe(PipeNum)%AspectRatio) CYCLE
          IF (TDDPipeStored(StoredNum)%Reflectance .EQ. Reflectance) THEN
            Found = .TRUE. ! StoredNum points to the matching TDDPipeStored
            EXIT
          END IF
        END DO ! StoredNum

        IF (.NOT. Found) THEN ! Not yet calculated

          ! Add a new pipe to TDDPipeStored
          NumStored = NumStored + 1
          TDDPipeStored(NumStored)%AspectRatio = TDDPipe(PipeNum)%AspectRatio
          TDDPipeStored(NumStored)%Reflectance = Reflectance

          ! Set beam transmittances for 0 and 90 degrees
          TDDPipeStored(NumStored)%TransBeam(1) = 0.0d0
          TDDPipeStored(NumStored)%TransBeam(NumOfAngles) = 1.0d0

          ! Calculate intermediate beam transmittances between 0 and 90 degrees
          Theta = 90.0d0 * DegToRadians
          DO AngleNum = 2, NumOfAngles - 1
            Theta = Theta - dTheta
            TDDPipeStored(NumStored)%TransBeam(AngleNum) = CalcPipeTransBeam(Reflectance, TDDPipe(PipeNum)%AspectRatio, Theta)
          END DO ! AngleNum

          StoredNum = NumStored
        END IF

        ! Assign stored values to TDDPipe
        IF (Loop .EQ. 1)  THEN ! Visible
          TDDPipe(PipeNum)%PipeTransVisBeam = TDDPipeStored(StoredNum)%TransBeam
        ELSE ! Solar
          TDDPipe(PipeNum)%PipeTransSolBeam = TDDPipeStored(StoredNum)%TransBeam
        END IF

        ! Second time thru use the solar reflectance
        Reflectance = TDDPipe(PipeNum)%ReflectSol
      END DO ! Loop

      ! Calculate the solar isotropic diffuse and horizon transmittances.  These values are constant for a given TDD.
      TDDPipe(PipeNum)%TransSolIso = CalcTDDTransSolIso(PipeNum)
      TDDPipe(PipeNum)%TransSolHorizon = CalcTDDTransSolHorizon(PipeNum)

      ! Initialize thermal properties
      SumTZoneLengths= 0.0d0
      DO TZoneNum = 1, TDDPipe(PipeNum)%NumOfTZones
        SumTZoneLengths = SumTZoneLengths + TDDPipe(PipeNum)%TZoneLength(TZoneNum)

        CALL SetupZoneInternalGain(TDDPipe(PipeNum)%TZone(TZoneNum), &
                                   'DaylightingDevice:Tubular', &
                                   TDDPipe(PipeNum)%Name, &
                                   IntGainTypeOf_DaylightingDeviceTubular, &
                                   ConvectionGainRate = TDDPipe(PipeNum)%TZoneHeatGain(TZoneNum) )

      END DO ! TZoneNum

      TDDPipe(PipeNum)%ExtLength = TDDPipe(PipeNum)%TotLength - SumTZoneLengths

      ! Setup report variables: CurrentModuleObject='DaylightingDevice:Tubular'
      CALL SetupOutputVariable('Tubular Daylighting Device Transmitted Solar Radiation Rate [W]', &
        TDDPipe(PipeNum)%TransmittedSolar,'Zone','Average', TDDPipe(PipeNum)%Name)
      CALL SetupOutputVariable('Tubular Daylighting Device Pipe Absorbed Solar Radiation Rate [W]', &
        TDDPipe(PipeNum)%PipeAbsorbedSolar,'Zone','Average', TDDPipe(PipeNum)%Name)
      CALL SetupOutputVariable('Tubular Daylighting Device Heat Gain Rate [W]',   &
         TDDPipe(PipeNum)%HeatGain,'Zone','Average', TDDPipe(PipeNum)%Name)
      CALL SetupOutputVariable('Tubular Daylighting Device Heat Loss Rate [W]',   &
         TDDPipe(PipeNum)%HeatLoss,'Zone','Average', TDDPipe(PipeNum)%Name)

      CALL SetupOutputVariable('Tubular Daylighting Device Beam Solar Transmittance []', &
        TDDPipe(PipeNum)%TransSolBeam,'Zone','Average', TDDPipe(PipeNum)%Name)
      CALL SetupOutputVariable('Tubular Daylighting Device Beam Visible Transmittance []', &
        TDDPipe(PipeNum)%TransVisBeam,'Zone','Average', TDDPipe(PipeNum)%Name)
      CALL SetupOutputVariable('Tubular Daylighting Device Diffuse Solar Transmittance []', &
        TDDPipe(PipeNum)%TransSolDiff,'Zone','Average',TDDPipe(PipeNum)%Name)
      CALL SetupOutputVariable('Tubular Daylighting Device Diffuse Visible Transmittance []', &
        TDDPipe(PipeNum)%TransVisDiff,'Zone','Average',TDDPipe(PipeNum)%Name)

    END DO ! PipeNum

    DEALLOCATE(TDDPipeStored)
  END IF

  ! Initialize daylighting shelves
  CALL GetShelfInput

  IF(NumOfShelf > 0) CALL DisplayString('Initializing Light Shelf Daylighting Devices')

  DO ShelfNum = 1, NumOfShelf
    WinSurf = Shelf(ShelfNum)%Window

    ShelfSurf = Shelf(ShelfNum)%InSurf
    IF (ShelfSurf > 0) THEN
      ! Double surface area so that both sides of the shelf are treated as internal mass
      Surface(ShelfSurf)%Area = 2.0d0* Surface(ShelfSurf)%Area
    END IF

    ShelfSurf = Shelf(ShelfNum)%OutSurf
    IF (ShelfSurf > 0) THEN
      Shelf(ShelfNum)%OutReflectVis = 1.0d0 - Construct(Shelf(ShelfNum)%Construction)%OutsideAbsorpVis
      Shelf(ShelfNum)%OutReflectSol = 1.0d0 - Construct(Shelf(ShelfNum)%Construction)%OutsideAbsorpSolar

      IF (Shelf(ShelfNum)%ViewFactor < 0) CALL CalcViewFactorToShelf(ShelfNum)

      IF (Shelf(ShelfNum)%ViewFactor + Surface(WinSurf)%ViewFactorSky + Surface(WinSurf)%ViewFactorGround > 1.0d0) THEN
        CALL ShowWarningError('DaylightingDevice:Shelf = '//TRIM(Shelf(ShelfNum)%Name)// &
          ':  Window view factors to sky ['//trim(RoundSigDigits(Surface(WinSurf)%ViewFactorSky,2))//'],')
        CALL ShowContinueError('ground ['//trim(RoundSigDigits(Surface(WinSurf)%ViewFactorGround,2))//  &
          '], and outside shelf ['//trim(RoundSigDigits(Shelf(ShelfNum)%ViewFactor,2))//'] add up to > 1.0.')
      ENDIF

      ! Report calculated view factor so that user knows what to make the view factor to ground
      IF (.not. ShelfReported) THEN
        Write(OutputFileInits,'(A)')   &
         '! <Shelf Details>,Name,View Factor to Outside Shelf,Window Name,Window View Factor to Sky,Window View Factor to Ground'
        ShelfReported=.true.
      ENDIF
      Write(OutputFileInits,'(A)') trim(Shelf(ShelfNum)%Name)//','//trim(RoundSigDigits(Shelf(ShelfNum)%ViewFactor,2))//','// &
        trim(Surface(WinSurf)%Name)//','//trim(RoundSigDigits(Surface(WinSurf)%ViewFactorSky,2))//','// &
        trim(RoundSigDigits(Surface(WinSurf)%ViewFactorGround,2))
!      CALL SetupOutputVariable('View Factor To Outside Shelf []', &
!        Shelf(ShelfNum)%ViewFactor,'Zone','Average',Shelf(ShelfNum)%Name)
    END IF
  END DO

  ! Warning that if Calculate Solar Reflection From Exterior Surfaces = Yes in Building input, then
  ! solar reflection calculated from obstructions will not be used in daylighting shelf or tubular device
  ! calculation

  IF(CalcSolRefl .AND. (NumOfTDDPipes > 0 .OR. NumOfShelf > 0)) THEN
    CALL ShowWarningError('InitDaylightingDevices: Solar Distribution Model includes Solar Reflection calculations;')
    CALL ShowContinueError('the resulting reflected solar values will not be used in the')
    CALL ShowContinueError('DaylightingDevice:Shelf or DaylightingDevice:Tubular calculations.')
  END IF

  RETURN

END SUBROUTINE InitDaylightingDevices


SUBROUTINE GetTDDInput

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   May 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Gets the input for TDD pipes and does some error checking.

          ! METHODOLOGY EMPLOYED:
          ! Standard EnergyPlus methodology.

          ! REFERENCES: na

          ! USE STATEMENTS:
  USE DataIPShortCuts
  USE InputProcessor, ONLY: GetNumObjectsFound, FindItemInList, GetObjectItem, VerifyName
  USE DataDaylighting, ONLY: ZoneDaylight
  USE General, ONLY: RoundSigDigits, SafeDivide

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS: na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
!unused1208  CHARACTER(len=MaxNameLength), &
!                   DIMENSION(20) :: Alphas                ! Alpha items for object
  LOGICAL                        :: ErrorsFound = .FALSE. ! Set to true if errors in input, fatal at end of routine
  INTEGER                        :: IOStatus              ! Used in GetObjectItem
  LOGICAL                        :: IsBlank               ! TRUE if the name is blank
  LOGICAL                        :: IsNotOk               ! TRUE if there was a problem with a list name
!unused1208  REAL(r64), DIMENSION(9)             :: Numbers               ! Numeric items for object
  INTEGER                        :: NumAlphas             ! Number of Alphas for each GetObjectItem call
  INTEGER                        :: NumNumbers            ! Number of Numbers for each GetObjectItem call
  INTEGER                        :: PipeNum               ! TDD pipe object number
  INTEGER                        :: SurfNum               ! Dome or diffuser surface
  INTEGER                        :: TZoneNum              ! Transition zone loop
  CHARACTER(len=MaxNameLength)   :: TZoneName             ! Transition zone name
  REAL(r64)                      :: PipeArea

          ! FLOW:
  cCurrentModuleObject='DaylightingDevice:Tubular'
  NumOfTDDPipes = GetNumObjectsFound(cCurrentModuleObject)

  IF (NumOfTDDPipes > 0) THEN
    ALLOCATE(TDDPipe(NumOfTDDPipes))

    DO PipeNum = 1, NumOfTDDPipes
      CALL GetObjectItem(cCurrentModuleObject,PipeNum,cAlphaArgs,NumAlphas,rNumericArgs,NumNumbers,IOStatus,  &
                   AlphaBlank=lAlphaFieldBlanks,NumBlank=lNumericFieldBlanks,  &
                   AlphaFieldnames=cAlphaFieldNames,NumericFieldNames=cNumericFieldNames)
      ! Pipe name
      IsNotOK = .FALSE.
      IsBlank = .FALSE.
      CALL VerifyName(cAlphaArgs(1),TDDPipe%Name,PipeNum-1,IsNotOK,IsBlank,TRIM(cCurrentModuleObject)//' Name')
      IF (IsNotOK) THEN
        ErrorsFound = .TRUE.
        IF (IsBlank) cAlphaArgs(1) = 'xxxxx'
      END IF
      TDDPipe(PipeNum)%Name = cAlphaArgs(1)

      ! Get TDD:DOME object
      SurfNum = FindItemInList(cAlphaArgs(2),Surface%Name,TotSurfaces)

      IF (SurfNum == 0) THEN
        CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  Dome '//TRIM(cAlphaArgs(2))//' not found.')
        ErrorsFound = .TRUE.
      ELSE
        IF (FindTDDPipe(SurfNum) > 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Dome '//TRIM(cAlphaArgs(2))//' is referenced by more than one TDD.')
          ErrorsFound = .TRUE.
        END IF

        IF (Surface(SurfNum)%Class .NE. SurfaceClass_TDD_Dome) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Dome '//TRIM(cAlphaArgs(2))//' is not of surface type TubularDaylightDome.')
          ErrorsFound = .TRUE.
        END IF

        IF (Construct(Surface(SurfNum)%Construction)%TotGlassLayers > 1) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Dome '//TRIM(cAlphaArgs(2))//' construction ('//  &
            trim(Construct(Surface(SurfNum)%Construction)%Name)//') must have only 1 glass layer.')
          ErrorsFound = .TRUE.
        END IF

        IF (Surface(SurfNum)%WindowShadingControlPtr > 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Dome '//TRIM(cAlphaArgs(2))//' must not have a shading control.')
          ErrorsFound = .TRUE.
        END IF

        IF (Surface(SurfNum)%FrameDivider > 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Dome '//TRIM(cAlphaArgs(2))//' must not have a frame/divider.')
          ErrorsFound = .TRUE.
        END IF

        IF (Construct(Surface(SurfNum)%Construction)%WindowTypeEQL) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Dome '//TRIM(cAlphaArgs(2))//' Equivalent Layer Window is not supported.')
          ErrorsFound = .TRUE.
        ENDIF
        ! Window multiplier is already handled in SurfaceGeometry.f90

        IF (.NOT. Surface(SurfNum)%ExtSolar) THEN
          CALL ShowWarningError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Dome '//TRIM(cAlphaArgs(2))//' is not exposed to exterior radiation.')
        END IF

        TDDPipe(PipeNum)%Dome = SurfNum
      END IF

      ! Get TDD:DIFFUSER object
      SurfNum = FindItemInList(cAlphaArgs(3),Surface%Name,TotSurfaces)

      IF (SurfNum == 0) THEN
        CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  Diffuser '//TRIM(cAlphaArgs(3))//' not found.')
        ErrorsFound = .TRUE.
      ELSE
        IF (FindTDDPipe(SurfNum) > 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Diffuser '//TRIM(cAlphaArgs(3))//' is referenced by more than one TDD.')
          ErrorsFound = .TRUE.
        END IF

        IF (SurfaceWindow(SurfNum)%OriginalClass .NE. SurfaceClass_TDD_Diffuser) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Diffuser '//TRIM(cAlphaArgs(3))//' is not of surface type TubularDaylightDiffuser.')
          ErrorsFound = .TRUE.
        END IF

        IF (Construct(Surface(SurfNum)%Construction)%TotGlassLayers > 1) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Diffuser '//TRIM(cAlphaArgs(3))//' construction ('//  &
            trim(Construct(Surface(SurfNum)%Construction)%Name)//') must have only 1 glass layer.')
          ErrorsFound = .TRUE.
        END IF

        IF (Construct(Surface(SurfNum)%Construction)%Transdiff <= 1.d-10) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Diffuser '//TRIM(cAlphaArgs(3))//' construction ('//  &
            trim(Construct(Surface(SurfNum)%Construction)%Name)//') invalid value.')
          CALL ShowContinueError('Diffuse solar transmittance of construction ['//  &
             trim(RoundSigDigits(Construct(Surface(SurfNum)%Construction)%Transdiff,4))//'] too small for calculations.')
          ErrorsFound = .TRUE.
        END IF

        IF (TDDPipe(PipeNum)%Dome > 0 .AND. ABS(Surface(SurfNum)%Area - Surface(TDDPipe(PipeNum)%Dome)%Area) > 0.1d0) THEN
          IF (SafeDivide(ABS(Surface(SurfNum)%Area - Surface(TDDPipe(PipeNum)%Dome)%Area),  &
                         Surface(TDDPipe(PipeNum)%Dome)%Area) > .1d0) THEN  ! greater than 10%
            CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
              ':  Dome and diffuser areas are significantly different (>10%).')
            CALL ShowContinueError('...Diffuser Area=['//trim(RoundSigDigits(Surface(SurfNum)%Area,4))//  &
              ']; Dome Area=['//trim(RoundSigDigits(Surface(TDDPipe(PipeNum)%Dome)%Area,4))//'].')
            ErrorsFound = .TRUE.
          ELSE
            CALL ShowWarningError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
              ':  Dome and diffuser areas differ by > .1 m2.')
            CALL ShowContinueError('...Diffuser Area=['//trim(RoundSigDigits(Surface(SurfNum)%Area,4))//  &
              ']; Dome Area=['//trim(RoundSigDigits(Surface(TDDPipe(PipeNum)%Dome)%Area,4))//'].')
          ENDIF
        END IF

        IF (Surface(SurfNum)%WindowShadingControlPtr > 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Diffuser '//TRIM(cAlphaArgs(3))//' must not have a shading control.')
          ErrorsFound = .TRUE.
        END IF

        IF (Surface(SurfNum)%FrameDivider > 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Diffuser '//TRIM(cAlphaArgs(3))//' must not have a frame/divider.')
          ErrorsFound = .TRUE.
        END IF

        IF (Construct(Surface(SurfNum)%Construction)%WindowTypeEQL) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Diffuser '//TRIM(cAlphaArgs(2))//' Equivalent Layer Window is not supported.')
          ErrorsFound = .TRUE.
        ENDIF

        ! Window multiplier is already handled in SurfaceGeometry.f90

        TDDPipe(PipeNum)%Diffuser = SurfNum
      END IF

      ! Construction
      TDDPipe(PipeNum)%Construction = FindItemInList(cAlphaArgs(4),Construct%Name,TotConstructs)

      IF(TDDPipe(PipeNum)%Construction == 0) THEN
        CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  Pipe construction '//TRIM(cAlphaArgs(4))//' not found.')
        ErrorsFound = .TRUE.
      ELSE
        Construct(TDDPipe(PipeNum)%Construction)%IsUsed=.true.
      END IF

      IF (rNumericArgs(1) > 0) THEN
        TDDPipe(PipeNum)%Diameter = rNumericArgs(1)
      ELSE
        CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  Pipe diameter must be greater than zero.')
        ErrorsFound = .TRUE.
      END IF

      PipeArea=0.25d0 * Pi * TDDPipe(PipeNum)%Diameter**2
      IF (TDDPipe(PipeNum)%Dome > 0 .AND. ABS(PipeArea - Surface(TDDPipe(PipeNum)%Dome)%Area) > 0.1d0) THEN
        IF (SafeDivide(ABS(PipeArea - Surface(TDDPipe(PipeNum)%Dome)%Area),  &
                         Surface(TDDPipe(PipeNum)%Dome)%Area) > .1d0) THEN  ! greater than 10%
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Pipe and dome/diffuser areas are significantly different (>10%).')
          CALL ShowContinueError('...Pipe Area=['//trim(RoundSigDigits(PipeArea,4))//']; Dome/Diffuser Area=['//  &
               trim(RoundSigDigits(Surface(TDDPipe(PipeNum)%Dome)%Area,4))//'].')
          ErrorsFound = .TRUE.
        ELSE
          CALL ShowWarningError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Pipe and dome/diffuser areas differ by > .1 m2.')
          CALL ShowContinueError('...Pipe Area=['//trim(RoundSigDigits(PipeArea,4))//']; Dome/Diffuser Area=['//  &
               trim(RoundSigDigits(Surface(TDDPipe(PipeNum)%Dome)%Area,4))//'].')
        ENDIF
      END IF

      IF (rNumericArgs(2) > 0) THEN
        TDDPipe(PipeNum)%TotLength = rNumericArgs(2)
      ELSE
        CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  Pipe length must be greater than zero.')
        ErrorsFound = .TRUE.
      END IF

      IF (rNumericArgs(3) > 0) THEN
        TDDPipe(PipeNum)%Reff = rNumericArgs(3)
      ELSE
        CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  Effective thermal resistance (R value) must be greater than zero.')
        ErrorsFound = .TRUE.
      END IF

      ! Transition zones
      TDDPipe(PipeNum)%NumOfTZones = NumAlphas - 4

      IF (TDDPipe(PipeNum)%NumOfTZones < 1) THEN
        CALL ShowWarningError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  No transition zones specified.  All pipe absorbed solar goes to exterior.')
      ELSE IF (TDDPipe(PipeNum)%NumOfTZones > MaxTZones) THEN
        CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  Maximum number of transition zones exceeded.')
        ErrorsFound = .TRUE.
      ELSE
        ALLOCATE(TDDPipe(PipeNum)%TZone(TDDPipe(PipeNum)%NumOfTZones))
        ALLOCATE(TDDPipe(PipeNum)%TZoneLength(TDDPipe(PipeNum)%NumOfTZones))
        ALLOCATE(TDDPipe(PipeNum)%TZoneHeatGain(TDDPipe(PipeNum)%NumOfTZones))

        TDDPipe(PipeNum)%TZone = 0
        TDDPipe(PipeNum)%TZoneLength = 0.d0
        TDDPipe(PipeNum)%TZoneHeatGain = 0.d0

        DO TZoneNum = 1, TDDPipe(PipeNum)%NumOfTZones
          TZoneName = cAlphaArgs(TZoneNum + 4)
          TDDPipe(PipeNum)%TZone(TZoneNum) = FindItemInList(TZoneName,Zone%Name,NumOfZones)
          IF (TDDPipe(PipeNum)%TZone(TZoneNum) == 0) THEN
            CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
              ':  Transition zone '//TRIM(TZoneName)//' not found.')
            ErrorsFound = .TRUE.
          END IF

          TDDPipe(PipeNum)%TZoneLength(TZoneNum) = rNumericArgs(TZoneNum + 3)
          IF (TDDPipe(PipeNum)%TZoneLength(TZoneNum) < 0) THEN
            CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1)) &
              //':  Transition zone length for '//TRIM(TZoneName)//' must be zero or greater.')
            ErrorsFound = .TRUE.
          END IF
        END DO ! TZoneNum
      END IF

    END DO ! PipeNum

    IF (ErrorsFound) CALL ShowFatalError('Errors in DaylightingDevice:Tubular input.')
  END IF

  RETURN

END SUBROUTINE GetTDDInput


SUBROUTINE GetShelfInput

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   August 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Gets the input for light shelves and does some error checking.

          ! METHODOLOGY EMPLOYED:
          ! Standard EnergyPlus methodology.

          ! REFERENCES: na

          ! USE STATEMENTS:
  USE InputProcessor, ONLY: GetNumObjectsFound, FindItemInList, GetObjectItem, VerifyName
  USE DataIPShortCuts

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS: na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  LOGICAL                        :: ErrorsFound = .FALSE. ! Set to true if errors in input, fatal at end of routine
  INTEGER                        :: IOStatus              ! Used in GetObjectItem
  LOGICAL                        :: IsBlank               ! TRUE if the name is blank
  LOGICAL                        :: IsNotOk               ! TRUE if there was a problem with a list name
  INTEGER                        :: NumAlphas             ! Number of Alphas for each GetObjectItem call
  INTEGER                        :: NumNumbers            ! Number of Numbers for each GetObjectItem call
  INTEGER                        :: ShelfNum              ! Daylighting shelf object number
  INTEGER                        :: SurfNum               ! Window, inside, or outside shelf surfaces
  INTEGER                        :: ConstrNum             ! Outside shelf construction object number

          ! FLOW:
  cCurrentModuleObject='DaylightingDevice:Shelf'
  NumOfShelf = GetNumObjectsFound(cCurrentModuleObject)

  IF (NumOfShelf > 0) THEN
    ALLOCATE(Shelf(NumOfShelf))

    DO ShelfNum = 1, NumOfShelf
      CALL GetObjectItem('DaylightingDevice:Shelf',ShelfNum,cAlphaArgs,NumAlphas,rNumericArgs,NumNumbers,IOStatus,  &
                   AlphaBlank=lAlphaFieldBlanks,NumBlank=lNumericFieldBlanks,  &
                   AlphaFieldnames=cAlphaFieldNames,NumericFieldNames=cNumericFieldNames)
      ! Shelf name
      IsNotOK = .FALSE.
      IsBlank = .FALSE.
      CALL VerifyName(cAlphaArgs(1),Shelf%Name,ShelfNum-1,IsNotOK,IsBlank,'DaylightingDevice:Shelf')
      IF (IsNotOK) THEN
        ErrorsFound = .TRUE.
        IF (IsBlank) cAlphaArgs(1) = 'xxxxx'
      END IF
      Shelf(ShelfNum)%Name = cAlphaArgs(1)

      ! Get window object
      SurfNum = FindItemInList(cAlphaArgs(2),Surface%Name,TotSurfaces)

      IF (SurfNum == 0) THEN
        CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  Window '//TRIM(cAlphaArgs(2))//' not found.')
        ErrorsFound = .TRUE.
      ELSE
        IF (Surface(SurfNum)%Class .NE. SurfaceClass_Window) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Window '//TRIM(cAlphaArgs(2))//' is not of surface type WINDOW.')
          ErrorsFound = .TRUE.
        END IF

        IF (Surface(SurfNum)%Shelf > 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Window '//TRIM(cAlphaArgs(2))//' is referenced by more than one shelf.')
          ErrorsFound = .TRUE.
        END IF

        IF (Surface(SurfNum)%WindowShadingControlPtr > 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Window '//TRIM(cAlphaArgs(2))//' must not have a shading control.')
          ErrorsFound = .TRUE.
        END IF

        IF (Surface(SurfNum)%FrameDivider > 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Window '//TRIM(cAlphaArgs(2))//' must not have a frame/divider.')
          ErrorsFound = .TRUE.
        END IF

        IF (Surface(SurfNum)%Sides /= 4) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Window '//TRIM(cAlphaArgs(2))//' must have 4 sides.')
          ErrorsFound = .TRUE.
        END IF
        !
        IF (Construct(Surface(SurfNum)%Construction)%WindowTypeEQL) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Window '//TRIM(cAlphaArgs(2))//' Equivalent Layer Window is not supported.')
          ErrorsFound = .TRUE.
        ENDIF


        Shelf(ShelfNum)%Window = SurfNum
        Surface(SurfNum)%Shelf = ShelfNum
      END IF

      ! Get inside shelf heat transfer surface (optional)
      IF (cAlphaArgs(3) .NE. '') THEN
        SurfNum = FindItemInList(cAlphaArgs(3),Surface%Name,TotSurfaces)

        IF (SurfNum == 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Inside shelf '//TRIM(cAlphaArgs(3))//' not found.')
          ErrorsFound = .TRUE.
        ELSE
          ! No error if shelf belongs to more than one window, e.g. concave corners

          IF (Surface(SurfNum)%ExtBoundCond .NE. SurfNum) THEN
            CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
              ':  Inside shelf '//TRIM(cAlphaArgs(3))//  &
              ' must be its own Outside Boundary Condition Object.')
            ErrorsFound = .TRUE.
          END IF

          IF (Surface(SurfNum)%Sides /= 4) THEN
            CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
              ':  Inside shelf '//TRIM(cAlphaArgs(3))//' must have 4 sides.')
            ErrorsFound = .TRUE.
          END IF

          Shelf(ShelfNum)%InSurf = SurfNum
        END IF
      END IF

        ! Get outside shelf attached shading surface (optional)
      IF (cAlphaArgs(4) .NE. '') THEN
        SurfNum = FindItemInList(cAlphaArgs(4),Surface%Name,TotSurfaces)

        IF (SurfNum == 0) THEN
          CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
            ':  Outside shelf '//TRIM(cAlphaArgs(4))//' not found.')
          ErrorsFound = .TRUE.
        ELSE
          ! No error if shelf belongs to more than one window, e.g. concave corners

          IF (Surface(SurfNum)%Class .NE. SurfaceClass_Shading) THEN
            CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
              ':  Outside shelf '//TRIM(cAlphaArgs(4))//' is not a Shading:Zone:Detailed object.')
            ErrorsFound = .TRUE.
          END IF

          IF (Surface(SurfNum)%SchedShadowSurfIndex > 0) THEN
            CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
              ':  Outside shelf '//TRIM(cAlphaArgs(4))//' must not have a transmittance schedule.')
            ErrorsFound = .TRUE.
          END IF

          IF (Surface(SurfNum)%Sides /= 4) THEN
            CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
              ':  Outside shelf '//TRIM(cAlphaArgs(4))//' must have 4 sides.')
            ErrorsFound = .TRUE.
          END IF

          ! Get outside shelf construction (required if outside shelf is specified)
          IF (cAlphaArgs(5) .NE. '') THEN
            ConstrNum = FindIteminList(cAlphaArgs(5),Construct%Name,TotConstructs)

            IF (ConstrNum == 0) THEN
              CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
                ':  Outside shelf construction '//TRIM(cAlphaArgs(5))//' not found.')
              ErrorsFound = .TRUE.
            ELSE IF (Construct(ConstrNum)%TypeIsWindow) THEN
              CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
                ':  Outside shelf construction '//TRIM(cAlphaArgs(5))//' must not have WindowMaterial:Glazing.')
              ErrorsFound = .TRUE.
            ELSE
              Shelf(ShelfNum)%Construction = ConstrNum
              Construct(ConstrNum)%IsUsed=.true.
            END IF
          ELSE
            CALL ShowSevereError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
              ':  Outside shelf requires an outside shelf construction to be specified.')
            ErrorsFound = .TRUE.
          END IF

          ! Get view factor to outside shelf (optional)
          IF (NumNumbers > 0) THEN
            Shelf(ShelfNum)%ViewFactor = rNumericArgs(1)

            IF (rNumericArgs(1) == 0.0d0) THEN
              CALL ShowWarningError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
                ':  View factor to outside shelf is zero.  Shelf does not reflect on window.')
            END IF
          ELSE
            Shelf(ShelfNum)%ViewFactor = -1.0d0! Flag to have the view factor calculated during initialization
          END IF

          Shelf(ShelfNum)%OutSurf = SurfNum

          ! Reset some properties of the SURFACE:SHADING:ATTACHED object in order to receive radiation and shading
          ! Normally this would be done during initialization, but that's not early enough for some shading calculations
          Surface(SurfNum)%BaseSurf = SurfNum
          Surface(SurfNum)%HeatTransSurf = .TRUE.
          Surface(SurfNum)%Construction = ConstrNum ! Kludge to allow shading surface to be a heat transfer surface
          Construct(ConstrNum)%IsUsed=.true.
        END IF
      END IF

      IF (Shelf(ShelfNum)%InSurf == 0 .AND. Shelf(ShelfNum)%OutSurf == 0) &
        CALL ShowWarningError(trim(cCurrentModuleObject)//' = '//TRIM(cAlphaArgs(1))// &
          ':  No inside shelf or outside shelf was specified.')

    END DO ! ShelfNum

    IF (ErrorsFound) CALL ShowFatalError('Errors in DaylightingDevice:Shelf input.')
  END IF

  RETURN

END SUBROUTINE GetShelfInput


REAL(r64) FUNCTION CalcPipeTransBeam(R, A, Theta)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   May 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Calculates the numerical integral for the transmittance of a reflective cylinder with
          ! incident collimated beam radiation as described in Swift and Smith.

          ! METHODOLOGY EMPLOYED:
          ! Since this integral can be slow, a table of values is calculated and stored during
          ! initialization of the TDD.  Intermediate values are calculated by interpolation.
          ! Transmittance of sky and ground diffuse radiation is done by other functions.

          ! REFERENCES:
          ! Swift, P. D., and Smith, G. B.  "Cylindrical Mirror Light Pipes",
          !   Solar Energy Materials and Solar Cells 36 (1995), pp. 159-168.

          ! OTHER NOTES:
          ! The execution time of this function can be reduced by adjusting parameters N and xTol below.
          ! However, there is some penalty in accuracy for N < 100,000 and xTol > 150.

          ! USE STATEMENTS: na

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! FUNCTION ARGUMENT DEFINITIONS:
  REAL(r64), INTENT(IN)            :: R            ! Reflectance of surface, constant (can be made R = f(theta) later)
  REAL(r64), INTENT(IN)            :: A            ! Aspect ratio, L / d
  REAL(r64), INTENT(IN)            :: Theta        ! Angle of entry in radians

          ! FUNCTION PARAMETER DEFINITIONS:
  REAL(r64), PARAMETER :: N = 100000.0d0 ! Number of integration points
  REAL(r64), PARAMETER :: xTol = 150.0d0 ! Tolerance factor to skip iterations where dT is approximately 0
                                              ! Must be >= 1.0, increase this number to decrease the execution time
  REAL(r64), PARAMETER :: myLocalTiny =  TINY(1.0D0)

          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
  REAL(r64)       :: i            ! Integration interval between points
  REAL(r64)       :: s            ! Entry point
  REAL(r64)       :: dT
  REAL(r64)       :: T            ! Beam transmittance for collimated solar real
  REAL(r64)       :: x, c1, c2    ! Intermediate variables for speed optimization
  REAL(r64)       :: xLimit       ! Limiting x value to prevent floating point underflow

          ! FLOW:
  CalcPipeTransBeam = 0.0d0

  T = 0.0d0
  i = 1.0d0 / N

  xLimit = (LOG(N**2.0d0*myLocalTiny)/LOG(R))/xTol

  c1 = A * TAN(Theta)
  c2 = 4.0d0 / Pi

  s = i
  DO WHILE (s < (1.0d0 - i))
    x = c1 / s

    IF (x < xLimit) THEN
      dT = c2 * (R**INT(x)) * (1.0d0 - (1.0d0 - R) * (x - INT(x))) * (s**2) / SQRT(1.0d0 - s**2)
      T = T + dT
    END IF

    s = s + i
  END DO

  T = T / (N - 1.0d0) ! - 1.0, because started on i, not 0

  CalcPipeTransBeam = T

  RETURN

END FUNCTION CalcPipeTransBeam


REAL(r64) FUNCTION CalcTDDTransSolIso(PipeNum)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   July 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Calculates the transmittance of sky isotropic radiation for use with the anisotropic sky transmittance.
          ! This value is also used for all ground reflected solar radiation (which is isotropic).

          ! METHODOLOGY EMPLOYED:
          ! The transmittance is calculated and stored once at initialization because the value is a constant.
          ! The routine numerically integrates over the entire sky.  All radiation is isotropic, but incident
          ! angle varies over the hemisphere.
          !
          ! Trans = Flux Transmitted / Flux Incident
          !
          ! Not sure if shading and tilt is adequately accounted for by DifShdgRatioIsoSky later on or not...

          ! REFERENCES:
          ! See AnisoSkyViewFactors in SolarShading.f90.

          ! USE STATEMENTS: na

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! FUNCTION ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN) :: PipeNum    ! TDD pipe object number

          ! FUNCTION PARAMETER DEFINITIONS:
  INTEGER, PARAMETER  :: NPH = 1000 ! Number of altitude integration points

          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
  REAL(r64)    :: FluxInc    ! Incident solar flux
  REAL(r64)    :: FluxTrans  ! Transmitted solar flux
  REAL(r64)    :: trans      ! Total beam solar transmittance of TDD
  INTEGER             :: N          ! Loop counter
  REAL(r64)           :: PH         ! Altitude angle of sky element
  REAL(r64)           :: dPH        ! Altitude angle increment
  REAL(r64)           :: COSI       ! Cosine of incident angle
  REAL(r64)           :: SINI       ! Sine of incident angle
  REAL(r64)           :: P          ! Angular distribution function

          ! FLOW:
  FluxInc = 0.0d0
  FluxTrans = 0.0d0

  ! Integrate from 0 to Pi/2 altitude
  dPH = 90.0d0 * DegToRadians / NPH
  PH = 0.5d0 * dPH
  DO N = 1, NPH
    COSI = COS(PiOvr2 - PH)
    SINI = SIN(PiOvr2 - PH)

    P = COSI ! Angular distribution function: P = COS(Incident Angle) for diffuse isotropic

    ! Calculate total TDD transmittance for given angle
    trans = TransTDD(PipeNum, COSI, SolarBeam)

    FluxInc = FluxInc + P * SINI * dPH
    FluxTrans = FluxTrans + trans * P * SINI * dPH

    PH = PH + dPH ! Increment the altitude angle
  END DO ! N

  CalcTDDTransSolIso = FluxTrans / FluxInc

  RETURN

END FUNCTION CalcTDDTransSolIso


REAL(r64) FUNCTION CalcTDDTransSolHorizon(PipeNum)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   July 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Calculates the transmittance of sky horizon radiation for use with the anisotropic sky transmittance.

          ! METHODOLOGY EMPLOYED:
          ! The transmittance is calculated and stored once at initialization because the value is a constant.
          ! The routine numerically integrates over the horizon as an infinitesimally narrow strip of the sky.
          ! Horizon radiation is isotropic, but incident angle varies over the semicircle.
          !
          ! Trans = Flux Transmitted / Flux Incident
          !
          ! Not sure if shading is adequately accounted for by DifShdgRatioHoriz later on or not...

          ! REFERENCES:
          ! See AnisoSkyViewFactors in SolarShading.f90.

          ! USE STATEMENTS:
  USE DataSurfaces

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! FUNCTION ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN) :: PipeNum    ! TDD pipe object number

          ! FUNCTION PARAMETER DEFINITIONS:
  INTEGER, PARAMETER  :: NTH = 18   ! Number of azimuth integration points

          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
  REAL(r64)    :: FluxInc    ! Incident solar flux
  REAL(r64)    :: FluxTrans  ! Transmitted solar flux
  REAL(r64)    :: trans      ! Total beam solar transmittance of TDD
  INTEGER             :: N          ! Loop counter
  REAL(r64)           :: TH         ! Azimuth angle of sky horizon element
  REAL(r64)           :: dTH        ! Azimuth angle increment
  REAL(r64)           :: THMIN      ! Minimum azimuth integration limit
  REAL(r64)           :: THMAX      ! Maximum azimuth integration limit
  REAL(r64)           :: CosPhi     ! Cosine of TDD:DOME altitude angle
  REAL(r64)           :: Theta      ! TDD:DOME azimuth angle
  REAL(r64)           :: COSI       ! Cosine of the incident angle

          ! FLOW:
  FluxInc = 0.0d0
  FluxTrans = 0.0d0

  CosPhi = COS(PiOvr2 - Surface(TDDPipe(PipeNum)%Dome)%Tilt * DegToRadians)
  Theta = Surface(TDDPipe(PipeNum)%Dome)%Azimuth * DegToRadians

  IF (CosPhi > 0.01d0) THEN ! Dome has a view of the horizon
    ! Integrate over the semicircle
    THMIN = Theta - PiOvr2
    THMAX = Theta + PiOvr2
    dTH = 180.0d0 * DegToRadians / NTH
    TH = THMIN + 0.5d0 * dTH
    DO N = 1, NTH
      ! Calculate incident angle between dome outward normal and horizon element
      COSI = CosPhi * COS(TH - Theta)

      ! Calculate total TDD transmittance for given angle
      trans = TransTDD(PipeNum, COSI, SolarBeam)

      FluxInc = FluxInc + COSI * dTH
      FluxTrans = FluxTrans + trans * COSI * dTH

      TH = TH + dTH ! Increment the azimuth angle
    END DO ! N

    CalcTDDTransSolHorizon = FluxTrans / FluxInc

  ELSE ! Dome is nearly horizontal and has almost no view of the horizon
    CalcTDDTransSolHorizon = 0.0d0 ! = TransTDD(PipeNum, ???, SolarBeam) ! Could change to an angle near the horizon
  END IF

  RETURN

END FUNCTION CalcTDDTransSolHorizon


REAL(r64) FUNCTION CalcTDDTransSolAniso(PipeNum, COSI)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   July 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Calculates the transmittance of the anisotropic sky.

          ! METHODOLOGY EMPLOYED:
          ! Similar to the Trans = FluxTrans/FluxInc integrations above, the anisotropic sky can be decomposed
          ! and have a different transmittance applied to each component.
          !
          !   FluxInc = IsoSkyRad + CircumSolarRad + HorizonRad
          !   FluxTrans = T1*IsoSkyRad + T2*CircumSolarRad + T3*HorizonRad
          !
          ! It turns out that FluxTrans/FluxInc is equivalent to AnisoSkyTDDMult/AnisoSkyMult.
          ! AnisoSkyMult has been conveniently calculated already in AnisoSkyViewFactors in SolarShading.f90.
          !
          ! AnisoSkyMult = MultIsoSky*DifShdgRatioIsoSky + MultCircumSolar*SunLitFrac + MultHorizonZenith*DifShdgRatioHoriz
          !
          ! In this routine a similar AnisoSkyTDDMult is calculated that applies the appropriate transmittance to each
          ! of the components above.  The result is Trans = AnisoSkyTDDMult/AnisoSkyMult.
          !
          ! Shading and orientation are already taken care of by DifShdgRatioIsoSky and DifShdgRatioHoriz.

          ! REFERENCES:
          ! See AnisoSkyViewFactors in SolarShading.f90.

          ! USE STATEMENTS: na
  USE DataGlobals, ONLY: HourOfDay, TimeStep
  USE DataHeatBalance, ONLY: SunlitFrac, AnisoSkyMult, DifShdgRatioIsoSky, DifShdgRatioHoriz, &
    MultIsoSky, MultCircumSolar, MultHorizonZenith, curDifShdgRatioIsoSky, DifShdgRatioHorizHRTS
  USE DataSystemVariables, ONLY: DetailedSkyDiffuseAlgorithm

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! FUNCTION ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN) :: PipeNum         ! TDD pipe object number
  REAL(r64), INTENT(IN)    :: COSI            ! Cosine of the incident angle

          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
  INTEGER             :: DomeSurf        ! TDD:DOME surface number
  REAL(r64)           :: IsoSkyRad       ! Isotropic sky radiation component
  REAL(r64)           :: CircumSolarRad  ! Circumsolar sky radiation component
  REAL(r64)           :: HorizonRad      ! Horizon sky radiation component
  REAL(r64)           :: AnisoSkyTDDMult ! Anisotropic sky multiplier for TDD

          ! FLOW:
  DomeSurf = TDDPipe(PipeNum)%Dome

  IF (.not. DetailedSkyDiffuseAlgorithm .or. .not.  ShadingTransmittanceVaries .or.  &
      SolarDistribution == MinimalShadowing) THEN
    IsoSkyRad = MultIsoSky(DomeSurf) * DifShdgRatioIsoSky(DomeSurf)
    HorizonRad = MultHorizonZenith(DomeSurf) * DifShdgRatioHoriz(DomeSurf)
  ELSE
    IsoSkyRad = MultIsoSky(DomeSurf) * curDifShdgRatioIsoSky(DomeSurf)
    HorizonRad = MultHorizonZenith(DomeSurf) * DifShdgRatioHorizHRTS(DomeSurf,HourOfDay,TimeStep)
  ENDIF
  CircumSolarRad = MultCircumSolar(DomeSurf) * SunlitFrac(DomeSurf,HourOfDay,TimeStep)

  AnisoSkyTDDMult = &
    TDDPipe(PipeNum)%TransSolIso * IsoSkyRad &
    + TransTDD(PipeNum, COSI, SolarBeam) * CircumSolarRad &
    + TDDPipe(PipeNum)%TransSolHorizon * HorizonRad

  IF (AnisoSkyMult(DomeSurf) > 0.0d0) THEN
    CalcTDDTransSolAniso = AnisoSkyTDDMult / AnisoSkyMult(DomeSurf)
  ELSE
    CalcTDDTransSolAniso = 0.0d0
  ENDIF

  RETURN

END FUNCTION CalcTDDTransSolAniso


RECURSIVE REAL(r64) FUNCTION TransTDD(PipeNum, COSI, RadiationType)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   May 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Calculates the total transmittance of the TDD for specified radiation type.

          ! METHODOLOGY EMPLOYED:
          ! The transmittances for each component (i.e. TDD:DIFFUSER, TDD:DOME, and pipe) are calculated.
          ! All transmittances are multiplied to get the total for the TDD:
          !   TransTDD = transDome * transPipe * transDiff
          !
          ! Transmittance of beam radiation is calculated by interpolating the values in a
          ! table created during initialization.  The table values are from Swift and Smith's
          ! numerical integral for collimated beam radiation.
          !
          ! Transmittances of isotropic and anisotropic diffuse radiation are more complicated and call
          ! other subroutines in this module.
          !
          ! All light reaching the TDD:DIFFUSER is assumed to be diffuse.
          ! NOTE: Dome transmittance could be improved by taking into account curvature of the dome.

          ! REFERENCES:
          ! Swift, P. D., and Smith, G. B.  "Cylindrical Mirror Light Pipes",
          !   Solar Energy Materials and Solar Cells 36 (1995), pp. 159-168.

          ! USE STATEMENTS:
  USE General, ONLY: POLYF

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! FUNCTION ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN)           :: PipeNum        ! TDD pipe object number
  REAL(r64), INTENT(IN)              :: COSI           ! Cosine of the incident angle
  INTEGER, INTENT(IN)           :: RadiationType  ! Radiation type flag

          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
  INTEGER                       :: constDome      ! Construction object number for TDD:DOME
  INTEGER                       :: constDiff      ! Construction object number for TDD:DIFFUSER
  REAL(r64)                     :: transDome
  REAL(r64)                     :: transPipe
  REAL(r64)                     :: transDiff

          ! FLOW:
  TransTDD = 0.0d0

  ! Get constructions of each TDD component
  constDome = Surface(TDDPipe(PipeNum)%Dome)%Construction
  constDiff = Surface(TDDPipe(PipeNum)%Diffuser)%Construction

  ! Get the transmittance of each component and of total TDD
  SELECT CASE (RadiationType)

    CASE (VisibleBeam)
      transDome = POLYF(COSI, Construct(constDome)%TransVisBeamCoef)
      transPipe = InterpolatePipeTransBeam(COSI, TDDPipe(PipeNum)%PipeTransVisBeam)
      transDiff = Construct(constDiff)%TransDiffVis ! May want to change to POLYF also!

      TransTDD = transDome * transPipe * transDiff

    CASE (SolarBeam)
      transDome = POLYF(COSI, Construct(constDome)%TransSolBeamCoef)
      transPipe = InterpolatePipeTransBeam(COSI, TDDPipe(PipeNum)%PipeTransSolBeam)
      transDiff = Construct(constDiff)%TransDiff ! May want to change to POLYF also!

      TransTDD = transDome * transPipe * transDiff

    CASE (SolarAniso)
      TransTDD = CalcTDDTransSolAniso(PipeNum, COSI)

    CASE (SolarIso)
      TransTDD = TDDPipe(PipeNum)%TransSolIso

  END SELECT

  RETURN

END FUNCTION TransTDD


REAL(r64) FUNCTION InterpolatePipeTransBeam(COSI, transBeam)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   July 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Interpolates the beam transmittance vs. cosine angle table.

          ! METHODOLOGY EMPLOYED: na
          ! REFERENCES: na

          ! USE STATEMENTS:
  USE FluidProperties, ONLY: FindArrayIndex ! USEd code could be copied here to eliminate dependence on FluidProperties

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! FUNCTION ARGUMENT DEFINITIONS:
  REAL(r64), INTENT(IN)                         :: COSI         ! Cosine of the incident angle
  REAL(r64), DIMENSION(NumOfAngles), INTENT(IN) :: transBeam    ! Table of beam transmittance vs. cosine angle

          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
  INTEGER                                  :: Lo, Hi
  REAL(r64)                                :: m, b

          ! FLOW:
  InterpolatePipeTransBeam = 0.0d0

  ! Linearly interpolate transBeam/COSAngle table to get value at current cosine of the angle
  Lo = FindArrayIndex(COSI, COSAngle)
  Hi = Lo + 1

  IF (Lo > 0 .AND. Hi <= NumOfAngles) THEN
    m = (transBeam(Hi) - transBeam(Lo)) / (COSAngle(Hi) - COSAngle(Lo))
    b = transBeam(Lo) - m * COSAngle(Lo)

    InterpolatePipeTransBeam = m * COSI + b
  ELSE
    InterpolatePipeTransBeam = 0.0d0
  END IF

  RETURN

END FUNCTION InterpolatePipeTransBeam


INTEGER FUNCTION FindTDDPipe(WinNum)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   May 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Given the TDD:DOME or TDD:DIFFUSER object number, returns TDD pipe number.

          ! METHODOLOGY EMPLOYED:
          ! Similar to FindItemInList defined in InputProcessor.

          ! REFERENCES: na
          ! USE STATEMENTS:
  USE DataSurfaces, ONLY: Surface

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! FUNCTION ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN) :: WinNum

          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
  INTEGER             :: PipeNum       ! TDD pipe object number

          ! FLOW:
  FindTDDPipe = 0

  IF (NumOfTDDPipes <= 0) THEN
    CALL ShowFatalError('FindTDDPipe: Surface='//TRIM(Surface(WinNum)%Name)//  &
        ', TDD:Dome object does not reference a valid Diffuser object.' // &
        '...needs DaylightingDevice:Tubular of same name as Surface.')
  ENDIF

  DO PipeNum = 1, NumOfTDDPipes
     IF ((WinNum .EQ. TDDPipe(PipeNum)%Dome) .OR. (WinNum .EQ. TDDPipe(PipeNum)%Diffuser)) THEN
       FindTDDPipe = PipeNum
       EXIT
     END IF
  END DO ! PipeNum

  RETURN

END FUNCTION FindTDDPipe


SUBROUTINE DistributeTDDAbsorbedSolar

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   July 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Sums the absorbed solar gains from TDD pipes that pass through transition zones.

          ! METHODOLOGY EMPLOYED:
          ! The total absorbed solar gain is a sum of the following gains:
          !   1. Inward bound solar absorbed by multiple pipe reflections (solar entering pipe - solar exiting pipe)
          !   2. Outward bound solar absorbed by multiple pipe reflections due to:
          !     a. Reflection off of diffuser surface (inside of TDD)
          !     b. Zone diffuse interior shortwave incident on the diffuser from windows, lights, etc.
          !   3. Inward absorbed solar in dome and diffuser glass
          !
          ! This subroutine is called by InitIntSolarDistribution in HeatBalanceSurfaceManager.f90.

          ! REFERENCES: na

          ! USE STATEMENTS:
  USE DataHeatBalance, ONLY: QRadSWOutIncident, QRadSWwinAbs, QRadSWwinAbsTot, QS, ZoneIntGain
  USE DataSurfaces, ONLY: WinTransSolar

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS: na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  INTEGER :: PipeNum        ! TDD pipe object number
  INTEGER :: DiffSurf       ! Surface number of TDD:DIFFUSER
  INTEGER :: TZoneNum       ! Transition zone index
!  INTEGER :: ActualZone     ! Actual transition zone number
  REAL(r64)    :: transDiff      ! Diffuse transmittance of TDD:DIFFUSER
  REAL(r64)    :: QRefl          ! Diffuse radiation reflected back up the pipe
  REAL(r64)    :: TotTDDPipeGain ! Total absorbed solar gain in the tubular daylighting device pipe

          ! FLOW:
  DO PipeNum = 1, NumOfTDDPipes
    DiffSurf = TDDPipe(PipeNum)%Diffuser
    transDiff = Construct(Surface(DiffSurf)%Construction)%TransDiff

    ! Calculate diffuse solar reflected back up the pipe by the inside surface of the TDD:DIFFUSER
    ! All solar arriving at the diffuser is assumed to be isotropically diffuse by this point
    QRefl = (QRadSWOutIncident(DiffSurf) - QRadSWwinAbsTot(DiffSurf)) * Surface(DiffSurf)%Area - WinTransSolar(DiffSurf)

    ! Add diffuse interior shortwave reflected from zone surfaces and from zone sources, lights, etc.
    QRefl = QRefl + QS(Surface(DiffSurf)%Zone) * Surface(DiffSurf)%Area * transDiff

    TotTDDPipeGain = WinTransSolar(TDDPipe(PipeNum)%Dome) & ! Solar entering pipe
      - QRadSWOutIncident(DiffSurf) * Surface(DiffSurf)%Area & ! Solar exiting pipe
      + QRefl * (1.0d0 - TDDPipe(PipeNum)%TransSolIso / transDiff) & ! Absorbed due to reflections on the way out
      + QRadSWwinAbs(TDDPipe(PipeNum)%Dome,1) * Surface(DiffSurf)%Area / 2.0d0 & ! Inward absorbed solar from dome glass
      + QRadSWwinAbs(DiffSurf,1) * Surface(DiffSurf)%Area / 2.0d0 ! Inward absorbed solar from diffuser glass

    TDDPipe(PipeNum)%PipeAbsorbedSolar = MAX(0.0d0, TotTDDPipeGain) ! Report variable [W]

    DO TZoneNum = 1, TDDPipe(PipeNum)%NumOfTZones
      ! Distribute absorbed solar gain in proportion to transition zone length
      TDDPipe(PipeNum)%TZoneHeatGain(TZoneNum) = &
          TotTDDPipeGain * (TDDPipe(PipeNum)%TZoneLength(TZoneNum) / TDDPipe(PipeNum)%TotLength)
    END DO ! TZoneNum
  END DO

  RETURN

END SUBROUTINE DistributeTDDAbsorbedSolar


SUBROUTINE CalcViewFactorToShelf(ShelfNum)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Peter Graham Ellis
          !       DATE WRITTEN   August 2003
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Attempts to calculate exact analytical view factor from window to outside shelf.

          ! METHODOLOGY EMPLOYED:
          ! Uses a standard analytical solution.  It is required that window and shelf have the same width, i.e.
          ! one edge (or two vertices) shared in common.  An error or warning is issued if not true.
          !
          ! A more general routine should be implemented at some point to solve for more complicated geometries.
          ! Until then, the user has the option to specify their own solution for the view factor in the input object.

          ! REFERENCES:
          ! Mills, A. F.  Heat and Mass Transfer, 1995, p. 499.  (Shape factor for adjacent rectangles.)

          ! USE STATEMENTS:
  USE Vectors, ONLY: Distance

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN) :: ShelfNum           ! Daylighting shelf object number

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  REAL(r64)           :: W, H, L            ! Width, height, and length of window/shelf geometry
  REAL(r64)           :: M, N               ! Intermediate variables
  REAL(r64)           :: E1, E2, E3, E4     ! Intermediate equations
  INTEGER             :: VWin, VShelf       ! Vertex indices
  INTEGER             :: NumMatch           ! Number of vertices matched

          ! FLOW:
  W = Surface(Shelf(ShelfNum)%Window)%Width
  H = Surface(Shelf(ShelfNum)%Window)%Height

  ! Find length, i.e. projection, of outside shelf
  IF (Surface(Shelf(ShelfNum)%OutSurf)%Width == W) THEN
    L = Surface(Shelf(ShelfNum)%OutSurf)%Height
  ELSE IF (Surface(Shelf(ShelfNum)%OutSurf)%Height == W) THEN
    L = Surface(Shelf(ShelfNum)%OutSurf)%Width
  ELSE
    CALL ShowFatalError('DaylightingDevice:Shelf = '//TRIM(Shelf(ShelfNum)%Name)// &
      ':  Width of window and outside shelf do not match.')
  END IF

  ! Error if more or less than two vertices match
  NumMatch = 0
  DO VWin = 1, 4
    DO VShelf = 1, 4
      IF (Distance(Surface(Shelf(ShelfNum)%Window)%Vertex(VWin), Surface(Shelf(ShelfNum)%OutSurf)%Vertex(VShelf)) == 0.0d0) &
        NumMatch = NumMatch + 1
    END DO
  END DO

  IF (NumMatch < 2) THEN
    CALL ShowWarningError('DaylightingDevice:Shelf = '//TRIM(Shelf(ShelfNum)%Name)// &
      ':  Window and outside shelf must share two vertices.  View factor calculation may be inaccurate.')
  ELSE IF (NumMatch > 2) THEN
    CALL ShowFatalError('DaylightingDevice:Shelf = '//TRIM(Shelf(ShelfNum)%Name)// &
      ':  Window and outside shelf share too many vertices.')
  END IF

  ! Calculate exact analytical view factor from window to outside shelf
  M = H / W
  N = L / W

  E1 = M * ATAN((1.0d0 / M)) + N * ATAN((1.0d0 / N)) - (SQRT(N**2 + M**2)) * ATAN(((N**2 + M**2))**(-0.5d0))
  E2 = ((1.0d0 + M**2) * (1.0d0 + N**2)) / (1.0d0 + M**2 + N**2)
  E3 = ((M**2) * (1.0d0 + M**2 + N**2) / ((1.0d0 + M**2) * (M**2 + N**2)))**(M**2)
  E4 = ((N**2) * (1.0d0 + M**2 + N**2) / ((1.0d0 + N**2) * (M**2 + N**2)))**(N**2)

  Shelf(ShelfNum)%ViewFactor = (1.0d0 / (Pi * M)) * (E1 + 0.25d0 * LOG(E2 * E3 * E4))

  RETURN

END SUBROUTINE CalcViewFactorToShelf

SUBROUTINE FigureTDDZoneGains

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         B. Griffith
          !       DATE WRITTEN   Dec 2011
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! intialize zone gains at begin new environment

          ! METHODOLOGY EMPLOYED:
          ! <description>

          ! REFERENCES:
          ! na

          ! USE STATEMENTS:
  USE DataGlobals, ONLY: BeginEnvrnFlag

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
          ! na

          ! SUBROUTINE PARAMETER DEFINITIONS:
          ! na

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  LOGICAL, SAVE :: MyEnvrnFlag = .TRUE.
  INTEGER   :: Loop

  IF (NumOfTDDPipes == 0) RETURN

  IF (BeginEnvrnFlag .AND. MyEnvrnFlag) THEN
    DO Loop = 1, NumOfTDDPipes
      TDDPipe(Loop)%TZoneHeatGain = 0.d0
    ENDDO
    MyEnvrnFlag = .FALSE.
  ENDIF
  IF( .NOT. BeginEnvrnFlag) MyEnvrnFlag = .TRUE.

  RETURN

END SUBROUTINE FigureTDDZoneGains

!     NOTICE
!
!     Copyright © 1996-2013 The Board of Trustees of the University of Illinois
!     and The Regents of the University of California through Ernest Orlando Lawrence
!     Berkeley National Laboratory.  All rights reserved.
!
!     Portions of the EnergyPlus software package have been developed and copyrighted
!     by other individuals, companies and institutions.  These portions have been
!     incorporated into the EnergyPlus software package under license.   For a complete
!     list of contributors, see "Notice" located in EnergyPlus.f90.
!
!     NOTICE: The U.S. Government is granted for itself and others acting on its
!     behalf a paid-up, nonexclusive, irrevocable, worldwide license in this data to
!     reproduce, prepare derivative works, and perform publicly and display publicly.
!     Beginning five (5) years after permission to assert copyright is granted,
!     subject to two possible five year renewals, the U.S. Government is granted for
!     itself and others acting on its behalf a paid-up, non-exclusive, irrevocable
!     worldwide license in this data to reproduce, prepare derivative works,
!     distribute copies to the public, perform publicly and display publicly, and to
!     permit others to do so.
!
!     TRADEMARKS: EnergyPlus is a trademark of the US Department of Energy.
!

END MODULE DaylightingDevices

AirflowNetworkBalanceManager.f90 AirflowNetworkSolver.f90 BaseboardRadiator.f90 BaseboardRadiatorElectric.f90 BaseboardRadiatorSteam.f90 BaseboardRadiatorWater.f90 BranchInputManager.f90 BranchNodeConnections.f90 ConductionTransferFunctionCalc.f90 CoolTower.f90 CostEstimateManager.f90 CurveManager.f90 CVFOnlyRoutines.f90 DataAirflowNetwork.f90 DataAirLoop.f90 DataAirSystems.f90 DataBranchAirLoopPlant.f90 DataBranchNodeConnections.f90 DataBSDFWindow.f90 DataComplexFenestration.f90 DataContaminantBalance.f90 DataConvergParams.f90 DataConversions.f90 DataCostEstimate.f90 DataDaylighting.f90 DataDaylightingDevices.f90 Datadefineequip.f90 DataDElight.f90 DataEnvironment.f90 DataEquivalentLayerWindow.f90 DataErrorTracking.f90 DataGenerators.f90 DataGlobalConstants.f90 DataGlobals.f90 DataHeatBalance.f90 DataHeatBalFanSys.f90 DataHeatBalSurface.f90 DataHVACControllers.f90 DataHVACGlobals.f90 DataInterfaces.f90 DataIPShortCuts.f90 DataLoopNode.f90 DataMoistureBalance.f90 DataMoistureBalanceEMPD.f90 DataOutputs.f90 DataPhotovoltaics.f90 DataPlant.f90 DataPlantPipingSystems.f90 DataPrecisionGlobals.f90 DataReportingFlags.f90 DataRoomAir.f90 DataRootFinder.f90 DataRuntimeLanguage.f90 DataShadowingCombinations.f90 DataSizing.f90 DataStringGlobals.f90 DataSurfaceColors.f90 DataSurfaceLists.f90 DataSurfaces.f90 DataSystemVariables.f90 DataTimings.f90 DataUCSDSharedData.f90 DataVectorTypes.f90 DataViewFactorInformation.f90 DataWater.f90 DataZoneControls.f90 DataZoneEnergyDemands.f90 DataZoneEquipment.f90 DaylightingDevices.f90 DaylightingManager.f90 DElightManagerF.f90 DElightManagerF_NO.f90 DemandManager.f90 DesiccantDehumidifiers.f90 DirectAir.f90 DisplayRoutines.f90 DXCoil.f90 EarthTube.f90 EconomicLifeCycleCost.f90 EconomicTariff.f90 EcoRoof.f90 ElectricPowerGenerators.f90 ElectricPowerManager.f90 EMSManager.f90 EnergyPlus.f90 ExteriorEnergyUseManager.f90 ExternalInterface_NO.f90 FanCoilUnits.f90 FaultsManager.f90 FluidProperties.f90 General.f90 GeneralRoutines.f90 GlobalNames.f90 HeatBalanceAirManager.f90 HeatBalanceConvectionCoeffs.f90 HeatBalanceHAMTManager.f90 HeatBalanceInternalHeatGains.f90 HeatBalanceIntRadExchange.f90 HeatBalanceManager.f90 HeatBalanceMovableInsulation.f90 HeatBalanceSurfaceManager.f90 HeatBalFiniteDifferenceManager.f90 HeatRecovery.f90 Humidifiers.f90 HVACControllers.f90 HVACCooledBeam.f90 HVACDualDuctSystem.f90 HVACDuct.f90 HVACDXSystem.f90 HVACEvapComponent.f90 HVACFanComponent.f90 HVACFurnace.f90 HVACHeatingCoils.f90 HVACHXAssistedCoolingCoil.f90 HVACInterfaceManager.f90 HVACManager.f90 HVACMixerComponent.f90 HVACMultiSpeedHeatPump.f90 HVACSingleDuctInduc.f90 HVACSingleDuctSystem.f90 HVACSplitterComponent.f90 HVACStandAloneERV.f90 HVACSteamCoilComponent.f90 HVACTranspiredCollector.f90 HVACUnitaryBypassVAV.f90 HVACUnitarySystem.f90 HVACVariableRefrigerantFlow.f90 HVACWaterCoilComponent.f90 HVACWatertoAir.f90 HVACWatertoAirMultiSpeedHP.f90 InputProcessor.f90 MatrixDataManager.f90 MixedAir.f90 MoistureBalanceEMPDManager.f90 NodeInputManager.f90 NonZoneEquipmentManager.f90 OutAirNodeManager.f90 OutdoorAirUnit.f90 OutputProcessor.f90 OutputReportPredefined.f90 OutputReports.f90 OutputReportTabular.f90 PackagedTerminalHeatPump.f90 PackagedThermalStorageCoil.f90 Photovoltaics.f90 PhotovoltaicThermalCollectors.f90 PlantAbsorptionChillers.f90 PlantBoilers.f90 PlantBoilersSteam.f90 PlantCentralGSHP.f90 PlantChillers.f90 PlantCondLoopOperation.f90 PlantCondLoopTowers.f90 PlantEIRChillers.f90 PlantEvapFluidCoolers.f90 PlantExhaustAbsorptionChiller.f90 PlantFluidCoolers.f90 PlantGasAbsorptionChiller.f90 PlantGroundHeatExchangers.f90 PlantHeatExchanger.f90 PlantIceThermalStorage.f90 PlantLoadProfile.f90 PlantLoopEquipment.f90 PlantLoopSolver.f90 PlantManager.f90 PlantOutsideEnergySources.f90 PlantPipeHeatTransfer.f90 PlantPipes.f90 PlantPipingSystemManager.f90 PlantPondGroundHeatExchanger.f90 PlantPressureSystem.f90 PlantPumps.f90 PlantSolarCollectors.f90 PlantSurfaceGroundHeatExchanger.f90 PlantUtilities.f90 PlantValves.f90 PlantWaterSources.f90 PlantWaterThermalTank.f90 PlantWatertoWaterGSHP.f90 PlantWaterUse.f90 PollutionAnalysisModule.f90 PoweredInductionUnits.f90 PsychRoutines.f90 Purchasedairmanager.f90 RadiantSystemHighTemp.f90 RadiantSystemLowTemp.f90 RefrigeratedCase.f90 ReportSizingManager.f90 ReturnAirPath.f90 RoomAirManager.f90 RoomAirModelCrossVent.f90 RoomAirModelDisplacementVent.f90 RoomAirModelMundt.f90 RoomAirModelUFAD.f90 RoomAirModelUserTempPattern.f90 RootFinder.f90 RuntimeLanguageProcessor.f90 ScheduleManager.f90 SetPointManager.f90 SimAirServingZones.f90 SimulationManager.f90 SizingManager.f90 SolarReflectionManager.f90 SolarShading.f90 SortAndStringUtilities.f90 sqlite3.c SQLiteCRoutines.c SQLiteFortranRoutines.f90 SQLiteFortranRoutines_NO.f90 StandardRatings.f90 SurfaceGeometry.f90 SystemAvailabilityManager.f90 SystemReports.f90 TarcogComplexFenestration.f90 ThermalChimney.f90 ThermalComfort.f90 UnitHeater.f90 UnitVentilator.f90 UserDefinedComponents.f90 UtilityRoutines.f90 VectorUtilities.f90 VentilatedSlab.f90 WaterManager.f90 WeatherManager.f90 WindowAC.f90 WindowComplexManager.f90 WindowEquivalentLayer.f90 WindowManager.f90 WindTurbine.f90 Zoneairloopequipmentmanager.f90 ZoneContaminantPredictorCorrector.f90 ZoneDehumidifier.f90 Zoneequipmentmanager.f90 ZonePlenumComponent.f90 ZoneTempPredictorCorrector.f90