Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
photovoltaic plugin revamp, now called solar panel
authorAdrien Gougeon <adrien.gougeon@ens-rennes.fr>
Thu, 14 Sep 2023 14:40:14 +0000 (16:40 +0200)
committerAdrien Gougeon <adrien.gougeon@ens-rennes.fr>
Thu, 14 Sep 2023 14:40:14 +0000 (16:40 +0200)
15 files changed:
ChangeLog
MANIFEST.in
docs/source/Plugins.rst
docs/source/Release_Notes.rst
examples/cpp/CMakeLists.txt
examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.cpp [deleted file]
examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.tesh [deleted file]
examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp [new file with mode: 0644]
examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh [new file with mode: 0644]
examples/platforms/photovoltaic_platform.xml [deleted file]
include/simgrid/plugins/photovoltaic.hpp [deleted file]
include/simgrid/plugins/solar_panel.hpp [new file with mode: 0644]
src/plugins/photovoltaic.cpp [deleted file]
src/plugins/solar_panel.cpp [new file with mode: 0644]
tools/cmake/DefinePackages.cmake

index 43e5acd..486acd8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -70,10 +70,10 @@ S4U:
    That is, callbacks registered in Exec::on_suspend_cb will not be fired for Comms nor Ios.
 
 New S4U plugins:
- - Battery: Enable the management of batteries on hosts.
+ - Battery: Enable the management of batteries.
    See the examples under examples/cpp/battery-* and the documentation in the Plugins page.
- - Photovoltaic: Enable the management of photovoltaic panels on hosts.
-   See the examples under examples/cpp/photovoltaic-* and the documentation in the Plugins page.
+ - SolarPanel: Enable the management of solar panels.
+   See the examples under examples/cpp/solar-panel-* and the documentation in the Plugins page.
 
 Kernel:
  - optimize an internal data structure (use a set instead of a list for ongoing activities),
index e0c96c2..493259a 100644 (file)
@@ -346,8 +346,8 @@ include examples/cpp/network-ns3/s4u-network-ns3-timed.tesh
 include examples/cpp/network-ns3/s4u-network-ns3.cpp
 include examples/cpp/network-wifi/s4u-network-wifi.cpp
 include examples/cpp/network-wifi/s4u-network-wifi.tesh
-include examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.cpp
-include examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.tesh
+include examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp
+include examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh
 include examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.cpp
 include examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.tesh
 include examples/cpp/platform-failures/s4u-platform-failures.cpp
@@ -1841,7 +1841,6 @@ include examples/platforms/onelink.xml
 include examples/platforms/optorsim/gridpp_grid_2004.conf
 include examples/platforms/optorsim/lcg_sept2004_grid.conf
 include examples/platforms/optorsim/transform_optorsim_platform.pl
-include examples/platforms/photovoltaic_platform.xml
 include examples/platforms/profiles/fafard_state.profile
 include examples/platforms/profiles/faulty_host.profile
 include examples/platforms/profiles/ginette_state.profile
@@ -1943,7 +1942,7 @@ include include/simgrid/plugins/jbod.hpp
 include include/simgrid/plugins/live_migration.h
 include include/simgrid/plugins/load.h
 include include/simgrid/plugins/ns3.hpp
-include include/simgrid/plugins/photovoltaic.hpp
+include include/simgrid/plugins/solar_panel.hpp
 include include/simgrid/s4u.hpp
 include include/simgrid/s4u/Activity.hpp
 include include/simgrid/s4u/ActivitySet.hpp
@@ -2320,7 +2319,7 @@ include src/plugins/jbod.cpp
 include src/plugins/link_energy.cpp
 include src/plugins/link_energy_wifi.cpp
 include src/plugins/link_load.cpp
-include src/plugins/photovoltaic.cpp
+include src/plugins/solar_panel.cpp
 include src/plugins/vm/VmLiveMigration.cpp
 include src/plugins/vm/VmLiveMigration.hpp
 include src/plugins/vm/dirty_page_tracking.cpp
index 46b6c01..003b81f 100644 (file)
@@ -24,7 +24,7 @@ documents some of the plugins distributed with SimGrid:
   - :ref:`Link Energy <plugin_link_energy>`: models the energy dissipation of the network.
   - :ref:`WiFi Energy <plugin_link_energy_wifi>`: models the energy dissipation of wifi links.
   - :ref:`Battery <plugin_battery>`: models batteries that get discharged by the energy consumption of a given host.
-  - :ref:`Photovoltaic <plugin_photovoltaic>`: models photovoltaic panels which energy production depends on the solar irradiance.
+  - :ref:`Solar Panel <plugin_solar_panel>`: models solar panels which energy production depends on the solar irradiance.
 
 You can activate these plugins with the :ref:`--cfg=plugin <cfg=plugin>` command
 line option, for example with ``--cfg=plugin:host_energy``. You can get the full
