Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
00f2051
add tests for all nmc cell data
dguittet Apr 23, 2021
adb543d
NREL NMC Lifetime Model Validation
dguittet May 25, 2021
009b97d
update results for other battery tests
dguittet May 25, 2021
54c0952
Merge branch 'develop' into nmc_life_tests
dguittet May 25, 2021
b435c7e
changes to compile on Linux and Windows
brtietz May 26, 2021
3c7665f
fix broken tests, fix calculate_Uneg & calculate_Voc w/ tests added
dguittet May 27, 2021
760e173
Merge remote-tracking branch 'origin/nmc_life_tests' into nmc_life_tests
dguittet May 27, 2021
bf3be76
fix calculate_Uneg & calculate_Voc fxns
dguittet May 27, 2021
d027176
Merge branch 'develop' of https://github.com/NREL/ssc into nmc_life_t…
brtietz Jun 1, 2021
42d3892
Merge branch 'develop' of https://github.com/NREL/ssc into nmc_life_t…
brtietz Jun 9, 2021
8ce020f
add replacement test for lib_battery_lifetime_nmc_test
dguittet Jun 10, 2021
68dbf58
Merge branch 'nmc_life_tests' of https://github.com/NREL/ssc into nmc…
brtietz Jun 14, 2021
1b8a0f0
CMake options in all CMake files
dguittet Jun 15, 2021
3b084dc
Merge branch 'nmc_life_tests' of https://github.com/NREL/ssc into nmc…
brtietz Jun 15, 2021
95f0398
Merge branch 'develop' into nmc_life_tests
dguittet Jun 15, 2021
a1b1f3c
update replacement test results
dguittet Jun 16, 2021
b2ea3a1
Merge branch 'nmc_life_tests' of https://github.com/NREL/ssc into nmc…
brtietz Jun 16, 2021
a62d3fe
Merge branch 'develop' of https://github.com/NREL/ssc into nmc_dod_ar…
brtietz Jun 17, 2021
7d611e0
add some write controls to batt stateful for battery arrays. Addition…
brtietz Jun 17, 2021
53c497f
add case sensitivity to vartable::unassign
dguittet Jun 17, 2021
75e116c
Update test to confirm that unassign runs as expected
brtietz Jun 18, 2021
9961960
update rainflow peaks test value in readjson
brtietz Jun 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions ssc/cmod_battery_stateful.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ void write_battery_state(const battery_state& state, var_table* vt) {
if (!lifetime->cycle->rainflow_peaks.empty()) {
vt->assign_match_case("rainflow_peaks", lifetime->cycle->rainflow_peaks);
}
else {
vt->unassign("rainflow_peaks");
}
vt->assign_match_case("rainflow_Xlt", lifetime->cycle->rainflow_Xlt);
vt->assign_match_case("rainflow_Ylt", lifetime->cycle->rainflow_Ylt);
vt->assign_match_case("rainflow_jlt", lifetime->cycle->rainflow_jlt);
Expand All @@ -253,9 +256,15 @@ void write_battery_state(const battery_state& state, var_table* vt) {
if (!lifetime->nmc_li_neg->cycle_DOD_max.empty()) {
vt->assign_match_case("cycle_DOD_max", lifetime->nmc_li_neg->cycle_DOD_max);
}
else {
vt->unassign("cycle_DOD_max");
}
if (!lifetime->nmc_li_neg->cycle_DOD_range.empty()) {
vt->assign_match_case("cycle_DOD_range", lifetime->nmc_li_neg->cycle_DOD_range);
}
else {
vt->unassign("cycle_DOD_range");
}
}

vt->assign_match_case("loss_kw", state.losses->loss_kw);
Expand Down Expand Up @@ -324,6 +333,9 @@ void read_battery_state(battery_state& state, var_table* vt) {
// If not assigned, leave empty
vt_get_array_vec(vt, "rainflow_peaks", lifetime->cycle->rainflow_peaks);
}
else {
lifetime->cycle->rainflow_peaks.clear();
}
if (choice == lifetime_params::CALCYC) {
vt_get_number(vt, "q_relative_calendar", &lifetime->calendar->q_relative_calendar);
vt_get_number(vt, "dq_relative_calendar_old", &lifetime->calendar->dq_relative_calendar_old);
Expand All @@ -347,10 +359,16 @@ void read_battery_state(battery_state& state, var_table* vt) {
{
vt_get_array_vec(vt, "cycle_DOD_range", lifetime->nmc_li_neg->cycle_DOD_range);
}
else {
lifetime->nmc_li_neg->cycle_DOD_range.clear();
}
if (vt->is_assigned("cycle_DOD_max"))
{
vt_get_array_vec(vt, "cycle_DOD_max", lifetime->nmc_li_neg->cycle_DOD_max);
}
else {
lifetime->nmc_li_neg->cycle_DOD_range.clear();
}
}

vt_get_number(vt, "loss_kw", &state.losses->loss_kw);
Expand Down
4 changes: 4 additions & 0 deletions ssc/vartab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ bool var_table::is_assigned( const std::string &name )
void var_table::unassign( const std::string &name )
{
var_hash::iterator it = m_hash.find( util::lower_case(name) );
if (it == m_hash.end())
{
it = m_hash.find( name );
}
if (it != m_hash.end())
{
delete (*it).second; // delete the associated data
Expand Down
25 changes: 25 additions & 0 deletions test/ssc_test/cmod_battery_stateful_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ TEST_F(CMBatteryStatefulIntegration_cmod_battery_stateful, ReadJson) {
ssc_data_get_number(copy, "V", &V);
ssc_data_get_number(copy, "SOC", &SOC);

int length;
ssc_number_t* rainflow_peaks = ssc_data_get_array(copy, "rainflow_peaks", &length);
EXPECT_EQ(length, 1);

EXPECT_TRUE(1); // means the variable retrievals all succeeded
}

Expand Down Expand Up @@ -240,3 +244,24 @@ TEST_F(CMBatteryStatefulIntegration_cmod_battery_stateful, AdaptiveTimestep) {
EXPECT_NEAR(adaptive_SOC, 23.657, 1e-3);
}

TEST_F(CMBatteryStatefulIntegration_cmod_battery_stateful, TestCycleCount) {
std::string js = "{\"control_mode\": 0.0, \"dt_hr\": 0.002777777777777778, \"input_current\": 0.0, \"C_rate\": 0.2, \"Qexp\": 60.75, \"Qfull\": 75.56, \"Qnom\": 73.58, \"Vcut\": 3.0, \"Vexp\": 3.529, \"Vfull\": 4.2, \"Vnom\": 3.35, \"Vnom_default\": 3.6, \"chem\": 1.0, \"initial_SOC\": 66.0, \"life_model\": 1.0, \"maximum_SOC\": 100.0, \"minimum_SOC\": 0.0, \"resistance\": 0.001155, \"voltage_choice\": 0.0, \"Cp\": 980.0, \"T_room_init\": 29.69998526573181, \"h\": 8.066, \"loss_choice\": 0.0, \"mass\": 1.55417, \"monthly_charge_loss\": [0.0], \"monthly_discharge_loss\": [0.0], \"monthly_idle_loss\": [0.0], \"nominal_energy\": 0.272, \"nominal_voltage\": 3.6, \"replacement_option\": 0.0, \"schedule_loss\": [0.0], \"surface_area\": 0.1548, \"I\": 0.0, \"I_chargeable\": -8045.99999999998, \"I_dischargeable\": 643.841000000002, \"P\": 0.0, \"P_chargeable\": -108.70616176055955, \"P_dischargeable\": 1.9341550347606316, \"Q\": 53.21000000000006, \"Q_max\": 75.56, \"SOC\": 70.42085759661204, \"T_batt\": 30.07627155118435, \"T_room\": 29.69998526573181, \"V\": 3.7667917861703755, \"heat_dissipated\": 0.0004698373776256373, \"indices_replaced\": [0.0], \"last_idx\": 8639.0, \"loss_kw\": 0.0, \"n_replacements\": 0.0, \"DOD_max\": 1.0, \"DOD_min\": 0.0, \"I_loss\": 0.0, \"SOC_prev\": 70.42085759661204, \"T_batt_prev\": 30.0747312729467, \"average_range\": 33.594321796748574, \"b1_dt\": 0.008196217640552396, \"b2_dt\": 1.1539245050321905e-05, \"b3_dt\": 0.0421665242517969, \"c0_dt\": 76.8158487840016, \"c2_dt\": 3.772090139902601e-05, \"cell_current\": 0.0, \"cell_voltage\": 3.7667917861703755, \"chargeChange\": 0.0, \"charge_mode\": 1.0, \"cum_dt\": 0.9998842592591438, \"cycle_DOD\": 100.0, \"cycle_DOD_max\": [0.0, 100.0, 100.0, 100.0], \"cycle_DOD_range\": [0.0, 0.16094315625949207, 100.0, 0.6220222339862289], \"cycle_range\": 0.6220222339862289, \"day_age_of_battery\": 0.9998842592591438, \"dq_relative_li1\": 0.0, \"dq_relative_li2\": 0.0, \"dq_relative_li3\": 0.0, \"dq_relative_neg\": 0.0, \"n_cycles\": 3.0, \"prev_charge\": 2.0, \"q0\": 53.21000000000006, \"q_relative\": 100.0, \"q_relative_cycle\": 0.0, \"q_relative_li\": 100.0, \"q_relative_neg\": 100.0, \"q_relative_thermal\": 100.0, \"qmax_lifetime\": 75.56, \"qmax_thermal\": 75.56, \"rainflow_Xlt\": 0.6220222339862431, \"rainflow_Ylt\": 20.103229221810423, \"rainflow_jlt\": 4.0, \"rainflow_peaks\": [100.0, 0.0, 20.103229221810423, 19.48120698782418]}";
data = json_to_ssc_data(js.c_str());

mod = ssc_module_create("battery_stateful");
EXPECT_TRUE(ssc_stateful_module_setup(mod, data));

data = json_to_ssc_data(js.c_str()); // Refresh the vtable data since setup overwrites some of the history

var_table* vt = static_cast<var_table*>(data);

EXPECT_TRUE(vt->is_assigned("cycle_DOD_range"));
EXPECT_TRUE(vt->is_assigned("cycle_DOD_max"));

EXPECT_TRUE(ssc_module_exec(mod, data)); // Executing one step with 0 input_current (default) will trip the next day using the nmc lifetime model

vt = static_cast<var_table*>(data);
EXPECT_FALSE(vt->is_assigned("cycle_DOD_range"));
EXPECT_FALSE(vt->is_assigned("cycle_DOD_max"));

}