Skip to content

Commit

Permalink
Expose clear sky calcs to walker method calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
mjprilliman committed Oct 2, 2023
1 parent 6dc0d4f commit 7c5084c
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 71 deletions.
4 changes: 1 addition & 3 deletions shared/lib_irradproc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2159,9 +2159,7 @@ int irrad::calc() {
}

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


planeOfArrayIrradianceFront[0] = planeOfArrayIrradianceFront[1] = planeOfArrayIrradianceFront[2] = 0;
Expand Down
2 changes: 1 addition & 1 deletion shared/lib_pv_io_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,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);
//p_subhourlyClippingLossFactor = cm->allocate("subhourly_clipping_loss_factor", numberOfLifetimeRecords);

p_DistributionClippingLoss = cm->allocate("distribution_clipping_loss", numberOfLifetimeRecords);

Expand Down
50 changes: 1 addition & 49 deletions shared/lib_shared_inverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ void SharedInverter::calculateTempDerate(double V, double tempC, double& p_dc_ra

double SharedInverter::getInverterDCMaxPower(double p_dc_rated)
{
double inv_dc_max_power;
double inv_dc_max_power = p_dc_rated * util::kilowatt_to_watt;
if (m_inverterType == SANDIA_INVERTER || m_inverterType == DATASHEET_INVERTER || m_inverterType == COEFFICIENT_GENERATOR)
//m_sandiaInverter->acpower(std::fabs(powerDC_Watts) / m_numInverters, DCStringVoltage, &powerAC_Watts, &P_par, &P_lr, &efficiencyAC, &powerClipLoss_kW, &powerConsumptionLoss_kW, &powerNightLoss_kW);
inv_dc_max_power = m_sandiaInverter->Pdco;
Expand Down Expand Up @@ -353,54 +353,6 @@ void SharedInverter::calculateACPower(const double powerDC_kW_in, const double D
}
}

void SharedInverter::calculateACPower(const double powerDC_kW_in, const double powerDC_kW_in_max, const double powerDC_kW_in_min, const double DCStringVoltage, double tempC)
{
double P_par, P_lr;
double P_par_clipping, P_lr_clipping;
double efficiencyAC_clipping, powerClipLoss_kW_clipping, powerConsumptionLoss_kW_clipping, powerNightLoss_kW_clipping = 0;
bool negativePower = powerDC_kW_in < 0 ? true : false;


dcWiringLoss_ond_kW = 0.0;
acWiringLoss_ond_kW = 0.0;

// Power quantities go in and come out in units of W
double powerDC_Watts = powerDC_kW_in * util::kilowatt_to_watt;
double powerAC_Watts = 0.0;
double powerAC_Watts_clipping = 0.0;
Tdry_C = tempC;
StringV = DCStringVoltage;
double tempLoss = 0.0;
double power_ratio = 1.0;
if (m_tempEnabled) {
calculateTempDerate(DCStringVoltage, tempC, powerDC_Watts, power_ratio, tempLoss);
}

m_sandiaInverter->acpower(std::abs(powerDC_Watts) / m_numInvertersClipping, DCStringVoltage, &powerAC_Watts_clipping, &P_par_clipping, &P_lr_clipping, &efficiencyAC_clipping, &powerClipLoss_kW_clipping, &powerConsumptionLoss_kW_clipping, &powerNightLoss_kW_clipping);


if (m_inverterType == SANDIA_INVERTER || m_inverterType == DATASHEET_INVERTER || m_inverterType == COEFFICIENT_GENERATOR)
m_sandiaInverter->acpower(std::abs(powerDC_Watts) / m_numInverters, DCStringVoltage, &powerAC_Watts, &P_par, &P_lr, &efficiencyAC, &powerClipLoss_kW, &powerConsumptionLoss_kW, &powerNightLoss_kW);
else if (m_inverterType == PARTLOAD_INVERTER)
m_partloadInverter->acpower(std::abs(powerDC_Watts) / m_numInverters, &powerAC_Watts, &P_lr, &P_par, &efficiencyAC, &powerClipLoss_kW, &powerNightLoss_kW);
else if (m_inverterType == OND_INVERTER)
m_ondInverter->acpower(std::abs(powerDC_Watts) / m_numInverters, DCStringVoltage, tempC, &powerAC_Watts, &P_par, &P_lr, &efficiencyAC, &powerClipLoss_kW, &powerConsumptionLoss_kW, &powerNightLoss_kW, &dcWiringLoss_ond_kW, &acWiringLoss_ond_kW);
else if (m_inverterType == NONE) {
powerClipLoss_kW = 0.;
powerConsumptionLoss_kW = 0.;
powerNightLoss_kW = 0.;
efficiencyAC = NONE_INVERTER_EFF;
powerAC_Watts = powerDC_Watts * efficiencyAC;
}



m_subhourlyClippingEnabled = true;
powerAC_kW_clipping = powerAC_Watts_clipping * m_numInvertersClipping * util::watt_to_kilowatt;
return;

}

/* This function takes input inverter DC power (kW) per MPPT input for a SINGLE multi-mppt inverter, DC voltage (V) per input, and ambient temperature (deg C), and calculates output for the total number of inverters in the system */
void SharedInverter::calculateACPower(const std::vector<double> powerDC_kW_in, const std::vector<double> DCStringVoltage, double tempC)
{
Expand Down
42 changes: 24 additions & 18 deletions ssc/cmod_pvsamv1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1508,7 +1508,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, as_boolean("enable_subhourly_clipping"));
Irradiance->useSpatialAlbedos, &Irradiance->userSpecifiedMonthlySpatialAlbedos, (as_boolean("enable_subhourly_clipping") || as_boolean("enable_subinterval_distribution")));

