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) | :: | PVNum | |||
logical, | intent(in) | :: | RunFlag |
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 CalcSandiaPV(PVNum, runFlag)
! SUBROUTINE INFORMATION:
! AUTHOR B. Griffith , (derived from Greg Barker's TRNSYS type101 for SANDIA PV model)
! DATE WRITTEN Jan 2004
! MODIFIED B. Griffith, Aug. 2008 reworked for new, single-PV-generator data structure
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! Calculate various PV system peformance indicies at the current timestep
! METHODOLOGY EMPLOYED:
! adapted code from a set of F77 routines by G. Barker that implement the model
! This routines works on a single photovoltaic object of the type 'GENERATOR:PV:SANDIA'
! Each major model equation has its own function (in this module)
! REFERENCES:
! King, David L. . Photovoltaic module and array performance characterization methods for all
! system operating conditions. Pro. NREL/SNL Photovoltaics Program Review, AIP Press, Lakewood CO
! Sandia National Laboratories
! Davis, M.W., A.H. Fanney, and B.P. Dougherty. Measured versus predicted performance of Building
! integrated photovoltaics. Solar 2002, Sunrise on the Reliable Energy Economy, June 15-19, 2002 Reno, NV
! USE STATEMENTS:
!
USE DataGlobals, ONLY: DegToRadians
USE DataEnvironment, ONLY: Elevation, SOLCOS
USE DataHeatBalance, ONLY: CosIncidenceAngle, QRadSWOutIncidentBeam, QRadSWOutIncident
USE DataHeatBalSurface, ONLY: TempSurfOut
USE DataSurfaces, ONLY: Surface
USE TranspiredCollector, ONLY: GetUTSCTsColl
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER, INTENT(IN) :: PVNum ! ptr to current PV system
LOGICAL, INTENT(IN) :: RunFlag ! controls if generator is scheduled *ON*
! SUBROUTINE PARAMETER DEFINITIONS:
! na
! INTERFACE BLOCK SPECIFICATIONS:
! na
! DERIVED TYPE DEFINITIONS:
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
INTEGER :: thisSurf ! working variable for indexing surfaces
!unused1208 INTEGER :: thisMod ! working variable for indexing module parameters
REAL(r64) :: Ee
thisSurf = PVarray(PVNum)%SurfacePtr
! get input from elsewhere in Energyplus for the current point in the simulation
PVArray(PVNum)%SNLPVinto%IcBeam = QRadSWOutIncidentBeam(thisSurf) !(W/m2)from DataHeatBalance
PVArray(PVNum)%SNLPVinto%IcDiffuse = QRadSWOutIncident(thisSurf) - QRadSWOutIncidentBeam(thisSurf) !(W/ m2)(was kJ/hr m2)
PVArray(PVNum)%SNLPVinto%IncidenceAngle = ACOS(CosIncidenceAngle(thisSurf) )/DegToRadians ! (deg) from dataHeatBalance
PVArray(PVNum)%SNLPVinto%ZenithAngle = ACOS (SOLCOS(3))/DegToRadians !(degrees),
PVArray(PVNum)%SNLPVinto%Tamb = Surface(thisSurf)%OutDryBulbTemp !(deg. C)
PVArray(PVNum)%SNLPVinto%WindSpeed = Surface(thisSurf)%WindSpeed ! (m/s)
PVArray(PVNum)%SNLPVinto%Altitude = Elevation ! from DataEnvironment via USE
IF (((PVArray(PVNum)%SNLPVinto%IcBeam+ PVArray(PVNum)%SNLPVinto%IcDiffuse) > MinIrradiance) &
.AND. (RunFlag) ) THEN
! first determine PV cell temperatures depending on model
SELECT CASE (PVarray(PVNum)%CellIntegrationMode)
CASE (iDecoupledCellIntegration) ! Sandia module temperature model for rack mounted PVs
! Calculate back-of-module temperature:
PVarray(PVNum)%SNLPVCalc%Tback = SandiaModuleTemperature(PVArray(PVNum)%SNLPVinto%IcBeam, &
PVArray(PVNum)%SNLPVinto%IcDiffuse, &
PVArray(PVNum)%SNLPVinto%WindSpeed, &
PVArray(PVNum)%SNLPVinto%Tamb, &
PVArray(PVNum)%SNLPVModule%fd, &
PVArray(PVNum)%SNLPVmodule%a, &
PVArray(PVNum)%SNLPVmodule%b )
! Calculate cell temperature:
PVarray(PVNum)%SNLPVCalc%Tcell = SandiaTcellFromTmodule(PVarray(PVNum)%SNLPVCalc%Tback,PVArray(PVNum)%SNLPVinto%IcBeam, &
PVArray(PVNum)%SNLPVinto%IcDiffuse, PVArray(PVNum)%SNLPVmodule%fd, &
PVArray(PVNum)%SNLPVmodule%DT0)
CASE (iSurfaceOutsideFaceCellIntegration)
! get back-of-module temperature from elsewhere in EnergyPlus
PVarray(PVNum)%SNLPVCalc%Tback = TempSurfOut(PVArray(PVNum)%SurfacePtr)
PVarray(PVNum)%SNLPVCalc%Tcell = SandiaTcellFromTmodule(PVarray(PVNum)%SNLPVCalc%Tback,PVArray(PVNum)%SNLPVinto%IcBeam, &
PVArray(PVNum)%SNLPVinto%IcDiffuse, PVArray(PVNum)%SNLPVmodule%fd, &
PVArray(PVNum)%SNLPVmodule%DT0)
CASE (iTranspiredCollectorCellIntegration)
CAll GetUTSCTsColl(PVArray(PVNum)%UTSCPtr, PVarray(PVNum)%SNLPVCalc%Tback)
PVarray(PVNum)%SNLPVCalc%Tcell = SandiaTcellFromTmodule(PVarray(PVNum)%SNLPVCalc%Tback,PVArray(PVNum)%SNLPVinto%IcBeam, &
PVArray(PVNum)%SNLPVinto%IcDiffuse, PVArray(PVNum)%SNLPVmodule%fd, &
PVArray(PVNum)%SNLPVmodule%DT0)
CASE (iExteriorVentedCavityCellIntegration)
CALL GetExtVentedCavityTsColl(PVArray(PVNum)%ExtVentCavPtr, &
PVarray(PVNum)%SNLPVCalc%Tback)
PVarray(PVNum)%SNLPVCalc%Tcell = SandiaTcellFromTmodule(PVarray(PVNum)%SNLPVCalc%Tback,PVArray(PVNum)%SNLPVinto%IcBeam, &
PVArray(PVNum)%SNLPVinto%IcDiffuse, PVArray(PVNum)%SNLPVmodule%fd, &
PVArray(PVNum)%SNLPVmodule%DT0)
CASE (iPVTSolarCollectorCellIntegration)
! add calls to PVT models here
CASE DEFAULT
Call ShowSevereError('Sandia PV Simulation Temperature Modeling Mode Error in ' &
//TRIM(PVArray(PVNum)%Name) )
END SELECT
! Calculate Air Mass function
PVarray(PVNum)%SNLPVCalc%AMa = AbsoluteAirMass(PVArray(PVNum)%SNLPVinto%ZenithAngle, PVArray(PVNum)%SNLPVinto%Altitude)
! Calculate F1 polynomial function:
PVarray(PVNum)%SNLPVCalc%F1 = SandiaF1(PVarray(PVNum)%SNLPVCalc%AMa,PVArray(PVNum)%SNLPVmodule%a_0, &
PVArray(PVNum)%SNLPVmodule%a_1,PVArray(PVNum)%SNLPVmodule%a_2, &
PVArray(PVNum)%SNLPVmodule%a_3,PVArray(PVNum)%SNLPVmodule%a_4)
! Calculate F2 polynomial function:
PVarray(PVNum)%SNLPVCalc%F2 = SandiaF2(PVArray(PVNum)%SNLPVinto%IncidenceAngle,PVArray(PVNum)%SNLPVmodule%b_0, &
PVArray(PVNum)%SNLPVmodule%b_1,PVArray(PVNum)%SNLPVmodule%b_2, &
PVArray(PVNum)%SNLPVmodule%b_3,PVArray(PVNum)%SNLPVmodule%b_4, &
PVArray(PVNum)%SNLPVmodule%b_5)
! Calculate short-circuit current function:
PVarray(PVNum)%SNLPVCalc%Isc = SandiaIsc( PVarray(PVNum)%SNLPVCalc%Tcell, PVArray(PVNum)%SNLPVmodule%Isc0, &
PVArray(PVNum)%SNLPVinto%IcBeam, PVArray(PVNum)%SNLPVinto%IcDiffuse, PVarray(PVNum)%SNLPVCalc%F1, &
PVarray(PVNum)%SNLPVCalc%F2, PVArray(PVNum)%SNLPVmodule%fd, PVArray(PVNum)%SNLPVmodule%aIsc )
! Calculate effective irradiance function:
Ee = SandiaEffectiveIrradiance(PVarray(PVNum)%SNLPVCalc%Tcell,PVarray(PVNum)%SNLPVCalc%Isc, &
PVArray(PVNum)%SNLPVmodule%Isc0, PVArray(PVNum)%SNLPVmodule%aIsc)
! Calculate Imp function:
PVarray(PVNum)%SNLPVCalc%Imp = SandiaImp(PVarray(PVNum)%SNLPVCalc%Tcell, Ee, PVArray(PVNum)%SNLPVmodule%Imp0, &
PVArray(PVNum)%SNLPVmodule%aImp,PVArray(PVNum)%SNLPVmodule%c_0, &
PVArray(PVNum)%SNLPVmodule%c_1)
! Calculate Voc function:
PVarray(PVNum)%SNLPVCalc%Voc = SandiaVoc(PVarray(PVNum)%SNLPVCalc%Tcell, Ee, PVArray(PVNum)%SNLPVmodule%Voc0, &
PVArray(PVNum)%SNLPVmodule%NcellSer,PVArray(PVNum)%SNLPVmodule%DiodeFactor, &
PVArray(PVNum)%SNLPVmodule%BVoc0,PVArray(PVNum)%SNLPVmodule%mBVoc)
! Calculate Vmp: voltagea at maximum powerpoint
PVarray(PVNum)%SNLPVCalc%Vmp = SandiaVmp(PVarray(PVNum)%SNLPVCalc%Tcell,Ee,PVArray(PVNum)%SNLPVmodule%Vmp0, &
PVArray(PVNum)%SNLPVmodule%NcellSer,PVArray(PVNum)%SNLPVmodule%DiodeFactor, &
PVArray(PVNum)%SNLPVmodule%BVmp0,PVArray(PVNum)%SNLPVmodule%mBVmp, &
PVArray(PVNum)%SNLPVmodule%c_2,PVArray(PVNum)%SNLPVmodule%c_3)
! Calculate Ix function:
PVarray(PVNum)%SNLPVCalc%Ix = SandiaIx(PVarray(PVNum)%SNLPVCalc%Tcell,Ee,PVArray(PVNum)%SNLPVmodule%Ix0, &
PVArray(PVNum)%SNLPVmodule%aIsc,PVArray(PVNum)%SNLPVmodule%aImp, &
PVArray(PVNum)%SNLPVmodule%c_4,PVArray(PVNum)%SNLPVmodule%c_5)
! Calculate Vx function:
PVarray(PVNum)%SNLPVCalc%Vx = PVarray(PVNum)%SNLPVCalc%Voc/2.0d0
! Calculate Ixx function:
PVarray(PVNum)%SNLPVCalc%Ixx = SandiaIxx(PVarray(PVNum)%SNLPVCalc%Tcell,Ee,PVArray(PVNum)%SNLPVmodule%Ixx0, &
PVArray(PVNum)%SNLPVmodule%aImp,PVArray(PVNum)%SNLPVmodule%c_6, &
PVArray(PVNum)%SNLPVmodule%c_7)
! Calculate Vxx :
PVarray(PVNum)%SNLPVCalc%Vxx = 0.5d0*(PVarray(PVNum)%SNLPVCalc%Voc+PVarray(PVNum)%SNLPVCalc%Vmp)
! Calculate Pmp, single module: power at maximum powerpoint
PVarray(PVNum)%SNLPVCalc%Pmp = PVarray(PVNum)%SNLPVCalc%Imp * PVarray(PVNum)%SNLPVCalc%Vmp ! W
! Calculate PV efficiency at maximum power point
PVarray(PVNum)%SNLPVCalc%EffMax = PVarray(PVNum)%SNLPVCalc%Pmp/ &
(PVArray(PVNum)%SNLPVinto%IcBeam+PVArray(PVNum)%SNLPVinto%IcDiffuse)/PVArray(PVNum)%SNLPVmodule%Acoll
! Scale to NumStrings and NumSeries:
PVarray(PVNum)%SNLPVCalc%Pmp = PVarray(PVNum)%SNLPVCalc%Pmp * PVarray(PVNum)%NumSeriesNParall &
* PVarray(PVNum)%NumModNSeries
PVarray(PVNum)%SNLPVCalc%Imp = PVarray(PVNum)%SNLPVCalc%Imp * PVarray(PVNum)%NumModNSeries
PVarray(PVNum)%SNLPVCalc%Vmp = PVarray(PVNum)%SNLPVCalc%Vmp * PVarray(PVNum)%NumModNSeries
PVarray(PVNum)%SNLPVCalc%Isc = PVarray(PVNum)%SNLPVCalc%Isc * PVarray(PVNum)%NumSeriesNParall
PVarray(PVNum)%SNLPVCalc%Voc = PVarray(PVNum)%SNLPVCalc%Voc * PVarray(PVNum)%NumModNSeries
PVarray(PVNum)%SNLPVCalc%Ix = PVarray(PVNum)%SNLPVCalc%Ix * PVarray(PVNum)%NumSeriesNParall
PVarray(PVNum)%SNLPVCalc%Ixx = PVarray(PVNum)%SNLPVCalc%Ixx * PVarray(PVNum)%NumSeriesNParall
PVarray(PVNum)%SNLPVCalc%Vx = PVarray(PVNum)%SNLPVCalc%Vx * PVarray(PVNum)%NumModNSeries
PVarray(PVNum)%SNLPVCalc%Vxx = PVarray(PVNum)%SNLPVCalc%Vxx * PVarray(PVNum)%NumModNSeries
PVarray(PVNum)%SNLPVCalc%SurfaceSink = PVarray(PVNum)%SNLPVCalc%Pmp
ELSE ! Ibeam+Idiff < MaxIrradiance or not RunFlag
! so zero things.
PVarray(PVNum)%SNLPVCalc%Vmp=0.0d0
PVarray(PVNum)%SNLPVCalc%Imp=0.0d0
PVarray(PVNum)%SNLPVCalc%Pmp=0.0d0
PVarray(PVNum)%SNLPVCalc%EffMax=0.0d0
PVarray(PVNum)%SNLPVCalc%Isc=0.0d0
PVarray(PVNum)%SNLPVCalc%Voc=0.0d0
PVarray(PVNum)%SNLPVCalc%Tcell=PVArray(PVNum)%SNLPVinto%Tamb
PVarray(PVNum)%SNLPVCalc%Tback=PVArray(PVNum)%SNLPVinto%Tamb
PVarray(PVNum)%SNLPVCalc%AMa=999.0d0
PVarray(PVNum)%SNLPVCalc%F1=0.0d0
PVarray(PVNum)%SNLPVCalc%F2=0.0d0
PVarray(PVNum)%SNLPVCalc%Ix=0.0d0
PVarray(PVNum)%SNLPVCalc%Vx=0.0d0
PVarray(PVNum)%SNLPVCalc%Ixx=0.0d0
PVarray(PVNum)%SNLPVCalc%Vxx=0.0d0
PVarray(PVNum)%SNLPVCalc%SurfaceSink = 0.0d0
ENDIF !Ibeam+Idiff > MinIrradiance and runflag
! update calculations to report variables
PVarray(PVNum)%Report%DCPower = PVarray(PVNum)%SNLPVCalc%Pmp
PVarray(PVNum)%Report%ArrayIsc = PVarray(PVNum)%SNLPVCalc%Isc
PVarray(PVNum)%Report%ArrayVoc = PVarray(PVNum)%SNLPVCalc%Voc
PVarray(PVNum)%Report%CellTemp = PVarray(PVNum)%SNLPVCalc%Tcell
PVarray(PVNum)%Report%ArrayEfficiency = PVarray(PVNum)%SNLPVCalc%EffMax
PVarray(PVNum)%SurfaceSink = PVarray(PVNum)%SNLPVCalc%SurfaceSink
RETURN
END SUBROUTINE CalcSandiaPV