Skip to content

Commit

Permalink
Debugging diff between hourly and annual application of factors
Browse files Browse the repository at this point in the history
  • Loading branch information
mjprilliman committed Sep 6, 2023
1 parent 4daa6ee commit 62ed07d
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 23 deletions.
51 changes: 37 additions & 14 deletions shared/lib_irradproc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1751,6 +1751,7 @@ void irrad::setup() {
poaRearDirectDiffuse = 0.;
poaRearRowReflections = 0.;
poaRearSelfShaded = 0.;

}

irrad::irrad() {
Expand All @@ -1765,7 +1766,7 @@ irrad::irrad(weather_record wf, weather_header hdr,
double groundCoverageRatioIn, double slopeTiltIn, double slopeAzmIn, std::vector<double> monthlyTiltDegrees,
std::vector<double> userSpecifiedAlbedo,
poaDecompReq *poaAllIn,
bool useSpatialAlbedos, const util::matrix_t<double>* userSpecifiedSpatialAlbedos) :
bool useSpatialAlbedos, const util::matrix_t<double>* userSpecifiedSpatialAlbedos, bool enableSubhourlyClipping) :
skyModel(skyModelIn), radiationMode(radiationModeIn), trackingMode(trackModeIn),
enableBacktrack(backtrackingEnabled), forceToStow(forceToStowIn),
delt(dtHour), tiltDegrees(tiltDegreesIn), surfaceAzimuthDegrees(azimuthDegreesIn),
Expand All @@ -1792,6 +1793,8 @@ irrad::irrad(weather_record wf, weather_header hdr,
set_optional(hdr.elev, wf.pres, wf.tdry);
set_sky_model(skyModel, albedo, albedoSpatial);

set_subhourly_clipping(enableSubhourlyClipping);

if (radiationMode == irrad::DN_DF) set_beam_diffuse(wf.dn, wf.df);
else if (radiationMode == irrad::DN_GH) set_global_beam(wf.gh, wf.dn);
else if (radiationMode == irrad::GH_DF) set_global_diffuse(wf.gh, wf.df);
Expand Down Expand Up @@ -1980,6 +1983,11 @@ void irrad::set_optional(double elev, double pres, double t_amb) //defaults of 0
this->tamb = t_amb;
}

void irrad::set_subhourly_clipping(bool enable)
{
if (enable) this->enableSubhourlyClipping = true;
}