int code = irr.calc();

Expand Down Expand Up @@ -2553,11 +2553,11 @@ void cm_pvsamv1::exec()
}
for (size_t inrec = 0; inrec < nrec; inrec++) {
idx = inrec;
double dcPower_kW_csky = PVSystem->p_systemDCPowerCS[idx];
double dcPower_kWcsky = PVSystem->p_systemDCPowerCS[idx];
//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_kWcsky, 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
nominal_annual_clipping_output += sharedInverter->powerAC_kW_clipping;
/*
double clip_pot = (dcPower_kW_csky - sharedInverter->powerAC_kW_clipping) / sharedInverter->powerAC_kW_clipping;
Expand Down Expand Up @@ -2619,9 +2619,7 @@ void cm_pvsamv1::exec()
double dcPower_kW = PVSystem->p_systemDCPower[idx];

double dcPower_kW_csky = PVSystem->p_systemDCPowerCS[idx];
double dcPower_kW_max = dcPower_kW_csky;
double dcPower_kW_min = dcPower_kW_max * 0.045 / 1.5; //AM?
double dcPower_kW_avg = dcPower_kW;

// Battery replacement
if (en_batt && (batt_topology == ChargeController::DC_CONNECTED))
{
Expand Down Expand Up @@ -2657,43 +2655,51 @@ void cm_pvsamv1::exec()
}
}

if (as_boolean("enable_subinterval_distribution")) {
if (dcPower_kW > 0) {
if (as_integer("enable_subinterval_distribution")==1) {
if (dcPower_kW > 0.0) {
double dcPower_kW_max = dcPower_kW_csky;
log(util::format("dcPower max is %lg", dcPower_kW_max), SSC_NOTICE);
double dcPower_kW_min = dcPower_kW_max * 0.045 / 1.5; //AM?
log(util::format("dcPower min is %lg", dcPower_kW_min), SSC_NOTICE);
double dcPower_kW_avg = dcPower_kW;
double CF = (dcPower_kW_avg - dcPower_kW_min) / (dcPower_kW_max - dcPower_kW_min);
double n = CF / (1 - CF);
int inverter_count = as_integer("inverter_count");
log(util::format("n is %lg", n), SSC_NOTICE);
//int inverter_count = as_integer("inverter_count");
int inverter_count = 99;
//sharedInverter->calculateACPower(dcPower_kW_csky, dcVoltagePerMppt[0], Irradiance->weatherRecord.tdry, as_boolean("enable_subhourly_clipping"));
double inv_dc_max = sharedInverter->getInverterDCMaxPower(0.0) / 1000.0 * inverter_count;
double inv_dc_max = sharedInverter->getInverterDCMaxPower(nameplate_kw) / 1000.0 * inverter_count;
//log(util::format("Inverter DC Max is %lg kW", inv_dc_max), SSC_NOTICE);
double T = 1.0;
double log_test = 1 - (inv_dc_max - dcPower_kW_min) / (dcPower_kW_max - dcPower_kW_min);
double t_lm = 0.0;
if (log_test > 0.0) {
t_lm = T * exp(std::log(1 - (inv_dc_max - dcPower_kW_min) / (dcPower_kW_max - dcPower_kW_min)) / n); //fraction of hours
double log_test = 1.0 - (inv_dc_max - dcPower_kW_min) / (dcPower_kW_max - dcPower_kW_min);
log(util::format("log_test is %lg", log_test), SSC_NOTICE);
ssc_number_t t_lm = 0.0;
if (log_test > 0.0 && n > 0.0) {
t_lm = T * std::exp(std::log(1.0 - (inv_dc_max - dcPower_kW_min) / (dcPower_kW_max - dcPower_kW_min)) / n); //fraction of hours
}
log(util::format("t_lm is %lg", t_lm), SSC_NOTICE);
double E_clipped = dcPower_kW_max * t_lm - ((dcPower_kW_max - dcPower_kW_min) * pow(t_lm, n + 1) / ((n + 1) * pow(T, n))) - inv_dc_max * t_lm;
log(util::format("E_clipped is %lg kW", E_clipped), SSC_NOTICE);
double E_remaining = (inv_dc_max - dcPower_kW_max) * T + ((dcPower_kW_max - dcPower_kW_min) * pow(T, n + 1) / ((n + 1) * pow(T, n))) - (inv_dc_max - dcPower_kW_max) * t_lm -
((dcPower_kW_max - dcPower_kW_min) * pow(t_lm, n + 1) / ((n + 1) * pow(T, n)));
double subinterval_clipping_loss = E_clipped;
if (E_clipped > 0) {
if (E_clipped > 0.0) {
for (size_t m = 0; m < PVSystem->Inverter->nMpptInputs; m++)
{
dcPowerNetPerMppt_kW[m] -= E_clipped * dcPowerNetPerMppt_kW[m] / dcPower_kW;
}
dcPower_kW -= E_clipped;
PVSystem->p_DistributionClippingLoss[idx] = E_clipped;
PVSystem->p_DistributionClippingLoss[idx] = (ssc_number_t)E_clipped;
if (iyear == 0) {
annual_distribution_clipping_loss += E_clipped;
}
}
else {
PVSystem->p_DistributionClippingLoss[idx] = 0.0;
PVSystem->p_DistributionClippingLoss[idx] = (ssc_number_t)1;
}
}
else {
PVSystem->p_DistributionClippingLoss[idx] = 0.0;
PVSystem->p_DistributionClippingLoss[idx] = (ssc_number_t)2;
}

}
Expand Down

0 comments on commit 7c5084c

Please sign in to comment.