Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
8e44734b82d5e948217e8748f082c3898e28c79f
[simgrid.git] / src / plugins / solar_panel.cpp
1 /* Copyright (c) 2023. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5 #include <simgrid/Exception.hpp>
6 #include <simgrid/plugins/solar_panel.hpp>
7 #include <simgrid/simix.hpp>
8 #include <xbt/asserts.h>
9 #include <xbt/log.h>
10
11 #include "src/kernel/resource/CpuImpl.hpp"
12 #include "src/simgrid/module.hpp"
13
14 SIMGRID_REGISTER_PLUGIN(solar_panel, "Solar Panel management", nullptr)
15
16 /** @defgroup plugin_solar_panel Plugin Solar Panel
17
18   @beginrst
19
20 This is the solar panel plugin, enabling management of solar panels on hosts.
21
22 This plugin allows the use of solar panels to generate power during simulation depending on size, solar
23 irradiance and conversion factor.
24
25 The power model is taken from the paper `"Reinforcement Learning Based Load Balancing for
26 Geographically Distributed Data Centres" <https://dro.dur.ac.uk/33395/1/33395.pdf?DDD280+kkgc95+vbdv77>`_ by Max Mackie
27 et. al.
28
29 Solar Panel
30 ....................
31
32 A solar panel has an area :math:`A` in m², a conversion efficiency :math:`\eta` and a solar irradiance :math:`S` in
33 W/m². The power generated :math:`P` in W by a solar panel is given by the following equation:
34
35 .. math::
36
37   P = A \times \eta \times S
38
39   @endrst
40  */
41
42 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(SolarPanel, kernel, "Logging specific to the solar panel plugin");
43
44 namespace simgrid::plugins {
45
46 /* SolarPanelModel */
47
48 SolarPanelModel::SolarPanelModel() : Model("SolarPanelModel") {}
49
50 void SolarPanelModel::add_solar_panel(SolarPanelPtr b)
51 {
52   solar_panels_.push_back(b);
53 }
54
55 void SolarPanelModel::update_actions_state(double now, double delta)
56 {
57   for (auto solar_panel : solar_panels_)
58     solar_panel->update();
59 }
60
61 double SolarPanelModel::next_occurring_event(double now)
62 {
63   return -1;
64 }
65
66 /* SolarPanel */
67
68 std::shared_ptr<SolarPanelModel> SolarPanel::solar_panel_model_;
69
70 void SolarPanel::init_plugin()
71 {
72   auto model = std::make_shared<SolarPanelModel>();
73   simgrid::s4u::Engine::get_instance()->add_model(model);
74   SolarPanel::solar_panel_model_ = model;
75 }
76
77 void SolarPanel::update()
78 {
79   simgrid::kernel::actor::simcall_answered([this] {
80     double now = simgrid::s4u::Engine::get_clock();
81     if (now <= last_updated_)
82       return;
83     double power_w = conversion_efficiency_ * area_m2_ * solar_irradiance_w_per_m2_;
84     if (power_w_ < min_power_w_)
85       power_w = 0;
86     if (power_w_ > max_power_w_)
87       power_w = max_power_w_;
88     power_w_      = power_w;
89     last_updated_ = now;
90   });
91 }
92
93 SolarPanel::SolarPanel(std::string name, double area_m2, double conversion_efficiency, double solar_irradiance_w_per_m2,
94                        double min_power_w, double max_power_w)
95     : name_(name)
96     , area_m2_(area_m2)
97     , conversion_efficiency_(conversion_efficiency)
98     , solar_irradiance_w_per_m2_(solar_irradiance_w_per_m2)
99     , min_power_w_(min_power_w)
100     , max_power_w_(max_power_w)
101 {
102   xbt_assert(area_m2 >= 0, " : area must be >= 0 (provided: %f)", area_m2);
103   xbt_assert(conversion_efficiency >= 0 and conversion_efficiency <= 1,
104              " : conversion efficiency must be in [0,1] (provided: %f)", conversion_efficiency);
105   xbt_assert(solar_irradiance_w_per_m2 >= 0, " : solar irradiance must be >= 0 (provided: %f)",
106              solar_irradiance_w_per_m2);
107   xbt_assert(min_power_w >= 0, " : minimal power must be >= 0 (provided: %f)", min_power_w);
108   xbt_assert(max_power_w > 0, " : maximal power must be > 0 (provided: %f)", max_power_w);
109   xbt_assert(max_power_w > min_power_w, " : maximal power must be above minimal power (provided: %f, %f)", max_power_w,
110              min_power_w);
111 }
112
113 /** @ingroup plugin_solar_panel
114  *  @param name The name of the Solar Panel.
115  *  @param area_m2 The area of the Solar Panel in m² (> 0).
116  *  @param conversion_efficiency The conversion efficiency of the Solar Panel [0,1].
117  *  @param solar_irradiance_w_per_m2 The solar irradiance of the Solar Panel in W/m² (> 0).
118  *  @param min_power_w The minimal power delivered by the Solar Panel in W (> 0 and < max_power_w).
119  *  @param max_power_w The maximal power delivered by the Solar Panel in W (> 0 and > min_power_w).
120  *  @return A SolarPanelPtr pointing to the new SolarPanel.
121  */
122 SolarPanelPtr SolarPanel::init(const std::string& name, double area_m2, double conversion_efficiency,
123                                double solar_irradiance_w_per_m2, double min_power_w, double max_power_w)
124 {
125   static bool plugin_inited = false;
126   if (not plugin_inited) {
127     init_plugin();
128     plugin_inited = true;
129   }
130   auto solar_panel = SolarPanelPtr(
131       new SolarPanel(name, area_m2, conversion_efficiency, solar_irradiance_w_per_m2, min_power_w, max_power_w));
132   solar_panel_model_->add_solar_panel(solar_panel);
133   return solar_panel;
134 }
135
136 /** @ingroup plugin_solar_panel
137  *  @param name The new name of the Solar Panel.
138  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
139  */
140 SolarPanelPtr SolarPanel::set_name(std::string name)
141 {
142   kernel::actor::simcall_answered([this, name] { name_ = name; });
143   return this;
144 }
145
146 /** @ingroup plugin_solar_panel
147  *  @param area_m2 The new area of the Solar Panel in m².
148  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
149  */
150 SolarPanelPtr SolarPanel::set_area(double area_m2)
151 {
152   xbt_assert(area_m2 >= 0, " : area must be > 0 (provided: %f)", area_m2);
153   kernel::actor::simcall_answered([this, area_m2] { area_m2_ = area_m2; });
154   return this;
155 }
156
157 /** @ingroup plugin_solar_panel
158  *  @param e The new convesion efficiency of the Solar Panel.
159  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
160  */
161 SolarPanelPtr SolarPanel::set_conversion_efficiency(double e)
162 {
163   xbt_assert(e >= 0 and e <= 1, " : conversion efficiency must be in [0,1] (provided: %f)", e);
164   kernel::actor::simcall_answered([this, e] { conversion_efficiency_ = e; });
165   return this;
166 }
167
168 /** @ingroup plugin_solar_panel
169  *  @param solar_irradiance_w_per_m2 The new solar irradiance of the Solar Panel in W/m².
170  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
171  */
172 SolarPanelPtr SolarPanel::set_solar_irradiance(double solar_irradiance_w_per_m2)
173 {
174   xbt_assert(solar_irradiance_w_per_m2 >= 0, " : solar irradiance must be >= 0 (provided: %f)",
175              solar_irradiance_w_per_m2);
176   kernel::actor::simcall_answered(
177       [this, solar_irradiance_w_per_m2] { solar_irradiance_w_per_m2_ = solar_irradiance_w_per_m2; });
178   return this;
179 }
180
181 /** @ingroup plugin_solar_panel
182  *  @param power_w The new minimal power of the Solar Panel in W.
183  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
184  */
185 SolarPanelPtr SolarPanel::set_min_power(double power_w)
186 {
187   xbt_assert(power_w >= 0, " : minimal power must be >= 0 (provided: %f)", power_w);
188   xbt_assert(max_power_w_ > power_w, " : maximal power must be above minimal power (provided: %f, max: %f)", power_w,
189              max_power_w_);
190   kernel::actor::simcall_answered([this, power_w] { min_power_w_ = power_w; });
191   return this;
192 }
193
194 /** @ingroup plugin_solar_panel
195  *  @param power_w The new maximal power of the Solar Panel in W.
196  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
197  */
198 SolarPanelPtr SolarPanel::set_max_power(double power_w)
199 {
200   xbt_assert(power_w > 0, " : maximal power must be > 0 (provided: %f)", power_w);
201   xbt_assert(min_power_w_ < power_w, " : maximal power must be above minimal power (provided: %f, min: %f)", power_w,
202              min_power_w_);
203   kernel::actor::simcall_answered([this, power_w] { max_power_w_ = power_w; });
204   return this;
205 }
206
207 } // namespace simgrid::plugins