Skip to content

Commit

Permalink
Merge pull request #1154 from NREL/patch
Browse files Browse the repository at this point in the history
Patch to develop 4/3/24
  • Loading branch information
brtietz committed Apr 3, 2024
2 parents af06594 + 848d831 commit eb0c377
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 32 deletions.
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
6 changes: 3 additions & 3 deletions ssc/cmod_pvwattsv7.cpp
Expand Up @@ -1261,7 +1261,7 @@ class cm_pvwattsv7 : public compute_module
p_tpoa[idx] = (ssc_number_t)tpoa; // W/m2
p_tmod[idx] = (ssc_number_t)tmod;
p_dc[idx] = (ssc_number_t)dc; // power, Watts
p_ac[idx] = (ssc_number_t)(ac * haf(hour_of_year)); // power, Watts
p_ac[idx] = (ssc_number_t)(ac * haf(wdprov->annualSimulation() ? hour_of_year : idx)); // power, Watts

// accumulate hourly energy (kWh) (was initialized to zero when allocated)
p_gen[idx_life] = (ssc_number_t)(p_ac[idx]* util::watt_to_kilowatt);
Expand All @@ -1270,8 +1270,8 @@ class cm_pvwattsv7 : public compute_module
annual_kwh += p_gen[idx] / step_per_hour;
}

if (y == 0 && wdprov->annualSimulation()) ld("ac_loss_adjustments") += ac * (1.0 - haf(hour_of_year)) * ts_hour; //ts_hour required to correctly convert to Wh for subhourly data
if (y == 0 && wdprov->annualSimulation()) ld("ac_delivered") += ac * haf(hour_of_year) * ts_hour; //ts_hour required to correctly convert to Wh for subhourly data
if (y == 0 && wdprov->annualSimulation()) ld("ac_loss_adjustments") += ac * (1.0 - haf(wdprov->annualSimulation() ? hour_of_year : idx)) * ts_hour; //ts_hour required to correctly convert to Wh for subhourly data
if (y == 0 && wdprov->annualSimulation()) ld("ac_delivered") += ac * haf(wdprov->annualSimulation() ? hour_of_year : idx) * ts_hour; //ts_hour required to correctly convert to Wh for subhourly data

idx_life++;
}
Expand Down
6 changes: 3 additions & 3 deletions ssc/cmod_pvwattsv8.cpp
Expand Up @@ -1359,7 +1359,7 @@ class cm_pvwattsv8 : public compute_module
p_tmod[idx] = (ssc_number_t)tmod;
p_dc[idx] = (ssc_number_t)dc; // power, Watts
p_ac_pre_adjust[idx] = (ssc_number_t)ac; //power, Watts
p_ac[idx] = (ssc_number_t)(ac * haf(hour_of_year)); // power, Watts
p_ac[idx] = (ssc_number_t)(ac * haf(wdprov->annualSimulation() ? hour_of_year : idx)); // power, Watts

// accumulate hourly energy (kWh) (was initialized to zero when allocated)
p_gen[idx_life] = (ssc_number_t)(p_ac[idx] * util::watt_to_kilowatt);
Expand All @@ -1369,8 +1369,8 @@ class cm_pvwattsv8 : public compute_module
annual_kwh += p_gen[idx] / step_per_hour;
}

if (y == 0 && wdprov->annualSimulation()) ld("ac_loss_adjustments") += ac * (1.0 - haf(hour_of_year)) * ts_hour; //ts_hour required to correctly convert to Wh for subhourly data
if (y == 0 && wdprov->annualSimulation()) ld("ac_delivered") += ac * haf(hour_of_year) * ts_hour; //ts_hour required to correctly convert to Wh for subhourly data
if (y == 0 && wdprov->annualSimulation()) ld("ac_loss_adjustments") += ac * (1.0 - haf(wdprov->annualSimulation() ? hour_of_year : idx)) * ts_hour; //ts_hour required to correctly convert to Wh for subhourly data
if (y == 0 && wdprov->annualSimulation()) ld("ac_delivered") += ac * haf(wdprov->annualSimulation() ? hour_of_year : idx) * ts_hour; //ts_hour required to correctly convert to Wh for subhourly data

