Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Complete revamp of battery plugin
authorAdrien Gougeon <adrien.gougeon@ens-rennes.fr>
Wed, 28 Jun 2023 15:32:58 +0000 (17:32 +0200)
committerAdrien Gougeon <adrien.gougeon@ens-rennes.fr>
Tue, 11 Jul 2023 10:04:52 +0000 (12:04 +0200)
MANIFEST.in
docs/source/img/battery_degradation.svg
examples/cpp/battery-degradation/s4u-battery-degradation.cpp
examples/cpp/battery-degradation/s4u-battery-degradation.tesh
examples/cpp/battery-energy/s4u-battery-energy.cpp
examples/cpp/battery-energy/s4u-battery-energy.tesh
examples/cpp/battery-simple/s4u-battery-simple.cpp
examples/cpp/battery-simple/s4u-battery-simple.tesh
examples/platforms/battery_platform.xml [deleted file]
include/simgrid/plugins/battery.hpp
src/plugins/battery.cpp

index 3896bde..85b0de1 100644 (file)
@@ -1807,7 +1807,6 @@ include examples/README.rst
 include examples/c/CMakeLists.txt
 include examples/cpp/CMakeLists.txt
 include examples/platforms/CMakeLists.txt
-include examples/platforms/battery_platform.xml
 include examples/platforms/bypassRoute.xml
 include examples/platforms/bypassZoneRoute.xml
 include examples/platforms/cloud.xml
index 630744b..a887272 100644 (file)
@@ -6,7 +6,7 @@
   <rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <cc:Work>
     <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:date>2023-03-30T14:42:09.493393</dc:date>
+    <dc:date>2023-06-28T16:42:29.585725</dc:date>
     <dc:format>image/svg+xml</dc:format>
     <dc:creator>
      <cc:Agent>
@@ -40,13 +40,13 @@ z
    <g id="matplotlib.axis_1">
     <g id="xtick_1">
      <g id="line2d_1">
-      <path d="M 184.581818 512.64 
-L 184.581818 69.12 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 181.865242 512.64 
+L 181.865242 69.12 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_1">
       <!-- 0 -->
-      <g style="fill: #262626" transform="translate(181.082443 530.498281) scale(0.11 -0.11)">
+      <g style="fill: #262626" transform="translate(178.365867 530.498281) scale(0.11 -0.11)">
        <defs>
         <path id="DejaVuSans-30" d="M 2034 4250 
 Q 1547 4250 1301 3770 
@@ -76,13 +76,13 @@ z
     </g>
     <g id="xtick_2">
      <g id="line2d_2">
-      <path d="M 341.1509 512.64 
-L 341.1509 69.12 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 321.467091 512.64 
+L 321.467091 69.12 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_2">
       <!-- 10000 -->
-      <g style="fill: #262626" transform="translate(323.654025 530.498281) scale(0.11 -0.11)">
+      <g style="fill: #262626" transform="translate(303.970216 530.498281) scale(0.11 -0.11)">
        <defs>
         <path id="DejaVuSans-31" d="M 794 531 
 L 1825 531 
@@ -109,13 +109,13 @@ z
     </g>
     <g id="xtick_3">
      <g id="line2d_3">
-      <path d="M 497.719982 512.64 
-L 497.719982 69.12 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 461.06894 512.64 
+L 461.06894 69.12 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_3">
       <!-- 20000 -->
-      <g style="fill: #262626" transform="translate(480.223107 530.498281) scale(0.11 -0.11)">
+      <g style="fill: #262626" transform="translate(443.572065 530.498281) scale(0.11 -0.11)">
        <defs>
         <path id="DejaVuSans-32" d="M 1228 531 
 L 3431 531 
@@ -152,13 +152,13 @@ z
     </g>
     <g id="xtick_4">
      <g id="line2d_4">
-      <path d="M 654.289063 512.64 
-L 654.289063 69.12 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 600.670789 512.64 
+L 600.670789 69.12 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_4">
       <!-- 30000 -->
-      <g style="fill: #262626" transform="translate(636.792188 530.498281) scale(0.11 -0.11)">
+      <g style="fill: #262626" transform="translate(583.173914 530.498281) scale(0.11 -0.11)">
        <defs>
         <path id="DejaVuSans-33" d="M 2597 2516 
 Q 3050 2419 3304 2112 
@@ -203,13 +203,13 @@ z
     </g>
     <g id="xtick_5">
      <g id="line2d_5">
-      <path d="M 810.858145 512.64 
-L 810.858145 69.12 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 740.272638 512.64 
+L 740.272638 69.12 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_5">
       <!-- 40000 -->
-      <g style="fill: #262626" transform="translate(793.36127 530.498281) scale(0.11 -0.11)">
+      <g style="fill: #262626" transform="translate(722.775763 530.498281) scale(0.11 -0.11)">
        <defs>
         <path id="DejaVuSans-34" d="M 2419 4116 
 L 825 1625 
@@ -241,13 +241,13 @@ z
     </g>
     <g id="xtick_6">
      <g id="line2d_6">
-      <path d="M 967.427227 512.64 
-L 967.427227 69.12 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 879.874487 512.64 
+L 879.874487 69.12 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_6">
       <!-- 50000 -->
-      <g style="fill: #262626" transform="translate(949.930352 530.498281) scale(0.11 -0.11)">
+      <g style="fill: #262626" transform="translate(862.377612 530.498281) scale(0.11 -0.11)">
        <defs>
         <path id="DejaVuSans-35" d="M 691 4666 
 L 3169 4666 
@@ -283,7 +283,56 @@ z
       </g>
      </g>
     </g>
-    <g id="text_7">
+    <g id="xtick_7">
+     <g id="line2d_7">
+      <path d="M 1019.476336 512.64 
+L 1019.476336 69.12 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+     </g>
+     <g id="text_7">
+      <!-- 60000 -->
+      <g style="fill: #262626" transform="translate(1001.979461 530.498281) scale(0.11 -0.11)">
+       <defs>
+        <path id="DejaVuSans-36" d="M 2113 2584 
+Q 1688 2584 1439 2293 
+Q 1191 2003 1191 1497 
+Q 1191 994 1439 701 
+Q 1688 409 2113 409 
+Q 2538 409 2786 701 
+Q 3034 994 3034 1497 
+Q 3034 2003 2786 2293 
+Q 2538 2584 2113 2584 
+z
+M 3366 4563 
+L 3366 3988 
+Q 3128 4100 2886 4159 
+Q 2644 4219 2406 4219 
+Q 1781 4219 1451 3797 
+Q 1122 3375 1075 2522 
+Q 1259 2794 1537 2939 
+Q 1816 3084 2150 3084 
+Q 2853 3084 3261 2657 
+Q 3669 2231 3669 1497 
+Q 3669 778 3244 343 
+Q 2819 -91 2113 -91 
+Q 1303 -91 875 529 
+Q 447 1150 447 2328 
+Q 447 3434 972 4092 
+Q 1497 4750 2381 4750 
+Q 2619 4750 2861 4703 
+Q 3103 4656 3366 4563 
+z
+" transform="scale(0.015625)"/>
+       </defs>
+       <use xlink:href="#DejaVuSans-36"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
+       <use xlink:href="#DejaVuSans-30" x="127.246094"/>
+       <use xlink:href="#DejaVuSans-30" x="190.869141"/>
+       <use xlink:href="#DejaVuSans-30" x="254.492188"/>
+      </g>
+     </g>
+    </g>
+    <g id="text_8">
      <!-- Time -->
      <g style="fill: #262626" transform="translate(575.719687 545.904063) scale(0.12 -0.12)">
       <defs>
@@ -376,14 +425,14 @@ z
    </g>
    <g id="matplotlib.axis_2">
     <g id="ytick_1">
-     <g id="line2d_7">
-      <path d="M 144 492.488871 
-L 1036.8 492.488871 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+     <g id="line2d_8">
+      <path d="M 144 447.44377 
+L 1036.8 447.44377 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
-     <g id="text_8">
-      <!-- 0.0 -->
-      <g style="fill: #262626" transform="translate(117.006563 496.668011) scale(0.11 -0.11)">
+     <g id="text_9">
+      <!-- 0.2 -->
+      <g style="fill: #262626" transform="translate(117.006563 451.62291) scale(0.11 -0.11)">
        <defs>
         <path id="DejaVuSans-2e" d="M 684 794 
 L 1344 794 
@@ -393,98 +442,51 @@ L 684 794
 z
 " transform="scale(0.015625)"/>
        </defs>
-       <use xlink:href="#DejaVuSans-30"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-30" x="95.410156"/>
-      </g>
-     </g>
-    </g>
-    <g id="ytick_2">
-     <g id="line2d_8">
-      <path d="M 144 411.847096 
-L 1036.8 411.847096 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
-     </g>
-     <g id="text_9">
-      <!-- 0.2 -->
-      <g style="fill: #262626" transform="translate(117.006563 416.026237) scale(0.11 -0.11)">
        <use xlink:href="#DejaVuSans-30"/>
        <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
        <use xlink:href="#DejaVuSans-32" x="95.410156"/>
       </g>
      </g>
     </g>
-    <g id="ytick_3">
+    <g id="ytick_2">
      <g id="line2d_9">
-      <path d="M 144 331.205322 
-L 1036.8 331.205322 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 144 357.565447 
+L 1036.8 357.565447 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_10">
       <!-- 0.4 -->
-      <g style="fill: #262626" transform="translate(117.006563 335.384463) scale(0.11 -0.11)">
+      <g style="fill: #262626" transform="translate(117.006563 361.744587) scale(0.11 -0.11)">
        <use xlink:href="#DejaVuSans-30"/>
        <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
        <use xlink:href="#DejaVuSans-34" x="95.410156"/>
       </g>
      </g>
     </g>
-    <g id="ytick_4">
+    <g id="ytick_3">
      <g id="line2d_10">
-      <path d="M 144 250.563548 
-L 1036.8 250.563548 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 144 267.687123 
+L 1036.8 267.687123 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_11">
       <!-- 0.6 -->
-      <g style="fill: #262626" transform="translate(117.006563 254.742689) scale(0.11 -0.11)">
-       <defs>
-        <path id="DejaVuSans-36" d="M 2113 2584 
-Q 1688 2584 1439 2293 
-Q 1191 2003 1191 1497 
-Q 1191 994 1439 701 
-Q 1688 409 2113 409 
-Q 2538 409 2786 701 
-Q 3034 994 3034 1497 
-Q 3034 2003 2786 2293 
-Q 2538 2584 2113 2584 
-z
-M 3366 4563 
-L 3366 3988 
-Q 3128 4100 2886 4159 
-Q 2644 4219 2406 4219 
-Q 1781 4219 1451 3797 
-Q 1122 3375 1075 2522 
-Q 1259 2794 1537 2939 
-Q 1816 3084 2150 3084 
-Q 2853 3084 3261 2657 
-Q 3669 2231 3669 1497 
-Q 3669 778 3244 343 
-Q 2819 -91 2113 -91 
-Q 1303 -91 875 529 
-Q 447 1150 447 2328 
-Q 447 3434 972 4092 
-Q 1497 4750 2381 4750 
-Q 2619 4750 2861 4703 
-Q 3103 4656 3366 4563 
-z
-" transform="scale(0.015625)"/>
-       </defs>
+      <g style="fill: #262626" transform="translate(117.006563 271.866264) scale(0.11 -0.11)">
        <use xlink:href="#DejaVuSans-30"/>
        <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
        <use xlink:href="#DejaVuSans-36" x="95.410156"/>
       </g>
      </g>
     </g>
-    <g id="ytick_5">
+    <g id="ytick_4">
      <g id="line2d_11">
-      <path d="M 144 169.921774 
-L 1036.8 169.921774 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 144 177.8088 
+L 1036.8 177.8088 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_12">
       <!-- 0.8 -->
-      <g style="fill: #262626" transform="translate(117.006563 174.100915) scale(0.11 -0.11)">
+      <g style="fill: #262626" transform="translate(117.006563 181.987941) scale(0.11 -0.11)">
        <defs>
         <path id="DejaVuSans-38" d="M 2034 2216 
 Q 1584 2216 1326 1975 
@@ -532,15 +534,15 @@ z
       </g>
      </g>
     </g>
-    <g id="ytick_6">
+    <g id="ytick_5">
      <g id="line2d_12">
-      <path d="M 144 89.28 
-L 1036.8 89.28 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
+      <path d="M 144 87.930477 
+L 1036.8 87.930477 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #ffffff; stroke-linecap: round"/>
      </g>
      <g id="text_13">
       <!-- 1.0 -->
-      <g style="fill: #262626" transform="translate(117.006563 93.459141) scale(0.11 -0.11)">
+      <g style="fill: #262626" transform="translate(117.006563 92.109618) scale(0.11 -0.11)">
        <use xlink:href="#DejaVuSans-31"/>
        <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
        <use xlink:href="#DejaVuSans-30" x="95.410156"/>
    <g id="PolyCollection_1"/>
    <g id="PolyCollection_2"/>
    <g id="line2d_13">
