Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
better comments on examples
[simgrid.git] / examples / cpp / battery-chiller-solar / s4u-battery-chiller-solar.cpp
1 /* Copyright (c) 2017-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
6 /* This example combine the battery plugin, the chiller plugin and the solar
7    panel plugin. It illustrates how to use them together to evaluate the amount
8    of brown energy (from the electrical grid) and green energy (from the solar
9    panel) consumed by several machines.
10
11    In this scenario we have two host placed in a room.
12    The room is maintained at 24°C by a chiller, powered by the electrical grid
13    and consumes brown energy.
14    The two hosts are powered by a battery when available, and the electrical
15    grid otherwise. The battery is charged by a solar panel.
16
17    We simulate two days from 00h00 to 00h00.
18    The solar panel generates power from 8h to 20h with a peak at 14h.
19    During the simulation, when the charge of the battery goes:
20     - below 75% the solar panel is connected to the battery
21     - above 80% the solar panel is disconnected from the battery
22     - below 20% the hosts are disconnected from the battery
23     - above 25% the hosts are connected to the battery
24
25    The two hosts are always idle, except from 12h to 16h on the first day.
26 */
27
28 #include "simgrid/plugins/battery.hpp"
29 #include "simgrid/plugins/chiller.hpp"
30 #include "simgrid/plugins/energy.h"
31 #include "simgrid/plugins/solar_panel.hpp"
32 #include "simgrid/s4u.hpp"
33 #include <math.h>
34
35 XBT_LOG_NEW_DEFAULT_CATEGORY(battery_chiller_solar, "Messages specific for this s4u example");
36 namespace sg4 = simgrid::s4u;
37 namespace sp  = simgrid::plugins;
38
39 static void irradiance_manager(sp::SolarPanelPtr solar_panel)
40 {
41   int time         = 0;
42   int time_step    = 10;
43   double amplitude = 1000 / 2.0;
44   double period    = 24 * 60 * 60;
45   double shift     = 16 * 60 * 60;
46   double irradiance;
47   while (true) {
48     irradiance = amplitude * sin(2 * M_PI * (time + shift) / period);
49     irradiance = irradiance < 0 ? 0 : irradiance;
50     solar_panel->set_solar_irradiance(irradiance);
51     sg4::this_actor::sleep_for(time_step);
52     time += time_step;
53   }
54 }
55
56 static void host_job_manager(double start, double duration)
57 {
58   sg4::this_actor::sleep_until(start);
59   sg4::this_actor::get_host()->execute(duration * sg4::this_actor::get_host()->get_speed());
60 }
61
62 static void end_manager(sp::BatteryPtr b)
63 {
64   sg4::this_actor::sleep_until(86400 * 2);
65   for (auto& handler : b->get_handlers())
66     b->delete_handler(handler);
67 }
68
69 int main(int argc, char* argv[])
70 {
71   sg4::Engine e(&argc, argv);
72   e.load_platform(argv[1]);
73   sg_host_energy_plugin_init();
74
75   auto myhost1 = e.host_by_name("MyHost1");
76   auto myhost2 = e.host_by_name("MyHost2");
77
78   auto battery     = sp::Battery::init("Battery", 0.2, -1e3, 1e3, 0.9, 0.9, 2000, 1000);
79   auto chiller     = sp::Chiller::init("Chiller", 50, 1006, 0.2, 0.9, 24, 24, 1e3);
80   auto solar_panel = sp::SolarPanel::init("Solar Panel", 1.1, 0.9, 0, 0, 1e3);
81   chiller->add_host(myhost1);
82   chiller->add_host(myhost2);
83   solar_panel->on_this_power_change_cb(
84       [battery](sp::SolarPanel* s) { battery->set_load("Solar Panel", s->get_power() * -1); });
85
86   // These handlers connect/disconnect the solar panel and the hosts depending on the state of charge of the battery
87   battery->schedule_handler(0.8, sp::Battery::CHARGE, sp::Battery::Handler::PERSISTANT,
88                             [battery]() { battery->set_load("Solar Panel", false); });
89   battery->schedule_handler(0.75, sp::Battery::DISCHARGE, sp::Battery::Handler::PERSISTANT,
90                             [battery]() { battery->set_load("Solar Panel", true); });
91   battery->schedule_handler(0.2, sp::Battery::DISCHARGE, sp::Battery::Handler::PERSISTANT,
92                             [battery, &myhost1, &myhost2]() {
93                               battery->connect_host(myhost1, false);
94                               battery->connect_host(myhost2, false);
95                             });
96   battery->schedule_handler(0.25, sp::Battery::CHARGE, sp::Battery::Handler::PERSISTANT,
97                             [battery, &myhost1, &myhost2]() {
98                               battery->connect_host(myhost1);
99                               battery->connect_host(myhost2);
100                             });
101
102   /* Handlers create simulation events preventing the simulation from finishing
103      To avoid this behaviour this actor sleeps for 2 days and then delete all handlers
104   */
105   sg4::Actor::create("end_manager", myhost1, end_manager, battery);
106
107   // This actor updates the solar irradiance of the solar panel
108   sg4::Actor::create("irradiance_manager", myhost1, irradiance_manager, solar_panel)->daemonize();
109
110   // These actors start a job on a host for a specific duration
111   sg4::Actor::create("host_job_manager", myhost1, host_job_manager, 12 * 60 * 60, 4 * 60 * 60);
112   sg4::Actor::create("host_job_manager", myhost2, host_job_manager, 12 * 60 * 60, 4 * 60 * 60);
113
114   e.run();
115   XBT_INFO("State of charge of the battery: %0.1f%%", battery->get_state_of_charge() * 100);
116   XBT_INFO(
117       "Energy consumed by the hosts (green / brown): %.2fMJ "
118       "/ %.2fMJ",
119       battery->get_energy_provided() / 1e6,
120       (sg_host_get_consumed_energy(myhost1) + sg_host_get_consumed_energy(myhost2) - battery->get_energy_provided()) /
121           1e6);
122   XBT_INFO("Energy consumed by the chiller (brown): %.2fMJ", chiller->get_energy_consumed() / 1e6);
123   return 0;
124 }