void irrad::set_sky_model(int sm, double alb, const std::vector<double> &albSpatial) {
this->skyModel = sm;
this->albedo = alb;
Expand Down Expand Up @@ -2151,7 +2159,9 @@ int irrad::calc() {
}

//clearsky
ineichen(clearskyIrradiance, RTOD * sunAnglesRadians[1], 1.5, 1.0, elevation);
if (enableSubhourlyClipping) {
ineichen(clearskyIrradiance, RTOD * sunAnglesRadians[1], 1.5, 1.0, elevation);
}


planeOfArrayIrradianceFront[0] = planeOfArrayIrradianceFront[1] = planeOfArrayIrradianceFront[2] = 0;
Expand Down Expand Up @@ -2211,35 +2221,48 @@ int irrad::calc() {
isotropic(hextra, calculatedDirectNormal, calculatedDiffuseHorizontal, albedo,
surfaceAnglesRadians[0], surfaceAnglesRadians[1], sunAnglesRadians[1],
planeOfArrayIrradianceFront, diffuseIrradianceFront);
isotropic(hextra, clearskyIrradiance[1], clearskyIrradiance[2], albedo,
surfaceAnglesRadians[0], surfaceAnglesRadians[1], sunAnglesRadians[1],
planeOfArrayIrradianceFrontCS, diffuseIrradianceFrontCS);
break;
case 1:
hdkr(hextra, calculatedDirectNormal, calculatedDiffuseHorizontal, albedo, surfaceAnglesRadians[0],
surfaceAnglesRadians[1], sunAnglesRadians[1], planeOfArrayIrradianceFront,
diffuseIrradianceFront);
hdkr(hextra, clearskyIrradiance[1], clearskyIrradiance[2], albedo, surfaceAnglesRadians[0],
surfaceAnglesRadians[1], sunAnglesRadians[1], planeOfArrayIrradianceFrontCS,
diffuseIrradianceFrontCS);
break;
default:
perez(hextra, calculatedDirectNormal, calculatedDiffuseHorizontal, albedo, surfaceAnglesRadians[0],
surfaceAnglesRadians[1], sunAnglesRadians[1], planeOfArrayIrradianceFront,
diffuseIrradianceFront);
perez(hextra, clearskyIrradiance[1], clearskyIrradiance[2], albedo, surfaceAnglesRadians[0],
surfaceAnglesRadians[1], sunAnglesRadians[1], planeOfArrayIrradianceFrontCS,
diffuseIrradianceFrontCS);
break;
}

if (enableSubhourlyClipping) {
switch (skyModel) {
case 0:
isotropic(hextra, clearskyIrradiance[1], clearskyIrradiance[2], albedo,
surfaceAnglesRadians[0], surfaceAnglesRadians[1], sunAnglesRadians[1],
planeOfArrayIrradianceFrontCS, diffuseIrradianceFrontCS);
break;
case 1:
hdkr(hextra, clearskyIrradiance[1], clearskyIrradiance[2], albedo, surfaceAnglesRadians[0],
surfaceAnglesRadians[1], sunAnglesRadians[1], planeOfArrayIrradianceFrontCS,
diffuseIrradianceFrontCS);
break;
default:
perez(hextra, clearskyIrradiance[1], clearskyIrradiance[2], albedo, surfaceAnglesRadians[0],
surfaceAnglesRadians[1], sunAnglesRadians[1], planeOfArrayIrradianceFrontCS,
diffuseIrradianceFrontCS);
break;
}
}
}
else { // Sev 2015/09/11 - perform a POA decomp.
int errorcode = poaDecomp(weatherFilePOA, surfaceAnglesRadians, sunAnglesRadians, albedo, poaAll,
directNormal, diffuseHorizontal, globalHorizontal, planeOfArrayIrradianceFront,
diffuseIrradianceFront);
int errorcode_cs = poaDecomp(weatherFilePOA, surfaceAnglesRadians, sunAnglesRadians, albedo, poaAll,
clearskyIrradiance[1], clearskyIrradiance[2], clearskyIrradiance[0], planeOfArrayIrradianceFrontCS,
diffuseIrradianceFrontCS);
if (enableSubhourlyClipping) {
int errorcode_cs = poaDecomp(weatherFilePOA, surfaceAnglesRadians, sunAnglesRadians, albedo, poaAll,
clearskyIrradiance[1], clearskyIrradiance[2], clearskyIrradiance[0], planeOfArrayIrradianceFrontCS,
diffuseIrradianceFrontCS);
}
calculatedDirectNormal = directNormal;
calculatedDiffuseHorizontal = diffuseHorizontal;

Expand Down
8 changes: 7 additions & 1 deletion shared/lib_irradproc.h
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,9 @@ class irrad
int year, month, day, hour;
double minute, delt;

//Enable subhourly clipping correction
bool enableSubhourlyClipping;

// Subarray properties
double tiltDegrees; ///< Surface tilt of subarray in degrees
double surfaceAzimuthDegrees; ///< Surface azimuth of subarray in degrees
Expand Down Expand Up @@ -1052,7 +1055,7 @@ class irrad
double dtHour, double tiltDegrees, double azimuthDegrees, double trackerRotationLimitDegrees, double stowAngleDegreesIn,
double groundCoverageRatio, double slopeTilt, double slopeAzm, std::vector<double> monthlyTiltDegrees, std::vector<double> userSpecifiedAlbedo,
poaDecompReq* poaAllIn,
bool useSpatialAlbedos = false, const util::matrix_t<double>* userSpecifiedSpatialAlbedos = nullptr);
bool useSpatialAlbedos = false, const util::matrix_t<double>* userSpecifiedSpatialAlbedos = nullptr, bool enableSubhourlyClipping = false);

/// Construct the irrad class with an Irradiance_IO() object and Subarray_IO() object
irrad();
Expand All @@ -1072,6 +1075,9 @@ class irrad
// Set optional parameters for solarpos_spa calculation
void set_optional(double elev = 0, double pres = 1013.25, double t_amb = 15);