-    <path d="M 184.581818 169.921774 
-L 187.96371 411.847096 
-L 191.33433 169.921774 
-L 194.693713 411.847096 
-L 198.041899 169.921774 
-L 201.378924 411.847096 
-L 204.704826 169.921774 
-L 208.019642 411.847096 
-L 211.323408 169.921774 
-L 214.616161 411.847096 
-L 217.897939 169.921774 
-L 221.168777 411.847096 
-L 224.428713 169.921774 
-L 227.677782 411.847096 
-L 230.916021 169.921774 
-L 234.143466 411.847096 
-L 237.360153 169.921774 
-L 240.566117 411.847096 
-L 243.761395 169.921774 
-L 246.946022 411.847096 
-L 250.120033 169.921774 
-L 253.283465 411.847096 
-L 256.436351 169.921774 
-L 259.578728 411.847096 
-L 262.710631 169.921774 
-L 265.832094 411.847096 
-L 268.943152 169.921774 
-L 272.043839 411.847096 
-L 275.134191 169.921774 
-L 278.214242 411.847096 
-L 281.284026 169.921774 
-L 284.343578 411.847096 
-L 287.392931 169.921774 
-L 290.432119 411.847096 
-L 293.461177 169.921774 
-L 296.480138 411.847096 
-L 299.489036 169.921774 
-L 302.487904 411.847096 
-L 305.476776 169.921774 
-L 308.455685 411.847096 
-L 311.424664 169.921774 
-L 314.383747 411.847096 
-L 317.332966 169.921774 
-L 320.272354 411.847096 
-L 323.201945 169.921774 
-L 326.12177 411.847096 
-L 329.031862 169.921774 
-L 331.932254 411.847096 
-L 334.822978 169.921774 
-L 337.704066 411.847096 
-L 340.575551 169.921774 
-L 343.437464 411.847096 
-L 346.289838 169.921774 
-L 349.132703 411.847096 
-L 351.966092 169.921774 
-L 354.790037 411.847096 
-L 357.604568 169.921774 
-L 360.409718 411.847096 
-L 363.205517 169.921774 
-L 365.991997 411.847096 
-L 368.769188 169.921774 
-L 371.537123 411.847096 
-L 374.295831 169.921774 
-L 377.045343 411.847096 
-L 379.78569 169.921774 
-L 382.516902 411.847096 
-L 385.239011 169.921774 
-L 387.952046 411.847096 
-L 390.656037 169.921774 
-L 393.351015 411.847096 
-L 396.03701 169.921774 
-L 398.714052 411.847096 
-L 401.38217 169.921774 
-L 404.041394 411.847096 
-L 406.691754 169.921774 
-L 409.33328 411.847096 
-L 411.966001 169.921774 
-L 414.589945 411.847096 
-L 417.205144 169.921774 
-L 419.811625 411.847096 
-L 422.409418 169.921774 
-L 424.998551 411.847096 
-L 427.579054 169.921774 
-L 430.150956 411.847096 
-L 432.714284 169.921774 
-L 435.269068 411.847096 
-L 437.815336 169.921774 
-L 440.353116 411.847096 
-L 442.882438 169.921774 
-L 445.403328 411.847096 
-L 447.915815 169.921774 
-L 450.419927 411.847096 
-L 452.915692 169.921774 
-L 455.403138 411.847096 
-L 457.882293 169.921774 
-L 460.353183 411.847096 
-L 462.815837 169.921774 
-L 465.270283 411.847096 
-L 467.716547 169.921774 
-L 470.154657 411.847096 
-L 472.584639 169.921774 
-L 475.006522 411.847096 
-L 477.420332 169.921774 
-L 479.826096 411.847096 
-L 482.22384 169.921774 
-L 484.613592 411.847096 
-L 486.995379 169.921774 
-L 489.369225 411.847096 
-L 491.73516 169.921774 
-L 494.093207 411.847096 
-L 496.443395 169.921774 
-L 498.785748 411.847096 
-L 501.120294 169.921774 
-L 503.447058 411.847096 
-L 505.766066 169.921774 
-L 508.077344 411.847096 
-L 510.380918 169.921774 
-L 512.676813 411.847096 
-L 514.965055 169.921774 
-L 517.24567 411.847096 
-L 519.518683 169.921774 
-L 521.784119 411.847096 
-L 524.042003 169.921774 
-L 526.292361 411.847096 
-L 528.535218 169.921774 
-L 530.770599 411.847096 
-L 532.998529 169.921774 
-L 535.219032 411.847096 
-L 537.432133 169.921774 
-L 539.637858 411.847096 
-L 541.83623 169.921774 
-L 544.027274 411.847096 
-L 546.211014 169.921774 
-L 548.387476 411.847096 
-L 550.556683 169.921774 
-L 552.718659 411.847096 
-L 554.873428 169.921774 
-L 557.021015 411.847096 
-L 559.161443 169.921774 
-L 561.294736 411.847096 
-L 563.420919 169.921774 
-L 565.540014 411.847096 
-L 567.652045 169.921774 
-L 569.757037 411.847096 
-L 571.855012 169.921774 
-L 573.945993 411.847096 
-L 576.030005 169.921774 
-L 578.10707 411.847096 
-L 580.177211 169.921774 
-L 582.240452 411.847096 
-L 584.296815 169.921774 
-L 586.346324 411.847096 
-L 588.389001 169.921774 
-L 590.424869 411.847096 
-L 592.453951 169.921774 
-L 594.47627 411.847096 
-L 596.491847 169.921774 
-L 598.500706 411.847096 
-L 600.502868 169.921774 
-L 602.498357 411.847096 
-L 604.487194 169.921774 
-L 606.469402 411.847096 
-L 608.445002 169.921774 
-L 610.414017 411.847096 
-L 612.376468 169.921774 
-L 614.332378 411.847096 
-L 616.281769 169.921774 
-L 618.224661 411.847096 
-L 620.161077 169.921774 
-L 622.091038 411.847096 
-L 624.014566 169.921774 
-L 625.931683 411.847096 
-L 627.842409 169.921774 
-L 629.746766 411.847096 
-L 631.644775 169.921774 
-L 633.536457 411.847096 
-L 635.421834 169.921774 
-L 637.300926 411.847096 
-L 639.173754 169.921774 
-L 641.04034 411.847096 
-L 642.900704 169.921774 
-L 644.754866 411.847096 
-L 646.602848 169.921774 
-L 648.44467 411.847096 
-L 650.280353 169.921774 
-L 652.109917 411.847096 
-L 653.933382 169.921774 
-L 655.750769 411.847096 
-L 657.562098 169.921774 
-L 659.367389 411.847096 
-L 661.166663 169.921774 
-L 662.959939 411.847096 
-L 664.747237 169.921774 
-L 666.528578 411.847096 
-L 668.303981 169.921774 
-L 670.073466 411.847096 
-L 671.837052 169.921774 
-L 673.59476 411.847096 
-L 675.346609 169.921774 
-L 677.092619 411.847096 
-L 678.832808 169.921774 
-L 680.567197 411.847096 
-L 682.295805 169.921774 
-L 684.01865 411.847096 
-L 685.735753 169.921774 
-L 687.447132 411.847096 
-L 689.152807 169.921774 
-L 690.852796 411.847096 
-L 692.547118 169.921774 
-L 694.235792 411.847096 
-L 695.918838 169.921774 
-L 697.596273 411.847096 
-L 699.268117 169.921774 
-L 700.934388 411.847096 
-L 702.595105 169.921774 
-L 704.250287 411.847096 
-L 705.899951 169.921774 
-L 707.544116 411.847096 
-L 709.1828 169.921774 
-L 710.816022 411.847096 
-L 712.4438 169.921774 
-L 714.066153 411.847096 
-L 715.683097 169.921774 
-L 717.294652 411.847096 
-L 718.900834 169.921774 
-L 720.501663 411.847096 
-L 722.097156 169.921774 
-L 723.68733 411.847096 
-L 725.272204 169.921774 
-L 726.851795 411.847096 
-L 728.42612 169.921774 
-L 729.995198 411.847096 
-L 731.559046 169.921774 
-L 733.117681 411.847096 
-L 734.67112 169.921774 
-L 736.219381 411.847096 
-L 737.762481 169.921774 
-L 739.300438 411.847096 
-L 740.833268 169.921774 
-L 742.360989 411.847096 
-L 743.883617 169.921774 
-L 745.40117 411.847096 
-L 746.913664 169.921774 
-L 748.421117 411.847096 
-L 749.923545 169.921774 
-L 751.420964 411.847096 
-L 752.913393 169.921774 
-L 754.400846 411.847096 
-L 755.883342 169.921774 
-L 757.360896 411.847096 
-L 758.833524 169.921774 
-L 760.301244 411.847096 
-L 761.764071 169.921774 
-L 763.222023 411.847096 
-L 764.675114 169.921774 
-L 766.123362 411.847096 
-L 767.566782 169.921774 
-L 769.005391 411.847096 
-L 770.439205 169.921774 
-L 771.868239 411.847096 
-L 773.29251 169.921774 
-L 774.712033 411.847096 
-L 776.126824 169.921774 
-L 777.5369 411.847096 
-L 778.942275 169.921774 
-L 780.342966 411.847096 
-L 781.738987 169.921774 
-L 783.130356 411.847096 
-L 784.517086 169.921774 
-L 785.899194 411.847096 
-L 787.276695 169.921774 
-L 788.649604 411.847096 
-L 790.017937 169.921774 
-L 791.381709 411.847096 
-L 792.740935 169.921774 
-L 794.09563 411.847096 
-L 795.445809 169.921774 
-L 796.791488 411.847096 
-L 798.132681 169.921774 
-L 799.469404 411.847096 
-L 800.801671 169.921774 
-L 802.129497 411.847096 
-L 803.452897 169.921774 
-L 804.771885 411.847096 
-L 806.086477 169.921774 
-L 807.396687 411.847096 
-L 808.70253 169.921774 
-L 810.00402 411.847096 
-L 811.301171 169.921774 
-L 812.593999 411.847096 
-L 813.882517 169.921774 
-L 815.16674 411.847096 
-L 816.446683 169.921774 
-L 817.722359 411.847096 
-L 818.993782 169.921774 
-L 820.260968 411.847096 
-L 821.52393 169.921774 
-L 822.782681 411.847096 
-L 824.037237 169.921774 
-L 825.287611 411.847096 
-L 826.533818 169.921774 
-L 827.77587 411.847096 
-L 829.013782 169.921774 
-L 830.247567 411.847096 
-L 831.47724 169.921774 
-L 832.702815 411.847096 
-L 833.924303 169.921774 
-L 835.141721 411.847096 
-L 836.35508 169.921774 
-L 837.564394 411.847096 
-L 838.769678 169.921774 
-L 839.970944 411.847096 
-L 841.168206 169.921774 
-L 842.361477 411.847096 
-L 843.55077 169.921774 
-L 844.736099 411.847096 
-L 845.917477 169.921774 
-L 847.094917 411.847096 
-L 848.268432 169.921774 
-L 849.438035 411.847096 
-L 850.60374 169.921774 
-L 851.765559 411.847096 
-L 852.923506 169.921774 
-L 854.077592 411.847096 
-L 855.227832 169.921774 
-L 856.374237 411.847096 
-L 857.516821 169.921774 
-L 858.655597 411.847096 
-L 859.790576 169.921774 
-L 860.921773 411.847096 
-L 862.049198 169.921774 
-L 863.172866 411.847096 
-L 864.292788 169.921774 
-L 865.408977 411.847096 
-L 866.521445 169.921774 
-L 867.630205 411.847096 
-L 868.735269 169.921774 
-L 869.83665 411.847096 
-L 870.934359 169.921774 
-L 872.02841 411.847096 
-L 873.118813 169.921774 
-L 874.205582 411.847096 
-L 875.288728 169.921774 
-L 876.368264 411.847096 
-L 877.444202 169.921774 
-L 878.516552 411.847096 
-L 879.585329 169.921774 
-L 880.650543 411.847096 
-L 881.712206 169.921774 
-L 882.77033 411.847096 
-L 883.824927 169.921774 
-L 884.876009 411.847096 
-L 885.923587 169.921774 
-L 886.967673 411.847096 
-L 888.008279 169.921774 
-L 889.045417 411.847096 
-L 890.079097 169.921774 
-L 891.109331 411.847096 
-L 892.136132 169.921774 
-L 893.15951 411.847096 
-L 894.179476 169.921774 
-L 895.196043 411.847096 
-L 896.209221 169.921774 
-L 897.219022 411.847096 
-L 898.225457 169.921774 
-L 899.228537 411.847096 
-L 900.228273 169.921774 
-L 901.224677 411.847096 
-L 902.21776 169.921774 
-L 903.207532 411.847096 
-L 904.194005 169.921774 
-L 905.17719 411.847096 
-L 906.157098 169.921774 
-L 907.133739 411.847096 
-L 908.107125 169.921774 
-L 909.077266 411.847096 
-L 910.044173 169.921774 
-L 911.007857 411.847096 
-L 911.968329 169.921774 
-L 912.9256 411.847096 
-L 913.879679 169.921774 
-L 914.830579 411.847096 
-L 915.778308 169.921774 
-L 916.722879 411.847096 
-L 917.664301 169.921774 
-L 918.602585 411.847096 
-L 919.537741 169.921774 
-L 920.46978 411.847096 
-L 921.398712 169.921774 
-L 922.324548 411.847096 
-L 923.247298 169.921774 
-L 924.166972 411.847096 
-L 925.08358 169.921774 
-L 925.997133 411.847096 
-L 926.907641 169.921774 
-L 927.815114 411.847096 
-L 928.719562 169.921774 
-L 929.620995 411.847096 
-L 930.519423 169.921774 
-L 931.414856 411.847096 
-L 932.307305 169.921774 
-L 933.196779 411.847096 
-L 934.083288 169.921774 
-L 934.966842 411.847096 
-L 935.847451 169.921774 
-L 936.725124 411.847096 
-L 937.599872 169.921774 
-L 938.471704 411.847096 
-L 939.34063 169.921774 
-L 940.206659 411.847096 
-L 941.069802 169.921774 
-L 941.930067 411.847096 
-L 942.787465 169.921774 
-L 943.642005 411.847096 
-L 944.493697 169.921774 
-L 945.342549 411.847096 
-L 946.188572 169.921774 
-L 947.031775 411.847096 
-L 947.872168 169.921774 
-L 948.709759 411.847096 
-L 949.544558 169.921774 
-L 950.376574 411.847096 
-L 951.205817 169.921774 
-L 952.032296 411.847096 
-L 952.85602 169.921774 
-L 953.676998 411.847096 
-L 954.49524 169.921774 
-L 955.310754 411.847096 
-L 956.123549 169.921774 
-L 956.933636 411.847096 
-L 957.741022 169.921774 
-L 958.545717 411.847096 
-L 959.347729 169.921774 
-L 960.147068 411.847096 
-L 960.943743 169.921774 
-L 961.737762 411.847096 
-L 962.529134 169.921774 
-L 963.317869 411.847096 
-L 964.103974 169.921774 
-L 964.887459 411.847096 
-L 965.668333 169.921774 
-L 966.446603 411.847096 
-L 967.222279 169.921774 
-L 967.99537 411.847096 
-L 968.765884 169.921774 
-L 969.533829 411.847096 
-L 970.299214 169.921774 
-L 971.062048 411.847096 
-L 971.82234 169.921774 
-L 972.580097 411.847096 
-L 973.335328 169.921774 
-L 974.088042 411.847096 
-L 974.838247 169.921774 
-L 975.585951 411.847096 
-L 976.331163 169.921774 
-L 977.07389 411.847096 
-L 977.814142 169.921774 
-L 978.551927 411.847096 
-L 979.287252 169.921774 
-L 980.020126 411.847096 
-L 980.750557 169.921774 
-L 981.478553 411.847096 
-L 982.204123 169.921774 
-L 982.927274 411.847096 
-L 983.648015 169.921774 
-L 984.366353 411.847096 
-L 985.082297 169.921774 
-L 985.795854 411.847096 
-L 986.507033 169.921774 
-L 987.215841 411.847096 
-L 987.922286 169.921774 
-L 988.626377 411.847096 
-L 989.32812 169.921774 
-L 990.027525 411.847096 
-L 990.724598 169.921774 
-L 991.419348 411.847096 
-L 992.111781 169.921774 
-L 992.801907 411.847096 
-L 993.489732 169.921774 
-L 994.175265 411.847096 
-L 994.858512 169.921774 
-L 995.539482 411.847096 
-L 996.218182 169.921774 
-L 996.218182 169.921774 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #4c72b0; stroke-width: 1.5; stroke-linecap: round"/>
+    <path d="M 184.581818 447.44377 
+L 187.905786 177.8088 
+L 190.604223 447.44377 
+L 193.905996 177.8088 
+L 196.586414 447.44377 
+L 199.866139 177.8088 
+L 202.528659 447.44377 
+L 205.786484 177.8088 
+L 208.431225 447.44377 
+L 211.667297 177.8088 
+L 214.294377 447.44377 
+L 217.50884 177.8088 
+L 220.118379 447.44377 
+L 223.311377 177.8088 
+L 225.903491 447.44377 
+L 229.075168 177.8088 
+L 231.649973 447.44377 
+L 234.800471 177.8088 
+L 237.358083 447.44377 
+L 240.487544 177.8088 
+L 243.028078 447.44377 
+L 246.136642 177.8088 
+L 248.660212 447.44377 
+L 251.748019 177.8088 
+L 254.254737 447.44377 
+L 257.321926 177.8088 
+L 259.811905 447.44377 
+L 262.858613 177.8088 
+L 265.331966 447.44377 
+L 268.35833 177.8088 
+L 270.815167 447.44377 
+L 273.821322 177.8088 
+L 276.261754 447.44377 
+L 279.247836 177.8088 
+L 281.671972 447.44377 
+L 284.638114 177.8088 
+L 287.046064 447.44377 
+L 289.9924 177.8088 
+L 292.38427 447.44377 
+L 295.310932 177.8088 
+L 297.686831 447.44377 
+L 300.59395 177.8088 
+L 302.953984 447.44377 
+L 305.841691 177.8088 
+L 308.185966 447.44377 
+L 311.054391 177.8088 
+L 313.383012 447.44377 
+L 316.232283 177.8088 
+L 318.545355 447.44377 
+L 321.3756 177.8088 
+L 323.673227 447.44377 
+L 326.484573 177.8088 
+L 328.766857 447.44377 
+L 331.559431 177.8088 
+L 333.826476 447.44377 
+L 336.600402 177.8088 
+L 338.852308 447.44377 
+L 341.607712 177.8088 
+L 343.844582 447.44377 
+L 346.581587 177.8088 
+L 348.803519 447.44377 
+L 351.522248 177.8088 
+L 353.729344 447.44377 
+L 356.429919 177.8088 
+L 358.622277 447.44377 
+L 361.304818 177.8088 
+L 363.482537 447.44377 
+L 366.147166 177.8088 
+L 368.310344 447.44377 
+L 370.95718 177.8088 
+L 373.105913 447.44377 
+L 375.735075 177.8088 
+L 377.86946 447.44377 
+L 380.481066 177.8088 
+L 382.601198 447.44377 
+L 385.195366 177.8088 
+L 387.301341 447.44377 
+L 389.878186 177.8088 
+L 391.970099 447.44377 
+L 394.529737 177.8088 
+L 396.607681 447.44377 
+L 399.150228 177.8088 
+L 401.214297 447.44377 
+L 403.739865 177.8088 
+L 405.790152 447.44377 
+L 408.298856 177.8088 
+L 410.335451 447.44377 
+L 412.827404 177.8088 
+L 414.8504 447.44377 
+L 417.325713 177.8088 
+L 419.335201 447.44377 
+L 421.793985 177.8088 
+L 423.790055 447.44377 
+L 426.23242 177.8088 
+L 428.215161 447.44377 
+L 430.641218 177.8088 
+L 432.61072 447.44377 
+L 435.020576 177.8088 
+L 436.976927 447.44377 
+L 439.370692 177.8088 
+L 441.313979 447.44377 
+L 443.69176 177.8088 
+L 445.622071 447.44377 
+L 447.983974 177.8088 
+L 449.901395 447.44377 
+L 452.247527 177.8088 
+L 454.152145 447.44377 
+L 456.482611 177.8088 
+L 458.374511 447.44377 
+L 460.689415 177.8088 
+L 462.568682 447.44377 
+L 464.868128 177.8088 
+L 466.734846 447.44377 
+L 469.018939 177.8088 
+L 470.873192 447.44377 
+L 473.142032 177.8088 
+L 474.983904 447.44377 
+L 477.237594 177.8088 
+L 479.067166 447.44377 
+L 481.305808 177.8088 
+L 483.123164 447.44377 
+L 485.346857 177.8088 
+L 487.152077 447.44377 
+L 489.360922 177.8088 
+L 491.154088 447.44377 
+L 493.348183 177.8088 
+L 495.129375 447.44377 
+L 497.308819 177.8088 
+L 499.078118 447.44377 
+L 501.243009 177.8088 
+L 503.000493 447.44377 
+L 505.150928 177.8088 
+L 506.896677 447.44377 
+L 509.032752 177.8088 
+L 510.766844 447.44377 
+L 512.888656 177.8088 
+L 514.611168 447.44377 
+L 516.718812 177.8088 
+L 518.429822 447.44377 
+L 520.523393 177.8088 
+L 522.222978 447.44377 
+L 524.302568 177.8088 
+L 525.990805 447.44377 
+L 528.056509 177.8088 
+L 529.733472 447.44377 
+L 531.785383 177.8088 
+L 533.451148 447.44377 
+L 535.489357 177.8088 
+L 537.143999 447.44377 
+L 539.168598 177.8088 
+L 540.812192 447.44377 
+L 542.823272 177.8088 
+L 544.45589 447.44377 
+L 546.453541 177.8088 
+L 548.075258 447.44377 
+L 550.05957 177.8088 
+L 551.670458 447.44377 
+L 553.64152 177.8088 
+L 555.241651 447.44377 
+L 557.199551 177.8088 
+L 558.788998 447.44377 
+L 560.733824 177.8088 
+L 562.312657 447.44377 
+L 564.244497 177.8088 
+L 565.812787 447.44377 
+L 567.731728 177.8088 
+L 569.289546 447.44377 
+L 571.195672 177.8088 
+L 572.743089 447.44377 
+L 574.636487 177.8088 
+L 576.17357 447.44377 
+L 578.054326 177.8088 
+L 579.581145 447.44377 
+L 581.449342 177.8088 
+L 582.965966 447.44377 
+L 584.821689 177.8088 
+L 586.328186 447.44377 
+L 588.171516 177.8088 
+L 589.667954 447.44377 
+L 591.498976 177.8088 
+L 592.985421 447.44377 
+L 594.804216 177.8088 
+L 596.280736 447.44377 
+L 598.087386 177.8088 
+L 599.554046 447.44377 
+L 601.348633 177.8088 
+L 602.8055 447.44377 
+L 604.588103 177.8088 
+L 606.035242 447.44377 
+L 607.805942 177.8088 
+L 609.243417 447.44377 
+L 611.002294 177.8088 
+L 612.43017 447.44377 
+L 614.177302 177.8088 
+L 615.595644 447.44377 
+L 617.331109 177.8088 
+L 618.73998 447.44377 
+L 620.463857 177.8088 
+L 621.863321 447.44377 
+L 623.575687 177.8088 
+L 624.965805 447.44377 
+L 626.666737 177.8088 
+L 628.047573 447.44377 
+L 629.737147 177.8088 
+L 631.108763 447.44377 
+L 632.787054 177.8088 
+L 634.149511 447.44377 
+L 635.816596 177.8088 
+L 637.169955 447.44377 
+L 638.825908 177.8088 
+L 640.170231 447.44377 
+L 641.815126 177.8088 
+L 643.150472 447.44377 
+L 644.784384 177.8088 
+L 646.110813 447.44377 
+L 647.733814 177.8088 
+L 649.051386 447.44377 
+L 650.66355 177.8088 
+L 651.972324 447.44377 
+L 653.573723 177.8088 
+L 654.873757 447.44377 
+L 656.464463 177.8088 
+L 657.755817 447.44377 
+L 659.3359 177.8088 
+L 660.618631 447.44377 
+L 662.188164 177.8088 
+L 663.462329 447.44377 
+L 665.021382 177.8088 
+L 666.287039 447.44377 
+L 667.835681 177.8088 
+L 669.092887 447.44377 
+L 670.631188 177.8088 
+L 671.879999 447.44377 
+L 673.408028 177.8088 
+L 674.6485 447.44377 
+L 676.166326 177.8088 
+L 677.398514 447.44377 
+L 678.906205 177.8088 
+L 680.130166 447.44377 
+L 681.627789 177.8088 
+L 682.843577 447.44377 
+L 684.3312 177.8088 
+L 685.53887 447.44377 
+L 687.016559 177.8088 
+L 688.216165 447.44377 
+L 689.683987 177.8088 
+L 690.875582 447.44377 
+L 692.333603 177.8088 
+L 693.517241 447.44377 
+L 694.965526 177.8088 
+L 696.141261 447.44377 
+L 697.579875 177.8088 
+L 698.747759 447.44377 
+L 700.176767 177.8088 
+L 701.336852 447.44377 
+L 702.756318 177.8088 
+L 703.908657 447.44377 
+L 705.318645 177.8088 
+L 706.463289 447.44377 
+L 707.863861 177.8088 
+L 709.000862 447.44377 
+L 710.392082 177.8088 
+L 711.521491 447.44377 
+L 712.903421 177.8088 
+L 714.025289 447.44377 
+L 715.397991 177.8088 
+L 716.512367 447.44377 
+L 717.875903 177.8088 
+L 718.982838 447.44377 
+L 720.33727 177.8088 
+L 721.436813 447.44377 
+L 722.7822 177.8088 
+L 723.874402 447.44377 
+L 725.210805 177.8088 
+L 726.295713 447.44377 
+L 727.623193 177.8088 
+L 728.700857 447.44377 
+L 730.019473 177.8088 
+L 731.08994 447.44377 
+L 732.399751 177.8088 
+L 733.463071 447.44377 
+L 734.764135 177.8088 
+L 735.820355 447.44377 
+L 737.112731 177.8088 
+L 738.161898 447.44377 
+L 739.445645 177.8088 
+L 740.487806 447.44377 
+L 741.76298 177.8088 
+L 742.798182 447.44377 
+L 744.064842 177.8088 
+L 745.093132 447.44377 
+L 746.351333 177.8088 
+L 747.372757 447.44377 
+L 748.622557 177.8088 
+L 749.637159 447.44377 
+L 750.878614 177.8088 
+L 751.886442 447.44377 
+L 753.119607 177.8088 
+L 754.120705 447.44377 
+L 755.345635 177.8088 
+L 756.340049 447.44377 
+L 757.5568 177.8088 
+L 758.544573 447.44377 
+L 759.753199 177.8088 
+L 760.734377 447.44377 
+L 761.934933 177.8088 
+L 762.909558 447.44377 
+L 764.102097 177.8088 
+L 765.070215 447.44377 
+L 766.254791 177.8088 
+L 767.216444 447.44377 
+L 768.39311 177.8088 
+L 769.348342 447.44377 
+L 770.517151 177.8088 
+L 771.466004 447.44377 
+L 772.627009 177.8088 
+L 773.569526 447.44377 
+L 774.722778 177.8088 
+L 775.659001 447.44377 
+L 776.804553 177.8088 
+L 777.734525 447.44377 
+L 778.872426 177.8088 
+L 779.796189 447.44377 
+L 780.926492 177.8088 
+L 781.844086 447.44377 
+L 782.966842 177.8088 
+L 783.878309 447.44377 
+L 784.993567 177.8088 
+L 785.898948 447.44377 
+L 787.00676 177.8088 
+L 787.906094 447.44377 
+L 789.006509 177.8088 
+L 789.899838 447.44377 
+L 790.992905 177.8088 
+L 791.880269 447.44377 
+L 792.966037 177.8088 
+L 793.847476 447.44377 
+L 794.925993 177.8088 
+L 795.801547 447.44377 
+L 796.872862 177.8088 
+L 797.742569 447.44377 
+L 798.806731 177.8088 
+L 799.670631 447.44377 
+L 800.727687 177.8088 
+L 801.585818 447.44377 
+L 802.635815 177.8088 
+L 803.488216 447.44377 
+L 804.531203 177.8088 
+L 805.377911 447.44377 
+L 806.413933 177.8088 
+L 807.254988 447.44377 
+L 808.284092 177.8088 
+L 809.119531 447.44377 
+L 810.141763 177.8088 
+L 810.971624 447.44377 
+L 811.98703 177.8088 
+L 812.811349 447.44377 
+L 813.819975 177.8088 
+L 814.63879 447.44377 
+L 815.640681 177.8088 
+L 816.454028 447.44377 
+L 817.449229 177.8088 
+L 818.257144 447.44377 
+L 819.2457 177.8088 
+L 820.048221 447.44377 
+L 821.030176 177.8088 
+L 821.827338 447.44377 
+L 822.802736 177.8088 
+L 823.594575 447.44377 
+L 824.563459 177.8088 
+L 825.350011 447.44377 
+L 826.312426 177.8088 
+L 827.093726 447.44377 
+L 828.049714 177.8088 
+L 828.825797 447.44377 
+L 829.775401 177.8088 
+L 830.546302 447.44377 
+L 831.489566 177.8088 
+L 832.255318 447.44377 
+L 833.192284 177.8088 
+L 833.952923 447.44377 
+L 834.883632 177.8088 
+L 835.639192 447.44377 
+L 836.563686 177.8088 
+L 837.314201 447.44377 
+L 838.232522 177.8088 
+L 838.978026 447.44377 
+L 839.890214 177.8088 
+L 840.63074 447.44377 
+L 841.536837 177.8088 
+L 842.272418 447.44377 
+L 843.172465 177.8088 
+L 843.903134 447.44377 
+L 844.797171 177.8088 
+L 845.522961 447.44377 
+L 846.411029 177.8088 
+L 847.131972 447.44377 
+L 848.01411 177.8088 
+L 848.730239 447.44377 
+L 849.606486 177.8088 
+L 850.317833 447.44377 
+L 851.188229 177.8088 
+L 851.894827 447.44377 
+L 852.759411 177.8088 
+L 853.46129 447.44377 
+L 854.3201 177.8088 
+L 855.017293 447.44377 
+L 855.870369 177.8088 
+L 856.562906 447.44377 
+L 857.410286 177.8088 
+L 858.098198 447.44377 
+L 858.93992 177.8088 
+L 859.623239 447.44377 
+L 860.459339 177.8088 
+L 861.138096 447.44377 
+L 861.968614 177.8088 
+L 862.642838 447.44377 
+L 863.46781 177.8088 
+L 864.137532 447.44377 
+L 864.956995 177.8088 
+L 865.622245 447.44377 
+L 866.436236 177.8088 
+L 867.097044 447.44377 
+L 867.9056 177.8088 
+L 868.561995 447.44377 
+L 869.365152 177.8088 
+L 870.017164 447.44377 
+L 870.814958 177.8088 
+L 871.462616 447.44377 
+L 872.255083 177.8088 
+L 872.898417 447.44377 
+L 873.685592 177.8088 
+L 874.32463 447.44377 
+L 875.106548 177.8088 
+L 875.741319 447.44377 
+L 876.518017 177.8088 
+L 877.148549 447.44377 
+L 877.92006 177.8088 
+L 878.546382 447.44377 
+L 879.312741 177.8088 
+L 879.934881 447.44377 
+L 880.696123 177.8088 
+L 881.314108 447.44377 
+L 882.070267 177.8088 
+L 882.684126 447.44377 
+L 883.435235 177.8088 
+L 884.044995 447.44377 
+L 884.791089 177.8088 
+L 885.396777 447.44377 
+L 886.137889 177.8088 
+L 886.739533 447.44377 
+L 887.475697 177.8088 
+L 888.073323 447.44377 
+L 888.804571 177.8088 
+L 889.398206 447.44377 
+L 890.124571 177.8088 
+L 890.714243 447.44377 
+L 891.435757 177.8088 
+L 892.021492 447.44377 
+L 892.738188 177.8088 
+L 893.320011 447.44377 
+L 894.031922 177.8088 
+L 894.60986 447.44377 
+L 895.317018 177.8088 
+L 895.891096 447.44377 
+L 896.593532 177.8088 
+L 897.163777 447.44377 
+L 897.861522 177.8088 
+L 898.427959 447.44377 
+L 899.121045 177.8088 
+L 899.6837 447.44377 
+L 900.372158 177.8088 
+L 900.931056 447.44377 
+L 901.614917 177.8088 
+L 902.170083 447.44377 
+L 902.849377 177.8088 
+L 903.400836 447.44377 
+L 904.075594 177.8088 
+L 904.623371 447.44377 
+L 905.293623 177.8088 
+L 905.837742 447.44377 
+L 906.503519 177.8088 
+L 907.044005 447.44377 
+L 907.705336 177.8088 
+L 908.242213 447.44377 
+L 908.899128 177.8088 
+L 909.432419 447.44377 
+L 910.084948 177.8088 
+L 910.614679 447.44377 
+L 911.26285 177.8088 
+L 911.789044 447.44377 
+L 912.432887 177.8088 
+L 912.955567 447.44377 
+L 913.595111 177.8088 
+L 914.1143 447.44377 
+L 914.749574 177.8088 
+L 915.265297 447.44377 
+L 915.896328 177.8088 
+L 916.408607 447.44377 
+L 917.035425 177.8088 
+L 917.544284 447.44377 
+L 918.166916 177.8088 
+L 918.672377 447.44377 
+L 919.290851 177.8088 
+L 919.792937 447.44377 
+L 920.407282 177.8088 
+L 920.906014 447.44377 
+L 921.516257 177.8088 
+L 922.011659 447.44377 
+L 922.617827 177.8088 
+L 923.109922 447.44377 
+L 923.712042 177.8088 
+L 924.20085 447.44377 
+L 924.79895 177.8088 
+L 925.284494 447.44377 
+L 925.8786 177.8088 
+L 926.360902 447.44377 
+L 926.951041 177.8088 
+L 927.430123 447.44377 
+L 928.016321 177.8088 
+L 928.492203 447.44377 
+L 929.074487 177.8088 
+L 929.547192 447.44377 
+L 930.125588 177.8088 
+L 930.595136 447.44377 
+L 931.16967 177.8088 
+L 931.636083 447.44377 
+L 932.20678 177.8088 
+L 932.670079 447.44377 
+L 933.236965 177.8088 
+L 933.69717 447.44377 
+L 934.260271 177.8088 
+L 934.717403 447.44377 
+L 935.276744 177.8088 
+L 935.730823 447.44377 
+L 936.286429 177.8088 
+L 936.737477 447.44377 
+L 937.289372 177.8088 
+L 937.737408 447.44377 
+L 938.285619 177.8088 
+L 938.730662 447.44377 
+L 939.275212 177.8088 
+L 939.717285 447.44377 
+L 940.258198 177.8088 
+L 940.697319 447.44377 
+L 941.23462 177.8088 
+L 941.670808 447.44377 
+L 942.204522 177.8088 
+L 942.637798 447.44377 
+L 943.167948 177.8088 
+L 943.59833 447.44377 
+L 944.12494 177.8088 
+L 944.552449 447.44377 
+L 945.075543 177.8088 
+L 945.500196 447.44377 
+L 946.019797 177.8088 
+L 946.441615 447.44377 
+L 946.957746 177.8088 
+L 947.376748 447.44377 
+L 947.889433 177.8088 
+L 948.305636 447.44377 
+L 948.814898 177.8088 
+L 949.228322 447.44377 
+L 949.734183 177.8088 
+L 950.144847 447.44377 
+L 950.64733 177.8088 
+L 951.055251 447.44377 
+L 951.554379 177.8088 
+L 951.959577 447.44377 
+L 952.455371 177.8088 
+L 952.857863 447.44377 
+L 953.350348 177.8088 
+L 953.750152 447.44377 
+L 954.239348 177.8088 
+L 954.636482 447.44377 
+L 955.122411 177.8088 
+L 955.516894 447.44377 
+L 955.999579 177.8088 
+L 956.391427 447.44377 
+L 956.870888 177.8088 
+L 957.260121 447.44377 
+L 957.73638 177.8088 
+L 958.123013 447.44377 
+L 958.596093 177.8088 
+L 958.980144 447.44377 
+L 959.450065 177.8088 
+L 959.831552 447.44377 
+L 960.298334 177.8088 
+L 960.677274 447.44377 
+L 961.14094 177.8088 
+L 961.517349 447.44377 
+L 961.977918 177.8088 
+L 962.351814 447.44377 
+L 962.809308 177.8088 
+L 963.180708 447.44377 
+L 963.635147 177.8088 
+L 964.004066 447.44377 
+L 964.455471 177.8088 
+L 964.821926 447.44377 
+L 965.270317 177.8088 
+L 965.634326 447.44377 
+L 966.079722 177.8088 
+L 966.4413 447.44377 
+L 966.883722 177.8088 
+L 967.242886 447.44377 
+L 967.682354 177.8088 
+L 968.03912 447.44377 
+L 968.475653 177.8088 
+L 968.830036 447.44377 
+L 969.263655 177.8088 
+L 969.615672 447.44377 
+L 970.046395 177.8088 
+L 970.396061 447.44377 
+L 970.823908 177.8088 
+L 971.171239 447.44377 
+L 971.596229 177.8088 
+L 971.941241 447.44377 
+L 972.363394 177.8088 
+L 972.706102 447.44377 
+L 973.125435 177.8088 
+L 973.465855 447.44377 
+L 973.882388 177.8088 
+L 974.220535 447.44377 
+L 974.634287 177.8088 
+L 974.970176 447.44377 
+L 975.381165 177.8088 
+L 975.71481 447.44377 
+L 976.123055 177.8088 
+L 976.454473 447.44377 
+L 976.859992 177.8088 
+L 977.189197 447.44377 
+L 977.592008 177.8088 
+L 977.919014 447.44377 
+L 978.319136 177.8088 
+L 978.643959 447.44377 
+L 979.041408 177.8088 
+L 979.364062 447.44377 
+L 979.758858 177.8088 
+L 980.079357 447.44377 
+L 980.471516 177.8088 
+L 980.789876 447.44377 
+L 981.179416 177.8088 
+L 981.49565 447.44377 
+L 981.88259 177.8088 
+L 982.196712 447.44377 
+L 982.581067 177.8088 
+L 982.893092 447.44377 
+L 983.274881 177.8088 
+L 983.584822 447.44377 
+L 983.964062 177.8088 
+L 984.271933 447.44377 
+L 984.648641 177.8088 
+L 984.954456 447.44377 
+L 985.328648 177.8088 
+L 985.632422 447.44377 
+L 986.004115 177.8088 
+L 986.30586 447.44377 
+L 986.675072 177.8088 
+L 986.974802 447.44377 
+L 987.341548 177.8088 
+L 987.639276 447.44377 
+L 988.003574 177.8088 
+L 988.299314 447.44377 
+L 988.661179 177.8088 
+L 988.954945 447.44377 
+L 989.314393 177.8088 
+L 989.606197 447.44377 
+L 989.963245 177.8088 
+L 990.253101 447.44377 
+L 990.607765 177.8088 
+L 990.895685 447.44377 
+L 991.247981 177.8088 
+L 991.533978 447.44377 
+L 991.883922 177.8088 
+L 992.16801 447.44377 
+L 992.515616 177.8088 
+L 992.797807 447.44377 
+L 993.143092 177.8088 
+L 993.423399 447.44377 
+L 993.766379 177.8088 
+L 994.044814 447.44377 
+L 994.385503 177.8088 
+L 994.662079 447.44377 
+L 995.000494 177.8088 
+L 995.275222 447.44377 
+L 995.611377 177.8088 
+L 995.884272 447.44377 
+L 996.218182 177.8088 
+L 996.218182 177.8088 
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #4c72b0; stroke-width: 1.5; stroke-linecap: round"/>
    </g>
    <g id="line2d_14">
     <path d="M 184.581818 89.28 
 L 996.218182 492.48 
 L 996.218182 492.48 
