Skip to content

Commit c7d7ce5

Browse files
committed
UPdate wind stow methods
1 parent 8efe281 commit c7d7ce5

File tree

8 files changed

+92
-47
lines changed

8 files changed

+92
-47
lines changed

shared/lib_irradproc.cpp

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,9 +1233,9 @@ solarpos_spa(int year, int month, int day, int hour, double minute, double secon
12331233
sunn[8] = hextra; //extraterrestrial solar irradaince on horizontal at particular time (W/m2)
12341234
}
12351235

1236-
void incidence(int mode, double tilt, double sazm, double rlim, double alim, double zen,
1236+
void incidence(int mode, double tilt, double sazm, double rlim, double alim, double aref, double zen,
12371237
double azm, bool en_backtrack, double gcr, double slope_tilt, double slope_azm,
1238-
bool force_to_stow, double stow_angle_deg, bool useCustomAngle, double customAngle, double angle[5]) {
1238+
bool force_to_stow, double stow_angle_deg, bool useCustomAngle, double customAngle, bool wind_stow_active, double stow_angle_tilt, double stow_angle_azm, double angle[5]) {
12391239
/*
12401240
Calculate panel orientation, angle of incidence with beam radiation, and
12411241
tracker rotation angles (where applicable).
@@ -1247,26 +1247,33 @@ void incidence(int mode, double tilt, double sazm, double rlim, double alim, dou
12471247
axis when viewed from the raised end of the 1-axis tracker. If rotated
12481248
counter clockwise the angle is negative. Range is -180 to +180 degrees.
12491249
When xsazm = azm : rot = 0, tilt = xtilt, and sazm = xsazm = azm */
1250-
1250+
12511251
double arg, inc = 0, xsazm, xtilt, rot = 0, btdiff = 0, truetracking_rotation = 0;
12521252

1253-
if (mode == 4)
1253+
if (mode == 4 || wind_stow_active == true)
12541254
mode = 0; //treat timeseries tilt as fixed tilt for each timestep
12551255

12561256
switch (mode) {
12571257
case 0: /* Fixed-Tilt, */
12581258
case 3: /* or Azimuth Axis*/
12591259
tilt = tilt * DTOR; /* Change tilt and surface azimuth to radians */
1260-
if (mode == 0) {
1261-
sazm = sazm * DTOR;
1260+
if (wind_stow_active) {
1261+
sazm = stow_angle_azm * DTOR;
1262+
tilt = stow_angle_tilt * DTOR;
12621263
}
12631264
else {
1264-
sazm = azm;
1265-
alim = alim * DTOR;
1266-
if (sazm < (M_PI - alim) )/* Do not let azimuth exceed physical constraints */
1267-
sazm = M_PI - alim;
1268-
else if (sazm > (M_PI + alim))
1269-
sazm = M_PI + alim;
1265+
if (mode == 0) {
1266+
sazm = sazm * DTOR;
1267+
}
1268+
else {
1269+
sazm = azm;
1270+
alim = alim * DTOR;
1271+
aref = aref * DTOR;
1272+
if (sazm < (aref - alim)) /* Do not let azimuth exceed physical constraints */
1273+
sazm = aref - alim;
1274+
else if (sazm > (aref + alim))
1275+
sazm = aref + alim;
1276+
}
12701277
}
12711278
//sazm = (mode == 0) ? sazm * DTOR : azm; /* either fixed surface azimuth or solar azimuth */
12721279
arg = sin(zen) * cos(azm - sazm) * sin(tilt) + cos(zen) * cos(tilt);
@@ -1881,13 +1888,13 @@ irrad::irrad() {
18811888
irrad::irrad(weather_header hdr,
18821889
int skyModelIn, int radiationModeIn, int trackModeIn,
18831890
bool instantaneousWeather, bool backtrackingEnabled, bool forceToStowIn,
1884-
double dtHour, double tiltDegreesIn, double azimuthDegreesIn, double trackerRotationLimitDegreesIn, double azimuthLimitDegrees, double stowAngleDegreesIn,
1885-
double groundCoverageRatioIn, double slopeTiltIn, double slopeAzmIn, poaDecompReq *poaAllIn, bool enableSubhourlyClipping) :
1891+
double dtHour, double tiltDegreesIn, double azimuthDegreesIn, double trackerRotationLimitDegreesIn, double azimuthLimitDegrees, double azimuthRefDegrees, double stowAngleDegreesIn,
1892+
double groundCoverageRatioIn, double slopeTiltIn, double slopeAzmIn, bool windStowActive, double windStowTilt, double windStowAzm, poaDecompReq *poaAllIn, bool enableSubhourlyClipping) :
18861893
skyModel(skyModelIn), radiationMode(radiationModeIn), trackingMode(trackModeIn),
18871894
enableBacktrack(backtrackingEnabled), forceToStow(forceToStowIn),
18881895
delt(dtHour), tiltDegrees(tiltDegreesIn), surfaceAzimuthDegrees(azimuthDegreesIn),
1889-
rotationLimitDegrees(trackerRotationLimitDegreesIn), azimuthLimitDegrees(azimuthLimitDegrees),
1890-
stowAngleDegrees(stowAngleDegreesIn), groundCoverageRatio(groundCoverageRatioIn), slopeTilt(slopeTiltIn), slopeAzm(slopeAzmIn), poaAll(poaAllIn) {
1896+
rotationLimitDegrees(trackerRotationLimitDegreesIn), azimuthLimitDegrees(azimuthLimitDegrees), azimuthRefDegrees(azimuthRefDegrees),
1897+
stowAngleDegrees(stowAngleDegreesIn), groundCoverageRatio(groundCoverageRatioIn), slopeTilt(slopeTiltIn), slopeAzm(slopeAzmIn), windStowMode(windStowActive), windStowTiltDegrees(windStowTilt), windStowAzmDegrees(windStowAzm), poaAll(poaAllIn) {
18911898
setup();
18921899

18931900
delt = instantaneousWeather ? IRRADPROC_NO_INTERPOLATE_SUNRISE_SUNSET : dtHour;
@@ -2249,15 +2256,15 @@ void irrad::set_sun_component(size_t index, double value) {
22492256

22502257
void irrad::set_from_weather_record(weather_record wf, weather_header hdr, int trackModeIn, std::vector<double>& monthlyTiltDegrees,
22512258
bool useWeatherFileAlbedo, std::vector<double>& userSpecifiedAlbedo, poaDecompReq *poaAllIn, bool useSpatialAlbedos, const util::matrix_t<double>* userSpecifiedSpatialAlbedos,
2252-
bool useCustomRotAngles, double customRotAngle) {
2259+
bool useCustomRotAngles, double customRotAngle, bool windStowActive) {
22532260
set_time(wf.year, wf.month, wf.day, wf.hour, wf.minute, delt);
22542261
set_optional(hdr.elev, wf.pres, wf.tdry);
22552262
if (radiationMode == irrad::DN_DF) set_beam_diffuse(wf.dn, wf.df);
22562263
else if (radiationMode == irrad::DN_GH) set_global_beam(wf.gh, wf.dn);
22572264
else if (radiationMode == irrad::GH_DF) set_global_diffuse(wf.gh, wf.df);
22582265
else if (radiationMode == irrad::POA_R) set_poa_reference(wf.poa, poaAllIn);
22592266
else if (radiationMode == irrad::POA_P) set_poa_pyranometer(wf.poa, poaAllIn);
2260-
2267+
windStowMode = windStowActive;
22612268
int month_idx = wf.month - 1;
22622269
if (useWeatherFileAlbedo && std::isfinite(wf.alb) && wf.alb > 0 && wf.alb < 1) {
22632270
albedo = wf.alb;
@@ -2399,9 +2406,9 @@ int irrad::calc() {
23992406
// do irradiance calculations if sun is up
24002407
if (timeStepSunPosition[2] > 0) {
24012408
// compute incidence angles onto fixed or tracking surface
2402-
incidence(trackingMode, tiltDegrees, surfaceAzimuthDegrees, rotationLimitDegrees, azimuthLimitDegrees, sunAnglesRadians[1],
2409+
incidence(trackingMode, tiltDegrees, surfaceAzimuthDegrees, rotationLimitDegrees, azimuthLimitDegrees, azimuthRefDegrees, sunAnglesRadians[1],
24032410
sunAnglesRadians[0],
2404-
enableBacktrack, groundCoverageRatio, slopeTilt, slopeAzm, forceToStow, stowAngleDegrees, useCustomRotAngles, customRotAngle, surfaceAnglesRadians);
2411+
enableBacktrack, groundCoverageRatio, slopeTilt, slopeAzm, forceToStow, stowAngleDegrees, useCustomRotAngles, customRotAngle, windStowMode, windStowTiltDegrees, windStowAzmDegrees, surfaceAnglesRadians);
24052412
if (radiationMode < irrad::POA_R) {
24062413
double hextra = sunAnglesRadians[8];
24072414
double hbeam = directNormal *
@@ -2824,8 +2831,8 @@ void irrad::getFrontSurfaceIrradiances(double pvFrontShadeFraction, double rowTo
28242831

28252832
// Calculate irradiance components for a 90 degree tilt to get horizon brightening
28262833
double angleTmp[5] = {0, 0, 0, 0, 0}; // ([0] = incidence angle, [1] = tilt)
2827-
incidence(0, 90.0, 180.0, 45.0, 45.0, solarZenithRadians, solarAzimuthRadians, this->enableBacktrack,
2828-
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle, angleTmp);
2834+
incidence(0, 90.0, 180.0, 45.0, 45.0, 180, solarZenithRadians, solarAzimuthRadians, this->enableBacktrack,
2835+
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle, windStowMode, windStowTiltDegrees, windStowAzmDegrees, angleTmp);
28292836
perez(0, calculatedDirectNormal, calculatedDiffuseHorizontal, albedo, angleTmp[0], angleTmp[1], solarZenithRadians,
28302837
poa, diffc);
28312838
double horizonDiffuse = diffc[2];
@@ -2959,9 +2966,9 @@ void irrad::getFrontSurfaceIrradiances(double pvFrontShadeFraction, double rowTo
29592966
(1.0 - MarionAOICorrectionFactorsGlass[j] * (1.0 - reflectanceNormalIncidence));
29602967
}
29612968
// Calculate and add direct and circumsolar irradiance components
2962-
incidence(0, tiltRadians * RTOD, surfaceAzimuthRadians * RTOD, 45.0, 45.0, solarZenithRadians, solarAzimuthRadians,
2969+
incidence(0, tiltRadians * RTOD, surfaceAzimuthRadians * RTOD, 45.0, 45.0,180.0, solarZenithRadians, solarAzimuthRadians,
29632970
this->enableBacktrack, this->groundCoverageRatio, this->slopeTilt, this->slopeAzm,
2964-
this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle, surfaceAnglesRadians);
2971+
this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle, windStowMode, windStowTiltDegrees, windStowAzmDegrees, surfaceAnglesRadians);
29652972
perez(0, calculatedDirectNormal, calculatedDiffuseHorizontal, albedo, surfaceAnglesRadians[0],
29662973
surfaceAnglesRadians[1], solarZenithRadians, poa, diffc);
29672974

@@ -3005,8 +3012,8 @@ void irrad::getBackSurfaceIrradiances(double pvBackShadeFraction, double rowToRo
30053012

30063013
// Calculate components for a 90 degree tilt to get horizon brightening
30073014
double surfaceAnglesRadians90[5] = {0, 0, 0, 0, 0};
3008-
incidence(0, 90.0, 180.0, 45.0, 45.0, solarZenithRadians, solarAzimuthRadians, this->enableBacktrack,
3009-
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle, surfaceAnglesRadians90);
3015+
incidence(0, 90.0, 180.0, 45.0, 45.0, 180.0, solarZenithRadians, solarAzimuthRadians, this->enableBacktrack,
3016+
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle, windStowMode, windStowTiltDegrees, windStowAzmDegrees, surfaceAnglesRadians90);
30103017
perez(0, calculatedDirectNormal, calculatedDiffuseHorizontal, albedo, surfaceAnglesRadians90[0],
30113018
surfaceAnglesRadians90[1], solarZenithRadians, planeOfArrayIrradianceRear, diffuseIrradianceRear);
30123019
double horizonDiffuse = diffuseIrradianceRear[2];
@@ -3204,9 +3211,10 @@ void irrad::getBackSurfaceIrradiances(double pvBackShadeFraction, double rowToRo
32043211
rearGroundReflected[i] += rear_ground_reflected;
32053212
}
32063213
// Calculate and add direct and circumsolar irradiance components
3207-
incidence(0, 180.0 - tiltRadians * RTOD, (surfaceAzimuthRadians * RTOD - 180.0), 45.0, 45.0, solarZenithRadians,
3214+
incidence(0, 180.0 - tiltRadians * RTOD, (surfaceAzimuthRadians * RTOD - 180.0), 45.0, 45.0, 180.0, solarZenithRadians,
32083215
solarAzimuthRadians, this->enableBacktrack,
3209-
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle, surfaceAnglesRadians);
3216+
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle,
3217+
windStowMode, windStowTiltDegrees, windStowAzmDegrees, surfaceAnglesRadians);
32103218
perez(0, calculatedDirectNormal, calculatedDiffuseHorizontal, albedo, surfaceAnglesRadians[0],
32113219
surfaceAnglesRadians[1], solarZenithRadians, planeOfArrayIrradianceRear, diffuseIrradianceRear);
32123220

@@ -3266,8 +3274,9 @@ void irrad::getBackSurfaceIrradiancesCS(double pvBackShadeFraction, double rowTo
32663274

32673275
// Calculate components for a 90 degree tilt to get horizon brightening
32683276
double surfaceAnglesRadians90[5] = { 0, 0, 0, 0, 0 };
3269-
incidence(0, 90.0, 180.0, 45.0, 45.0, solarZenithRadians, solarAzimuthRadians, this->enableBacktrack,
3270-
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle, surfaceAnglesRadians90);
3277+
incidence(0, 90.0, 180.0, 45.0, 45.0, 180.0, solarZenithRadians, solarAzimuthRadians, this->enableBacktrack,
3278+
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles,
3279+
windStowMode, windStowTiltDegrees, windStowAzmDegrees, this->customRotAngle, surfaceAnglesRadians90);
32713280
perez(0, clearskyIrradiance[1], clearskyIrradiance[2], albedo, surfaceAnglesRadians90[0],
32723281
surfaceAnglesRadians90[1], solarZenithRadians, planeOfArrayIrradianceRearCS, diffuseIrradianceRear);
32733282
double horizonDiffuse = diffuseIrradianceRearCS[2];
@@ -3465,9 +3474,10 @@ void irrad::getBackSurfaceIrradiancesCS(double pvBackShadeFraction, double rowTo
34653474
rearGroundReflected[i] += rear_ground_reflected;
34663475
}
34673476
// Calculate and add direct and circumsolar irradiance components
3468-
incidence(0, 180.0 - tiltRadians * RTOD, (surfaceAzimuthRadians * RTOD - 180.0), 45.0, 45.0, solarZenithRadians,
3477+
incidence(0, 180.0 - tiltRadians * RTOD, (surfaceAzimuthRadians * RTOD - 180.0), 45.0, 45.0, 180.0, solarZenithRadians,
34693478
solarAzimuthRadians, this->enableBacktrack,
3470-
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle, surfaceAnglesRadians);
3479+
this->groundCoverageRatio, this->slopeTilt, this->slopeAzm, this->forceToStow, this->stowAngleDegrees, this->useCustomRotAngles, this->customRotAngle,
3480+
windStowMode, windStowTiltDegrees, windStowAzmDegrees, surfaceAnglesRadians);
34713481
perez(0, clearskyIrradiance[1], clearskyIrradiance[2], albedo, surfaceAnglesRadians[0],
34723482
surfaceAnglesRadians[1], solarZenithRadians, planeOfArrayIrradianceRearCS, diffuseIrradianceRearCS);
34733483

shared/lib_irradproc.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ void solarpos_spa(int year, int month, int day, int hour, double minute, double
780780
* \param[out] angle[3] tracking axis rotation angle in radians, measured from surface normal of unrotating axis (only for 1 axis trackers)
781781
* \param[out] angle[4] backtracking difference (rot - ideal_rot) will be zero except in case of backtracking for 1 axis tracking
782782
*/
783-
void incidence(int mode, double tilt, double sazm, double rlim, double alim, double zen, double azm, bool en_backtrack, double gcr, double slope_tilt, double slope_azm, bool force_to_stow, double stow_angle_deg, bool useCustomAngle, double customAngle, double angle[5]);
783+
void incidence(int mode, double tilt, double sazm, double rlim, double alim, double aref, double zen, double azm, bool en_backtrack, double gcr, double slope_tilt, double slope_azm, bool force_to_stow, double stow_angle_deg, bool useCustomAngle, double customAngle, bool wind_stow_active, double wind_stow_tilt, double wind_stow_azm, double angle[5]);
784784

785785

786786
/**
@@ -1046,12 +1046,16 @@ class irrad
10461046
//Custom rotation angles for single-axis trackers
10471047
bool useCustomRotAngles;
10481048
double customRotAngle; // custom tracker rotation angle in degrees
1049+
bool windStowMode; // is wind stow active?
10491050

10501051
// Subarray properties
10511052
double tiltDegrees; ///< Surface tilt of subarray in degrees
10521053
double surfaceAzimuthDegrees; ///< Surface azimuth of subarray in degrees
10531054
double rotationLimitDegrees; ///< Rotation limit for subarray in degrees
10541055
double azimuthLimitDegrees; ///< Azimuth limit for subarray in degrees
1056+
double azimuthRefDegrees; ///< Azimuth reference for subarray in degrees
1057+
double windStowTiltDegrees; ///< Wind stow tilt angle for the subarray in degrees
1058+
double windStowAzmDegrees; ///< Wind stow azimuth angle for the subarray in degrees
10551059
double stowAngleDegrees; ///< Optional stow angle for the subarray in degrees
10561060
double groundCoverageRatio; ///< Ground coverage ratio of subarray
10571061
double slopeTilt;
@@ -1122,8 +1126,8 @@ class irrad
11221126
irrad(weather_header wh,
11231127
int skyModel, int radiationModeIn, int trackModeIn,
11241128
bool instantaneousWeather, bool backtrackingEnabled, bool forceToStowIn,
1125-
double dtHour, double tiltDegrees, double azimuthDegrees, double trackerRotationLimitDegrees, double azimuthLimitDegrees, double stowAngleDegreesIn,
1126-
double groundCoverageRatio, double slopeTilt, double slopeAzm, poaDecompReq *poaAllIn, bool enableSubhourlyClipping = false);
1129+
double dtHour, double tiltDegrees, double azimuthDegrees, double trackerRotationLimitDegrees, double azimuthLimitDegrees, double azimuthRefDegrees, double stowAngleDegreesIn,
1130+
double groundCoverageRatio, double slopeTilt, double slopeAzm, bool windStowActive, double windStowTilt, double windStowAzm, poaDecompReq *poaAllIn, bool enableSubhourlyClipping = false);
11271131

11281132
/// Construct the irrad class with an Irradiance_IO() object and Subarray_IO() object
11291133
irrad();
@@ -1181,7 +1185,7 @@ class irrad
11811185
/// Function to set time, albedo, tracking and optional inputs from weather record
11821186
void set_from_weather_record(weather_record wf, weather_header hdr, int trackModeIn, std::vector<double>& monthlyTiltDegrees,
11831187
bool useWeatherFileAlbedo, std::vector<double>& userSpecifiedAlbedo, poaDecompReq *poaAllIn, bool useSpatialAlbedos, const util::matrix_t<double>* userSpecifiedSpatialAlbedos,
1184-
bool useCustomRotAngles = false, double customRotAngle = 0);
1188+
bool useCustomRotAngles = false, double customRotAngle = 0, bool windStowActive = false);
11851189

11861190
/// Run the irradiance processor and calculate the plane-of-array irradiance and diffuse components of irradiance
11871191
int calc();

shared/lib_pv_io_manager.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,10 @@ Subarray_IO::Subarray_IO(compute_module* cm, const std::string& cmName, size_t s
452452

453453
trackerRotationLimitDegrees = cm->as_double(prefix + "rotlim");
454454
azimuthTrackerRotationLimitDegrees = cm->as_double(prefix + "azmlim");
455+
azimuthTrackerRefDegrees = cm->as_double(prefix + "azmref");
456+
windStowTiltDegrees = cm->as_double(prefix + "windstow_tilt");
457+
windStowAzimuthDegrees = cm->as_double(prefix + "windstow_azm");
458+
windStowSpeedLimit = cm->as_double(prefix + "windstow_limit");
455459
groundCoverageRatio = cm->as_double(prefix + "gcr");
456460
slopeTilt = cm->as_double(prefix + "slope_tilt");
457461
slopeAzm = cm->as_double(prefix + "slope_azm");
@@ -710,7 +714,7 @@ void PVSystem_IO::SetupPOAInput()
710714

711715

712716
if (tms[2] > 0) {
713-
incidence(Subarrays[nn]->trackMode, Subarrays[nn]->tiltDegrees, Subarrays[nn]->azimuthDegrees, Subarrays[nn]->trackerRotationLimitDegrees, Subarrays[nn]->azimuthTrackerRotationLimitDegrees, sun[1], sun[0], Subarrays[nn]->backtrackingEnabled, Subarrays[nn]->groundCoverageRatio, Subarrays[nn]->slopeTilt, Subarrays[nn]->slopeAzm, false, 0.0, false, 0.0, angle);
717+
incidence(Subarrays[nn]->trackMode, Subarrays[nn]->tiltDegrees, Subarrays[nn]->azimuthDegrees, Subarrays[nn]->trackerRotationLimitDegrees, Subarrays[nn]->azimuthTrackerRotationLimitDegrees, Subarrays[nn]->azimuthTrackerRefDegrees, sun[1], sun[0], Subarrays[nn]->backtrackingEnabled, Subarrays[nn]->groundCoverageRatio, Subarrays[nn]->slopeTilt, Subarrays[nn]->slopeAzm, false, 0.0, false, 0.0, false, 0.0, 0.0, angle);
714718
}
715719
else {
716720
angle[0] = -999;

0 commit comments

Comments
 (0)