idx_life++;
}
Expand Down
10 changes: 10 additions & 0 deletions ssc/sscapi.cpp
Expand Up @@ -712,6 +712,16 @@ SSCEXPORT ssc_var_t ssc_data_get_data_matrix(ssc_data_t p_data, const char *name
}
return dat;
}

SSCEXPORT ssc_bool_t ssc_data_deep_copy(ssc_data_t source, ssc_data_t dest) {
auto source_vt = static_cast<var_table*>(source);
if (!source_vt) return 0;
auto dest_vt = static_cast<var_table*>(dest);
if (!dest_vt) return 0;
*dest_vt = *source_vt; // invokes operator= for deep copy
return 1;
}

/*
void json_to_ssc_var(const Json::Value& json_val, ssc_var_t ssc_val){
if (!ssc_val)
Expand Down
2 changes: 2 additions & 0 deletions ssc/sscapi.h
Expand Up @@ -284,6 +284,8 @@ SSCEXPORT ssc_var_t ssc_data_get_data_array(ssc_data_t p_data, const char *name,
/** Returns the reference of a @a SSC_DATAMAT variable with the given name. */
SSCEXPORT ssc_var_t ssc_data_get_data_matrix(ssc_data_t p_data, const char *name, int* nrows, int* ncols );

SSCEXPORT ssc_bool_t ssc_data_deep_copy(ssc_data_t source, ssc_data_t dest);

/**@}*/


Expand Down
36 changes: 18 additions & 18 deletions test/input_cases/weather_inputs.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/input_cases/weather_inputs.h
Expand Up @@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Creates resources as var_data, as opposed to resources from files, for testing use through SDK
*/

var_table* create_weatherdata_array(size_t length);
var_table* create_weatherdata_array(size_t length, size_t start_idx=0);

void free_weatherdata_array(var_table* data);

Expand Down
Expand Up @@ -19,7 +19,6 @@
"wind_resource_model_choice" : 0,
"wind_turbine_hub_ht" : 80,
"avail_turb_loss" : 3.5800000000000001,
"wind_resource_filename" : "C:/Projects/Github/NREL/working/SAM/deploy/wind_resource/AZ Eastern-Rolling Hills.srw",
"adjust_constant" : 0,
"weibull_k_factor" : 2,
"wind_resource_shear" : 0.14000000000000001,
Expand Down Expand Up @@ -215,7 +214,6 @@
"adjust_en_periods" : 0,
"inv_eff" : 96,
"analysis_period" : 25,
"solar_resource_file" : "C:/Projects/Github/NREL/working/SAM/deploy/solar_resource/phoenix_az_33.450495_-111.983688_psmv3_60_tmy.csv",
"om_production_escal" : 0,
"system_use_lifetime_output" : 0,
"batt_simple_enable" : 0,
Expand Down
Expand Up @@ -19,7 +19,6 @@
"wind_resource_model_choice" : 0,
"wind_turbine_hub_ht" : 80,
"avail_turb_loss" : 3.5800000000000001,
"wind_resource_filename" : "C:/Projects/Github/NREL/working/SAM/deploy/wind_resource/AZ Eastern-Rolling Hills.srw",
"adjust_constant" : 0,
"weibull_k_factor" : 2,
"wind_resource_shear" : 0.14000000000000001,
Expand Down Expand Up @@ -65,7 +64,6 @@
"shading_string_option" : 0,
"inv_eff" : 96,
"analysis_period" : 25,
"solar_resource_file" : "C:/Projects/Github/NREL/working/SAM/deploy/solar_resource/phoenix_az_33.450495_-111.983688_psmv3_60_tmy.csv",
"om_production_escal" : 0,
"system_use_lifetime_output" : 0,
"batt_simple_enable" : 0,
Expand Down
Expand Up @@ -19,7 +19,6 @@
"wind_resource_model_choice" : 0,
"wind_turbine_hub_ht" : 80,
"avail_turb_loss" : 3.5800000000000001,
"wind_resource_filename" : "C:/Projects/Github/NREL/working/SAM/deploy/wind_resource/AZ Eastern-Rolling Hills.srw",
"adjust_constant" : 0,
"weibull_k_factor" : 2,
"wind_resource_shear" : 0.14000000000000001,
Expand Down Expand Up @@ -67,7 +66,6 @@
"adjust_en_periods" : 0,
"inv_eff" : 96,
"analysis_period" : 25,
"solar_resource_file" : "C:/Projects/Github/NREL/working/SAM/deploy/solar_resource/phoenix_az_33.450495_-111.983688_psmv3_60_tmy.csv",
"om_production_escal" : 0,
"system_use_lifetime_output" : 0,
"batt_simple_enable" : 0,
Expand Down
51 changes: 51 additions & 0 deletions test/shared_test/lib_battery_dispatch_automatic_btm_test.cpp
Expand Up @@ -1619,3 +1619,54 @@ TEST_F(AutoBTMTest_lib_battery_dispatch, DispatchAutoBTMGridOutageFuelCellCharge
EXPECT_NEAR(batteryPower->powerCritLoadUnmet, expectedCritLoadUnmet[h], 0.1) << " error in crit load at hour " << h;
}
}

