Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
photovoltaic plugin revamp, now called solar panel
[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
15 SIMGRID_REGISTER_PLUGIN(solar_panel, "Solar Panel management", nullptr)
16
17 /** @defgroup plugin_solar_panel Plugin Solar Panel
18
19   @beginrst
20
21 This is the solar panel plugin, enabling management of solar panels on hosts.
22
23 This plugin allows the use of solar panels to generate power during simulation depending on size, solar
24 irradiance and conversion factor.
25
26 The power model is taken from the paper `"Reinforcement Learning Based Load Balancing for
27 Geographically Distributed Data Centres" <https://dro.dur.ac.uk/33395/1/33395.pdf?DDD280+kkgc95+vbdv77>`_ by Max Mackie 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 W/m². 
33 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, double min_power_w, double max_power_w)
94     : name_(name)
95     , area_m2_(area_m2)
96     , conversion_efficiency_(conversion_efficiency)
97     , solar_irradiance_w_per_m2_(solar_irradiance_w_per_m2)
98     , min_power_w_(min_power_w)
99     , max_power_w_(max_power_w)
100 {
101   xbt_assert(area_m2 >= 0, " : area must be >= 0 (provided: %f)", area_m2);
102   xbt_assert(conversion_efficiency >= 0 and conversion_efficiency <= 1, " : conversion efficiency must be in [0,1] (provided: %f)", conversion_efficiency);
103   xbt_assert(solar_irradiance_w_per_m2 >= 0, " : solar irradiance must be >= 0 (provided: %f)", solar_irradiance_w_per_m2);
104   xbt_assert(min_power_w >= 0, " : minimal power must be >= 0 (provided: %f)", min_power_w);
105   xbt_assert(max_power_w > 0, " : maximal power must be > 0 (provided: %f)", max_power_w);
106   xbt_assert(max_power_w > min_power_w, " : maximal power must be above minimal power (provided: %f, %f)", max_power_w, min_power_w);
107 }
108
109 /** @ingroup plugin_solar_panel
110  *  @param name The name of the Solar Panel.
111  *  @param area_m2 The area of the Solar Panel in m² (> 0).
112  *  @param conversion_efficiency The conversion efficiency of the Solar Panel [0,1].
113  *  @param solar_irradiance_w_per_m2 The solar irradiance of the Solar Panel in W/m² (> 0).
114  *  @param min_power_w The minimal power delivered by the Solar Panel in W (> 0 and < max_power_w).
115  *  @param max_power_w The maximal power delivered by the Solar Panel in W (> 0 and > min_power_w).
116  *  @return A SolarPanelPtr pointing to the new SolarPanel.
117  */
118 SolarPanelPtr SolarPanel::init(const std::string& name, double area_m2, double conversion_efficiency, double solar_irradiance_w_per_m2, double min_power_w, double max_power_w)
119 {
120   static bool plugin_inited = false;
121   if (not plugin_inited) {
122     init_plugin();
123     plugin_inited = true;
124   }
125   auto solar_panel = SolarPanelPtr(new SolarPanel(name, area_m2, conversion_efficiency, solar_irradiance_w_per_m2, min_power_w, max_power_w));
126   solar_panel_model_->add_solar_panel(solar_panel);
127   return solar_panel;
128 }
129
130 /** @ingroup plugin_solar_panel
131  *  @param name The new name of the Solar Panel.
132  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
133  */
134 SolarPanelPtr SolarPanel::set_name(std::string name)
135 {
136   kernel::actor::simcall_answered([this, name] {name_ = name;});
137   return this;
138 }
139
140 /** @ingroup plugin_solar_panel
141  *  @param area_m2 The new area of the Solar Panel in m².
142  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
143  */
144 SolarPanelPtr SolarPanel::set_area(double area_m2)
145 {
146   xbt_assert(area_m2 >= 0, " : area must be > 0 (provided: %f)", area_m2);
147   kernel::actor::simcall_answered([this, area_m2] {area_m2_ = area_m2;});
148   return this;
149 }
150
151 /** @ingroup plugin_solar_panel
152  *  @param e The new convesion efficiency of the Solar Panel.
153  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
154  */
155 SolarPanelPtr SolarPanel::set_conversion_efficiency(double e)
156 {
157   xbt_assert(e >= 0 and e <= 1, " : conversion efficiency must be in [0,1] (provided: %f)", e);
158   kernel::actor::simcall_answered([this, e] {conversion_efficiency_ = e;});
159   return this;
160 }
161
162 /** @ingroup plugin_solar_panel
163  *  @param solar_irradiance_w_per_m2 The new solar irradiance of the Solar Panel in W/m².
164  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
165  */
166 SolarPanelPtr SolarPanel::set_solar_irradiance(double solar_irradiance_w_per_m2)
167 {
168   xbt_assert(solar_irradiance_w_per_m2 >= 0, " : solar irradiance must be >= 0 (provided: %f)", solar_irradiance_w_per_m2);
169   kernel::actor::simcall_answered([this, solar_irradiance_w_per_m2] {solar_irradiance_w_per_m2_ = solar_irradiance_w_per_m2;});
170   return this;
171 }
172
173 /** @ingroup plugin_solar_panel
174  *  @param power_w The new minimal power of the Solar Panel in W.
175  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
176  */
177 SolarPanelPtr SolarPanel::set_min_power(double power_w)
178 {
179   xbt_assert(power_w >= 0, " : minimal power must be >= 0 (provided: %f)", power_w);
180   xbt_assert(max_power_w_ > power_w, " : maximal power must be above minimal power (provided: %f, max: %f)", power_w, max_power_w_);
181   kernel::actor::simcall_answered([this, power_w] {min_power_w_ = power_w;});
182   return this;
183 }
184
185 /** @ingroup plugin_solar_panel
186  *  @param power_w The new maximal power of the Solar Panel in W.
187  *  @return A SolarPanelPtr pointing to the modified SolarPanel.
188  */
189 SolarPanelPtr SolarPanel::set_max_power(double power_w)
190 {
191   xbt_assert(power_w > 0, " : maximal power must be > 0 (provided: %f)", power_w);
192   xbt_assert(min_power_w_ < power_w, " : maximal power must be above minimal power (provided: %f, min: %f)", power_w, min_power_w_);
193   kernel::actor::simcall_answered([this, power_w] {max_power_w_ = power_w;});
194   return this;
195 }
196
197 } // namespace simgrid::plugins