Skip to content

Commit

Permalink
Merge branch 'patch' into SAM_1477
Browse files Browse the repository at this point in the history
  • Loading branch information
sjanzou committed Apr 10, 2024
2 parents c4fb6a9 + 9903df9 commit b7fee04
Show file tree
Hide file tree
Showing 41 changed files with 2,060 additions and 98,261 deletions.
4 changes: 1 addition & 3 deletions shared/lib_irradproc.cpp
Expand Up @@ -2193,9 +2193,7 @@ int irrad::calc() {
}

//clearsky
if (enableSubhourlyClipping) {
ineichen(clearskyIrradiance, RTOD * sunAnglesRadians[1], month, day, pressure * 100.0, 1.0, elevation, 0, true);
}
ineichen(clearskyIrradiance, RTOD * sunAnglesRadians[1], month, day, pressure * 100.0, 1.0, elevation, 0, true);


planeOfArrayIrradianceFront[0] = planeOfArrayIrradianceFront[1] = planeOfArrayIrradianceFront[2] = 0;
Expand Down
11 changes: 8 additions & 3 deletions shared/lib_pv_io_manager.cpp
Expand Up @@ -505,7 +505,7 @@ Subarray_IO::Subarray_IO(compute_module* cm, const std::string& cmName, size_t s
if (trackMode == irrad::SEASONAL_TILT)
throw exec_error(cmName, "Time-series tilt input may not be used with the snow model at this time: subarray " + util::to_string((int)(subarrayNumber)));
// if tracking mode is 1-axis tracking, don't need to limit tilt angles
if (snowModel.setup(selfShadingInputs.nmody, (float)tiltDegrees, (trackMode != irrad::SINGLE_AXIS))) {
if (snowModel.setup(selfShadingInputs.nmody, (float)tiltDegrees, cm->as_double("snow_slide_coefficient"), (trackMode != irrad::SINGLE_AXIS))) {
if (!snowModel.good) {
cm->log(snowModel.msg, SSC_ERROR);
}
Expand Down Expand Up @@ -973,10 +973,15 @@ void PVSystem_IO::AllocateOutputs(compute_module* cm)
p_dcLifetimeLoss = cm->allocate("dc_lifetime_loss", numberOfWeatherFileRecords);
p_systemDCPower = cm->allocate("dc_net", numberOfLifetimeRecords);
p_systemACPower = cm->allocate("gen", numberOfLifetimeRecords);
p_systemACPowerMax = cm->allocate("ac_csky_max", numberOfLifetimeRecords);

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 (cm->as_boolean("enable_subhourly_clipping")) {
p_subhourlyClippingLoss = cm->allocate("subhourly_clipping_loss", numberOfLifetimeRecords);
}
if (cm->as_boolean("enable_subinterval_distribution")) {
p_DistributionClippingLoss = cm->allocate("distribution_clipping_loss", numberOfLifetimeRecords);
}

if (Simulation->useLifetimeOutput)
{
Expand Down
2 changes: 2 additions & 0 deletions shared/lib_pv_io_manager.h
Expand Up @@ -419,10 +419,12 @@ struct PVSystem_IO
ssc_number_t *p_systemDCPower; // kWdc
ssc_number_t* p_systemDCPowerCS; // kWdc
ssc_number_t *p_systemACPower; // kWac
ssc_number_t* p_systemACPowerMax; //kWac

ssc_number_t *p_subhourlyClippingLoss;
ssc_number_t* p_subhourlyClippingLossFactor;
ssc_number_t* p_ClippingPotential;
ssc_number_t* p_DistributionClippingLoss;
//ssc_number_t* p_DNIIndex;
ssc_number_t* p_CPBin;
ssc_number_t* p_DNIIndexBin;
Expand Down
5 changes: 1 addition & 4 deletions shared/lib_shared_inverter.cpp
Expand Up @@ -230,7 +230,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 the inverter type isn't one of the following, assume that max power is equal to rated power"
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 All @@ -240,9 +240,6 @@ double SharedInverter::getInverterDCMaxPower(double p_dc_rated)
else if (m_inverterType == OND_INVERTER)
//m_ondInverter->acpower(std::fabs(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);
inv_dc_max_power = m_ondInverter->PMaxDC;
else if (m_inverterType == NONE) {
inv_dc_max_power = p_dc_rated * util::kilowatt_to_watt;
}

return inv_dc_max_power;
}
Expand Down
6 changes: 3 additions & 3 deletions shared/lib_snowmodel.cpp
Expand Up @@ -62,7 +62,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pvsnowmodel::pvsnowmodel()
{
mSlope = -80;
sSlope = (float)1.97;
//sSlope = (float)1.97;
deltaThreshold = 1.00;
depthThreshold = 1.00;
previousDepth = 0;
Expand All @@ -76,11 +76,11 @@ pvsnowmodel::pvsnowmodel()

}

bool pvsnowmodel::setup(int nmody_in, float baseTilt_in, bool limitTilt){
bool pvsnowmodel::setup(int nmody_in, float baseTilt_in, float snow_slide_coeff, bool limitTilt){

nmody = nmody_in;
baseTilt = baseTilt_in;

sSlope = snow_slide_coeff;
if(limitTilt && (baseTilt>45 || baseTilt < 10)){
good = true;
msg = util::format("The snow model is designed to work for PV arrays with a tilt angle between 10 and 45 degrees, but will generate results for tilt angles outside this range. The system you are modeling includes a subarray tilt angle of %f degrees.", baseTilt);
Expand Down
4 changes: 2 additions & 2 deletions shared/lib_snowmodel.h
Expand Up @@ -41,7 +41,7 @@ class pvsnowmodel
pvsnowmodel();

// limitTilt requires tilt to be between 10 and 45 degrees
bool setup(int, float, bool limitTilt = true);
bool setup(int, float, float snow_slide_coeff = 1.97, bool limitTilt = true);

bool getLoss(float poa, float tilt, float wspd, float tdry, float snowDepth, int sunup, float dt, float &returnLoss);

Expand All @@ -63,4 +63,4 @@ class pvsnowmodel
// if an error has occured
};

#endif
#endif
3 changes: 2 additions & 1 deletion shared/lib_utility_rate_equations.cpp
Expand Up @@ -1352,6 +1352,7 @@ void forecast_setup::setup(rate_data* rate, std::vector<double>& P_pv_ac, std::v
}
for (size_t idx = 0; idx < num_recs && idx < array_size; idx++)
{
size_t year_one_index = util::yearOneIndex(1.0 / _steps_per_hour, idx);
double grid_power = P_pv_ac[idx] - P_load_ac[idx];

gross_load_during_month += P_load_ac[idx] * _dt_hour;
Expand All @@ -1367,7 +1368,7 @@ void forecast_setup::setup(rate_data* rate, std::vector<double>& P_pv_ac, std::v
}

if (rate->dc_enabled) {
int dc_tou_period = rate->get_dc_tou_row(idx, curr_month - 1);
int dc_tou_period = rate->get_dc_tou_row(year_one_index, curr_month - 1);
size_t month_idx = year * 12 + (curr_month - 1);
double peak = monthly_peaks.at(month_idx, dc_tou_period) - peak_offset; // Peak for dispatch calcs in battery: peak minus battery capacity
if (-1.0 * grid_power > peak) {
Expand Down
8 changes: 5 additions & 3 deletions shared/lib_weatherfile.cpp
Expand Up @@ -116,7 +116,7 @@ static float col_or_nan(const std::string& s)
}
}
else
return std::numeric_limits<float>::quiet_NaN();;
return std::numeric_limits<float>::quiet_NaN();
}

static double conv_deg_min_sec(double degrees,
Expand Down Expand Up @@ -824,9 +824,11 @@ bool weatherfile::open(const std::string& file, bool header_only)
{
m_hdr.lon = col_or_nan(value);
}
else if (name == "tz" || name == "timezone" || name == "time zone") // require "time zone" and "local time zone" columns in NSRDB files are the same
else if (name == "tz" || name == "timezone" || name == "time zone" || name == "local time zone") // require "time zone" and "local time zone" columns in NSRDB files are the same
{
m_hdr.tz = col_or_nan(value);
// some nsrdb endpoints like nsrdb-msg-v1-0-0 have both "local time zone" and "time zone" with "time zone" empty, so we need to read "local time zone" and ignore "time zone"
if (std::isnan(m_hdr.tz)) // only assign value if one was not assigned in an earlier pass
m_hdr.tz = col_or_nan(value);
}
else if (name == "el" || name == "elev" || name == "elevation" || name == "site elevation" || name == "altitude")
{
Expand Down
18 changes: 9 additions & 9 deletions ssc/cmod_battery.cpp
Expand Up @@ -204,16 +204,16 @@ var_info vtab_battery_inputs[] = {
{ SSC_INPUT, SSC_NUMBER, "batt_cycle_cost_choice", "Use SAM cost model for degradaton penalty or input custom via batt_cycle_cost", "0/1", "0=UseCostModel,1=InputCost", "BatteryDispatch", "?=0", "", "" },
{ SSC_INPUT, SSC_ARRAY, "batt_cycle_cost", "Input battery cycle degradaton penalty per year", "$/cycle-kWh","length 1 or analysis_period, length 1 will be extended using inflation", "BatteryDispatch", "batt_cycle_cost_choice=1", "", "" },

{ SSC_INPUT, SSC_NUMBER, "inflation_rate", "Inflation rate", "%", "", "Lifetime", "?=0", "MIN=-99", "" },
{ SSC_INPUT, SSC_ARRAY, "load_escalation", "Annual load escalation", "%/year", "", "Load", "?=0", "", "" },
{ SSC_INPUT, SSC_ARRAY, "om_batt_replacement_cost" , "Replacement cost 1" , "$/kWh" , "" , "System Costs" , "?=0.0" , "" , "" },
{ SSC_INPUT, SSC_NUMBER, "om_replacement_cost_escal" , "Replacement cost escalation" , "%/year" , "" , "System Costs" , "?=0.0" , "" , "" },
{ SSC_INPUT, SSC_NUMBER, "inflation_rate", "Inflation rate", "%", "", "Lifetime", "?=0", "MIN=-99", "" },
{ SSC_INPUT, SSC_ARRAY, "load_escalation", "Annual load escalation", "%/year", "", "Load", "?=0", "", "" },
{ SSC_INPUT, SSC_ARRAY, "om_batt_replacement_cost", "Replacement cost 1", "$/kWh", "", "System Costs" , "?=0.0" , "" , "" },
{ SSC_INPUT, SSC_NUMBER, "om_replacement_cost_escal", "Replacement cost escalation", "%/year", "", "System Costs" , "?=0.0" , "" , "" },

{ SSC_INPUT,SSC_ARRAY , "om_batt_variable_cost" , "Battery production-based System Costs amount" , "$/MWh" , "" , "System Costs" , "?=0.0" , "" , "" },
{ SSC_INPUT, SSC_NUMBER, "om_production_escal", "Production-based O&M escalation", "%/year", "", "System Costs", "?=0.0", "", "" },
{ SSC_INPUT, SSC_ARRAY, "om_batt_variable_cost", "Battery production-based System Costs amount", "$/MWh", "", "System Costs" , "?=0.0" , "" , "" },
{ SSC_INPUT, SSC_NUMBER, "om_production_escal", "Production-based O&M escalation", "%/year", "", "System Costs", "?=0.0", "", "" },

// Powerflow calculation inputs
{ SSC_INPUT, SSC_ARRAY, "fuelcell_power", "Electricity from fuel cell AC", "kW", "", "FuelCell", "", "", "" },
{ SSC_INPUT, SSC_ARRAY, "fuelcell_power", "Electricity from fuel cell AC", "kW", "", "FuelCell", "", "", "" },


var_info_invalid
Expand Down Expand Up @@ -1111,7 +1111,7 @@ battstor::battstor(var_table& vt, bool setup_model, size_t nrec, double dt_hr, c
}

if (batt_vars->T_room.size() != nrec) {
throw exec_error("battery", "Length of battery environment temperature batt_room_temperature_celsius must equal number of weather file and/or electric load data records.");
throw exec_error("battery", util::format("Length of battery environment temperature batt_room_temperature_celsius must equal number of weather file and/or electric load data records: %d records or %d-minute time steps.", nrec, 60/(nrec/8760)));
}

if (batt_vars->batt_life_model == lifetime_params::NMC) {
Expand Down Expand Up @@ -2261,7 +2261,7 @@ class cm_battery : public compute_module
add_var_info(vtab_resilience_outputs);
add_var_info(vtab_utility_rate_common);
add_var_info(vtab_grid_curtailment);
add_var_info(vtab_hybrid_tech_om);
add_var_info(vtab_hybrid_tech_om_outputs);

}

Expand Down
2 changes: 1 addition & 1 deletion ssc/cmod_fuelcell.cpp
Expand Up @@ -120,7 +120,7 @@ cm_fuelcell::cm_fuelcell()
add_var_info(vtab_fuelcell_input);
add_var_info(vtab_fuelcell_output);
add_var_info(vtab_technology_outputs);
add_var_info(vtab_hybrid_tech_om);
add_var_info(vtab_hybrid_tech_om_outputs);
}

// Have to add this since compute module isn't actually fully constructed until compute is called with
Expand Down
2 changes: 1 addition & 1 deletion ssc/cmod_generic_system.cpp
Expand Up @@ -81,7 +81,7 @@ class cm_generic_system : public compute_module
// performance adjustment factors
add_var_info(vtab_adjustment_factors);
add_var_info(vtab_technology_outputs);
add_var_info(vtab_hybrid_tech_om);
add_var_info(vtab_hybrid_tech_om_outputs);
}

void exec( )
Expand Down
2 changes: 1 addition & 1 deletion ssc/cmod_host_developer.cpp
Expand Up @@ -2201,7 +2201,7 @@ class cm_host_developer : public compute_module
// recalculate debt size with constrained dscr
size_of_debt = 0.0;
for (i = 0; i <= nyears; i++) {
if (dscr != 0)
if (dscr > 0)
cf.at(CF_debt_size, i) = cf.at(CF_pv_cash_for_ds, i) / dscr;
else
cf.at(CF_debt_size, i) = 0.0; // default behavior of initialization of cash flow line items
Expand Down

0 comments on commit b7fee04

Please sign in to comment.