TEST_F(AutoBTMTest_lib_battery_dispatch, DispatchAutoBTMSetupRateForecastMultiYear) {
double dtHour = 1;
CreateBattery(dtHour);

util_rate = new rate_data();
util_rate->dc_enabled = true;
set_up_default_commercial_rate_data(*util_rate);

double defaultEff = 0.96;
size_t nyears = 25;

dispatchAutoBTM = new dispatch_automatic_behind_the_meter_t(batteryModel, dtHour, SOC_min, SOC_max, currentChoice,
max_current,
max_current, max_power * defaultEff, max_power / defaultEff, max_power, max_power,
0, dispatch_t::BTM_MODES::RETAIL_RATE, dispatch_t::WEATHER_FORECAST_CHOICE::WF_LOOK_AHEAD, 0, nyears, 24, 1, true,
true, false, false, util_rate, replacementCost, cyclingChoice, cyclingCost, omCost, interconnection_limit, chargeOnlySystemExceedLoad,
dischargeOnlyLoadExceedSystem, dischargeToGrid, min_outage_soc, dispatch_t::LOAD_FORECAST_CHOICE::LOAD_LOOK_AHEAD);

// Setup pv and load signal for peak shaving algorithm
for (size_t h = 0; h < 8760 * nyears; h++) {
if (h % 24 > 6 && h % 24 < 16) {
pv_prediction.push_back(700);
}
else if (h % 24 == 18) {
pv_prediction.push_back(750);
}
else {
pv_prediction.push_back(0);
}

if (h % 24 == 6) {
load_prediction.push_back(600);
}
else if (h % 24 > 16) {
load_prediction.push_back(700);
}
else {
load_prediction.push_back(50);
}
}

dispatchAutoBTM->update_load_data(load_prediction);
dispatchAutoBTM->update_pv_data(pv_prediction);
dispatchAutoBTM->setup_rate_forecast();

// Testing to make sure there are no errors thrown

delete util_rate;

}
25 changes: 25 additions & 0 deletions test/ssc_test/cmod_pvwattsv8_test.cpp
Expand Up @@ -503,6 +503,31 @@ TEST_F(CMPvwattsv8Integration_cmod_pvwattsv8, NonAnnual)
free_weatherdata_array(weather_data);
}

TEST_F(CMPvwattsv8Integration_cmod_pvwattsv8, NonAnnualSummerStart)
{
//set up a weather data array and unassign the solar resource file

auto weather_data = create_weatherdata_array(24, 24 * 180);

ssc_data_unassign(data, "solar_resource_file");
ssc_data_set_table(data, "solar_resource_data", weather_data);

//run the tests
EXPECT_FALSE(run_module(data, "pvwattsv8"));

ssc_number_t dc, gen, ac;
dc = ssc_data_get_array(data, "dc", nullptr)[12];
EXPECT_NEAR(dc, 769.13, 1.) << "DC Energy at noon";

ac = ssc_data_get_array(data, "ac", nullptr)[12];
EXPECT_NEAR(ac, 726.023, 1.) << "AC Energy at noon";

gen = ssc_data_get_array(data, "gen", nullptr)[12];
EXPECT_NEAR(gen, 0.726, 0.01) << "Gen at noon";

free_weatherdata_array(weather_data);
}


TEST_F(CMPvwattsv8Integration_cmod_pvwattsv8, IntermediateOutputTesting)
{
Expand Down

0 comments on commit eb0c377

Please sign in to comment.