<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>
<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
</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
</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
</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
</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
</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
</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>
</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
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
</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"/>
</g>
</g>
<defs>
- <clipPath id="pb647630257">
+ <clipPath id="p2cce2f2c75">
<rect x="144" y="69.12" width="892.8" height="443.52"/>
</clipPath>
</defs>
* 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