//Set whether to use subhourly clipping model
void set_subhourly_clipping(bool enable = false);

/// Set the sky model for the irradiance processor, using \link Irradiance_IO::SKYMODEL
void set_sky_model(int skymodel, double albedo, const std::vector<double> &albedoSpatial = std::vector<double>());

Expand Down
1 change: 1 addition & 0 deletions shared/lib_pv_io_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,7 @@ void PVSystem_IO::AllocateOutputs(compute_module* cm)

p_systemDCPowerCS = cm->allocate("dc_net_clearsky", numberOfLifetimeRecords);
p_subhourlyClippingLoss = cm->allocate("subhourly_clipping_loss", numberOfLifetimeRecords);
p_subhourlyClippingLossFactor = cm->allocate("subhourly_clipping_loss_factor", numberOfLifetimeRecords);

if (Simulation->useLifetimeOutput)
{
Expand Down
1 change: 1 addition & 0 deletions shared/lib_pv_io_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ struct PVSystem_IO
ssc_number_t *p_systemACPower; // kWac

ssc_number_t *p_subhourlyClippingLoss;
ssc_number_t* p_subhourlyClippingLossFactor;
ssc_number_t* p_ClippingPotential;
};

Expand Down
2 changes: 2 additions & 0 deletions shared/lib_shared_inverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ SharedInverter::SharedInverter(int inverterType, size_t numberOfInverters,

powerDC_kW = 0.;
powerAC_kW = 0.;
powerAC_kW_clipping = 0.;
efficiencyAC = 96.;
powerClipLoss_kW = 0.;
powerConsumptionLoss_kW = 0.;
Expand All @@ -84,6 +85,7 @@ SharedInverter::SharedInverter(const SharedInverter& orig) {

powerDC_kW = orig.powerDC_kW;
powerAC_kW = orig.powerAC_kW;
powerAC_kW_clipping = orig.powerAC_kW_clipping;
powerClipLoss_kW = orig.powerClipLoss_kW;
powerConsumptionLoss_kW = orig.powerConsumptionLoss_kW;
powerNightLoss_kW = orig.powerNightLoss_kW;
Expand Down
25 changes: 17 additions & 8 deletions ssc/cmod_pvsamv1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ static var_info _cm_vtab_pvsamv1[] = {
{ SSC_OUTPUT, SSC_ARRAY, "subarray1_modeff", "Subarray 1 Module efficiency", "%", "", "Time Series (Subarray 1)", "*", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "subarray1_celltemp", "Subarray 1 Cell temperature", "C", "", "Time Series (Subarray 1)", "*", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "subarray1_celltempSS", "Subarray 1 Cell temperature (steady state)", "C", "", "Time Series (Subarray 1)", "*", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "subarray1_dni_index", "Subarray 1 DNI Index", "W/m2", "", "Time Series (Subarray 1)", "", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "subarray1_dni_index", "Subarray 1 DNI Index", "", "", "Time Series (Subarray 1)", "", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "subarray1_poa_beam_front_cs", "Subarray 1 beam clearsky irradiance", "W/m2", "", "Time Series (Subarray 1)", "", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "subarray1_poa_diffuse_front_cs", "Subarray 1 diffuse clearsky irradiance", "W/m2", "", "Time Series (Subarray 1)", "", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "subarray1_poa_ground_front_cs", "Subarray 1 ground reflected clearsky irradiance", "W/m2", "", "Time Series (Subarray 1)", "", "", "" },
Expand Down Expand Up @@ -794,7 +794,7 @@ static var_info _cm_vtab_pvsamv1[] = {
//SEV: total dc snow loss time series (not a required output)
{ SSC_OUTPUT, SSC_ARRAY, "dc_snow_loss", "DC power loss due to snow", "kW", "", "Time Series (Array)", "", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "dc_net", "Inverter DC input power", "kW", "", "Time Series (Array)", "*", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "dc_net_clearsky", "Inverter DC clearsky input power", "kW", "", "Time Series (Array)", "", "", "" },
//{ SSC_OUTPUT, SSC_ARRAY, "dc_net_clearsky", "Inverter DC clearsky input power", "kW", "", "Time Series (Array)", "", "", "" },

// DC Daily losses
{ SSC_OUTPUT, SSC_ARRAY, "dc_lifetime_loss", "DC lifetime daily loss", "kW", "", "Time Series (DC Loss)", "", "", "" },
Expand All @@ -817,6 +817,7 @@ static var_info _cm_vtab_pvsamv1[] = {
{ SSC_OUTPUT, SSC_ARRAY, "ac_gross", "Inverter AC output power", "kW", "", "Time Series (Array)", "*", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "clipping_potential", "Clipping potential", "", "", "Time Series (Inverter)", "", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "subhourly_clipping_loss", "Subhourly clipping correction loss", "kW", "", "Time Series (Inverter)", "", "", "" },
{ SSC_OUTPUT, SSC_ARRAY, "subhourly_clipping_loss_factor", "Subhourly clipping correction loss factor", "", "", "Time Series (Inverter)", "", "", "" },

// transformer model outputs
{ SSC_OUTPUT, SSC_ARRAY, "xfmr_nll_ts", "Transformer no load loss", "kW", "", "Time Series (Transformer)", "", "", "" },
Expand Down Expand Up @@ -997,6 +998,7 @@ static var_info _cm_vtab_pvsamv1[] = {
*/
{ SSC_OUTPUT, SSC_NUMBER, "annual_ac_wiring_loss", "AC wiring loss", "kWh", "", "Annual (Year 1)", "", "", "" },
{ SSC_OUTPUT, SSC_NUMBER, "annual_subhourly_clipping_loss", "Subhourly clipping correction loss", "kWh", "", "Annual (Year 1)", "", "", "" },
{ SSC_OUTPUT, SSC_NUMBER, "annual_subhourly_clipping_factor", "Subhourly clipping correction loss factor", "", "", "Annual (Year 1)", "", "", "" },

{ SSC_OUTPUT, SSC_NUMBER, "annual_transmission_loss", "Transmission loss", "kWh", "", "Annual (Year 1)", "", "", "" },

Expand Down Expand Up @@ -1508,7 +1510,7 @@ void cm_pvsamv1::exec()
Irradiance->dtHour, Subarrays[nn]->tiltDegrees, Subarrays[nn]->azimuthDegrees, Subarrays[nn]->trackerRotationLimitDegrees, 0.0, Subarrays[nn]->groundCoverageRatio, Subarrays[nn]->slopeTilt, Subarrays[nn]->slopeAzm,
Subarrays[nn]->monthlyTiltDegrees, Irradiance->userSpecifiedMonthlyAlbedo,
Subarrays[nn]->poa.poaAll.get(),
Irradiance->useSpatialAlbedos, &Irradiance->userSpecifiedMonthlySpatialAlbedos);
Irradiance->useSpatialAlbedos, &Irradiance->userSpecifiedMonthlySpatialAlbedos, as_boolean("enable_subhourly_clipping"));

int code = irr.calc();

Expand Down Expand Up @@ -2541,6 +2543,7 @@ void cm_pvsamv1::exec()

double annual_dc_loss_ond = 0, annual_ac_loss_ond = 0; // (TR)
double annual_subhourly_clipping_loss = 0;
double annual_subhourly_clipping_factor = 0;
/*
if (as_boolean("enable_subhourly_clipping")) {
for (size_t inrec = 0; inrec < nrec; inrec++) {
Expand Down Expand Up @@ -2623,6 +2626,7 @@ void cm_pvsamv1::exec()

double acpwr_gross = 0, ac_wiringloss = 0, transmissionloss = 0;
double ac_subhourlyclipping_loss = 0;
double ac_subhourlyclipping_factor = 0;
cur_load = p_load_full[idx];

//set DC voltages for use in AC power calculation
Expand Down Expand Up @@ -2700,7 +2704,7 @@ void cm_pvsamv1::exec()
//Calculate DNI clearness index (time step basis)
double dni_clearness_index = PVSystem->p_DNIIndex[0][idx];
//Calculate Clipping Potential ((P_dc,dryclean - P_ac,0) / P_ac,0) (time step basis)
//sharedInverter->calculateACPower(dcPower_kW_csky, dcVoltagePerMppt[0], Irradiance->weatherRecord.tdry, as_boolean("enable_subhourly_clipping")); //DC batteries not allowed with multiple MPPT, so can just use MPPT 1's voltage
sharedInverter->calculateACPower(dcPower_kW_csky, dcVoltagePerMppt[0], Irradiance->weatherRecord.tdry, as_boolean("enable_subhourly_clipping")); //DC batteries not allowed with multiple MPPT, so can just use MPPT 1's voltage
//double clip_pot = (dcPower_kW_csky - sharedInverter->powerAC_kW_clipping) / sharedInverter->powerAC_kW_clipping;
double clip_pot = (dcPower_kW_csky - paco ) / (paco);

Expand Down Expand Up @@ -2737,6 +2741,8 @@ void cm_pvsamv1::exec()
//acpwr_gross *= (1 - sub_clipping_matrix.at(dni_row, clip_pot_col));
if (dcPower_kW_csky > 0.0) {
ac_subhourlyclipping_loss = sub_clipping_matrix.at(dni_row, clip_pot_col) * std::abs(acpwr_gross);
//ac_subhourlyclipping_loss = sub_clipping_matrix.at(dni_row, clip_pot_col) * sharedInverter->powerAC_kW_clipping;
ac_subhourlyclipping_factor = sub_clipping_matrix.at(dni_row, clip_pot_col);
}
else { //No inverter clipping at night time, skip checks?
ac_subhourlyclipping_loss = 0.0;
Expand All @@ -2758,6 +2764,7 @@ void cm_pvsamv1::exec()

annual_ac_wiring_loss += ac_wiringloss * ts_hour;
annual_subhourly_clipping_loss += ac_subhourlyclipping_loss;
annual_subhourly_clipping_factor += ac_subhourlyclipping_factor;
}

if (iyear == 0 || save_full_lifetime_variables == 1)
Expand All @@ -2769,6 +2776,7 @@ void cm_pvsamv1::exec()
PVSystem->p_inverterThermalLoss[idx] = (ssc_number_t)(sharedInverter->powerTempLoss_kW);
PVSystem->p_acWiringLoss[idx] = (ssc_number_t)(ac_wiringloss);
PVSystem->p_subhourlyClippingLoss[idx] = (ssc_number_t)(ac_subhourlyclipping_loss);
PVSystem->p_subhourlyClippingLossFactor[idx] = (ssc_number_t)(ac_subhourlyclipping_factor);

if (offline) {
PVSystem->p_inverterNightTimeLoss[idx] = 0.0;
Expand Down Expand Up @@ -3198,6 +3206,7 @@ void cm_pvsamv1::exec()

assign("annual_ac_wiring_loss", var_data((ssc_number_t)annual_ac_wiring_loss));
assign("annual_subhourly_clipping_loss", var_data((ssc_number_t)annual_subhourly_clipping_loss));
assign("annual_subhourly_clipping_factor", var_data((ssc_number_t)annual_subhourly_clipping_factor));

assign("annual_transmission_loss", var_data((ssc_number_t)annual_transmission_loss));

Expand Down Expand Up @@ -3343,15 +3352,15 @@ void cm_pvsamv1::exec()
assign("annual_ac_battery_loss_percent", var_data((ssc_number_t)percent));
sys_output -= annual_ac_battery_loss;

if (annual_ac_gross > 0) percent = 100.0 * annual_subhourly_clipping_loss / annual_ac_gross;
assign("annual_subhourly_clipping_loss_percent", var_data((ssc_number_t)percent));
sys_output -= annual_subhourly_clipping_loss;

percent = 0.;
if (annual_ac_gross > 0) percent = 100.0 * annual_ac_wiring_loss / annual_ac_gross;
assign("annual_ac_wiring_loss_percent", var_data((ssc_number_t)percent));
sys_output -= annual_ac_wiring_loss;

if (annual_ac_gross > 0) percent = 100.0 * annual_subhourly_clipping_loss / annual_ac_gross;
assign("annual_subhourly_clipping_loss_percent", var_data((ssc_number_t)percent));
sys_output -= annual_subhourly_clipping_loss;

percent = 0.;
if (annual_ac_gross > 0) percent = 100.0 * annual_transmission_loss / annual_ac_gross;
assign("annual_transmission_loss_percent", var_data((ssc_number_t)percent));
Expand Down

0 comments on commit 62ed07d

Please sign in to comment.