-" clip-path="url(#pb647630257)" style="fill: none; stroke: #dd8452; stroke-width: 1.5; stroke-linecap: round"/>
+" clip-path="url(#p2cce2f2c75)" style="fill: none; stroke: #dd8452; stroke-width: 1.5; stroke-linecap: round"/>
    </g>
    <g id="line2d_15"/>
    <g id="line2d_16"/>
@@ -1307,7 +1514,7 @@ L 992.865937 116.787969
   </g>
  </g>
  <defs>
-  <clipPath id="pb647630257">
+  <clipPath id="p2cce2f2c75">
    <rect x="144" y="69.12" width="892.8" height="443.52"/>
   </clipPath>
  </defs>
index 3a56ff0..829efef 100644 (file)
@@ -5,20 +5,39 @@
 
 #include "simgrid/plugins/battery.hpp"
 #include "simgrid/s4u.hpp"
+#include <memory>
+#include <simgrid/s4u/Actor.hpp>
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(battery_degradation, "Messages specific for this s4u example");
 
 static void manager()
 {
-  const auto* battery = simgrid::s4u::this_actor::get_host();
-  double power = 100;
-  while (sg_battery_get_state_of_health(battery) > 0) {
-    XBT_INFO("%f,%f,SoC", simgrid::s4u::Engine::get_clock(), sg_battery_get_state_of_charge(battery));
-    XBT_INFO("%f,%f,SoH", simgrid::s4u::Engine::get_clock(), sg_battery_get_state_of_health(battery));
-    sg_battery_set_power(battery, power);
-    simgrid::s4u::this_actor::sleep_until(sg_battery_get_next_event_date(battery));
-    power *= -1;
-  }
+  auto battery = simgrid::plugins::Battery::init("Battery", 0.8, 0.9, 0.9, 10, 100, 0.9);
+
+  battery->set_load("load", 100);
+
+  auto event1 = battery->create_event(
+      0.2, simgrid::plugins::Battery::DISCHARGE,
+      [battery]() {
+        XBT_INFO("%f,%f,SoC", simgrid::s4u::Engine::get_clock(), battery->get_state_of_charge());
+        XBT_INFO("%f,%f,SoH", simgrid::s4u::Engine::get_clock(), battery->get_state_of_health());
+        battery->set_load("load", -100);
+      },
+      true);
+
+  std::shared_ptr<simgrid::plugins::Battery::Event> event2;
+  event2 = battery->create_event(
+      0.8, simgrid::plugins::Battery::CHARGE,
+      [battery, event1, event2]() {
+        XBT_INFO("%f,%f,SoC", simgrid::s4u::Engine::get_clock(), battery->get_state_of_charge());
+        XBT_INFO("%f,%f,SoH", simgrid::s4u::Engine::get_clock(), battery->get_state_of_health());
+        if (battery->get_state_of_health() < 0.1) {
+          battery->delete_event(event1);
+          battery->delete_event(event2);
+        }
+        battery->set_load("load", 100);
+      },
+      true);
 }
 
 int main(int argc, char* argv[])
@@ -26,9 +45,8 @@ int main(int argc, char* argv[])
   simgrid::s4u::Engine e(&argc, argv);
   e.load_platform(argv[1]);
 
-  sg_battery_plugin_init();
+  simgrid::s4u::Actor::create("manager", e.host_by_name("MyHost1"), manager);
 
-  simgrid::s4u::Actor::create("manager", e.get_all_hosts()[0], manager);
   e.run();
   return 0;
 }
index 876bd7a..5af4728 100644 (file)
@@ -2,4 +2,4 @@
 
 ! output ignore 
 
-$ ${bindir:=.}/s4u-battery-degradation ${platfdir}/battery_platform.xml
+$ ${bindir:=.}/s4u-battery-degradation ${platfdir}/energy_platform.xml
index 558cbc2..09645ca 100644 (file)
@@ -6,68 +6,57 @@
 #include "simgrid/plugins/battery.hpp"
 #include "simgrid/plugins/energy.h"
 #include "simgrid/s4u.hpp"
-
-#include <iostream>
+#include <simgrid/s4u/Actor.hpp>
+#include <simgrid/s4u/Engine.hpp>
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(battery_energy, "Messages specific for this s4u example");
 
 static void manager()
 {
-  const auto* battery = simgrid::s4u::Engine::get_instance()->host_by_name("battery");
-  auto* host1         = simgrid::s4u::Engine::get_instance()->host_by_name("host1");
-  auto* host2         = simgrid::s4u::Engine::get_instance()->host_by_name("host2");
-
-  XBT_INFO("Initial Battery: SoC: %f SoH: %f Capacity (Total): %fWh Capacity (Usable): %fWh P: %fW",
-           sg_battery_get_state_of_charge(battery), sg_battery_get_state_of_health(battery),
-           sg_battery_get_capacity(battery),
-           sg_battery_get_capacity(battery) *
-               (sg_battery_get_state_of_charge_max(battery) - sg_battery_get_state_of_charge_min(battery)),
-           sg_battery_get_power(battery));
-
-  // Start execs on each host
-  simgrid::s4u::ExecPtr exec1 = simgrid::s4u::Exec::init();
-  exec1->set_flops_amount(1e10);
-  exec1->set_host(host1);
-  exec1->start();
-  simgrid::s4u::ExecPtr exec2 = simgrid::s4u::Exec::init();
-  exec2->set_flops_amount(1e10);
-  exec2->set_host(host2);
-  exec2->start();
-  // Set power generation from the battery
-  double total_power_w =
-      sg_host_get_wattmax_at(host1, host1->get_pstate()) + sg_host_get_wattmax_at(host2, host2->get_pstate());
-  sg_battery_set_power(battery, total_power_w);
-  XBT_INFO("Battery power set to: %fW (host1) + %fW (host2)", sg_host_get_wattmax_at(host1, host1->get_pstate()),
-           sg_host_get_wattmax_at(host2, host2->get_pstate()));
-  double end = sg_battery_get_next_event_date(battery);
-  XBT_INFO("The battery will be depleted at: %f", end);
-  XBT_INFO("Exec1 will be finished in: %f", exec1->get_remaining() / host1->get_speed());
-  XBT_INFO("Exec2 will be finished in: %f", exec2->get_remaining() / host2->get_speed());
-  simgrid::s4u::this_actor::sleep_until(end);
-
-  // Battery depleted
-  XBT_INFO("Battery depleted: SoC: %f SoH: %f P: %fW", sg_battery_get_state_of_charge(battery),
-           sg_battery_get_state_of_health(battery), sg_battery_get_power(battery));
-  double energy_battery = sg_host_get_consumed_energy(host1) + sg_host_get_consumed_energy(host2);
-  XBT_INFO("Pursuing with power from the grid until both execs are finished");
-  simgrid::s4u::this_actor::sleep_for(
-      std::max(exec1->get_remaining() / host1->get_speed(), exec2->get_remaining() / host2->get_speed()));
-
-  // Execs finished
-  double energy_grid = sg_host_get_consumed_energy(host1) + sg_host_get_consumed_energy(host2) - energy_battery;
-  XBT_INFO("Energy consumed: Battery: %fJ (%fWh) Grid: %fJ (%fWh)", energy_battery, energy_battery / 3600, energy_grid,
-           energy_grid / 3600);
+  auto battery = simgrid::plugins::Battery::init("Battery", 0.8, 0.9, 0.9, 10, 1000, 0.9);
+
+  auto* host1 = simgrid::s4u::Engine::get_instance()->host_by_name("MyHost1");
+  auto* host2 = simgrid::s4u::Engine::get_instance()->host_by_name("MyHost2");
+  auto* host3 = simgrid::s4u::Engine::get_instance()->host_by_name("MyHost3");
+
+  battery->create_event(0.2, simgrid::plugins::Battery::DISCHARGE, [battery, &host1, &host2, &host3]() {
+    XBT_INFO("Event -> Battery low: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ",
+             battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(),
+             battery->get_energy_provided(), battery->get_energy_consumed());
+    XBT_INFO("Disconnecting hosts %s and %s", host1->get_cname(), host2->get_cname());
+    battery->connect_host(host1, false);
+    battery->connect_host(host2, false);
+    XBT_INFO("Energy consumed this far by: %s: %fJ, %s: %fJ, %s: %fJ", host1->get_cname(),
+             sg_host_get_consumed_energy(host1), host2->get_cname(), sg_host_get_consumed_energy(host2),
+             host3->get_cname(), sg_host_get_consumed_energy(host3));
+  });
+
+  XBT_INFO("Battery state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ",
+           battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(),
+           battery->get_energy_provided(), battery->get_energy_consumed());
+  XBT_INFO("Connecting hosts %s and %s to the battery", host1->get_cname(), host2->get_cname());
+  battery->connect_host(host1);
+  battery->connect_host(host2);
+
+  double flops = 1e9;
+  XBT_INFO("Host %s will now execute %f flops", host1->get_cname(), flops);
+  host1->execute(flops);
+
+  simgrid::s4u::this_actor::sleep_until(200);
+  XBT_INFO("Battery state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ",
+           battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(),
+           battery->get_energy_provided(), battery->get_energy_consumed());
 }
 
 int main(int argc, char* argv[])
 {
   simgrid::s4u::Engine e(&argc, argv);
+  // if you plan to use Battery::connect_host you have to init the energy plugin at start.
+  sg_host_energy_plugin_init();
   e.load_platform(argv[1]);
 
-  sg_host_energy_plugin_init();
-  sg_battery_plugin_init();
+  simgrid::s4u::Actor::create("manager", e.host_by_name("MyHost1"), manager);
 
-  simgrid::s4u::Actor::create("manager", e.host_by_name("host1"), manager);
   e.run();
   return 0;
 }
index e0ecf55..43094f4 100644 (file)
@@ -1,15 +1,14 @@
 #!/usr/bin/env tesh
 
-$ ${bindir:=.}/s4u-battery-energy ${platfdir}/battery_platform.xml
-> [host1:manager:(1) 0.000000] [battery_energy/INFO] Initial Battery: SoC: 0.800000 SoH: 1.000000 Capacity (Total): 10.000000Wh Capacity (Usable): 6.000000Wh P: 0.000000W
-> [host1:manager:(1) 0.000000] [battery_energy/INFO] Battery power set to: 200.000000W (host1) + 170.000000W (host2)
-> [host1:manager:(1) 0.000000] [battery_energy/INFO] The battery will be depleted at: 58.378378
-> [host1:manager:(1) 0.000000] [battery_energy/INFO] Exec1 will be finished in: 100.000000
-> [host1:manager:(1) 0.000000] [battery_energy/INFO] Exec2 will be finished in: 200.000000
-> [host1:manager:(1) 58.378378] [battery_energy/INFO] Battery depleted: SoC: 0.200000 SoH: 0.995833 P: 0.000000W
-> [host1:manager:(1) 58.378378] [battery_energy/INFO] Pursuing with power from the grid until both execs are finished
-> [host1:manager:(1) 200.000000] [battery_energy/INFO] Energy consumed: Battery: 21600.000000J (6.000000Wh) Grid: 42400.000000J (11.777778Wh)
-> [200.000000] [host_energy/INFO] Total energy consumption: 64000.000000 Joules (used hosts: 64000.000000 Joules; unused/idle hosts: 0.000000)
-> [200.000000] [host_energy/INFO] Energy consumption of host battery: 0.000000 Joules
-> [200.000000] [host_energy/INFO] Energy consumption of host host1: 30000.000000 Joules
-> [200.000000] [host_energy/INFO] Energy consumption of host host2: 34000.000000 Joules
+$ ${bindir:=.}/s4u-battery-energy ${platfdir}/energy_platform.xml
+> [MyHost1:manager:(1) 0.000000] [battery_energy/INFO] Battery state: SoC: 0.800000 SoH: 1.000000 Energy stored: 28800.000000J Energy provided: 0.000000J Energy consumed 0.000000J
+> [MyHost1:manager:(1) 0.000000] [battery_energy/INFO] Connecting hosts MyHost1 and MyHost2 to the battery
+> [MyHost1:manager:(1) 0.000000] [battery_energy/INFO] Host MyHost1 will now execute 1000000000.000000 flops
+> [96.209721] [battery_energy/INFO] Event -> Battery low: SoC: 0.200000 SoH: 0.999700 Energy stored: 7197.839784J Energy provided: 19441.944194J Energy consumed 0.000000J
+> [96.209721] [battery_energy/INFO] Disconnecting hosts MyHost1 and MyHost2
+> [96.209721] [battery_energy/INFO] Energy consumed this far by: MyHost1: 9820.972097J, MyHost2: 9620.972097J, MyHost3: 9620.972097J
+> [MyHost1:manager:(1) 200.000000] [battery_energy/INFO] Battery state: SoC: 0.200000 SoH: 0.999700 Energy stored: 7197.839784J Energy provided: 19441.944194J Energy consumed 0.000000J
+> [200.000000] [host_energy/INFO] Total energy consumption: 60200.000000 Joules (used hosts: 20200.000000 Joules; unused/idle hosts: 40000.000000)
+> [200.000000] [host_energy/INFO] Energy consumption of host MyHost1: 20200.000000 Joules
+> [200.000000] [host_energy/INFO] Energy consumption of host MyHost2: 20000.000000 Joules
+> [200.000000] [host_energy/INFO] Energy consumption of host MyHost3: 20000.000000 Joules
index 03e9a57..a499370 100644 (file)
@@ -5,37 +5,40 @@
 
 #include "simgrid/plugins/battery.hpp"
 #include "simgrid/s4u.hpp"
+#include <simgrid/s4u/Actor.hpp>
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(battery_simple, "Messages specific for this s4u example");
 
-static void manager()
-{
-  const auto* battery  = simgrid::s4u::Engine::get_instance()->host_by_name("battery");
-  double consumption_w = 200;
-
-  XBT_INFO("Initial Battery: SoC: %f SoH: %f Capacity (Total): %fWh Capacity (Usable): %fWh P: %f",
-           sg_battery_get_state_of_charge(battery), sg_battery_get_state_of_health(battery),
-           sg_battery_get_capacity(battery),
-           sg_battery_get_capacity(battery) *
-               (sg_battery_get_state_of_charge_max(battery) - sg_battery_get_state_of_charge_min(battery)),
-           sg_battery_get_power(battery));
-  double start = simgrid::s4u::Engine::get_clock();
-  sg_battery_set_power(battery, consumption_w);
-  XBT_INFO("Battery power set to: %fW", consumption_w);
-  double end = sg_battery_get_next_event_date(battery);
-  XBT_INFO("The battery will be depleted at: %f", end);
-  simgrid::s4u::this_actor::sleep_until(end);
-  XBT_INFO("Energy consumed : %fJ (%fWh)", (end - start) * consumption_w, (end - start) * consumption_w / 3600);
-}
-
 int main(int argc, char* argv[])
 {
   simgrid::s4u::Engine e(&argc, argv);
   e.load_platform(argv[1]);
 
-  sg_battery_plugin_init();
+  auto battery = simgrid::plugins::Battery::init("Battery", 0.8, 0.9, 0.9, 10, 1000, 0.9);
+
+  XBT_INFO("Initial state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ",
+           battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(),
+           battery->get_energy_provided(), battery->get_energy_consumed());
+
+  double load_w = 100;
+  battery->set_load("load", load_w);
+  XBT_INFO("Set load to %fW", load_w);
+
+  battery->create_event(0.2, simgrid::plugins::Battery::DISCHARGE, [battery, &load_w]() {
+    XBT_INFO("Discharged state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ",
+             battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(),
+             battery->get_energy_provided(), battery->get_energy_consumed());
+    battery->set_load("load", -load_w);
+    XBT_INFO("Set load to %fW", -load_w);
+  });
+
+  battery->create_event(0.8, simgrid::plugins::Battery::CHARGE, [battery]() {
+    XBT_INFO("Charged state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ",
+             battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(),
+             battery->get_energy_provided(), battery->get_energy_consumed());
+    XBT_INFO("Set load to %fW", 0.0);
+  });
 
-  simgrid::s4u::Actor::create("manager", e.host_by_name("host1"), manager);
   e.run();
   return 0;
-}
+}
\ No newline at end of file
index b269145..8870651 100644 (file)
@@ -1,7 +1,9 @@
 #!/usr/bin/env tesh
 
