Skip to content

Commit

Permalink
finalize powerflow loss accounting that allows the ac connected batte…
Browse files Browse the repository at this point in the history
…ry to deliver sufficient power to load
  • Loading branch information
brtietz committed Oct 2, 2023
1 parent 46b1945 commit 0c4da87
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 22 deletions.
39 changes: 20 additions & 19 deletions shared/lib_battery_powerflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ void BatteryPowerFlow::calculateACConnected()

// Code simplification to remove redundancy for code that should use either critical load or actual load
double calc_load_ac = (m_BatteryPower->isOutageStep ? P_crit_load_ac : P_load_ac);
double P_required_for_load = calc_load_ac;

if (ac_loss_percent_post_battery < 1) { // Account for possible divide by zero
P_required_for_load /= (1 - ac_loss_percent_post_battery);
}

// charging and idle
if (P_battery_ac <= 0)
Expand All @@ -365,11 +370,11 @@ void BatteryPowerFlow::calculateACConnected()
if (m_BatteryPower->chargeOnlySystemExceedLoad) {
P_pv_to_load_ac = P_pv_ac;

if (P_pv_to_load_ac > calc_load_ac) {
P_pv_to_load_ac = calc_load_ac;
if (P_pv_to_load_ac > P_required_for_load) {
P_pv_to_load_ac = P_required_for_load;
}
// Fuel cell goes to load next
P_fuelcell_to_load_ac = std::fmin(calc_load_ac - P_pv_to_load_ac, P_fuelcell_ac);
P_fuelcell_to_load_ac = std::fmin(P_required_for_load - P_pv_to_load_ac, P_fuelcell_ac);
}

// Excess PV can go to battery, if PV can cover charging losses
Expand Down Expand Up @@ -398,11 +403,11 @@ void BatteryPowerFlow::calculateACConnected()
P_pv_to_load_ac = P_pv_ac - P_pv_to_batt_ac;
}

if (P_pv_to_load_ac > calc_load_ac) {
P_pv_to_load_ac = calc_load_ac;
if (P_pv_to_load_ac > P_required_for_load) {
P_pv_to_load_ac = P_required_for_load;
}
// Fuel cell goes to load next
P_fuelcell_to_load_ac = std::fmin(calc_load_ac - P_pv_to_load_ac, P_fuelcell_ac);
P_fuelcell_to_load_ac = std::fmin(P_required_for_load - P_pv_to_load_ac, P_fuelcell_ac);
}

