From 0916a247fd24046970ae757d4dff9e840cfb952e Mon Sep 17 00:00:00 2001 From: Adrien Gougeon Date: Thu, 13 Jul 2023 15:08:31 +0200 Subject: [PATCH] SoH now based on internal values (lost/gained energy) instead of external values (consumed/provided energy). Improved doc. --- docs/source/img/battery_degradation.svg | 1947 ++++++++++------- .../battery-energy/s4u-battery-energy.tesh | 8 +- .../battery-simple/s4u-battery-simple.tesh | 8 +- src/plugins/battery.cpp | 84 +- 4 files changed, 1272 insertions(+), 775 deletions(-) diff --git a/docs/source/img/battery_degradation.svg b/docs/source/img/battery_degradation.svg index a887272992..432fa43288 100644 --- a/docs/source/img/battery_degradation.svg +++ b/docs/source/img/battery_degradation.svg @@ -6,7 +6,7 @@ - 2023-06-28T16:42:29.585725 + 2023-07-13T14:07:53.987014 image/svg+xml @@ -40,13 +40,13 @@ z - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -465,13 +465,13 @@ L 1036.8 357.565447 - + - + @@ -480,13 +480,13 @@ L 1036.8 267.687123 - + - + - + - + @@ -637,702 +637,1167 @@ z - + +" clip-path="url(#pc407524690)" style="fill: none; stroke: #dd8452; stroke-width: 1.5; stroke-linecap: round"/> @@ -1514,7 +1979,7 @@ L 992.865937 116.787969 - + diff --git a/examples/cpp/battery-energy/s4u-battery-energy.tesh b/examples/cpp/battery-energy/s4u-battery-energy.tesh index eed565dcd8..43094f468a 100644 --- a/examples/cpp/battery-energy/s4u-battery-energy.tesh +++ b/examples/cpp/battery-energy/s4u-battery-energy.tesh @@ -4,10 +4,10 @@ $ ${bindir:=.}/s4u-battery-energy ${platfdir}/energy_platform.xml > [MyHost1:manager:(1) 0.000000] [battery_energy/INFO] Battery state: SoC: 0.800000 SoH: 1.000000 Energy stored: 28800.000000J Energy provided: 0.000000J Energy consumed 0.000000J > [MyHost1:manager:(1) 0.000000] [battery_energy/INFO] Connecting hosts MyHost1 and MyHost2 to the battery > [MyHost1:manager:(1) 0.000000] [battery_energy/INFO] Host MyHost1 will now execute 1000000000.000000 flops -> [96.208749] [battery_energy/INFO] Event -> Battery low: SoC: 0.200000 SoH: 0.999730 Energy stored: 7198.055825J Energy provided: 19441.749757J Energy consumed 0.000000J -> [96.208749] [battery_energy/INFO] Disconnecting hosts MyHost1 and MyHost2 -> [96.208749] [battery_energy/INFO] Energy consumed this far by: MyHost1: 9820.874879J, MyHost2: 9620.874879J, MyHost3: 9620.874879J -> [MyHost1:manager:(1) 200.000000] [battery_energy/INFO] Battery state: SoC: 0.200000 SoH: 0.999730 Energy stored: 7198.055825J Energy provided: 19441.749757J Energy consumed 0.000000J +> [96.209721] [battery_energy/INFO] Event -> Battery low: SoC: 0.200000 SoH: 0.999700 Energy stored: 7197.839784J Energy provided: 19441.944194J Energy consumed 0.000000J +> [96.209721] [battery_energy/INFO] Disconnecting hosts MyHost1 and MyHost2 +> [96.209721] [battery_energy/INFO] Energy consumed this far by: MyHost1: 9820.972097J, MyHost2: 9620.972097J, MyHost3: 9620.972097J +> [MyHost1:manager:(1) 200.000000] [battery_energy/INFO] Battery state: SoC: 0.200000 SoH: 0.999700 Energy stored: 7197.839784J Energy provided: 19441.944194J Energy consumed 0.000000J > [200.000000] [host_energy/INFO] Total energy consumption: 60200.000000 Joules (used hosts: 20200.000000 Joules; unused/idle hosts: 40000.000000) > [200.000000] [host_energy/INFO] Energy consumption of host MyHost1: 20200.000000 Joules > [200.000000] [host_energy/INFO] Energy consumption of host MyHost2: 20000.000000 Joules diff --git a/examples/cpp/battery-simple/s4u-battery-simple.tesh b/examples/cpp/battery-simple/s4u-battery-simple.tesh index 1ea75eda37..253e7d1d97 100644 --- a/examples/cpp/battery-simple/s4u-battery-simple.tesh +++ b/examples/cpp/battery-simple/s4u-battery-simple.tesh @@ -3,7 +3,7 @@ $ ${bindir:=.}/s4u-battery-simple ${platfdir}/energy_platform.xml > [0.000000] [battery_simple/INFO] Initial state: SoC: 0.800000 SoH: 1.000000 Energy stored: 28800.000000J Energy provided: 0.000000J Energy consumed 0.000000J > [0.000000] [battery_simple/INFO] Set load to 100.000000W -> [194.417498] [battery_simple/INFO] Discharged state: SoC: 0.200000 SoH: 0.999730 Energy stored: 7198.055825J Energy provided: 19441.749757J Energy consumed 0.000000J -> [194.417498] [battery_simple/INFO] Set load to -100.000000W -> [434.246101] [battery_simple/INFO] Charged state: SoC: 0.800000 SoH: 0.999397 Energy stored: 28782.630156J Energy provided: 19441.749757J Energy consumed 23982.860368J -> [434.246101] [battery_simple/INFO] Set load to 0.000000W \ No newline at end of file +> [194.419442] [battery_simple/INFO] Discharged state: SoC: 0.200000 SoH: 0.999700 Energy stored: 7197.839784J Energy provided: 19441.944194J Energy consumed 0.000000J +> [194.419442] [battery_simple/INFO] Set load to -100.000000W +> [434.251502] [battery_simple/INFO] Charged state: SoC: 0.800000 SoH: 0.999400 Energy stored: 28782.725182J Energy provided: 19441.944194J Energy consumed 23983.205998J +> [434.251502] [battery_simple/INFO] Set load to 0.000000W diff --git a/src/plugins/battery.cpp b/src/plugins/battery.cpp index df6ae46cef..15c715a976 100644 --- a/src/plugins/battery.cpp +++ b/src/plugins/battery.cpp @@ -21,33 +21,61 @@ SIMGRID_REGISTER_PLUGIN(battery, "Battery management", nullptr) This is the battery plugin, enabling management of batteries. -With this plugin you can: +Batteries +......... -- create Batteries -- associate positive or negative load to Batteries -- connect Hosts to Batteries -- create Events triggered whenever a Battery reach a specific state of charge +A battery has an initial State of Charge :math:`SoC`, a charge efficiency :math:`\eta_{charge}`, a discharge efficiency +:math:`\eta_{discharge}`, an initial capacity :math:`C_{initial}` and a number of cycle :math:`N`. -The natural depletion of batteries over time is not taken into account. +We distinguish the energy provided :math:`E_{provided}` / consumed :math:`E_{consumed}` from the energy lost +:math:`E_{lost}` / gained :math:`E_{gained}`. The energy provided / consumed shows the external point of view, and the +energy lost / gained shows the internal point of view: + +.. math:: + + E_{lost} = {E_{provided} \over \eta_{discharge}} -A battery starts with an energy budget :math:`E` such as: + E_{gained} = E_{consumed} \times \eta_{charge} + +For instance, if you apply a load of 100W to a battery for 10s with a discharge efficiency of 0.8, the energy provided +will be equal to 10kJ, and the energy lost will be equal to 12.5kJ. + +Use the battery reduces its State of Health :math:`SoH` and its capacity :math:`C` linearly in consequence: .. math:: - E = C \times N \times 2 + SoH = 1 - {E_{lost} + E_{gained} \over E_{budget}} -Where :math:`C` is the initial capacity and :math:`N` is the number of cycles of the battery. + C = C_{initial} \times SoH -The SoH represents the consumption of this energy budget during the lifetime of the battery. -Use the battery reduces its SoH and its capacity in consequence. -When the SoH reaches 0, the battery becomes unusable. +With: + +.. math:: -Plotting the output of the example "battery-degradation" highlights the linear decrease of the SoH due to a continuous -use of the battery and the decreasing cycle duration as its capacity reduces: + E_{budget} = C_{initial} \times N \times 2 + +Plotting the output of the example "battery-degradation" highlights the linear decrease of the :math:`SoH` due to a +continuous use of the battery alternating between charge and discharge: .. image:: /img/battery_degradation.svg :align: center +The natural depletion of batteries over time is not taken into account. + +Loads & Hosts +.............. + +You can add named loads to a battery. Those loads may be positive and consume energy from the battery, or negative and +add energy to the battery. You can also connect hosts to a battery. Theses hosts will consume their energy from the +battery until the battery is empty or until the connection between the hosts and the battery is set inactive. + +Events +...... + +You can create events that will happen at specific SoC of the battery and trigger a callback. +Theses events may be recurrent, for instance you may want to always set all loads to zero and deactivate all hosts +connections when the battery reaches 20% SoC. + @endrst */ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Battery, kernel, "Logging specific to the battery plugin"); @@ -143,7 +171,9 @@ void Battery::update() // Updating battery energy_provided_j_ += energy_lost_delta_j * discharge_efficiency_; energy_consumed_j_ += energy_gained_delta_j / charge_efficiency_; - capacity_wh_ = initial_capacity_wh_ * (1 - (energy_provided_j_ + energy_consumed_j_) / energy_budget_j_); + capacity_wh_ = + initial_capacity_wh_ * + (1 - (energy_provided_j_ / discharge_efficiency_ + energy_consumed_j_ * charge_efficiency_) / energy_budget_j_); energy_stored_j_ += energy_gained_delta_j - energy_lost_delta_j; energy_stored_j_ = std::min(energy_stored_j_, 3600 * capacity_wh_); last_updated_ = now; @@ -191,12 +221,13 @@ double Battery::next_occurring_event() /* The time to reach a state of charge depends on the capacity, but charging and discharging deteriorate the * capacity, so we need to evaluate the time considering a capacity that also depends on time */ - event->time_delta_ = (3600 * event->state_of_charge_ * initial_capacity_wh_ * - (1 - (energy_provided_j_ + energy_consumed_j_) / energy_budget_j_) - - energy_stored_j_) / - (gained_power_w - lost_power_w + - 3600 * event->state_of_charge_ * initial_capacity_wh_ * - (consumed_power_w + provided_power_w) / energy_budget_j_); + event->time_delta_ = + (3600 * event->state_of_charge_ * initial_capacity_wh_ * + (1 - (energy_provided_j_ / discharge_efficiency_ + energy_consumed_j_ * charge_efficiency_) / + energy_budget_j_) - + energy_stored_j_) / + (gained_power_w - lost_power_w + + 3600 * event->state_of_charge_ * initial_capacity_wh_ * (gained_power_w + lost_power_w) / energy_budget_j_); if ((time_delta == -1 or event->time_delta_ < time_delta) and abs(event->time_delta_) > 0.000000001) time_delta = event->time_delta_; } @@ -241,8 +272,8 @@ BatteryPtr Battery::init(const std::string& name, double state_of_charge, double init_plugin(); plugin_inited = true; } - auto battery = BatteryPtr(new Battery(name, state_of_charge, charge_efficiency, discharge_efficiency, - initial_capacity_wh, cycles)); + auto battery = BatteryPtr( + new Battery(name, state_of_charge, charge_efficiency, discharge_efficiency, initial_capacity_wh, cycles)); battery_model_->add_battery(battery); return battery; } @@ -257,7 +288,7 @@ void Battery::set_load(const std::string& name, double power_w) } /** @ingroup plugin_battery - * @param h The Host to connect. + * @param host The Host to connect. * @param active Status of the connected Host (default true). * @brief Connect a Host to the Battery with the status active. As long as the status is true the Host takes its energy from the Battery. To modify this status connect again the same Host with a different status. @@ -282,7 +313,8 @@ double Battery::get_state_of_charge() */ double Battery::get_state_of_health() { - return 1 - ((energy_provided_j_ + energy_consumed_j_) / energy_budget_j_); + return 1 - + ((energy_provided_j_ / discharge_efficiency_ + energy_consumed_j_ * charge_efficiency_) / energy_budget_j_); } /** @ingroup plugin_battery @@ -314,7 +346,7 @@ double Battery::get_energy_consumed() } /** @ingroup plugin_battery - * @param Unit Valid units are J (default) and Wh. + * @param unit Valid units are J (default) and Wh. * @return Energy stored in the Battery. */ double Battery::get_energy_stored(std::string unit) -- 2.20.1