X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/dcc19da1a2396ecf08021c0e4ec7683c19ab0340..3f9b311ec56db95ec539001a860ae3c838c48312:/src/plugins/battery.cpp diff --git a/src/plugins/battery.cpp b/src/plugins/battery.cpp index 73da963817..0cbfdbc8c5 100644 --- a/src/plugins/battery.cpp +++ b/src/plugins/battery.cpp @@ -6,10 +6,7 @@ #include #include #include -#include #include -#include -#include #include "src/kernel/resource/CpuImpl.hpp" #include "src/simgrid/module.hpp" @@ -71,19 +68,25 @@ continuous use of the battery alternating between charge and discharge: 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 provide 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. Handlers -...... +........ You can schedule handlers that will happen at specific SoC of the battery and trigger a callback. Theses handlers 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. +Connector +......... + +A Battery can act as a connector to connect Solar Panels direcly to loads. Such Battery is created without any +parameter, cannot store energy and has a transfer efficiency of 100%. + @endrst */ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Battery, kernel, "Logging specific to the battery plugin"); @@ -107,6 +110,11 @@ void BatteryModel::update_actions_state(double now, double delta) double BatteryModel::next_occurring_event(double now) { + static bool init = false; + if (!init) { + init = true; + return 0; + } double time_delta = -1; for (auto battery : batteries_) { double time_delta_battery = battery->next_occurring_handler(); @@ -154,12 +162,15 @@ void Battery::update() double consumed_power_w = 0; for (auto const& [host, active] : host_loads_) provided_power_w += active ? sg_host_get_current_consumption(host) : 0; - for (auto const& [name, load] : named_loads_) { - if (load > 0) - provided_power_w += load; + for (auto const& [name, pair] : named_loads_) { + if (not pair.first) + continue; + if (pair.second > 0) + provided_power_w += pair.second; else - consumed_power_w += -load; + consumed_power_w += -pair.second; } + provided_power_w = std::min(provided_power_w, nominal_discharge_power_w_ * discharge_efficiency_); consumed_power_w = std::min(consumed_power_w, -nominal_charge_power_w_); @@ -182,6 +193,14 @@ void Battery::update() // Updating battery energy_provided_j_ += energy_lost_delta_j * discharge_efficiency_; energy_consumed_j_ += energy_gained_delta_j / charge_efficiency_; + + // This battery is a simple connector, we only update energy provided and consumed + if (energy_budget_j_ == 0) { + energy_consumed_j_ = energy_provided_j_; + last_updated_ = now; + return; + } + capacity_wh_ = initial_capacity_wh_ * (1 - (energy_provided_j_ / discharge_efficiency_ + energy_consumed_j_ * charge_efficiency_) / energy_budget_j_); @@ -189,18 +208,16 @@ void Battery::update() energy_stored_j_ = std::min(energy_stored_j_, 3600 * capacity_wh_); last_updated_ = now; - std::vector> to_delete = {}; - for (auto handler : handlers_) { + auto handlers_2 = handlers_; + for (auto handler : handlers_2) { if (abs(handler->time_delta_ - time_delta_s) < 0.000000001) { handler->callback_(); if (handler->persistancy_ == Handler::Persistancy::PERSISTANT) handler->time_delta_ = -1; else - to_delete.push_back(handler); + delete_handler(handler); } } - for (auto handler : to_delete) - delete_handler(handler); }); } @@ -210,11 +227,13 @@ double Battery::next_occurring_handler() double consumed_power_w = 0; for (auto const& [host, active] : host_loads_) provided_power_w += active ? sg_host_get_current_consumption(host) : 0; - for (auto const& [name, load] : named_loads_) { - if (load > 0) - provided_power_w += load; + for (auto const& [name, pair] : named_loads_) { + if (not pair.first) + continue; + if (pair.second > 0) + provided_power_w += pair.second; else - consumed_power_w += -load; + consumed_power_w += -pair.second; } provided_power_w = std::min(provided_power_w, nominal_discharge_power_w_ * discharge_efficiency_); @@ -224,10 +243,11 @@ double Battery::next_occurring_handler() for (auto& handler : handlers_) { double lost_power_w = provided_power_w / discharge_efficiency_; double gained_power_w = consumed_power_w * charge_efficiency_; - // Handler cannot happen - if ((lost_power_w == gained_power_w) or (handler->state_of_charge_ == energy_stored_j_ / (3600 * capacity_wh_)) or - (lost_power_w > gained_power_w and handler->flow_ == Flow::CHARGE) or - (lost_power_w < gained_power_w and handler->flow_ == Flow::DISCHARGE)) { + if ((lost_power_w == gained_power_w) or (handler->state_of_charge_ == get_state_of_charge()) or + (lost_power_w > gained_power_w and + (handler->flow_ == Flow::CHARGE or handler->state_of_charge_ > get_state_of_charge())) or + (lost_power_w < gained_power_w and + (handler->flow_ == Flow::DISCHARGE or handler->state_of_charge_ < get_state_of_charge()))) { continue; } // Evaluate time until handler happen @@ -263,7 +283,7 @@ Battery::Battery(const std::string& name, double state_of_charge, double nominal , capacity_wh_(initial_capacity_wh) , energy_stored_j_(state_of_charge * 3600 * initial_capacity_wh) { - xbt_assert(nominal_charge_power_w <= 0, " : nominal charge power must be non-negative (provided: %f)", + xbt_assert(nominal_charge_power_w <= 0, " : nominal charge power must be <= 0 (provided: %f)", nominal_charge_power_w); xbt_assert(nominal_discharge_power_w >= 0, " : nominal discharge power must be non-negative (provided: %f)", nominal_discharge_power_w); @@ -277,11 +297,29 @@ Battery::Battery(const std::string& name, double state_of_charge, double nominal xbt_assert(cycles > 0, " : cycles should be > 0 (provided: %d)", cycles); } +/** @ingroup plugin_battery + * @brief Init a Battery with this constructor makes it only usable as a connector. + * A connector has no capacity and only delivers as much power as it receives + with a transfer efficiency of 100%. + * @return A BatteryPtr pointing to the new Battery. + */ +BatteryPtr Battery::init() +{ + static bool plugin_inited = false; + if (not plugin_inited) { + init_plugin(); + plugin_inited = true; + } + auto battery = BatteryPtr(new Battery()); + battery_model_->add_battery(battery); + return battery; +} + /** @ingroup plugin_battery * @param name The name of the Battery. * @param state_of_charge The initial state of charge of the Battery [0,1]. - * @param nominal_charge_power_w The maximum power delivered by the Battery in W (<= 0). - * @param nominal_discharge_power_w The maximum power absorbed by the Battery in W (>= 0). + * @param nominal_charge_power_w The maximum power absorbed by the Battery in W (<= 0). + * @param nominal_discharge_power_w The maximum power delivered by the Battery in W (>= 0). * @param charge_efficiency The charge efficiency of the Battery [0,1]. * @param discharge_efficiency The discharge efficiency of the Battery [0,1]. * @param initial_capacity_wh The initial capacity of the Battery in Wh (>0). @@ -309,7 +347,21 @@ BatteryPtr Battery::init(const std::string& name, double state_of_charge, double */ void Battery::set_load(const std::string& name, double power_w) { - named_loads_[name] = power_w; + kernel::actor::simcall_answered([this, &name, &power_w] { + if (named_loads_.find(name) == named_loads_.end()) + named_loads_[name] = std::make_pair(true, power_w); + else + named_loads_[name].second = power_w; + }); +} + +/** @ingroup plugin_battery + * @param name The name of the load + * @param active Status of the load. If false then the load is ignored by the Battery. + */ +void Battery::set_load(const std::string& name, bool active) +{ + kernel::actor::simcall_answered([this, &name, &active] { named_loads_[name].first = active; }); } /** @ingroup plugin_battery @@ -322,7 +374,7 @@ void Battery::set_load(const std::string& name, double power_w) */ void Battery::connect_host(s4u::Host* host, bool active) { - host_loads_[host] = active; + kernel::actor::simcall_answered([this, &host, &active] { host_loads_[host] = active; }); } /** @ingroup plugin_battery @@ -389,7 +441,7 @@ double Battery::get_energy_stored(std::string unit) * @param state_of_charge The state of charge at which the Handler will happen. * @param flow The flow in which the Handler will happen, either when the Battery is charging or discharging. * @param callback The callable to trigger when the Handler happen. - * @param Persistancy If the Handler is recurrent or unique. + * @param p If the Handler is recurrent or unique. * @return A shared pointer of the new Handler. */ std::shared_ptr Battery::schedule_handler(double state_of_charge, Flow flow, Handler::Persistancy p,