Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PV Zone Multiplier Fix #6283

Merged
merged 3 commits into from
Sep 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/EnergyPlus/DataPhotovoltaics.hh
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ namespace DataPhotovoltaics {
std::string SurfaceName; // named surface in heat balance domain
std::string PerfObjName;
int SurfacePtr; // index for named surface
int Zone; // index for zone (for getting any zone multipliers)
int PVModelType; // type of performance modeling, Simple, TRNSYS or Equivalent 1-diode, or Sandia/King model
int CellIntegrationMode; // how are PV cells integrated with other E+ modeling
Real64 NumModNSeries; // number of modules in series in one string
Expand All @@ -427,6 +428,7 @@ namespace DataPhotovoltaics {
// Default Constructor
PVArrayStruct() :
SurfacePtr( 0 ),
Zone( 0 ),
PVModelType( 0 ),
CellIntegrationMode( 0 ),
NumModNSeries( 1.0 ),
Expand Down
58 changes: 34 additions & 24 deletions src/EnergyPlus/Photovoltaics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ namespace Photovoltaics {
ShowContinueError( "Entered in " + cCurrentModuleObject + " = " + cAlphaArgs( 1 ) );
ShowContinueError( "Surface is not exposed to solar, check surface bounday condition" );
}
PVarray( PVnum ).Zone = GetPVZone( PVarray( PVnum ).SurfacePtr );

// check surface orientation, warn if upside down
if ( ( Surface( SurfNum ).Tilt < -95.0 ) || ( Surface( SurfNum ).Tilt > 95.0 ) ) {
Expand Down Expand Up @@ -757,6 +758,34 @@ namespace Photovoltaics {

}

int
GetPVZone( int const SurfNum )
{
// SUBROUTINE INFORMATION:
// AUTHOR Rick Strand
// DATE WRITTEN Sept 2017

// PURPOSE OF THIS SUBROUTINE:
// Get the zone number for this PV array for use when zone multipliers are applied

using DataHeatBalance::Zone;
using DataGlobals::NumOfZones;
using DataSurfaces::Surface;
using InputProcessor::FindItemInList;

int GetPVZone( 0 );

if ( SurfNum > 0 ) {
GetPVZone = Surface( SurfNum ).Zone;
if ( GetPVZone == 0 ) { // might need to get the zone number from the name
GetPVZone = FindItemInList( Surface( SurfNum ).ZoneName, Zone, NumOfZones );
}
}

return GetPVZone;

}

// **************************************

void
Expand Down Expand Up @@ -856,47 +885,28 @@ namespace Photovoltaics {
// AUTHOR B. Griffith
// DATE WRITTEN Jan. 2004
// MODIFIED B. Griffith, Aug. 2008
// RE-ENGINEERED na

// PURPOSE OF THIS SUBROUTINE:
// collect statements that assign to variables tied to output variables

// METHODOLOGY EMPLOYED:
// <description>

// REFERENCES:
// na

// USE STATEMENTS:
// na
// Using/Aliasing
using DataHeatBalance::Zone;
using DataGlobals::NumOfZones;
using DataSurfaces::Surface;
using DataHeatBalFanSys::QPVSysSource;
using TranspiredCollector::SetUTSCQdotSource;

// Locals
// SUBROUTINE ARGUMENT DEFINITIONS:

// SUBROUTINE PARAMETER DEFINITIONS:
// na

// INTERFACE BLOCK SPECIFICATIONS:
// na

// DERIVED TYPE DEFINITIONS:
// na
using InputProcessor::FindItemInList;

// SUBROUTINE LOCAL VARIABLE DECLARATIONS:
int thisZone; // working index for zones

PVarray( PVnum ).Report.DCEnergy = PVarray( PVnum ).Report.DCPower * ( TimeStepSys * SecInHour );

// add check for multiplier. if surface is attached to a zone that is on a multiplier
// then PV production should be multiplied out as well

if ( Surface( PVarray( PVnum ).SurfacePtr ).Zone != 0 ) { // might need to apply multiplier
thisZone = Surface( PVarray( PVnum ).SurfacePtr ).Zone;
thisZone = PVarray( PVnum ).Zone;
if ( thisZone != 0 ) { // might need to apply multiplier
PVarray( PVnum ).Report.DCEnergy *= ( Zone( thisZone ).Multiplier * Zone( thisZone ).ListMultiplier );
PVarray( PVnum ).Report.DCPower *= ( Zone( thisZone ).Multiplier * Zone( thisZone ).ListMultiplier );
}
Expand Down
5 changes: 5 additions & 0 deletions src/EnergyPlus/Photovoltaics.hh
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ namespace Photovoltaics {

void
GetPVInput();

int
GetPVZone(
int const SurfNum
);

// **************************************

Expand Down
62 changes: 62 additions & 0 deletions tst/EnergyPlus/unit/Photovoltaics.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@

// EnergyPlus Headers
#include <Photovoltaics.hh>
#include <DataPhotovoltaics.hh>
#include <DataHeatBalance.hh>
#include <DataSurfaces.hh>

#include "Fixtures/EnergyPlusFixture.hh"

Expand All @@ -73,3 +76,62 @@ TEST_F( EnergyPlusFixture, PV_Sandia_AirMassAtHighZenith )
EXPECT_NEAR( airMass, 26.24135, 0.1 );

}

TEST_F( EnergyPlusFixture, PV_ReportPV_ZoneIndexNonZero )
{
// unit test for issue #6222, test to make sure zone index in surface on which PV is placed is not zero so zone multiplier is applied properly

EnergyPlus::DataPhotovoltaics::PVarray.deallocate();
DataHeatBalance::Zone.deallocate();
DataSurfaces::Surface.deallocate();

EnergyPlus::DataPhotovoltaics::PVarray.allocate( 3 );
DataHeatBalance::Zone.allocate( 2 );
DataSurfaces::Surface.allocate( 3 );

DataGlobals::NumOfZones = 2;
DataHeatBalance::Zone( 1 ).Name = "Zone1";
DataHeatBalance::Zone( 1 ).ListMultiplier = 1.0;
DataHeatBalance::Zone( 1 ).Multiplier = 5.0;
DataHeatBalance::Zone( 2 ).Name = "Zone2";
DataHeatBalance::Zone( 2 ).ListMultiplier = 10.0;
DataHeatBalance::Zone( 2 ).Multiplier = 1.0;

EnergyPlus::DataPhotovoltaics::NumPVs = 3;
EnergyPlus::DataPhotovoltaics::PVarray( 1 ).SurfacePtr = 1;
EnergyPlus::DataPhotovoltaics::PVarray( 1 ).CellIntegrationMode = -9999;
EnergyPlus::DataPhotovoltaics::PVarray( 2 ).SurfacePtr = 2;
EnergyPlus::DataPhotovoltaics::PVarray( 2 ).CellIntegrationMode = -9999;
EnergyPlus::DataPhotovoltaics::PVarray( 3 ).SurfacePtr = 3;
EnergyPlus::DataPhotovoltaics::PVarray( 3 ).CellIntegrationMode = -9999;

DataSurfaces::Surface( 1 ).Zone = 1;
DataSurfaces::Surface( 1 ).ZoneName = "Zone1";
DataSurfaces::Surface( 2 ).Zone = 0;
DataSurfaces::Surface( 2 ).ZoneName = "Zone2";
DataSurfaces::Surface( 3 ).Zone = 0;
DataSurfaces::Surface( 3 ).ZoneName = "None";

// Test 1: Zone 1--PV has multiplier, Zone index already set
EnergyPlus::DataPhotovoltaics::PVarray( 1 ).Report.DCPower = 1000.0;
EnergyPlus::DataPhotovoltaics::PVarray( 1 ).Zone = Photovoltaics::GetPVZone( EnergyPlus::DataPhotovoltaics::PVarray( 1 ).SurfacePtr );
Photovoltaics::ReportPV( 1 );
EXPECT_EQ( EnergyPlus::DataPhotovoltaics::PVarray( 1 ).Zone, 1 );
EXPECT_NEAR( EnergyPlus::DataPhotovoltaics::PVarray( 1 ).Report.DCPower, 5000.0, 0.1 );

// Test 2: Zone 2--PV has multiplier, Zone index not set yet
EnergyPlus::DataPhotovoltaics::PVarray( 2 ).Report.DCPower = 1000.0;
EnergyPlus::DataPhotovoltaics::PVarray( 2 ).Zone = Photovoltaics::GetPVZone( EnergyPlus::DataPhotovoltaics::PVarray( 2 ).SurfacePtr );
Photovoltaics::ReportPV( 2 );
EXPECT_EQ( EnergyPlus::DataPhotovoltaics::PVarray( 2 ).Zone, 2 );
EXPECT_NEAR( EnergyPlus::DataPhotovoltaics::PVarray( 2 ).Report.DCPower, 10000.0, 0.1 );

// Test 3: Zone 3--PV not attached to any zone, Zone Index does not get set
EnergyPlus::DataPhotovoltaics::PVarray( 3 ).Report.DCPower = 1000.0;
EnergyPlus::DataPhotovoltaics::PVarray( 3 ).Zone = Photovoltaics::GetPVZone( EnergyPlus::DataPhotovoltaics::PVarray( 3 ).SurfacePtr );
Photovoltaics::ReportPV( 3 );
EXPECT_EQ( EnergyPlus::DataPhotovoltaics::PVarray( 3 ).Zone, 0 );
EXPECT_NEAR( EnergyPlus::DataPhotovoltaics::PVarray( 3 ).Report.DCPower, 1000.0, 0.1 );

}