1 #include <simgrid/Exception.hpp>
2 #include <simgrid/plugins/photovoltaic.hpp>
3 #include <simgrid/s4u/Actor.hpp>
4 #include <simgrid/s4u/Engine.hpp>
5 #include <simgrid/s4u/Host.hpp>
6 #include <simgrid/s4u/VirtualMachine.hpp>
7 #include <simgrid/simix.hpp>
9 #include "src/kernel/resource/CpuImpl.hpp"
10 #include "src/simgrid/module.hpp"
12 #include <boost/algorithm/string/classification.hpp>
13 #include <boost/algorithm/string/split.hpp>
15 SIMGRID_REGISTER_PLUGIN(photovoltaic, "Photovoltaic management", &sg_photovoltaic_plugin_init)
17 /** @defgroup plugin_photovoltaic plugin_photovoltaic Plugin photovoltaic
21 This is the photovoltaic plugin, enabling management of photovoltaic panels on hosts.
22 To activate this plugin, first call :cpp:func:`sg_photovoltaic_plugin_init()`.
24 This plugin allows evaluation of photovoltaic panels power generation during simulation depending on size, solar
25 irradiance and conversion factor.
27 Photovoltaic Panel properties
30 Properties of panels are defined as properties of hosts in the platform XML file.
32 Here is an example of XML declaration where we consider a host as a photovoltaic panel:
36 <host id="pv_panel" speed="0f">
37 <prop id="photovoltaic_area" value="4" />
38 <prop id="photovoltaic_conversion_efficiency" value="0.2" />
41 The different properties are:
43 - ``photovoltaic_area``: Set the area of the panel in m² (default=0)
44 - ``photovoltaic_conversion_efficiency``: Set the conversion efficiency of the panel (default=0)
45 - ``photovoltaic_solar_irradiance``: Set the initial solar irradiance in W/m² (default=0)
46 - ``photovoltaic_min_power``: Set the minimum power of the panel in W (default=-1). Power generation below this value is automatically 0. Value is ignored if negative
47 - ``photovoltaic_max_power``: Set the maximal power of the panel in W (default=-1). Power generation above this value is automatically truncated. Value is ignored if negative
48 - ``photovoltaic_eval_cost``: Evaluate the cost of the panel during the simulation if set to 1 (defaulf=0)
49 - ``photovoltaic_lifespan``: Set the lifespan of the panel in years (default=0)
50 - ``photovoltaic_investment_cost``: Set the investment cost of the panel (default=0)
51 - ``photovoltaic_maintenance_cost``: Set the maintenance cost of the panel (default=0)
56 /*These equations are taken from the paper "Reinforcement Learning Based Load Balancing for
57 Geographically Distributed Data Centres" of Max Mackie et. al
58 https://dro.dur.ac.uk/33395/1/33395.pdf?DDD280+kkgc95+vbdv77
61 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(photovoltaic, kernel, "Logging specific to the photovoltaic plugin");
63 namespace simgrid::plugin {
66 simgrid::s4u::Host* host_ = nullptr;
69 double conversion_efficiency_ = 0;
70 double solar_irradiance_w_per_m2_ = 0;
71 double min_power_w_ = -1;
72 double max_power_w_ = -1;
75 double last_updated_ = 0;
77 // Calculation of costs from Bei Li thesis (link :https://tel.archives-ouvertes.fr/tel-02077668/document) (chapter 4)
78 bool eval_cost_ = false;
79 double cumulative_cost_ = 0;
80 int lifespan_years_ = 0;
81 double investment_cost_per_w_ = 0;
82 double maintenance_cost_per_wh_ = 0;
84 void init_photovoltaic_params();
85 void init_cost_params();
88 Photovoltaic* set_area(double a);
89 Photovoltaic* set_conversion_efficiency(double e);
90 Photovoltaic* set_min_power(double p);
91 Photovoltaic* set_max_power(double p);
92 Photovoltaic* set_eval_cost(bool eval);
93 Photovoltaic* set_lifespan(int l);
94 Photovoltaic* set_investment_cost(double c);
95 Photovoltaic* set_maintenance_cost(double c);
98 static simgrid::xbt::Extension<simgrid::s4u::Host, Photovoltaic> EXTENSION_ID;
100 explicit Photovoltaic(simgrid::s4u::Host* host);
103 Photovoltaic* set_solar_irradiance(double s);
108 Photovoltaic* Photovoltaic::set_area(double a)
110 xbt_assert(a > 0, " : area should be > 0 (provided: %f)", a);
111 simgrid::kernel::actor::simcall_answered([this, a] { area_m2_ = a; });
115 Photovoltaic* Photovoltaic::set_conversion_efficiency(double e)
117 xbt_assert(e > 0 and e <= 1, " : conversion efficiency should be in [0,1] (provided: %f)", e);
118 simgrid::kernel::actor::simcall_answered([this, e] { conversion_efficiency_ = e; });
122 Photovoltaic* Photovoltaic::set_solar_irradiance(double s)
124 xbt_assert(s > 0, " : solar irradiance should be > 0 (provided: %f)", s);
125 simgrid::kernel::actor::simcall_answered([this, s] { solar_irradiance_w_per_m2_ = s; });
129 Photovoltaic* Photovoltaic::set_min_power(double p)
131 simgrid::kernel::actor::simcall_answered([this, p] { min_power_w_ = p; });
135 Photovoltaic* Photovoltaic::set_max_power(double p)
137 simgrid::kernel::actor::simcall_answered([this, p] { max_power_w_ = p; });
141 Photovoltaic* Photovoltaic::set_eval_cost(bool e)
143 simgrid::kernel::actor::simcall_answered([this, e] { eval_cost_ = e; });
147 Photovoltaic* Photovoltaic::set_lifespan(int l)
149 xbt_assert(l > 0, " : lifespan should be > 0 (provided: %d)", l);
150 simgrid::kernel::actor::simcall_answered([this, l] { lifespan_years_ = l; });
154 Photovoltaic* Photovoltaic::set_investment_cost(double c)
156 xbt_assert(c > 0, " : investment cost should be > 0 (provided: %f)", c);
157 simgrid::kernel::actor::simcall_answered([this, c] { investment_cost_per_w_ = c; });
161 Photovoltaic* Photovoltaic::set_maintenance_cost(double c)
163 xbt_assert(c > 0, " : maintenance cost hould be > 0 (provided: %f)", c);
164 simgrid::kernel::actor::simcall_answered([this, c] { maintenance_cost_per_wh_ = c; });
168 double Photovoltaic::get_power()
174 simgrid::xbt::Extension<simgrid::s4u::Host, Photovoltaic> Photovoltaic::EXTENSION_ID;
176 void Photovoltaic::init_photovoltaic_params()
178 const char* prop_chars;
179 prop_chars = host_->get_property("photovoltaic_area");
181 set_area(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
182 prop_chars = host_->get_property("photovoltaic_conversion_efficiency");
184 set_conversion_efficiency(
185 xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
186 prop_chars = host_->get_property("photovoltaic_solar_irradiance");
188 set_solar_irradiance(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
189 prop_chars = host_->get_property("photovoltaic_min_power");
191 set_min_power(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
192 prop_chars = host_->get_property("photovoltaic_max_power");
194 set_max_power(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
195 prop_chars = host_->get_property("photovoltaic_eval_cost");
197 set_eval_cost(xbt_str_parse_int(prop_chars, ("cannot parse int: " + std::string(prop_chars)).c_str()));
198 prop_chars = host_->get_property("photovoltaic_lifespan");
200 set_lifespan(xbt_str_parse_int(prop_chars, ("cannot parse int: " + std::string(prop_chars)).c_str()));
201 prop_chars = host_->get_property("photovoltaic_investment_cost");
203 set_investment_cost(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
204 prop_chars = host_->get_property("photovoltaic_maintenance_cost");
206 set_maintenance_cost(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
207 simgrid::kernel::actor::simcall_answered([this] { last_updated_ = simgrid::s4u::Engine::get_clock(); });
210 void Photovoltaic::update()
212 simgrid::kernel::actor::simcall_answered([this] {
213 double now = simgrid::s4u::Engine::get_clock();
214 if (now <= last_updated_)
216 double power_w = conversion_efficiency_ * area_m2_ * solar_irradiance_w_per_m2_;
217 if (min_power_w_ > 0 and power_w_ < min_power_w_)
219 if (max_power_w_ > 0 and power_w_ > max_power_w_)
220 power_w = max_power_w_;
223 xbt_assert(max_power_w_ > 0, " : max power must be > 0 (provided: %f)", max_power_w_);
224 cumulative_cost_ += max_power_w_ * (now - last_updated_) *
225 (investment_cost_per_w_ / (lifespan_years_ * 8760 * 3600) + maintenance_cost_per_wh_ / 3600);
231 Photovoltaic::Photovoltaic(simgrid::s4u::Host* host) : host_(host)
233 init_photovoltaic_params();
236 Photovoltaic::~Photovoltaic() = default;
237 } // namespace simgrid::plugin
239 using simgrid::plugin::Photovoltaic;
241 /* **************************** events callback *************************** */
243 static void on_creation(simgrid::s4u::Host& host)
245 if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
247 host.extension_set(new Photovoltaic(&host));
250 /* **************************** Public interface *************************** */
252 static void ensure_plugin_inited()
254 if (not Photovoltaic::EXTENSION_ID.valid())
255 throw simgrid::xbt::InitializationError(
256 "The Photovoltaic plugin is not active. Please call sg_photovoltaic_plugin_init() "
257 "before calling any function related to that plugin.");
260 /** @ingroup plugin_photovoltaic
261 * @brief Enable photovoltaic plugin.
263 void sg_photovoltaic_plugin_init()
265 if (Photovoltaic::EXTENSION_ID.valid())
267 Photovoltaic::EXTENSION_ID = simgrid::s4u::Host::extension_create<Photovoltaic>();
268 simgrid::s4u::Host::on_creation_cb(&on_creation);
271 /** @ingroup plugin_photovoltaic
272 * @param s The solar irradiance to set in W/m².
274 void sg_photovoltaic_set_solar_irradiance(const_sg_host_t host, double s)
276 ensure_plugin_inited();
277 host->extension<Photovoltaic>()->set_solar_irradiance(s);
280 /** @ingroup plugin_photovoltaic
281 * @return Power generation in W.
283 double sg_photovoltaic_get_power(const_sg_host_t host)
285 ensure_plugin_inited();
286 return host->extension<Photovoltaic>()->get_power();