-$ ${bindir:=.}/s4u-battery-simple ${platfdir}/battery_platform.xml
-> [host1:manager:(1) 0.000000] [battery_simple/INFO] Initial Battery: SoC: 0.800000 SoH: 1.000000 Capacity (Total): 10.000000Wh Capacity (Usable): 6.000000Wh P: 0.000000
-> [host1:manager:(1) 0.000000] [battery_simple/INFO] Battery power set to: 200.000000W
-> [host1:manager:(1) 0.000000] [battery_simple/INFO] The battery will be depleted at: 108.000000
-> [host1:manager:(1) 108.000000] [battery_simple/INFO] Energy consumed : 21600.000000J (6.000000Wh)
+$ ${bindir:=.}/s4u-battery-simple ${platfdir}/energy_platform.xml
+> [0.000000] [battery_simple/INFO] Initial state: SoC: 0.800000 SoH: 1.000000 Energy stored: 28800.000000J Energy provided: 0.000000J Energy consumed 0.000000J
+> [0.000000] [battery_simple/INFO] Set load to 100.000000W
+> [194.419442] [battery_simple/INFO] Discharged state: SoC: 0.200000 SoH: 0.999700 Energy stored: 7197.839784J Energy provided: 19441.944194J Energy consumed 0.000000J
+> [194.419442] [battery_simple/INFO] Set load to -100.000000W
+> [434.229010] [battery_simple/INFO] Charged state: SoC: 0.800000 SoH: 0.999330 Energy stored: 28780.700933J Energy provided: 19441.944194J Energy consumed 23980.956832J
+> [434.229010] [battery_simple/INFO] Set load to 0.000000W
\ No newline at end of file
diff --git a/examples/platforms/battery_platform.xml b/examples/platforms/battery_platform.xml
deleted file mode 100644 (file)
index 210b4cb..0000000
+++ /dev/null
@@ -1,33 +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="battery" speed="0f">
-      <!-- For Energy plugin -->
-      <prop id="wattage_per_state" value="0:0:0" />
-      <!---->
-      <!-- For Battery plugin -->
-      <prop id="battery_active" value="1" />
-      <prop id="battery_capacity" value="10" />
-      <prop id="battery_cycles" value="100" />
-      <prop id="battery_state_of_charge" value="0.8" />
-      <!---->
-    </host>
-
-    <host id="host1" core="1" pstate="0" speed="100.0Mf,50.0Mf,20.0Mf">
-      <!-- For Energy plugin -->
-      <prop id="wattage_per_state" value="100.0:200.0:200.0, 93.0:170.0:170.0, 90.0:150.0:150.0" />
-      <prop id="wattage_off" value="10" />
-      <!---->
-    </host>
-
-    <host id="host2" core="1" pstate="1" speed="100.0Mf,50.0Mf,20.0Mf">
-      <!-- For Energy plugin -->
-      <prop id="wattage_per_state" value="100.0:200.0:200.0, 93.0:170.0:170.0, 90.0:150.0:150.0" />
-      <prop id="wattage_off" value="10" />
-      <!---->
-    </host>
-
-
-  </zone>
-</platform>
index d6d7e2c..87746d3 100644 (file)
 
 /* 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_BATTERY_H_
-#define SIMGRID_PLUGINS_BATTERY_H_
 
-#include <simgrid/config.h>
-#include <simgrid/forward.h>
-#include <xbt/base.h>
+#ifndef SIMGRID_PLUGINS_BATTERY_HPP_
+#define SIMGRID_PLUGINS_BATTERY_HPP_
 
-SG_BEGIN_DECL
+#include <memory>
+#include <simgrid/kernel/resource/Model.hpp>
+#include <simgrid/s4u/Activity.hpp>
+#include <xbt/Extendable.hpp>
 
-XBT_PUBLIC void sg_battery_plugin_init();
+namespace simgrid::plugins {
 
-XBT_PUBLIC void sg_battery_set_state(const_sg_host_t host, bool state);
-XBT_PUBLIC void sg_battery_set_power(const_sg_host_t host, double power);
+class Battery;
+using BatteryPtr = boost::intrusive_ptr<Battery>;
+XBT_PUBLIC void intrusive_ptr_release(Battery* o);
+XBT_PUBLIC void intrusive_ptr_add_ref(Battery* o);
 
-XBT_PUBLIC bool sg_battery_is_active(const_sg_host_t host);
-XBT_PUBLIC double sg_battery_get_power(const_sg_host_t host);
-XBT_PUBLIC double sg_battery_get_state_of_charge(const_sg_host_t host);
-XBT_PUBLIC double sg_battery_get_state_of_charge_min(const_sg_host_t host);
-XBT_PUBLIC double sg_battery_get_state_of_charge_max(const_sg_host_t host);
-XBT_PUBLIC double sg_battery_get_state_of_health(const_sg_host_t host);
-XBT_PUBLIC double sg_battery_get_capacity(const_sg_host_t host);
-XBT_PUBLIC double sg_battery_get_cumulative_cost(const_sg_host_t host);
-XBT_PUBLIC double sg_battery_get_next_event_date(const_sg_host_t host);
+class BatteryModel : public kernel::resource::Model {
+  std::vector<BatteryPtr> batteries_;
 
-SG_END_DECL
+public:
+  explicit BatteryModel();
 
+  void add_battery(BatteryPtr b);
+  void update_actions_state(double now, double delta) override;
+  double next_occurring_event(double now) override;
+};
+
+class Battery {
+
+  friend BatteryModel;
+
+public:
+  enum Flow { CHARGE, DISCHARGE };
+
+  class Event {
+  public:
+    double state_of_charge_;
+    Flow flow_;
+    double time_delta_ = -1;
+    std::function<void()> callback_;
+    bool repeat_;
+
+    Event(double state_of_charge, Flow flow, std::function<void()> callback, bool repeat);
+    static std::shared_ptr<Event> init(double state_of_charge, Flow flow, std::function<void()> callback, bool repeat);
+  };
+
+private:
+  static std::shared_ptr<BatteryModel> battery_model_;
+
+  std::string name_;
+  double charge_efficiency_;
+  double discharge_efficiency_;
+  double initial_capacity_wh_;
+  int cycles_; // total complete cycles (charge + discharge) the battery can do before complete depletion.
+  double depth_of_discharge_;
+  double energy_budget_j_;
+
+  // std::map<const s4u::Host*, double> host_loads_ = {};
+  std::map<const s4u::Host*, bool> host_loads_     = {};
+  std::map<const std::string, double> named_loads_ = {};
+  std::vector<std::shared_ptr<Event>> events_;
+
+  double capacity_wh_       = 0;
+  double energy_stored_j_   = 0;
+  double energy_provided_j_ = 0;
+  double energy_consumed_j_ = 0;
+  double last_updated_      = 0;
+
+  explicit Battery(const std::string& name, double state_of_charge, double charge_efficiency,
+                   double discharge_efficiency, double initial_capacity_wh, int cycles, double depth_of_discharge);
+  static void init_plugin();
+  void update();
+  double next_occurring_event();
+
+  std::atomic_int_fast32_t refcount_{0};
+#ifndef DOXYGEN
+  friend void intrusive_ptr_release(Battery* 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(Battery* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); }
+#endif
+
+public:
+  static BatteryPtr init(const std::string& name, double state_of_charge, double charge_efficiency,
+                         double discharge_efficiency, double initial_capacity_wh, int cycles,
+                         double depth_of_discharge);
+  void set_load(const std::string& name, double power_w);
+  void connect_host(s4u::Host* host, bool active = true);
+  double get_state_of_charge();
+  double get_state_of_health();
+  double get_capacity();
+  double get_energy_provided();
+  double get_energy_consumed();
+  double get_energy_stored(std::string unit = "J");
+  std::shared_ptr<Event> create_event(double state_of_charge, Flow flow, std::function<void()> callback,
+                                      bool repeat = false);
+  std::vector<std::shared_ptr<Event>> get_events();
+  void delete_event(std::shared_ptr<Event> event);
+};
+} // namespace simgrid::plugins
 #endif
\ No newline at end of file
index 21d1ceb..c8f602d 100644 (file)
  * under the terms of the license (GNU LGPL) which comes with this package. */
 #include <simgrid/Exception.hpp>
 #include <simgrid/plugins/battery.hpp>
