1 /* Copyright (c) 2023. The SimGrid Team. All rights reserved. */
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>
11 #include "src/kernel/resource/CpuImpl.hpp"
12 #include "src/simgrid/module.hpp"
14 SIMGRID_REGISTER_PLUGIN(solar_panel, "Solar Panel management", nullptr)
16 /** @defgroup plugin_solar_panel Plugin Solar Panel
20 This is the solar panel plugin, enabling management of solar panels on hosts.
22 This plugin allows the use of solar panels to generate power during simulation depending on size, solar
23 irradiance and conversion factor.
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
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:
37 P = A \times \eta \times S
42 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(SolarPanel, kernel, "Logging specific to the solar panel plugin");
44 namespace simgrid::plugins {
48 SolarPanelModel::SolarPanelModel() : Model("SolarPanelModel") {}
50 void SolarPanelModel::add_solar_panel(SolarPanelPtr b)
52 solar_panels_.push_back(b);
55 void SolarPanelModel::update_actions_state(double now, double delta)
57 for (auto solar_panel : solar_panels_)
58 solar_panel->update();
61 double SolarPanelModel::next_occurring_event(double now)
68 std::shared_ptr<SolarPanelModel> SolarPanel::solar_panel_model_;
70 void SolarPanel::init_plugin()
72 auto model = std::make_shared<SolarPanelModel>();
73 simgrid::s4u::Engine::get_instance()->add_model(model);
74 SolarPanel::solar_panel_model_ = model;
77 void SolarPanel::update()
79 simgrid::kernel::actor::simcall_answered([this] {
80 double now = simgrid::s4u::Engine::get_clock();
81 if (now <= last_updated_)
83 double power_w = conversion_efficiency_ * area_m2_ * solar_irradiance_w_per_m2_;
84 if (power_w_ < min_power_w_)
86 if (power_w_ > max_power_w_)
87 power_w = max_power_w_;
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)
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)
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,
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.
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)
125 static bool plugin_inited = false;
126 if (not plugin_inited) {
128 plugin_inited = true;
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);
136 /** @ingroup plugin_solar_panel
137 * @param name The new name of the Solar Panel.
138 * @return A SolarPanelPtr pointing to the modified SolarPanel.
140 SolarPanelPtr SolarPanel::set_name(std::string name)
142 kernel::actor::simcall_answered([this, name] { name_ = name; });
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.
150 SolarPanelPtr SolarPanel::set_area(double area_m2)
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; });
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.
161 SolarPanelPtr SolarPanel::set_conversion_efficiency(double e)
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; });
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.
172 SolarPanelPtr SolarPanel::set_solar_irradiance(double solar_irradiance_w_per_m2)
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; });
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.
185 SolarPanelPtr SolarPanel::set_min_power(double power_w)
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,
190 kernel::actor::simcall_answered([this, power_w] { min_power_w_ = power_w; });
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.
198 SolarPanelPtr SolarPanel::set_max_power(double power_w)
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,
203 kernel::actor::simcall_answered([this, power_w] { max_power_w_ = power_w; });
207 } // namespace simgrid::plugins