// Fuelcell can also charge battery
Expand Down Expand Up @@ -439,6 +444,7 @@ void BatteryPowerFlow::calculateACConnected()
// discharging, not idle
else
{

// Test if battery is discharging erroneously
if (!m_BatteryPower->canDischarge && P_battery_ac > 0) {
P_batt_to_grid_ac = P_batt_to_load_ac = 0;
Expand All @@ -448,9 +454,9 @@ void BatteryPowerFlow::calculateACConnected()
P_pv_to_load_ac = P_pv_ac;

// Excess PV production, no other component meets load
if (P_pv_ac >= calc_load_ac)
if (P_pv_ac >= P_required_for_load)
{
P_pv_to_load_ac = calc_load_ac;
P_pv_to_load_ac = P_required_for_load;
P_fuelcell_to_load_ac = 0;
P_batt_to_load_ac = 0;

Expand All @@ -459,14 +465,14 @@ void BatteryPowerFlow::calculateACConnected()
P_fuelcell_to_grid_ac = P_fuelcell_ac;
}
else {
P_fuelcell_to_load_ac = std::fmin(P_fuelcell_ac, calc_load_ac - P_pv_to_load_ac);
P_batt_to_load_ac = std::fmin(P_battery_ac - P_system_loss_ac, calc_load_ac - P_pv_to_load_ac - P_fuelcell_to_load_ac);
P_fuelcell_to_load_ac = std::fmin(P_fuelcell_ac, P_required_for_load - P_pv_to_load_ac);
P_batt_to_load_ac = std::fmin(P_battery_ac - P_system_loss_ac, P_required_for_load - P_pv_to_load_ac - P_fuelcell_to_load_ac);
}
}
else {
P_batt_to_load_ac = std::fmin(P_battery_ac, calc_load_ac);
P_fuelcell_to_load_ac = std::fmin(P_fuelcell_ac, calc_load_ac - P_batt_to_load_ac);
P_pv_to_load_ac = std::fmin(std::fmax(0, calc_load_ac - P_fuelcell_to_load_ac - P_batt_to_load_ac), P_pv_ac);
P_batt_to_load_ac = std::fmin(P_battery_ac, P_required_for_load);
P_fuelcell_to_load_ac = std::fmin(P_fuelcell_ac, P_required_for_load - P_batt_to_load_ac);
P_pv_to_load_ac = std::fmin(std::fmax(0, P_required_for_load - P_fuelcell_to_load_ac - P_batt_to_load_ac), P_pv_ac);
P_pv_to_grid_ac = std::fmax(0, P_pv_ac - P_pv_to_load_ac);
P_fuelcell_to_grid_ac = std::fmax(0, P_fuelcell_ac - P_fuelcell_to_load_ac);
}
Expand Down Expand Up @@ -503,11 +509,7 @@ void BatteryPowerFlow::calculateACConnected()
// Final batt to grid for outage accounting
if (P_battery_ac > 0)
{
double P_required_for_load = P_batt_to_load_ac;
if (ac_loss_percent_post_battery < 1) { // Account for possible divide by zero
P_required_for_load /= (1 - ac_loss_percent_post_battery);
}
P_batt_to_grid_ac = P_battery_ac * (1 - ac_loss_percent_post_battery) - P_system_loss_ac - P_required_for_load - P_batt_to_pv_inverter;
P_batt_to_grid_ac = P_battery_ac * (1 - ac_loss_percent_post_battery) - P_system_loss_ac - P_batt_to_load_ac - P_batt_to_pv_inverter;
if (m_BatteryPower->isOutageStep && P_batt_to_grid_ac > tolerance) {
m_BatteryPower->powerBatteryDC = (P_battery_ac - P_batt_to_grid_ac) / m_BatteryPower->singlePointEfficiencyDCToAC;
return calculateACConnected();
Expand All @@ -520,7 +522,6 @@ void BatteryPowerFlow::calculateACConnected()
P_pv_to_batt_ac *= (1 - ac_loss_percent_post_battery);
P_pv_to_grid_ac *= (1 - ac_loss_percent_post_battery);
P_grid_to_batt_ac *= (1 - ac_loss_percent_post_battery);
P_grid_to_load_ac *= (1 - ac_loss_percent_post_battery);
P_batt_to_load_ac *= (1 - ac_loss_percent_post_battery);
P_fuelcell_to_batt_ac *= (1 - ac_loss_percent_post_battery);
P_fuelcell_to_load_ac *= (1 - ac_loss_percent_post_battery);
Expand Down
4 changes: 1 addition & 3 deletions test/shared_test/lib_battery_powerflow_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3093,7 +3093,7 @@ TEST_F(BatteryPowerFlowTest_lib_battery_powerflow, AC_system_w_ac_losses) {
EXPECT_NEAR(m_batteryPower->powerBatteryToLoad, 50.0, error);
EXPECT_NEAR(m_batteryPower->powerCritLoadUnmet, 0.0, error);
EXPECT_NEAR(m_batteryPower->powerSystemToGrid, 0, error);
EXPECT_NEAR(m_batteryPower->powerConversionLoss, 2.083, error);
EXPECT_NEAR(m_batteryPower->powerConversionLoss, 2.308, error);
EXPECT_NEAR(m_batteryPower->powerSystemLoss, 0.0, error);
EXPECT_NEAR(m_batteryPower->powerLoad, 50, error);
}
Expand Down Expand Up @@ -3320,7 +3320,6 @@ TEST_F(BatteryPowerFlowTest_lib_battery_powerflow, DC_system_w_ac_losses) {
EXPECT_NEAR(m_batteryPower->powerBatteryToLoad, 43.947, error);
EXPECT_NEAR(m_batteryPower->powerCritLoadUnmet, 6.053, error);
EXPECT_NEAR(m_batteryPower->powerSystemToGrid, 0, error);
EXPECT_NEAR(m_batteryPower->powerBatteryToLoad, 0, error);
EXPECT_NEAR(m_batteryPower->powerConversionLoss, 3.738, error);
EXPECT_NEAR(m_batteryPower->powerSystemLoss, 0.0, error);
EXPECT_NEAR(m_batteryPower->powerLoad, 50, error);
Expand All @@ -3341,7 +3340,6 @@ TEST_F(BatteryPowerFlowTest_lib_battery_powerflow, DC_system_w_ac_losses) {
EXPECT_NEAR(m_batteryPower->powerBatteryToLoad, 50.0, error);
EXPECT_NEAR(m_batteryPower->powerCritLoadUnmet, 0.0, error);
EXPECT_NEAR(m_batteryPower->powerSystemToGrid, 0, error);
EXPECT_NEAR(m_batteryPower->powerBatteryToLoad, 0, error);
EXPECT_NEAR(m_batteryPower->powerConversionLoss, 3.99, error);
EXPECT_NEAR(m_batteryPower->powerSystemLoss, 0.0, error);
EXPECT_NEAR(m_batteryPower->powerLoad, 50, error);
Expand Down

0 comments on commit 0c4da87

Please sign in to comment.