-#include <simgrid/s4u/Actor.hpp>
+#include <simgrid/plugins/energy.h>
 #include <simgrid/s4u/Engine.hpp>
 #include <simgrid/s4u/Host.hpp>
-#include <simgrid/s4u/VirtualMachine.hpp>
 #include <simgrid/simix.hpp>
+#include <xbt/asserts.h>
+#include <xbt/log.h>
 
 #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(battery, "Battery management", &sg_battery_plugin_init)
-
+SIMGRID_REGISTER_PLUGIN(battery, "Battery management", nullptr)
 /** @defgroup plugin_battery plugin_battery Plugin Battery
 
   @beginrst
 
-This is the battery plugin, enabling management of batteries on hosts.
-To activate this plugin, first call :cpp:func:`sg_battery_plugin_init()`.
-
-We consider a constant energy exchange model.
-
-Properties of batteries such as State of Charge and State of Health are lazily updated, ie., when reading values and
-when the power is modified.
-
-State of Charge (SoC)
-.....................
-
-If the power of a battery is set to a negative value then the battery will act as a load and fill over time until it
-reaches its maximal SoC. Conversely, if the power of a battery is set to a positive value then the battery will act as a
-generator and deplete over time until it reaches its minimal SoC. When reaching either its maximal or minimal SoC it
-will set its power to 0.
-
-The natural depletion of batteries over time is not taken into account.
-
-State of Health (SoH)
-.....................
-
-A battery starts with an energy budget :math:`E` such as:
-
-.. math::
-
-  E = C \times U \times D \times N \times 2
-
-Where :math:`C` is the initial capacity, :math:`U` is the ratio of usable capacity, :math:`D` is the depth of discharge
-and :math:`N` is the number of cycles of the battery.
-
-The SoH represents the consumption of this energy budget during the lifetime of the battery.
-Use the battery reduces its SoH and its capacity in consequence.
-When the SoH reaches 0, the battery becomes unusable.
-
-.. warning::
-
-  Due to the decrease of the battery capacity with the SoH, a large usable capacity leads to very tiny battery capacity
-  when reaching low SoH. This may results in charge and discharge cycles too short to be evaluated by the simulator. To
-  avoid this situation you should not try to reach a SoH of 0 with a usable capacity set to 1.
-
-Plotting the output of the example "battery-degradation" highlights the linear decrease of the SoH due to a continuous
-use of the battery and the decreasing cycle duration as its capacity reduces:
-
-.. image:: /img/battery_degradation.svg
-   :align: center
-
-Batteries properties
-....................
-
-Properties of the batteries are defined as properties of hosts in the platform XML file.
-
-Here is an example of XML declaration:
-
-.. code-block:: xml
-
-   <host id="Host" speed="100.0Mf" core="1">
-       <prop id="battery_active" value="1" />
-       <prop id="battery_capacity" value="10" />
-       <prop id="battery_cycles" value="200" />
-       <prop id="battery_state_of_charge" value="0.8" />
-   </host>
-
-The different properties are:
-
-- ``battery_active``: Set the battery as active if set to 1 (default=0)
-- ``battery_power``: Set the initial power of the battery in W (default=0). A negative value indicates that the battery act as a load and charge. A positive value indicates that the battery act as a generator and discharge
-- ``battery_state_of_charge``: Set the initial state of charge of the battery (default=0)
-- ``battery_state_of_charge_min``: Set the minimal state of charge of the battery (default=0.2)
-- ``battery_state_of_charge_max``: Set the maximal state of charge of the battery (default=0.8)
-- ``battery_capacity``: Set the initial capacity of the battery in Wh (default=0)
-- ``battery_usable_capacity``: Set the ratio of usable capacity of the battery (default=0.8)
-- ``battery_depth_of_discharge``: Set the depth of discharge of the battery (default=0.9)
-- ``battery_charge_efficiency``: Set the charge efficiency of the battery (default=1)
-- ``battery_discharge_efficiency``: Set the charge efficiency of the battery (default=1)
-- ``battery_cycles``: Set the number of cycle of the battery (default=1)
-- ``battery_depth_of_discharge``: Set the number of cycle of the battery (default=1)
-- ``battery_eval_cost``: Evaluate the cost of the battery during the simulation if set to 1 (defaulf=0)
-- ``battery_investment_cost``: Set the investment cost of the battery (default=0)
-- ``battery_static_maintenance_cost``: Set the static maintenance cost of the battery (default=0)
-- ``battery_variable_maintenance_cost``: Set the variable maintenance cost of the battery (default=0)
+This is the battery plugin
 
   @endrst
  */
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(battery, kernel, "Logging specific to the battery plugin");
-
-namespace simgrid::plugin {
-class Battery {
-private:
-  simgrid::s4u::Host* host_ = nullptr;
-
-  double state_of_charge_min_  = 0.2;
-  double state_of_charge_max_  = 0.8;
-  double charge_efficiency_    = 1;
-  double discharge_efficiency_ = 1;
-  double initial_capacity_wh_  = 0;
-  double cycles_ = 1; // total complete cycles (charge + discharge) the battery can do before complete depletion.
-  double depth_of_discharge_ = 0.9;
-  double usable_capacity_    = 0.8;
-  double energy_budget_j_    = 0;
-
-  bool active_               = false;
-  double power_w_            = 0; // NEGATIVE when charging (consumes power) POSITIVE when discharging (generates power)
-  double state_of_charge_    = 0;
-  double capacity_wh_        = 0;
-  double next_event_         = -1;
-  double energy_exchanged_j_ = 0;
-  double last_updated_       = 0;
-
-  // Calculation of costs from Bei Li thesis (link :https://tel.archives-ouvertes.fr/tel-02077668/document) (chapter 4)
-  bool eval_cost_                                = false;
-  double cumulative_cost_                        = 0;
-  double investment_cost_per_wh_                 = 0;
-  double static_maintenance_cost_per_wh_times_h_ = 0;
-  double variable_maintenance_cost_per_wh_       = 0;
-
-  void init_battery_params();
-  void init_cost_params();
-  void update();
-
-  void set_state_of_charge(double soc);
-  void set_state_of_charge_min(double soc);
-  void set_state_of_charge_max(double soc);
-  void set_capacity(double c);
-  void set_initial_capacity(double c);
-  void set_cycles(int c);
-  void set_depth_of_discharge(double d);
-  void set_usable_capacity(double c);
-  void set_charge_efficiency(double e);
-  void set_discharge_efficiency(double e);
-  void set_eval_cost(bool eval);
-  void set_investment_cost(double c);
-  void set_static_maintenance_cost(double c);
-  void set_variable_maintenance_cost(double c);
-
-  bool is_charging();
-
-public:
-  static simgrid::xbt::Extension<simgrid::s4u::Host, Battery> EXTENSION_ID;
-
-  explicit Battery(simgrid::s4u::Host* host);
-  ~Battery();
-
-  void set_state(bool state);
-  void set_power(const double power);
-
-  bool is_active() const;
-  double get_power();
-  double get_state_of_charge();
-  double get_state_of_charge_min() const;
-  double get_state_of_charge_max() const;
-  double get_state_of_health();
-  double get_capacity();
-  double get_cumulative_cost();
-  double get_next_event_date();
-};
-
-simgrid::xbt::Extension<simgrid::s4u::Host, Battery> Battery::EXTENSION_ID;
-
-void Battery::set_power(const double p)
-{
-  update();
-  xbt_assert(p == 0 or (p > 0 and state_of_charge_ > state_of_charge_min_) or
-                 (p < 0 and state_of_charge_ < state_of_charge_max_),
-             "Incoherent power and state of charge. A battery cannot charge(discharge) past its maximal(minimal) state "
-             "of charge.");
-  xbt_assert(p == 0 or energy_exchanged_j_ < energy_budget_j_, "Cannot set power of a fully used battery.");
-  simgrid::kernel::actor::simcall_answered([this, p] {
-    power_w_ = p;
-    if (power_w_ == 0) {
-      next_event_ = -1;
-      return;
-    }
-    double soc_shutdown;
-    double soh_shutdown;
-    if (power_w_ > 0) {
-      soc_shutdown = capacity_wh_ * 3600 * (state_of_charge_ - state_of_charge_min_) / (power_w_ * charge_efficiency_);
-      soh_shutdown = (energy_budget_j_ - energy_exchanged_j_) / (power_w_ * charge_efficiency_);
-    } else { // power_w_ < 0
-      soc_shutdown =
-          capacity_wh_ * 3600 * (state_of_charge_max_ - state_of_charge_) / (abs(power_w_) / discharge_efficiency_);
-      soh_shutdown = (energy_budget_j_ - energy_exchanged_j_) / (abs(power_w_) / discharge_efficiency_);
-    }
-    if (soh_shutdown <= 0)
-      next_event_ = simgrid::s4u::Engine::get_clock() + soc_shutdown;
-    else
-      next_event_ = simgrid::s4u::Engine::get_clock() + std::min(soc_shutdown, soh_shutdown);
-  });
-}
-
-void Battery::set_state(bool state)
-{
-  update();
-  simgrid::kernel::actor::simcall_answered([this, state] { active_ = state; });
-}
-
-void Battery::set_state_of_charge(double soc)
-{
-  xbt_assert(soc > 0 and soc <= 1, " : state of charge should be in ]0,1] (provided: %f)", soc);
-  simgrid::kernel::actor::simcall_answered([this, soc] { state_of_charge_ = soc; });
-}
-
-void Battery::set_state_of_charge_min(double soc)
-{
-  xbt_assert(soc > 0 and soc <= 1 and soc < state_of_charge_max_,
-             " : state of charge min should be in ]0,1] and below state of charge max (provided: %f)", soc);
-  simgrid::kernel::actor::simcall_answered([this, soc] { state_of_charge_min_ = soc; });
-}
-
-void Battery::set_state_of_charge_max(double soc)
-{
-  xbt_assert(soc > 0 and soc <= 1 and soc > state_of_charge_min_,
-             " : state of charge max should be in ]0,1] and above state of charge min (provided: %f)", soc);
-  simgrid::kernel::actor::simcall_answered([this, soc] { state_of_charge_max_ = soc; });
-}
-
-void Battery::set_initial_capacity(double c)
-{
-  xbt_assert(c > 0, " : capacity should be > 0 (provided: %f)", c);
-  simgrid::kernel::actor::simcall_answered([this, c] { initial_capacity_wh_ = c; });
-}
-
-void Battery::set_capacity(double c)
-{
-  xbt_assert(c > 0, " : capacity should be > 0 (provided: %f)", c);
-  simgrid::kernel::actor::simcall_answered([this, c] { capacity_wh_ = c; });
-}
-
-void Battery::set_cycles(int c)
-{
-  xbt_assert(c > 0, " : cycles should be > 0 (provided: %d)", c);
-  simgrid::kernel::actor::simcall_answered([this, c] { cycles_ = c; });
-}
-
-void Battery::set_depth_of_discharge(double d)
-{
-  xbt_assert(d > 0 and d <= 1, " : depth of discharge should be in ]0, 1] (provided: %f)", d);
-  simgrid::kernel::actor::simcall_answered([this, d] { depth_of_discharge_ = d; });
-}
-
-void Battery::set_usable_capacity(double c)
-{
-  xbt_assert(c > 0 and c <= 1, " : usable capacity should be in ]0, 1] (provided: %f)", c);
-  simgrid::kernel::actor::simcall_answered([this, c] { usable_capacity_ = c; });
-}
-
-void Battery::set_charge_efficiency(double e)
-{
-  xbt_assert(e > 0 and e <= 1, " : charge efficiency should be in [0,1] (provided: %f)", e);
-  simgrid::kernel::actor::simcall_answered([this, e] { charge_efficiency_ = e; });
-}
-
-void Battery::set_discharge_efficiency(double e)
-{
-  xbt_assert(e > 0 and e <= 1, " : discharge efficiency should be in [0,1] (provided: %f)", e);
-  simgrid::kernel::actor::simcall_answered([this, e] { discharge_efficiency_ = e; });
-}
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Battery, kernel, "Logging specific to the battery plugin");
 
