Skip to content

Commit

Permalink
Merge branch 'particle_gen3_csp' of https://github.com/NREL/ssc into …
Browse files Browse the repository at this point in the history
…particle_gen3_csp
  • Loading branch information
qualand committed Jul 28, 2023
2 parents f84ec88 + 526b6bd commit 8cec304
Show file tree
Hide file tree
Showing 65 changed files with 2,009 additions and 1,100 deletions.
2 changes: 2 additions & 0 deletions nlopt/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
# include <windows.h>
#endif

// header needed to build on MacOS "Call to undeclared function 'gettimeofday'; ISO C99 and later do not support implicit function declarations" compile error
int gettimeofday(struct timeval * __restrict, void * __restrict);

/* return time in seconds since some arbitrary point in the past */
double nlopt_seconds(void)
{
Expand Down
21 changes: 20 additions & 1 deletion shared/lib_battery_dispatch_automatic_btm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ dispatch_automatic_behind_the_meter_t::dispatch_automatic_behind_the_meter_t(
bool chargeOnlySystemExceedLoad,
bool dischargeOnlyLoadExceedSystem,
bool behindTheMeterDischargeToGrid,
double SOC_min_outage
double SOC_min_outage,
int load_forecast_mode
) : dispatch_automatic_t(Battery, dt_hour, SOC_min, SOC_max, current_choice, Ic_max, Id_max, Pc_max_kwdc, Pd_max_kwdc, Pc_max_kwac, Pd_max_kwac,
t_min, dispatch_mode, weather_forecast_mode, pv_dispatch, nyears, look_ahead_hours, dispatch_update_frequency_hours, can_charge, can_clip_charge, can_grid_charge, can_fuelcell_charge,
battReplacementCostPerkWh, battCycleCostChoice, battCycleCost, battOMCost, interconnection_limit, chargeOnlySystemExceedLoad, dischargeOnlyLoadExceedSystem,
Expand All @@ -81,6 +82,8 @@ dispatch_automatic_behind_the_meter_t::dispatch_automatic_behind_the_meter_t(
_P_target_use.reserve(_num_steps);
_P_battery_use.reserve(_num_steps);

_load_forecast_mode = load_forecast_mode;

grid.reserve(_num_steps);
sorted_grid.reserve(_num_steps);

Expand Down Expand Up @@ -264,6 +267,20 @@ void dispatch_automatic_behind_the_meter_t::initialize(size_t hour_of_year, size
m_batteryPower->powerBatteryTarget = 0;
_day_index = 0;

// Give all algorithms real data for the current step (overwrite forecast if needed)
if (_load_forecast_mode != LOAD_LOOK_AHEAD) {
_P_load_ac[lifetimeIndex] = m_batteryPower->powerLoad;
}
// Lookahead forecasts may better account for losses than the code below, so don't run this if lookahead
if (_weather_forecast_mode != WF_LOOK_AHEAD) {
if (m_batteryPower->connectionMode == AC_CONNECTED) {
_P_pv_ac[lifetimeIndex] = m_batteryPower->powerSystem;
}
else {
_P_pv_ac[lifetimeIndex] = m_batteryPower->powerSystem * m_batteryPower->sharedInverter->efficiencyAC;
}
}

// clean up vectors
size_t lifetimeMax = _P_pv_ac.size();
for (size_t ii = 0; ii != _num_steps && lifetimeIndex < lifetimeMax; ii++)
Expand All @@ -274,6 +291,7 @@ void dispatch_automatic_behind_the_meter_t::initialize(size_t hour_of_year, size
_P_battery_use.push_back(0.);
lifetimeIndex++;
}

}
bool dispatch_automatic_behind_the_meter_t::check_new_month(size_t hour_of_year, size_t step)
{
Expand Down Expand Up @@ -320,6 +338,7 @@ void dispatch_automatic_behind_the_meter_t::sort_grid(size_t idx, FILE *p, const

// compute grid net from pv and load (no battery)
size_t count = 0;

for (size_t hour = 0; hour != 24 && idx < _P_load_ac.size(); hour++)
{
for (size_t step = 0; step != _steps_per_hour; step++)
Expand Down
6 changes: 5 additions & 1 deletion shared/lib_battery_dispatch_automatic_btm.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ class dispatch_automatic_behind_the_meter_t : public dispatch_automatic_t
bool chargeOnlySystemExceedLoad,
bool dischargeOnlyLoadExceedSystem,
bool behindTheMeterDischargeToGrid,
double SOC_min_outage
double SOC_min_outage,
int load_forecast_mode
);

~dispatch_automatic_behind_the_meter_t() override {};
Expand Down Expand Up @@ -166,6 +167,9 @@ class dispatch_automatic_behind_the_meter_t : public dispatch_automatic_t
/*! Full time-series of loads [kW] */
double_vec _P_load_ac;

/*! Forecast mode for loads (look ahead, look behind, custom) */
int _load_forecast_mode;

/*! Full time-series of target power [kW] */
double_vec _P_target_input;

Expand Down
17 changes: 10 additions & 7 deletions shared/lib_battery_voltage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ void voltage_table_t::initialize() {
double V0 = params->voltage_table[i - 1][1];
slope = (V - V0) / (DOD - DOD0);
intercept = V0 - (slope * DOD0);

if (fabs(slope) < 1e-7)
throw std::runtime_error("voltage_table_t error: Battery voltage matrix cannot have two identical voltages.");
}
slopes.emplace_back(slope);
intercepts.emplace_back(intercept);
Expand Down Expand Up @@ -253,9 +256,9 @@ double voltage_table_t::calculate_current_for_target_w(double P_watts, double q,

P_watts /= params->num_cells_series;
P_watts *= params->dt_hr;
double multiplier = 1.;
int multiplier = 1;
if (P_watts < 0)
multiplier = -1.;
multiplier = -1;

size_t row = 0;
while (row < params->voltage_table.size() && DOD > params->voltage_table[row][0]) {
Expand All @@ -266,12 +269,12 @@ double voltage_table_t::calculate_current_for_target_w(double P_watts, double q,
double B = qmax / 100.;

double DOD_new = 0.;
double incr = 0;
double DOD_best = DOD_best = multiplier == -1. ? 0 : 100;
int incr = 0;
double DOD_best = DOD_best = (multiplier == -1) ? 0 : 100;
double P_best = 0;
while (incr + row < slopes.size() && incr + row >= 0) {
size_t i = row + (size_t) incr;
incr += 1 * multiplier;
while (((incr + row) < slopes.size()) && ((incr + row) >= 0)) {
size_t i = row + incr;
incr += multiplier;

double a = B * slopes[i];
double b = A * slopes[i] + B * intercepts[i];
Expand Down
Loading

0 comments on commit 8cec304

Please sign in to comment.