@@ -224,11 +224,11 @@ Battery
 
 .. doxygengroup:: plugin_battery
 
-.. _plugin_photovoltaic:
+.. _plugin_solar_panel:
 
-Photovoltaic
+Solar Panel
 ===========
 
-.. doxygengroup:: plugin_photovoltaic
+.. doxygengroup:: plugin_solar_panel
 
 ..  LocalWords:  SimGrid
index 80cad37..55b0d5a 100644 (file)
@@ -627,8 +627,8 @@ completion) are now specialized by activity class. That is, callbacks registered
 Comms nor Ios
 
 Two new useful plugins were added: The :ref:`battery plugin<plugin_battery>` can be used to create batteries that get discharged
-by the energy consumption of a given host, while the :ref:`photovoltaic plugin <plugin_photovoltaic>` can be used to create
-photovoltaic panels which energy production depends on the solar irradiance. These plugins could probably be better integrated
+by the energy consumption of a given host, while the :ref:`solar panel plugin <plugin_solar_panel>` can be used to create
+solar panels which energy production depends on the solar irradiance. These plugins could probably be better integrated
 in the framework, but our goal is to include in SimGrid the building blocks upon which everybody would agree, while the model
 elements that are more arguable are provided as plugins, in the hope that the users will carefully assess the plugins and adapt
 them to their specific needs before usage. Here for example, there is several models of batteries (the one provided does not
index 72e060f..4907fdf 100644 (file)
@@ -172,7 +172,7 @@ foreach (example activityset-testany activityset-waitany activityset-waitall act
                  network-ns3 network-ns3-wifi network-wifi
                  io-async io-priority io-degradation io-file-system io-file-remote io-disk-raw io-dependent
                  task-io task-simple task-variable-load task-storm task-switch-host
-                 photovoltaic-simple
+                 solar-panel-simple
                  platform-comm-serialize platform-failures platform-profile platform-properties
                  plugin-host-load plugin-jbod plugin-link-load plugin-prodcons
                  replay-comm replay-io
diff --git a/examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.cpp b/examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.cpp
deleted file mode 100644 (file)
index afb65f0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved.          */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include "simgrid/plugins/photovoltaic.hpp"
-#include "simgrid/s4u.hpp"
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(photovoltaic_simple, "Messages specific for this s4u example");
-
-static void manager()
-{
-  const auto* pv_panel = simgrid::s4u::Engine::get_instance()->host_by_name("pv_panel");
-  std::vector<std::pair<double, double>> solar_irradiance = {{1, 10}, {100, 5}, {200, 20}};
-  for (auto [t, s] : solar_irradiance) {
-    simgrid::s4u::this_actor::sleep_until(t);
-    sg_photovoltaic_set_solar_irradiance(pv_panel, s);
-    XBT_INFO("%s power: %f", pv_panel->get_cname(), sg_photovoltaic_get_power(pv_panel));
-  }
-}
-
-int main(int argc, char* argv[])
-{
-  simgrid::s4u::Engine e(&argc, argv);
-  e.load_platform(argv[1]);
-  sg_photovoltaic_plugin_init();
-  simgrid::s4u::Actor::create("manager", e.host_by_name("pv_panel"), manager);
-  e.run();
-  return 0;
-}
diff --git a/examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.tesh b/examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.tesh
deleted file mode 100644 (file)
index 1146cc8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env tesh
-
-$ ${bindir:=.}/s4u-photovoltaic-simple ${platfdir}/photovoltaic_platform.xml
-> [pv_panel:manager:(1) 1.000000] [photovoltaic_simple/INFO] pv_panel power: 8.000000
-> [pv_panel:manager:(1) 100.000000] [photovoltaic_simple/INFO] pv_panel power: 4.000000
-> [pv_panel:manager:(1) 200.000000] [photovoltaic_simple/INFO] pv_panel power: 16.000000
diff --git a/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp b/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp
new file mode 100644 (file)
index 0000000..5f68a54
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "simgrid/plugins/photovoltaic.hpp"
+#include "simgrid/s4u.hpp"
+#include "simgrid/plugins/solar_panel.hpp"
+#include <simgrid/s4u/Actor.hpp>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(solar_panel_simple, "Messages specific for this s4u example");
+
+static void manager()
+{
+  auto solar_panel = simgrid::plugins::SolarPanel::init("Solar Panel", 10, 0.9, 10, 0, 1e3);
+  simgrid::s4u::this_actor::sleep_for(1);
+  XBT_INFO("%s: area: %fm² efficiency: %f irradiance: %fW/m² power: %fW", solar_panel->get_cname(), solar_panel->get_area(), solar_panel->get_conversion_efficiency(), solar_panel->get_solar_irradiance(), solar_panel->get_power());
+  
+  solar_panel->set_area(20);
+  simgrid::s4u::this_actor::sleep_for(1);
+  XBT_INFO("%s: area: %fm² efficiency: %f irradiance: %fW/m² power: %fW", solar_panel->get_cname(), solar_panel->get_area(), solar_panel->get_conversion_efficiency(), solar_panel->get_solar_irradiance(), solar_panel->get_power());
+
+  solar_panel->set_conversion_efficiency(0.8);
+  simgrid::s4u::this_actor::sleep_for(1);
+  XBT_INFO("%s: area: %fm² efficiency: %f irradiance: %fW/m² power: %fW", solar_panel->get_cname(), solar_panel->get_area(), solar_panel->get_conversion_efficiency(), solar_panel->get_solar_irradiance(), solar_panel->get_power());
+
+  solar_panel->set_solar_irradiance(20);
+  simgrid::s4u::this_actor::sleep_for(1);
+  XBT_INFO("%s: area: %fm² efficiency: %f irradiance: %fW/m² power: %fW", solar_panel->get_cname(), solar_panel->get_area(), solar_panel->get_conversion_efficiency(), solar_panel->get_solar_irradiance(), solar_panel->get_power());
+}
+
+int main(int argc, char* argv[])
+{
+  simgrid::s4u::Engine e(&argc, argv);
+  e.load_platform(argv[1]);
+  simgrid::s4u::Actor::create("manager", e.host_by_name("Tremblay"), manager);
+  e.run();
+  return 0;
+}
diff --git a/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh b/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh
new file mode 100644 (file)
index 0000000..53b64dc
--- /dev/null
@@ -0,0 +1,7 @@
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-solar-panel-simple ${platfdir}/small_platform.xml
+> [Tremblay:manager:(1) 1.000000] [solar_panel_simple/INFO] Solar Panel: area: 10.000000m² efficiency: 0.900000 irradiance: 10.000000W/m² power: 90.000000W
+> [Tremblay:manager:(1) 2.000000] [solar_panel_simple/INFO] Solar Panel: area: 20.000000m² efficiency: 0.900000 irradiance: 10.000000W/m² power: 180.000000W
+> [Tremblay:manager:(1) 3.000000] [solar_panel_simple/INFO] Solar Panel: area: 20.000000m² efficiency: 0.800000 irradiance: 10.000000W/m² power: 160.000000W
+> [Tremblay:manager:(1) 4.000000] [solar_panel_simple/INFO] Solar Panel: area: 20.000000m² efficiency: 0.800000 irradiance: 20.000000W/m² power: 320.000000W
diff --git a/examples/platforms/photovoltaic_platform.xml b/examples/platforms/photovoltaic_platform.xml
deleted file mode 100644 (file)
index 8e499e1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version='1.0'?>
-<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
-<platform version="4.1">
-  <zone id="world" routing="Floyd">
-    <host id="pv_panel" speed="0f">
-      <prop id="photovoltaic_area" value="4" />
-      <prop id="photovoltaic_conversion_efficiency" value="0.2" />
-    </host>
-  </zone>
-</platform>
diff --git a/include/simgrid/plugins/photovoltaic.hpp b/include/simgrid/plugins/photovoltaic.hpp
deleted file mode 100644 (file)
index 3941751..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2023. The SimGrid Team. All rights reserved.          */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-#ifndef SIMGRID_PLUGINS_PHOTOVOLTAIC_H_
-#define SIMGRID_PLUGINS_PHOTOVOLTAIC_H_
-
-#include <simgrid/config.h>
-#include <simgrid/forward.h>
-#include <xbt/base.h>
-
-SG_BEGIN_DECL
-
-XBT_PUBLIC void sg_photovoltaic_plugin_init();
-
-XBT_PUBLIC void sg_photovoltaic_set_solar_irradiance(const_sg_host_t host, double s);
-
-XBT_PUBLIC double sg_photovoltaic_get_power(const_sg_host_t host);
-
-SG_END_DECL
-
-#endif
diff --git a/include/simgrid/plugins/solar_panel.hpp b/include/simgrid/plugins/solar_panel.hpp
new file mode 100644 (file)
index 0000000..a25f1ae
--- /dev/null
@@ -0,0 +1,84 @@
+/* Copyright (c) 2023. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+#ifndef SIMGRID_PLUGINS_SOLAR_PANEL_H_
+#define SIMGRID_PLUGINS_SOLAR_PANEL_H_
+
+#include <simgrid/kernel/resource/Model.hpp>
+#include <simgrid/s4u/Activity.hpp>
+#include <xbt/Extendable.hpp>
+
+namespace simgrid::plugins {
+
+class SolarPanel;
+using SolarPanelPtr = boost::intrusive_ptr<SolarPanel>;
+XBT_PUBLIC void intrusive_ptr_release(SolarPanel* o);
+XBT_PUBLIC void intrusive_ptr_add_ref(SolarPanel* o);
+
+class SolarPanelModel : public kernel::resource::Model {
+  std::vector<SolarPanelPtr> solar_panels_;
+
+public:
+  explicit SolarPanelModel();
+
+  void add_solar_panel(SolarPanelPtr b);
+  void update_actions_state(double now, double delta) override;
+  double next_occurring_event(double now) override;
+};
+
+class SolarPanel {
+
+  friend SolarPanelModel;
+
+private:
+  static std::shared_ptr<SolarPanelModel> solar_panel_model_;
+
+  std::string name_;
+  double area_m2_;
+  double conversion_efficiency_;
+  double solar_irradiance_w_per_m2_ ;
+  double min_power_w_;
+  double max_power_w_;
+
+  double power_w_      = 0;
+  double last_updated_ = 0;
+
+  explicit SolarPanel(std::string name, double area_m2, double conversion_efficiency, double solar_irradiance_w_per_m2, double min_power_w, double max_power_w);
+  static void init_plugin();
+  void update();
+
+  std::atomic_int_fast32_t refcount_{0};
+#ifndef DOXYGEN
+  friend void intrusive_ptr_release(SolarPanel* o)
+  {
+    if (o->refcount_.fetch_sub(1, std::memory_order_release) == 1) {
+      std::atomic_thread_fence(std::memory_order_acquire);
+      delete o;
+    }
+  }
+  friend void intrusive_ptr_add_ref(SolarPanel* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); }
+#endif
+
+public:
+
+  static SolarPanelPtr 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);
+
+  SolarPanelPtr set_name(std::string name);
+  SolarPanelPtr set_area(double area_m2);
+  SolarPanelPtr set_conversion_efficiency(double e);
+  SolarPanelPtr set_solar_irradiance(double solar_irradiance_w_per_m2);
+  SolarPanelPtr set_min_power(double power_w);
+  SolarPanelPtr set_max_power(double power_w);
+
+  std::string get_name() { return name_; }
+  const char* get_cname() { return name_.c_str();}
+  double get_area() { return area_m2_;}
+  double get_conversion_efficiency() { return conversion_efficiency_; }
+  double get_solar_irradiance() { return solar_irradiance_w_per_m2_; }
+  double get_min_power() { return min_power_w_; }
+  double get_max_power() { return max_power_w_; }
+  double get_power() { return power_w_; }
+};
+} // namespace simgrid::plugins
+#endif
diff --git a/src/plugins/photovoltaic.cpp b/src/plugins/photovoltaic.cpp
deleted file mode 100644 (file)
index 9d8a717..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/* Copyright (c) 2023. The SimGrid Team. All rights reserved.          */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-#include <simgrid/Exception.hpp>
-#include <simgrid/plugins/photovoltaic.hpp>
-#include <simgrid/s4u/Actor.hpp>
-#include <simgrid/s4u/Engine.hpp>
-#include <simgrid/s4u/Host.hpp>
-#include <simgrid/s4u/VirtualMachine.hpp>
-#include <simgrid/simix.hpp>
-
-#include "src/kernel/resource/CpuImpl.hpp"
-#include "src/simgrid/module.hpp"
-
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/split.hpp>
-
-SIMGRID_REGISTER_PLUGIN(photovoltaic, "Photovoltaic management", &sg_photovoltaic_plugin_init)
-
-/** @defgroup plugin_photovoltaic plugin_photovoltaic Plugin photovoltaic
-
-  @beginrst
-
-This is the photovoltaic plugin, enabling management of photovoltaic panels on hosts.
-To activate this plugin, first call :cpp:func:`sg_photovoltaic_plugin_init()`.
-
-This plugin allows evaluation of photovoltaic panels power generation during simulation depending on size, solar
-irradiance and conversion factor.
-
-The power model is taken from the paper `"Reinforcement Learning Based Load Balancing for
-Geographically Distributed Data Centres" <https://dro.dur.ac.uk/33395/1/33395.pdf?DDD280+kkgc95+vbdv77>`_ by Max Mackie et. al.
-
-The cost model is taken from the chapter 4 of the thesis `Sizing and Operation of Multi-Energy Hydrogen-Based
-Microgrids <https://tel.archives-ouvertes.fr/tel-02077668/document>`_ by Bei Li.
-
-Photovoltaic Panel properties
-....................
-
-Properties of panels are defined as properties of hosts in the platform XML file.
-
-Here is an example of XML declaration where we consider a host as a photovoltaic panel:
-
-.. code-block:: xml
-
-   <host id="pv_panel" speed="0f">
-      <prop id="photovoltaic_area" value="4" />
-      <prop id="photovoltaic_conversion_efficiency" value="0.2" />
-    </host>
-
-The different properties are:
-
-- ``photovoltaic_area``: Set the area of the panel in m² (default=0)
-- ``photovoltaic_conversion_efficiency``: Set the conversion efficiency of the panel (default=0)
-- ``photovoltaic_solar_irradiance``: Set the initial solar irradiance in W/m² (default=0)
-- ``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
-- ``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
-- ``photovoltaic_eval_cost``: Evaluate the cost of the panel during the simulation if set to 1 (defaulf=0)
-- ``photovoltaic_lifespan``: Set the lifespan of the panel in years (default=0)
-- ``photovoltaic_investment_cost``: Set the investment cost of the panel (default=0)
-- ``photovoltaic_maintenance_cost``: Set the maintenance cost of the panel (default=0)
-
-  @endrst
- */
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(photovoltaic, kernel, "Logging specific to the photovoltaic plugin");
-
-namespace simgrid::plugin {
-class Photovoltaic {
-private:
-  simgrid::s4u::Host* host_ = nullptr;
-
-  double area_m2_                   = 0;
-  double conversion_efficiency_     = 0;
-  double solar_irradiance_w_per_m2_ = 0;
-  double min_power_w_               = -1;
-  double max_power_w_               = -1;
-
-  double power_w_      = 0;
-  double last_updated_ = 0;
-
-  bool eval_cost_                 = false;
-  double cumulative_cost_         = 0;
-  int lifespan_years_             = 0;
-  double investment_cost_per_w_   = 0;
-  double maintenance_cost_per_wh_ = 0;
-
-  void init_photovoltaic_params();
-  void init_cost_params();
-  void update();
-
-  Photovoltaic* set_area(double a);
-  Photovoltaic* set_conversion_efficiency(double e);
-  Photovoltaic* set_min_power(double p);
-  Photovoltaic* set_max_power(double p);
-  Photovoltaic* set_eval_cost(bool eval);
-  Photovoltaic* set_lifespan(int l);
-  Photovoltaic* set_investment_cost(double c);
-  Photovoltaic* set_maintenance_cost(double c);
-
-public:
-  static simgrid::xbt::Extension<simgrid::s4u::Host, Photovoltaic> EXTENSION_ID;
-
-  explicit Photovoltaic(simgrid::s4u::Host* host);
-  ~Photovoltaic();
-
-  Photovoltaic* set_solar_irradiance(double s);
-
-  double get_power();
-};
-
-Photovoltaic* Photovoltaic::set_area(double a)
-{
-  xbt_assert(a > 0, " : area should be > 0 (provided: %f)", a);
-  simgrid::kernel::actor::simcall_answered([this, a] { area_m2_ = a; });
-  return this;
-}
-
-Photovoltaic* Photovoltaic::set_conversion_efficiency(double e)
-{
-  xbt_assert(e > 0 and e <= 1, " : conversion efficiency should be in [0,1] (provided: %f)", e);
-  simgrid::kernel::actor::simcall_answered([this, e] { conversion_efficiency_ = e; });
-  return this;
-}
-
-Photovoltaic* Photovoltaic::set_solar_irradiance(double s)
-{
-  xbt_assert(s > 0, " : solar irradiance should be > 0 (provided: %f)", s);
-  simgrid::kernel::actor::simcall_answered([this, s] { solar_irradiance_w_per_m2_ = s; });
-  return this;
-}
-
-Photovoltaic* Photovoltaic::set_min_power(double p)
-{
-  simgrid::kernel::actor::simcall_answered([this, p] { min_power_w_ = p; });
-  return this;
-}
-
-Photovoltaic* Photovoltaic::set_max_power(double p)
-{
-  simgrid::kernel::actor::simcall_answered([this, p] { max_power_w_ = p; });
-  return this;
-}
-
-Photovoltaic* Photovoltaic::set_eval_cost(bool e)
-{
-  simgrid::kernel::actor::simcall_answered([this, e] { eval_cost_ = e; });
-  return this;
-}
-
-Photovoltaic* Photovoltaic::set_lifespan(int l)
-{
-  xbt_assert(l > 0, " : lifespan should be > 0 (provided: %d)", l);
-  simgrid::kernel::actor::simcall_answered([this, l] { lifespan_years_ = l; });
-  return this;
-}
-
-Photovoltaic* Photovoltaic::set_investment_cost(double c)
-{
-  xbt_assert(c > 0, " : investment cost should be > 0 (provided: %f)", c);
-  simgrid::kernel::actor::simcall_answered([this, c] { investment_cost_per_w_ = c; });
-  return this;
-}
-
-Photovoltaic* Photovoltaic::set_maintenance_cost(double c)
-{
-  xbt_assert(c > 0, " : maintenance cost hould be > 0 (provided: %f)", c);
-  simgrid::kernel::actor::simcall_answered([this, c] { maintenance_cost_per_wh_ = c; });
-  return this;
-}
-
-double Photovoltaic::get_power()
-{
-  update();
-  return power_w_;
-}
-
-simgrid::xbt::Extension<simgrid::s4u::Host, Photovoltaic> Photovoltaic::EXTENSION_ID;
-
-void Photovoltaic::init_photovoltaic_params()
-{
-  const char* prop_chars;
-  prop_chars = host_->get_property("photovoltaic_area");
-  if (prop_chars)
-    set_area(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("photovoltaic_conversion_efficiency");
-  if (prop_chars)
-    set_conversion_efficiency(
-        xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("photovoltaic_solar_irradiance");
-  if (prop_chars)
-    set_solar_irradiance(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("photovoltaic_min_power");
-  if (prop_chars)
-    set_min_power(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("photovoltaic_max_power");
-  if (prop_chars)
-    set_max_power(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("photovoltaic_eval_cost");
-  if (prop_chars)
-    set_eval_cost(xbt_str_parse_int(prop_chars, ("cannot parse int: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("photovoltaic_lifespan");
-  if (prop_chars)
-    set_lifespan(xbt_str_parse_int(prop_chars, ("cannot parse int: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("photovoltaic_investment_cost");
-  if (prop_chars)
-    set_investment_cost(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("photovoltaic_maintenance_cost");
-  if (prop_chars)
-    set_maintenance_cost(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  simgrid::kernel::actor::simcall_answered([this] { last_updated_ = simgrid::s4u::Engine::get_clock(); });
-}
-
-void Photovoltaic::update()
-{
-  simgrid::kernel::actor::simcall_answered([this] {
-    double now = simgrid::s4u::Engine::get_clock();
-    if (now <= last_updated_)
-      return;
-    double power_w = conversion_efficiency_ * area_m2_ * solar_irradiance_w_per_m2_;
-    if (min_power_w_ > 0 && power_w_ < min_power_w_)
-      power_w = 0;
-    if (max_power_w_ > 0 && power_w_ > max_power_w_)
-      power_w = max_power_w_;
-    power_w_ = power_w;
-    if (eval_cost_) {
-      xbt_assert(max_power_w_ > 0, " : max power must be > 0 (provided: %f)", max_power_w_);
-      cumulative_cost_ += max_power_w_ * (now - last_updated_) *
-                          (investment_cost_per_w_ / (lifespan_years_ * 8760 * 3600) + maintenance_cost_per_wh_ / 3600);
-    }
-    last_updated_ = now;
-  });
-}
-
-Photovoltaic::Photovoltaic(simgrid::s4u::Host* host) : host_(host)
-{
-  init_photovoltaic_params();
-}
-
-Photovoltaic::~Photovoltaic() = default;
-} // namespace simgrid::plugin
-
-using simgrid::plugin::Photovoltaic;
-
-/* **************************** events  callback *************************** */
-
-static void on_creation(simgrid::s4u::Host& host)
-{
-  if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
-    return;
-  host.extension_set(new Photovoltaic(&host));
-}
-
-/* **************************** Public interface *************************** */
-
-static void ensure_plugin_inited()
-{
-  if (not Photovoltaic::EXTENSION_ID.valid())
-    throw simgrid::xbt::InitializationError(
-        "The Photovoltaic plugin is not active. Please call sg_photovoltaic_plugin_init() "
-        "before calling any function related to that plugin.");
-}
-
-/** @ingroup plugin_photovoltaic
- *  @brief Enable photovoltaic plugin.
- */
-void sg_photovoltaic_plugin_init()
-{
-  if (Photovoltaic::EXTENSION_ID.valid())
-    return;
-  Photovoltaic::EXTENSION_ID = simgrid::s4u::Host::extension_create<Photovoltaic>();
-  simgrid::s4u::Host::on_creation_cb(&on_creation);
-}
-
-/** @ingroup plugin_photovoltaic
- *  @param s The solar irradiance to set in W/m².
- */
-void sg_photovoltaic_set_solar_irradiance(const_sg_host_t host, double s)
-{
-  ensure_plugin_inited();
-  host->extension<Photovoltaic>()->set_solar_irradiance(s);
-}
-
-/** @ingroup plugin_photovoltaic
- *  @return Power generation in W.
- */
-double sg_photovoltaic_get_power(const_sg_host_t host)
-{
-  ensure_plugin_inited();
-  return host->extension<Photovoltaic>()->get_power();
-}
diff --git a/src/plugins/solar_panel.cpp b/src/plugins/solar_panel.cpp
new file mode 100644 (file)
index 0000000..d4d37ca
--- /dev/null
@@ -0,0 +1,197 @@
+/* Copyright (c) 2023. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+#include <simgrid/Exception.hpp>
+#include <simgrid/plugins/solar_panel.hpp>
+#include <simgrid/simix.hpp>
+#include <xbt/asserts.h>
+#include <xbt/log.h>
+
+#include "src/kernel/resource/CpuImpl.hpp"
+#include "src/simgrid/module.hpp"
+
+
+SIMGRID_REGISTER_PLUGIN(solar_panel, "Solar Panel management", nullptr)
+
+/** @defgroup plugin_solar_panel Plugin Solar Panel
+
+  @beginrst
+
+This is the solar panel plugin, enabling management of solar panels on hosts.
+
+This plugin allows the use of solar panels to generate power during simulation depending on size, solar
+irradiance and conversion factor.
+
+The power model is taken from the paper `"Reinforcement Learning Based Load Balancing for
+Geographically Distributed Data Centres" <https://dro.dur.ac.uk/33395/1/33395.pdf?DDD280+kkgc95+vbdv77>`_ by Max Mackie et. al.
+
+Solar Panel
+....................
+
+A solar panel has an area :math:`A` in m², a conversion efficiency :math:`\eta` and a solar irradiance :math:`S` in W/m². 
+The power generated :math:`P` in W by a solar panel is given by the following equation: 
+
+.. math::
+
+  P = A \times \eta \times S
+
+  @endrst
+ */
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(SolarPanel, kernel, "Logging specific to the solar panel plugin");
+
+namespace simgrid::plugins {
+
+/* SolarPanelModel */
+
+SolarPanelModel::SolarPanelModel() : Model("SolarPanelModel") {}
+
+void SolarPanelModel::add_solar_panel(SolarPanelPtr b)
+{
+  solar_panels_.push_back(b);
+}
+
+void SolarPanelModel::update_actions_state(double now, double delta)
+{
+  for (auto solar_panel : solar_panels_)
+    solar_panel->update();
+}
+
+double SolarPanelModel::next_occurring_event(double now)
+{
+  return -1;
+}
+
+/* SolarPanel */
+
+std::shared_ptr<SolarPanelModel> SolarPanel::solar_panel_model_;
+
+void SolarPanel::init_plugin()
+{
+  auto model = std::make_shared<SolarPanelModel>();
+  simgrid::s4u::Engine::get_instance()->add_model(model);
+  SolarPanel::solar_panel_model_ = model;
+}
+
+void SolarPanel::update()
+{
+  simgrid::kernel::actor::simcall_answered([this] {
+    double now = simgrid::s4u::Engine::get_clock();
+    if (now <= last_updated_)
+      return;
+    double power_w = conversion_efficiency_ * area_m2_ * solar_irradiance_w_per_m2_;
+    if (power_w_ < min_power_w_)
+      power_w = 0;
+    if (power_w_ > max_power_w_)
+      power_w = max_power_w_;
+    power_w_ = power_w;
+    last_updated_ = now;
+  });
+}
+
+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)
+    : name_(name)
+    , area_m2_(area_m2)
+    , conversion_efficiency_(conversion_efficiency)
+    , solar_irradiance_w_per_m2_(solar_irradiance_w_per_m2)
+    , min_power_w_(min_power_w)
+    , max_power_w_(max_power_w)
+{
+  xbt_assert(area_m2 >= 0, " : area must be >= 0 (provided: %f)", area_m2);
+  xbt_assert(conversion_efficiency >= 0 and conversion_efficiency <= 1, " : conversion efficiency must be in [0,1] (provided: %f)", conversion_efficiency);
+  xbt_assert(solar_irradiance_w_per_m2 >= 0, " : solar irradiance must be >= 0 (provided: %f)", solar_irradiance_w_per_m2);
+  xbt_assert(min_power_w >= 0, " : minimal power must be >= 0 (provided: %f)", min_power_w);
+  xbt_assert(max_power_w > 0, " : maximal power must be > 0 (provided: %f)", max_power_w);
+  xbt_assert(max_power_w > min_power_w, " : maximal power must be above minimal power (provided: %f, %f)", max_power_w, min_power_w);
+}
+
+/** @ingroup plugin_solar_panel
+ *  @param name The name of the Solar Panel.
+ *  @param area_m2 The area of the Solar Panel in m² (> 0).
+ *  @param conversion_efficiency The conversion efficiency of the Solar Panel [0,1].
+ *  @param solar_irradiance_w_per_m2 The solar irradiance of the Solar Panel in W/m² (> 0).
+ *  @param min_power_w The minimal power delivered by the Solar Panel in W (> 0 and < max_power_w).
+ *  @param max_power_w The maximal power delivered by the Solar Panel in W (> 0 and > min_power_w).
+ *  @return A SolarPanelPtr pointing to the new SolarPanel.
+ */
+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)
+{
+  static bool plugin_inited = false;
+  if (not plugin_inited) {
+    init_plugin();
+    plugin_inited = true;
+  }
+  auto solar_panel = SolarPanelPtr(new SolarPanel(name, area_m2, conversion_efficiency, solar_irradiance_w_per_m2, min_power_w, max_power_w));
+  solar_panel_model_->add_solar_panel(solar_panel);
+  return solar_panel;
+}
+
+/** @ingroup plugin_solar_panel
+ *  @param name The new name of the Solar Panel.
+ *  @return A SolarPanelPtr pointing to the modified SolarPanel.
+ */
+SolarPanelPtr SolarPanel::set_name(std::string name)
+{
+  kernel::actor::simcall_answered([this, name] {name_ = name;});
+  return this;
+}
+
+/** @ingroup plugin_solar_panel
+ *  @param area_m2 The new area of the Solar Panel in m².
+ *  @return A SolarPanelPtr pointing to the modified SolarPanel.
+ */
+SolarPanelPtr SolarPanel::set_area(double area_m2)
+{
+  xbt_assert(area_m2 >= 0, " : area must be > 0 (provided: %f)", area_m2);
+  kernel::actor::simcall_answered([this, area_m2] {area_m2_ = area_m2;});
+  return this;
+}
+
+/** @ingroup plugin_solar_panel
+ *  @param e The new convesion efficiency of the Solar Panel.
+ *  @return A SolarPanelPtr pointing to the modified SolarPanel.
+ */
+SolarPanelPtr SolarPanel::set_conversion_efficiency(double e)
+{
+  xbt_assert(e >= 0 and e <= 1, " : conversion efficiency must be in [0,1] (provided: %f)", e);
+  kernel::actor::simcall_answered([this, e] {conversion_efficiency_ = e;});
+  return this;
+}
+
+/** @ingroup plugin_solar_panel
+ *  @param solar_irradiance_w_per_m2 The new solar irradiance of the Solar Panel in W/m².
+ *  @return A SolarPanelPtr pointing to the modified SolarPanel.
+ */
+SolarPanelPtr SolarPanel::set_solar_irradiance(double solar_irradiance_w_per_m2)
+{
+  xbt_assert(solar_irradiance_w_per_m2 >= 0, " : solar irradiance must be >= 0 (provided: %f)", solar_irradiance_w_per_m2);
+  kernel::actor::simcall_answered([this, solar_irradiance_w_per_m2] {solar_irradiance_w_per_m2_ = solar_irradiance_w_per_m2;});
+  return this;
+}
+
+/** @ingroup plugin_solar_panel
+ *  @param power_w The new minimal power of the Solar Panel in W.
+ *  @return A SolarPanelPtr pointing to the modified SolarPanel.
+ */
+SolarPanelPtr SolarPanel::set_min_power(double power_w)
+{
+  xbt_assert(power_w >= 0, " : minimal power must be >= 0 (provided: %f)", power_w);
+  xbt_assert(max_power_w_ > power_w, " : maximal power must be above minimal power (provided: %f, max: %f)", power_w, max_power_w_);
+  kernel::actor::simcall_answered([this, power_w] {min_power_w_ = power_w;});
+  return this;
+}
+
+/** @ingroup plugin_solar_panel
+ *  @param power_w The new maximal power of the Solar Panel in W.
+ *  @return A SolarPanelPtr pointing to the modified SolarPanel.
+ */
+SolarPanelPtr SolarPanel::set_max_power(double power_w)
+{
+  xbt_assert(power_w > 0, " : maximal power must be > 0 (provided: %f)", power_w);
+  xbt_assert(min_power_w_ < power_w, " : maximal power must be above minimal power (provided: %f, min: %f)", power_w, min_power_w_);
+  kernel::actor::simcall_answered([this, power_w] {max_power_w_ = power_w;});
+  return this;
+}
+
+} // namespace simgrid::plugins
\ No newline at end of file
index 8215478..267162f 100644 (file)
@@ -453,7 +453,7 @@ set(PLUGINS_SRC
   src/plugins/vm/VmLiveMigration.hpp
   src/plugins/vm/dirty_page_tracking.cpp
   src/plugins/battery.cpp
-  src/plugins/photovoltaic.cpp
+  src/plugins/solar_panel.cpp
   )
 
 
@@ -663,7 +663,7 @@ set(headers_to_install
   include/simgrid/plugins/jbod.hpp
   include/simgrid/plugins/live_migration.h
   include/simgrid/plugins/load.h
-  include/simgrid/plugins/photovoltaic.hpp
+  include/simgrid/plugins/solar_panel.hpp
   include/simgrid/plugins/ProducerConsumer.hpp
   include/simgrid/instr.h
   include/simgrid/mailbox.h
@@ -1141,7 +1141,6 @@ set(PLATFORMS_EXAMPLES
   examples/platforms/optorsim/gridpp_grid_2004.conf
   examples/platforms/optorsim/lcg_sept2004_grid.conf
   examples/platforms/optorsim/transform_optorsim_platform.pl
-  examples/platforms/photovoltaic_platform.xml
   examples/platforms/profiles/fafard_state.profile
   examples/platforms/profiles/faulty_host.profile
   examples/platforms/profiles/ginette_state.profile