-void Battery::set_eval_cost(bool eval)
-{
-  simgrid::kernel::actor::simcall_answered([this, eval] { eval_cost_ = eval; });
-}
-
-void Battery::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_wh_ = c; });
-}
-
-void Battery::set_static_maintenance_cost(double c)
-{
-  xbt_assert(c >= 0, " : static maintenance cost should be >= 0 (provided: %f)", c);
-  simgrid::kernel::actor::simcall_answered([this, c] { static_maintenance_cost_per_wh_times_h_ = c; });
-}
+namespace simgrid::plugins {
 
-void Battery::set_variable_maintenance_cost(double c)
-{
-  xbt_assert(c >= 0, " : variable maintenance cost should be >= 0 (provided: %f)", c);
-  simgrid::kernel::actor::simcall_answered([this, c] { variable_maintenance_cost_per_wh_ = c; });
-}
-
-bool Battery::is_charging()
-{
-  update();
-  return power_w_ < 0;
-}
+/* BatteryModel */
 
-bool Battery::is_active() const
-{
-  return active_;
-}
+BatteryModel::BatteryModel() : Model("BatteryModel") {}
 
-double Battery::get_power()
+void BatteryModel::add_battery(BatteryPtr b)
 {
-  update();
-  return power_w_;
+  batteries_.push_back(b);
 }
 
-double Battery::get_state_of_charge()
+void BatteryModel::update_actions_state(double now, double delta)
 {
-  update();
-  return state_of_charge_;
+  for (auto battery : batteries_)
+    battery->update();
 }
 
-double Battery::get_state_of_charge_min() const
+double BatteryModel::next_occurring_event(double now)
 {
-  return state_of_charge_min_;
+  double time_delta = -1;
+  for (auto battery : batteries_) {
+    double time_delta_battery = battery->next_occurring_event();
+    time_delta                = time_delta == -1 or time_delta_battery < time_delta ? time_delta_battery : time_delta;
+  }
+  return time_delta;
 }
 
-double Battery::get_state_of_charge_max() const
-{
-  return state_of_charge_max_;
-}
+/* Event */
 
-double Battery::get_state_of_health()
+Battery::Event::Event(double state_of_charge, Flow flow, std::function<void()> callback, bool repeat)
+    : state_of_charge_(state_of_charge), flow_(flow), callback_(callback), repeat_(repeat)
 {
-  update();
-  return 1 - (energy_exchanged_j_ / energy_budget_j_);
 }
 
-double Battery::get_capacity()
+std::shared_ptr<Battery::Event> Battery::Event::init(double state_of_charge, Flow flow, std::function<void()> callback,
+                                                     bool repeat)
 {
-  update();
-  return capacity_wh_;
+  return std::make_shared<Battery::Event>(state_of_charge, flow, callback, repeat);
 }
 
-double Battery::get_cumulative_cost()
-{
-  update();
-  return cumulative_cost_;
-}
+/* Battery */
 
-double Battery::get_next_event_date()
-{
-  update();
-  return next_event_;
-}
+std::shared_ptr<BatteryModel> Battery::battery_model_;
 
-void Battery::init_battery_params()
+void Battery::init_plugin()
 {
-  const char* prop_chars;
-  prop_chars = host_->get_property("battery_capacity");
-  if (prop_chars) {
-    set_capacity(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-    set_initial_capacity(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  }
-  prop_chars = host_->get_property("battery_usable_capacity");
-  if (prop_chars)
-    set_usable_capacity(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_depth_of_discharge");
-  if (prop_chars)
-    set_depth_of_discharge(
-        xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_cycles");
-  if (prop_chars)
-    set_cycles(xbt_str_parse_int(prop_chars, ("cannot parse int: " + std::string(prop_chars)).c_str()));
-  simgrid::kernel::actor::simcall_answered([this] {
-    energy_budget_j_ = (initial_capacity_wh_ * usable_capacity_ * depth_of_discharge_ * 3600 * cycles_ * 2);
-  });
-  prop_chars = host_->get_property("battery_active");
-  if (prop_chars)
-    set_state(xbt_str_parse_int(prop_chars, ("cannot parse int: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_state_of_charge_min");
-  if (prop_chars)
-    set_state_of_charge_min(
-        xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_state_of_charge_max");
-  if (prop_chars)
-    set_state_of_charge_max(
-        xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_charge_efficiency");
-  if (prop_chars)
-    set_charge_efficiency(
-        xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_discharge_efficiency");
-  if (prop_chars)
-    set_discharge_efficiency(
-        xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_state_of_charge");
-  if (prop_chars)
-    set_state_of_charge(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_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("battery_investment_cost");
-  if (prop_chars)
-    set_investment_cost(xbt_str_parse_int(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_static_maintenance_cost");
-  if (prop_chars)
-    set_static_maintenance_cost(
-        xbt_str_parse_int(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_variable_maintenance_cost");
-  if (prop_chars)
-    set_variable_maintenance_cost(
-        xbt_str_parse_int(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
-  prop_chars = host_->get_property("battery_power");
-  if (prop_chars)
-    set_power(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(); });
+  auto model = std::make_shared<BatteryModel>();
+  simgrid::s4u::Engine::get_instance()->add_model(model);
+  Battery::battery_model_ = model;
 }
 
 void Battery::update()
 {
-  simgrid::kernel::actor::simcall_answered([this] {
-    double now             = simgrid::s4u::Engine::get_clock();
-    double time_delta_real = now - last_updated_;
-    if (time_delta_real <= 0 || not is_active())
+  kernel::actor::simcall_answered([this] {
+    double now          = s4u::Engine::get_clock();
+    double time_delta_s = now - last_updated_;
+
+    // Nothing to update
+    if (time_delta_s <= 0)
       return;
-    double time_delta_until_event = next_event_ - last_updated_;
-    bool event                    = next_event_ != -1 and time_delta_until_event <= time_delta_real;
-    double power_real_w           = power_w_ < 0 ? power_w_ * charge_efficiency_ : power_w_ / discharge_efficiency_;
-    state_of_charge_ -= power_real_w * (event ? time_delta_until_event : time_delta_real) / (3600 * capacity_wh_);
-    energy_exchanged_j_ += (event ? time_delta_until_event : time_delta_real) * abs(power_real_w);
-    capacity_wh_ = initial_capacity_wh_ * usable_capacity_ * (1 - (energy_exchanged_j_ / energy_budget_j_)) +
-                   initial_capacity_wh_ * (1 - usable_capacity_);
-    capacity_wh_ = std::max(capacity_wh_, 0.0);
-    if (eval_cost_) {
-      double usage_cost_per_wh =
-          (investment_cost_per_wh_ / (depth_of_discharge_ * cycles_ * 2) + variable_maintenance_cost_per_wh_);
-      double usage_cost =
-          usage_cost_per_wh * abs(power_real_w) * (event ? time_delta_until_event : time_delta_real) / 3600;
-      double static_maintenance_cost =
-          static_maintenance_cost_per_wh_times_h_ * initial_capacity_wh_ * time_delta_real / 3600;
-      cumulative_cost_ += usage_cost + static_maintenance_cost;
+
+    // Calculate energy provided / consumed during this step
+    double provided_power_w = 0;
+    double consumed_power_w = 0;
+    for (auto const& [host, active] : host_loads_)
+      provided_power_w += active ? sg_host_get_current_consumption(host) : 0;
+    for (auto const& [name, load] : named_loads_) {
+      if (load > 0)
+        provided_power_w += load;
+      else
+        consumed_power_w += -load;
     }
-    if (event) {
-      power_w_    = 0;
-      next_event_ = -1;
+    double energy_lost_delta_j   = provided_power_w / discharge_efficiency_ * time_delta_s;
+    double energy_gained_delta_j = consumed_power_w * charge_efficiency_ * time_delta_s;
+
+    // Check that the provided/consumed energy is valid
+    energy_lost_delta_j = std::min(energy_lost_delta_j, energy_stored_j_ + energy_gained_delta_j);
+    /* Charging deteriorate the capacity, but the capacity is used to evaluate the maximum charge so
+       we need to evaluate the theorethical new capacity in the worst case when we fully charge the battery */
+    double new_tmp_capacity_wh =
+        (initial_capacity_wh_ *
+         (1 - (energy_provided_j_ + energy_lost_delta_j * discharge_efficiency_ + energy_consumed_j_ -
+               (energy_stored_j_ + energy_lost_delta_j) / charge_efficiency_) /
+                  energy_budget_j_)) /
+        (1 + 3600 * initial_capacity_wh_ / (charge_efficiency_ * energy_budget_j_));
+    energy_gained_delta_j =
+        std::min(energy_gained_delta_j, (3600 * new_tmp_capacity_wh) - energy_stored_j_ + energy_lost_delta_j);
+
+    // Updating battery
+    energy_provided_j_ += energy_lost_delta_j * discharge_efficiency_;
+    energy_consumed_j_ += energy_gained_delta_j / charge_efficiency_;
+    capacity_wh_ = initial_capacity_wh_ * (1 - (energy_provided_j_ + energy_consumed_j_) / energy_budget_j_);
+    energy_stored_j_ += energy_gained_delta_j - energy_lost_delta_j;
+    energy_stored_j_ = std::min(energy_stored_j_, 3600 * capacity_wh_);
+    last_updated_    = now;
+
+    std::vector<std::shared_ptr<Event>> to_delete = {};
+    for (auto event : events_) {
+      if (abs(event->time_delta_ - time_delta_s) < 0.000000001) {
+        event->callback_();
+        if (event->repeat_)
+          event->time_delta_ = -1;
+        else
+          to_delete.push_back(event);
+      }
     }
-    last_updated_ = now;
+    for (auto event : to_delete)
+      delete_event(event);
   });
 }
 
-Battery::Battery(simgrid::s4u::Host* host) : host_(host)
-{
-  init_battery_params();
-}
-
-Battery::~Battery() = default;
-} // namespace simgrid::plugin
-
-using simgrid::plugin::Battery;
-
-/* **************************** 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 Battery(&host));
-}
-
-/* **************************** Public interface *************************** */
-
-static void ensure_plugin_inited()
+double Battery::next_occurring_event()
 {
-  if (not Battery::EXTENSION_ID.valid())
-    throw simgrid::xbt::InitializationError("The Battery plugin is not active. Please call sg_battery_plugin_init() "
-                                            "before calling any function related to that plugin.");
-}
+  double provided_power_w = 0;
+  double consumed_power_w = 0;
+  for (auto const& [host, active] : host_loads_)
+    provided_power_w += active ? sg_host_get_current_consumption(host) : 0;
+  for (auto const& [name, load] : named_loads_) {
+    if (load > 0)
+      provided_power_w += load;
+    else
+      consumed_power_w += -load;
+  }
 
-/** @ingroup plugin_battery
- *  @brief Enable battery plugin.
- */
-void sg_battery_plugin_init()
-{
-  if (Battery::EXTENSION_ID.valid())
-    return;
-  Battery::EXTENSION_ID = simgrid::s4u::Host::extension_create<Battery>();
-  simgrid::s4u::Host::on_creation_cb(&on_creation);
+  double time_delta = -1;
+  for (auto& event : events_) {
+    double lost_power_w   = provided_power_w / discharge_efficiency_;
+    double gained_power_w = consumed_power_w * charge_efficiency_;
+    // Event cannot happen
+    if ((lost_power_w == gained_power_w) or (event->state_of_charge_ == energy_stored_j_ / (3600 * capacity_wh_)) or
+        (lost_power_w > gained_power_w and event->flow_ == Flow::CHARGE) or
+        (lost_power_w < gained_power_w and event->flow_ == Flow::DISCHARGE)) {
+      continue;
+    }
+    // Evaluate time until event happen
+    else {
+      /* The time to reach a state of charge depends on the capacity, but charging and discharging deteriorate the
+       * capacity, so we need to evaluate the time considering a capacity that also depends on time
+       */
+      event->time_delta_ = (3600 * event->state_of_charge_ * initial_capacity_wh_ *
+                                (1 - (energy_provided_j_ + energy_consumed_j_) / energy_budget_j_) -
+                            energy_stored_j_) /
+                           (gained_power_w - lost_power_w +
+                            3600 * event->state_of_charge_ * initial_capacity_wh_ *
+                                (consumed_power_w + provided_power_w) / energy_budget_j_);
+      if ((time_delta == -1 or event->time_delta_ < time_delta) and abs(event->time_delta_) > 0.000000001)
+        time_delta = event->time_delta_;
+    }
+  }
+  return time_delta;
+}
+
+Battery::Battery(const std::string& name, double state_of_charge, double charge_efficiency, double discharge_efficiency,
+                 double initial_capacity_wh, int cycles, double depth_of_discharge)
+    : name_(name)
+    , energy_stored_j_(state_of_charge * 3600 * initial_capacity_wh)
+    , charge_efficiency_(charge_efficiency)
+    , discharge_efficiency_(discharge_efficiency)
+    , initial_capacity_wh_(initial_capacity_wh)
+    , capacity_wh_(initial_capacity_wh)
+    , cycles_(cycles)
+    , depth_of_discharge_(depth_of_discharge)
+    , energy_budget_j_(initial_capacity_wh * depth_of_discharge * 3600 * cycles * 2)
+{
+  xbt_assert(state_of_charge >= 0 and state_of_charge <= 1, " : state of charge should be in [0, 1] (provided: %f)",
+             state_of_charge);
+  xbt_assert(charge_efficiency > 0 and charge_efficiency <= 1, " : charge efficiency should be in [0,1] (provided: %f)",
+             charge_efficiency);
+  xbt_assert(discharge_efficiency > 0 and discharge_efficiency <= 1,
+             " : discharge efficiency should be in [0,1] (provided: %f)", discharge_efficiency);
+  xbt_assert(initial_capacity_wh > 0, " : initial capacity should be > 0 (provided: %f)", initial_capacity_wh);
+  xbt_assert(cycles > 0, " : cycles should be > 0 (provided: %d)", cycles);
+  xbt_assert(depth_of_discharge > 0 and depth_of_discharge <= 1,
+             " : depth of discharge should be in ]0, 1] (provided: %f)", depth_of_discharge);
+}
+
+BatteryPtr Battery::init(const std::string& name, double state_of_charge, double charge_efficiency,
+                         double discharge_efficiency, double initial_capacity_wh, int cycles, double depth_of_discharge)
+{
+  static bool plugin_inited = false;
+  if (not plugin_inited) {
+    init_plugin();
+    plugin_inited = true;
+  }
+  auto battery = BatteryPtr(new Battery(name, state_of_charge, charge_efficiency, discharge_efficiency,
+                                        initial_capacity_wh, cycles, depth_of_discharge));
+  battery_model_->add_battery(battery);
+  return battery;
 }
 
-/** @ingroup plugin_battery
- *  @param state The state to set.
- *  @brief Set the state of the battery.
- * A battery set to inactive (false) will neither update its state of charge nor its state of health.
- */
-void sg_battery_set_state(const_sg_host_t host, bool state)
+void Battery::set_load(const std::string& name, double power_w)
 {
-  ensure_plugin_inited();
-  host->extension<Battery>()->set_state(state);
+  named_loads_[name] = power_w;
 }
 
-/** @ingroup plugin_battery
- *  @param power The power to set in W.
- *  @brief Set the power of the battery.
- *  @note A negative value makes the battery act as a load and charge.
- * A positive value makes the battery act as a generator and discharge.
- */
-void sg_battery_set_power(const_sg_host_t host, double power)
+void Battery::connect_host(s4u::Host* h, bool active)
 {
-  ensure_plugin_inited();
-  host->extension<Battery>()->set_power(power);
+  host_loads_[h] = active;
 }
 
-/** @ingroup plugin_battery
- *  @brief Return true if the battery is active.
- */
-bool sg_battery_is_active(const_sg_host_t host)
+double Battery::get_state_of_charge()
 {
-  ensure_plugin_inited();
-  return host->extension<Battery>()->is_active();
+  return energy_stored_j_ / (3600 * capacity_wh_);
 }
 
-/** @ingroup plugin_battery
- *  @brief Return the power of the battery in W.
- *  @note A negative value indicates that the battery act as a load and charge.
- * A positive value indicates that the battery act as a generator and discharge.
- */
-double sg_battery_get_power(const_sg_host_t host)
+double Battery::get_state_of_health()
 {
-  ensure_plugin_inited();
-  return host->extension<Battery>()->get_power();
+  return 1 - ((energy_provided_j_ + energy_consumed_j_) / energy_budget_j_);
 }
 
-/** @ingroup plugin_battery
- *  @brief Return the state of charge of the battery.
- */
-double sg_battery_get_state_of_charge(const_sg_host_t host)
+double Battery::get_capacity()
 {
-  ensure_plugin_inited();
-  return host->extension<Battery>()->get_state_of_charge();
+  return capacity_wh_;
 }
 
-/** @ingroup plugin_battery
- *  @brief Return the minimal state of charge of the battery.
- */
-double sg_battery_get_state_of_charge_min(const_sg_host_t host)
+double Battery::get_energy_provided()
 {
-  ensure_plugin_inited();
-  return host->extension<Battery>()->get_state_of_charge_min();
+  return energy_provided_j_;
 }
 
-/** @ingroup plugin_battery
- *  @brief Return the maximal state of charge of the battery.
- */
-double sg_battery_get_state_of_charge_max(const_sg_host_t host)
+double Battery::get_energy_consumed()
 {
-  ensure_plugin_inited();
-  return host->extension<Battery>()->get_state_of_charge_max();
+  return energy_consumed_j_;
 }
 
-/** @ingroup plugin_battery
- *  @brief Return the state of health of the battery.
- */
-double sg_battery_get_state_of_health(const_sg_host_t host)
+double Battery::get_energy_stored(std::string unit)
 {
-  ensure_plugin_inited();
-  return host->extension<Battery>()->get_state_of_health();
+  if (unit == "J")
+    return energy_stored_j_;
+  else if (unit == "Wh")
+    return energy_stored_j_ / 3600;
+  else
+    xbt_die("Invalid unit. Valid units are J (default) or Wh.");
 }
 
-/** @ingroup plugin_battery
- *  @brief Return the capacity of the battery in Wh.
- *  @note capacity is reduced by the state of health of the battery.
- */
-double sg_battery_get_capacity(const_sg_host_t host)
+std::shared_ptr<Battery::Event> Battery::create_event(double state_of_charge, Flow flow, std::function<void()> callback,
+                                                      bool repeat)
 {
-  ensure_plugin_inited();
-  return host->extension<Battery>()->get_capacity();
+  auto event = Event::init(state_of_charge, flow, callback, repeat);
+  events_.push_back(event);
+  return event;
 }
 
-/** @ingroup plugin_battery
- *  @brief Return the cumulative cost of the battery.
- */
-double sg_battery_get_cumulative_cost(const_sg_host_t host)
+std::vector<std::shared_ptr<Battery::Event>> Battery::get_events()
 {
-  ensure_plugin_inited();
-  return host->extension<Battery>()->get_cumulative_cost();
+  return events_;
 }
 
-/** @ingroup plugin_battery
- *  @brief Return the date of the next event, i.e., when the battery will be empty or full.
- *  @note If power is null then return -1.
- */
-double sg_battery_get_next_event_date(const_sg_host_t host)
+void Battery::delete_event(std::shared_ptr<Event> event)
 {
-  ensure_plugin_inited();
-  return host->extension<Battery>()->get_next_event_date();
+  events_.erase(
+      std::remove_if(events_.begin(), events_.end(), [&event](std::shared_ptr<Event> e) { return event == e; }),
+      events_.end());
 }
+} // namespace simgrid::plugins
\ No newline at end of file