From 983ffa8fde7f8d99b2c25167218036c05cdf3f29 Mon Sep 17 00:00:00 2001 From: andig Date: Fri, 24 Jul 2026 16:11:14 +0200 Subject: [PATCH 1/3] perf: scale the objective before handing the model to the solver CBC judges improvements against absolute tolerances of about 1e-7. Prices are given in currency per Wh, so the raw objective coefficients land close to that bound: the peak attenuation tie-breakers sit around 1e-9 per W, and the cost terms are not far above. Improvements that small are indis- tinguishable from numerical noise, so the solver both explores a degenerate search tree and stops on solutions that are not optimal. Multiplying the assembled objective by a constant does not change its argmax, but it lifts the coefficients into a range the solver can resolve. The reported objective value is recalculated from the solution by get_clean_objective_value(), so the API response stays in the original unit and no expected test result changes because of the scaling itself. Measured over all test cases, each run with the stored strategy and with every charging strategy (14 cases x 5 settings, interleaved A/B, min of 7): total solve time 12.78 s -> 10.07 s (0.79x) worst case, none 1.31 s -> 0.79 s (0.60x) worst case, grid peaks 2.17 s -> 1.03 s (0.47x) No solution got economically worse, several got better. The largest gain is 021-min-pv-use-case, where the previous model returned a solution 0.59% below the optimum. Case 018-high-soc-initial got slower (0.13 s -> 0.23 s with attenuate_grid_peaks), which is branching luck rather than a trend. The new test case pins the recovered optimum: it fails without the scaling. --- AGENTS.md | 1 + src/optimizer/optimizer.py | 13 +- .../023-objective-scaling-optimality.json | 2839 +++++++++++++++++ 3 files changed, 2852 insertions(+), 1 deletion(-) create mode 100644 test_cases/023-objective-scaling-optimality.json diff --git a/AGENTS.md b/AGENTS.md index a40c12046..0759c2e97 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -39,6 +39,7 @@ The model is a maximization problem. Read these before changing it: - Charging and discharging strategies are cost-neutral tie-breakers. They add tiny soft terms (coefficient around `min_import_price * 1e-6`) that only decide between economically equal solutions. They are intentionally excluded from `get_clean_objective_value()`, which recomputes the real economic value without strategy incentives or penalties. - `get_clean_objective_value()` measures battery value as `(s[T-1] - s[0]) * p_a`, but `s[0]` already includes the first time step's charging, so energy charged in the first step is not counted as a gain. The optimization objective itself uses the absolute final state of charge, `s[-1] * p_a`. Two solutions that are equal in the real objective can therefore report different clean values. Keep optional charging off the first time step when designing cost-neutrality scenarios. - Grid limits are soft: exceeding `p_max_imp` or `p_max_exp` is penalized rather than forbidden, so an over constrained request reports the violation instead of returning infeasible. +- The assembled objective is multiplied by `OBJECTIVE_SCALE` before it goes to the solver. Prices per Wh put the raw coefficients close to CBC's absolute tolerances, where real improvements are discarded as numerical noise. Scaling does not change the argmax. Keep new objective terms in the same unit and let the scaling do its work, do not compensate for it in individual coefficients. ## Python Coding Standards diff --git a/src/optimizer/optimizer.py b/src/optimizer/optimizer.py index 5e561f813..24845de04 100644 --- a/src/optimizer/optimizer.py +++ b/src/optimizer/optimizer.py @@ -22,6 +22,11 @@ class OptimizationStrategy: 'attenuate_grid_peaks': ('imp', 'exp'), } +# factor the objective is scaled by before handing the model to the solver, see +# _setup_target_function(). Argmax neutral, it only moves the coefficients away from the +# solver's absolute tolerances. +OBJECTIVE_SCALE = 1e6 + # grid energy variable and limit exceedance variable per leveled side PEAK_SIDE_VARIABLES = { 'imp': ('n', 'e_imp_lim_exc'), @@ -361,7 +366,13 @@ def _setup_target_function(self): objective += self.variables['c'][i][t] * self.min_import_price * 5e-5 * (self.T - t) * bat.c_priority objective += self.variables['d'][i][t] * self.min_import_price * 5e-5 * (self.T - t) * bat.c_priority - self.problem += objective + # CBC judges improvements against absolute tolerances (~1e-7). Prices are given in + # currency per Wh, so the raw coefficients of the objective land close to that bound and + # real improvements get pruned as numerical noise. Scaling the whole objective does not + # change its argmax but lifts the coefficients into a range the solver can resolve, which + # both speeds up the search and avoids stopping on a suboptimal solution. The reported + # objective value is recalculated from the solution, so it stays in the original unit. + self.problem += objective * OBJECTIVE_SCALE def _add_energy_balance_constraints(self): """ diff --git a/test_cases/023-objective-scaling-optimality.json b/test_cases/023-objective-scaling-optimality.json new file mode 100644 index 000000000..eeae76ea8 --- /dev/null +++ b/test_cases/023-objective-scaling-optimality.json @@ -0,0 +1,2839 @@ +{ + "request": { + "batteries": [ + { + "c_max": 11040, + "c_min": 1380, + "charge_from_grid": true, + "d_max": 0, + "p_a": 0.0002896641, + "p_demand": [ + 59.416664, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345, + 345 + ], + "s_initial": 22225.25, + "s_max": 36000, + "s_min": 0 + }, + { + "c_max": 1200, + "c_min": 0, + "d_max": 800, + "p_a": 0.0002896641, + "s_initial": 2304, + "s_max": 3763.2, + "s_min": 384 + } + ], + "eta_c": 0.9, + "eta_d": 0.9, + "grid": {}, + "strategy": { + "charging_strategy": "none" + }, + "time_series": { + "dt": [ + 155, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900, + 900 + ], + "ft": [ + 112.921265, + 728.34064, + 801.0094, + 873.6781, + 938.9219, + 996.7406, + 1054.5593, + 1112.3782, + 1155.2063, + 1183.0437, + 1210.8812, + 1238.7188, + 1249.4453, + 1243.0609, + 1236.6765, + 1230.2922, + 1197.9265, + 1139.5797, + 1081.2328, + 1022.8859, + 949.3641, + 860.6672, + 771.97034, + 683.27344, + 580.7531, + 464.40936, + 348.0656, + 231.72188, + 151.85625, + 108.46875, + 65.08125, + 21.69375, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0.5203125, + 1.5609375, + 2.6015625, + 3.6421876, + 6.4734373, + 11.095312, + 15.717188, + 20.339062, + 27.392187, + 36.876564, + 46.36094, + 55.845314, + 64.126564, + 71.20469, + 78.282814, + 85.36094, + 91.67344, + 97.220314, + 102.76719, + 108.314064, + 111.785934, + 113.182816, + 114.57969, + 115.97656, + 116.13281, + 115.04844, + 113.964066, + 112.879684, + 108.57969, + 101.064064, + 93.54844, + 86.032814, + 76.55937, + 65.12813, + 53.696877, + 42.265625, + 33.020313, + 25.960938, + 18.901562, + 11.842188, + 7.2734375, + 5.1953125, + 3.1171875, + 1.0390625, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "gt": [ + 21.393555, + 141.79106, + 118.81549, + 99.2091, + 109.34505, + 132.05226, + 123.809944, + 141.81425, + 135.75327, + 106.92932, + 140.49687, + 126.39748, + 114.454895, + 114.83157, + 133.39836, + 127.19294, + 121.62753, + 131.93904, + 125.489586, + 120.30516, + 145.8974, + 111.00469, + 109.803246, + 115.55383, + 110.95339, + 143.56088, + 141.53888, + 155.29164, + 165.85475, + 114.378586, + 112.033646, + 144.18939, + 115.97164, + 135.61955, + 120.56148, + 118.6445, + 94.84965, + 91.41663, + 108.5017, + 114.15888, + 108.08978, + 99.23897, + 96.08394, + 87.73309, + 85.94274, + 85.82203, + 88.0076, + 104.134254, + 93.09057, + 91.94959, + 86.898, + 80.40401, + 76.58926, + 74.85362, + 68.42451, + 64.79879, + 60.614475, + 61.24875, + 63.063812, + 62.15554, + 61.571392, + 58.47286, + 57.82632, + 60.407665, + 60.250023, + 59.18935, + 58.422638, + 56.657635, + 55.188343, + 59.011417, + 59.9491, + 59.66825, + 58.85921, + 54.93606, + 56.355854, + 57.735176, + 60.74794, + 59.263706, + 57.673912, + 55.405136, + 57.71855, + 58.83158, + 66.15803, + 62.891605, + 62.198093, + 82.32632, + 99.87082, + 106.07729, + 87.39631, + 85.34917, + 110.29032, + 110.94921, + 106.05359, + 103.05663, + 112.38872, + 126.82367, + 124.22064, + 141.79106, + 118.81549, + 99.2091, + 109.34505, + 132.05226, + 123.809944, + 141.81425, + 135.75327, + 106.92932, + 140.49687, + 126.39748, + 114.454895, + 114.83157, + 133.39836, + 127.19294, + 121.62753, + 131.93904, + 125.489586, + 120.30516, + 145.8974, + 111.00469, + 109.803246, + 115.55383, + 110.95339, + 143.56088, + 141.53888, + 155.29164, + 165.85475, + 114.378586, + 112.033646, + 144.18939, + 115.97164, + 135.61955, + 120.56148, + 118.6445, + 94.84965, + 91.41663, + 108.5017, + 114.15888, + 108.08978, + 99.23897, + 96.08394, + 87.73309, + 85.94274, + 85.82203, + 88.0076, + 104.134254, + 93.09057, + 91.94959, + 86.898, + 80.40401, + 76.58926, + 74.85362, + 68.42451, + 64.79879, + 60.614475, + 61.24875, + 63.063812, + 62.15554, + 61.571392, + 58.47286, + 57.82632, + 60.407665, + 60.250023, + 59.18935, + 58.422638, + 56.657635, + 55.188343, + 59.011417, + 59.9491, + 59.66825, + 58.85921, + 54.93606, + 56.355854, + 57.735176, + 60.74794, + 59.263706, + 57.673912, + 55.405136, + 57.71855, + 58.83158, + 66.15803, + 62.891605, + 62.198093, + 82.32632, + 99.87082, + 106.07729 + ], + "p_E": [ + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012, + 0.00012 + ], + "p_N": [ + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251, + 0.0003251 + ] + } + }, + "expected_response": { + "status": "Optimal", + "objective_value": 1.4327495658487992, + "limit_violations": { + "grid_import_limit_exceeded": false, + "grid_export_limit_hit": false + }, + "batteries": [ + { + "charging_power": [ + 59.416664, + 345.0, + 345.0, + 345.0, + 345.0, + 345.0, + 345.0, + 970.56395, + 1019.453, + 991.75262, + 345.0, + 1112.3213, + 345.0, + 345.0, + 1103.2781, + 1103.0993, + 1076.299, + 1007.6407, + 955.74321, + 902.58074, + 803.4667, + 749.66251, + 345.0, + -2.6935452e-10, + -1.3966531e-10, + -7.48207e-11, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "discharging_power": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "state_of_charge": [ + 22278.725, + 22589.225, + 22899.725, + 23210.225, + 23520.725, + 23831.225, + 24141.725, + 25015.233, + 25932.74, + 26825.318, + 27135.818, + 28136.907, + 28447.407, + 28757.907, + 29750.857, + 30743.646, + 31712.316, + 32619.192, + 33479.361, + 34291.684, + 35014.804, + 35689.5, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0, + 36000.0 + ] + }, + { + "charging_power": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 138.37637, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 300.0, + 300.0, + 300.0, + 300.0, + 206.52672, + 76.43024, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 6.253496, + 0.0, + 0.0, + 1.677915, + 0.21687, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "discharging_power": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 13.9985, + 5.909836, + 46.952396, + 122.49564, + 115.97164, + 135.61955, + 120.56148, + 118.6445, + 94.84965, + 91.41663, + 108.5017, + 114.15888, + 108.08978, + 99.23897, + 96.08394, + 87.73309, + 85.94274, + 85.82203, + 88.0076, + 104.13425, + 93.09057, + 91.94959, + 86.898, + 80.40401, + 76.58926, + 74.85362, + 68.42451, + 64.79879, + 60.614475, + 61.24875, + 63.063812, + 62.15554, + 61.571392, + 58.47286, + 57.82632, + 60.407665, + 60.250023, + 14.528007, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 5.0653318, + 0.0, + 0.0, + 0.0, + 1.5347759, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "state_of_charge": [ + 2304.0, + 2304.0, + 2304.0, + 2304.0, + 2304.0, + 2304.0, + 2304.0, + 2304.0, + 2304.0, + 2304.0, + 2304.0, + 2304.0, + 2428.5387, + 2428.5387, + 2428.5387, + 2428.5387, + 2428.5387, + 2428.5387, + 2428.5387, + 2428.5387, + 2428.5387, + 2428.5387, + 2698.5387, + 2968.5387, + 3238.5387, + 3508.5387, + 3694.4128, + 3763.2, + 3747.6461, + 3741.0796, + 3688.9103, + 3552.804, + 3423.9467, + 3273.2583, + 3139.3011, + 3007.4738, + 2902.0853, + 2800.5113, + 2679.9539, + 2553.1107, + 2433.0109, + 2322.7454, + 2215.9855, + 2118.5042, + 2023.0123, + 1927.6545, + 1829.8683, + 1714.1635, + 1610.7296, + 1508.5634, + 1412.01, + 1322.6722, + 1237.5731, + 1154.4024, + 1078.3751, + 1006.3765, + 939.02708, + 870.97291, + 800.90201, + 731.8403, + 663.42764, + 598.45779, + 534.20633, + 467.0867, + 400.14223, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 389.62815, + 384.0, + 384.0, + 385.51012, + 385.70531, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0, + 384.0 + ] + } + ], + "grid_import": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 44.661343, + 58.422638, + 56.657635, + 55.188343, + 59.011417, + 59.9491, + 59.66825, + 58.85921, + 54.93606, + 56.355854, + 57.735176, + 60.74794, + 59.263706, + 57.673912, + 55.405136, + 57.71855, + 58.83158, + 66.15803, + 62.891605, + 61.67778, + 80.765382, + 97.269257, + 102.4351, + 80.922873, + 74.253858, + 94.573132, + 90.610148, + 78.661403, + 66.180066, + 66.02778, + 70.978356, + 60.094076, + 70.58637, + 40.532676, + 13.84816, + 17.67161, + 34.831946, + 21.042754, + 33.500186, + 23.967336, + 0.0, + 20.851848, + 10.42092, + 0.0, + 0.0, + 17.899518, + 14.313256, + 13.04784, + 30.874976, + 31.941146, + 34.272346, + 69.33803, + 45.87656, + 56.106369, + 73.288205, + 77.933077, + 117.59994, + 122.63732, + 143.44945, + 158.58131, + 109.18327, + 108.91646, + 143.15033, + 115.97164, + 135.61955, + 120.56148, + 118.6445, + 94.84965, + 91.41663, + 108.5017, + 114.15888, + 108.08978, + 99.23897, + 96.08394, + 87.73309, + 85.94274, + 85.82203, + 88.0076, + 104.13425, + 93.09057, + 91.94959, + 86.898, + 80.40401, + 76.58926, + 74.85362, + 68.42451, + 64.79879, + 60.614475, + 61.24875, + 63.063812, + 62.15554, + 61.571392, + 58.47286, + 57.82632, + 60.407665, + 60.250023, + 59.18935, + 58.422638, + 56.657635, + 55.188343, + 59.011417, + 59.9491, + 59.66825, + 58.85921, + 54.93606, + 56.355854, + 57.735176, + 60.74794, + 59.263706, + 57.673912, + 55.405136, + 57.71855, + 58.83158, + 66.15803, + 62.891605, + 62.198093, + 82.32632, + 99.87082, + 106.07729 + ], + "grid_export": [ + 32.111046, + 241.54958, + 337.19391, + 429.469, + 484.57685, + 519.68834, + 585.74936, + 0.0, + 0.0, + 84.36176, + 725.38433, + 0.0, + 651.61403, + 783.22933, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 17.167094, + 267.71961, + 169.79971, + 20.84848, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "flow_direction": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "grid_import_overshoot": [], + "grid_export_overshoot": [] + } +} \ No newline at end of file From 6ab1c95177084f5922fbe09bd811ab8a39ca19cd Mon Sep 17 00:00:00 2001 From: andig Date: Fri, 24 Jul 2026 16:11:33 +0200 Subject: [PATCH 2/3] refactor: drop the unused ramp variable of the first time step The peak attenuation strategies create one ramp variable per time step, but the ramp constraints only cover the steps that have a predecessor. The variable of the first step is therefore never constrained, it only carries the ramp penalty and is driven to zero. Index the ramps by the step they lead into instead, which removes one variable per leveled grid side without changing the model. --- src/optimizer/optimizer.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/optimizer/optimizer.py b/src/optimizer/optimizer.py index 24845de04..777067d06 100644 --- a/src/optimizer/optimizer.py +++ b/src/optimizer/optimizer.py @@ -222,12 +222,13 @@ def _setup_variables(self): self.variables['p_max_imp_exc'] = pulp.LpVariable("p_max_imp_exc", lowBound=0) # highest grid power over the whole horizon (W) and step to step ramp of the grid power (W) - # per side, used by the peak attenuation strategies + # per side, used by the peak attenuation strategies. there is no ramp into the first time + # step, so the ramp of step t is held at index t - 1 for side in self.peak_sides: self.variables[f'p_{side}_peak'] = pulp.LpVariable(f"p_{side}_peak", lowBound=0) self.variables[f'p_{side}_ramp'] = [ pulp.LpVariable(f"p_{side}_ramp_{t}", lowBound=0) - for t in self.time_steps + for t in range(1, self.T) ] # Binary variable: power flow direction to / from grid variables @@ -466,10 +467,10 @@ def _add_energy_balance_constraints(self): for t in self.time_steps: self.problem += p_grid[t] <= self.variables[f'p_{side}_peak'] - # ramp magnitude: p_ramp[t] >= |p_grid[t] - p_grid[t-1]| + # ramp magnitude: p_ramp[t - 1] >= |p_grid[t] - p_grid[t-1]| for t in range(1, self.T): - self.problem += self.variables[f'p_{side}_ramp'][t] >= p_grid[t] - p_grid[t - 1] - self.problem += self.variables[f'p_{side}_ramp'][t] >= p_grid[t - 1] - p_grid[t] + self.problem += self.variables[f'p_{side}_ramp'][t - 1] >= p_grid[t] - p_grid[t - 1] + self.problem += self.variables[f'p_{side}_ramp'][t - 1] >= p_grid[t - 1] - p_grid[t] # if demand rate is applied, the maximum grid import power value # of all time steps drives the demand rate charge From 73b0332fec35f596976b483422aef902962c9bab Mon Sep 17 00:00:00 2001 From: andig Date: Fri, 24 Jul 2026 17:33:20 +0200 Subject: [PATCH 3/3] test: pin the recovered optimum with a focused test instead of a copied case The scenario that proves the objective scaling is 021 solved without a charging strategy. Adding it as a data driven case duplicated 2839 lines of fixture that differ from the existing file in one field. Read the request from that file instead and assert the objective in a dedicated test module, as AGENTS.md suggests for behaviour the data driven harness cannot express. The assertion is a lower bound rather than an equality: a future model that finds an even better solution here should not fail this test. Also drops the duplicated rationale at the call site, the comment on OBJECTIVE_SCALE covers it. --- src/optimizer/optimizer.py | 15 +- .../023-objective-scaling-optimality.json | 2839 ----------------- tests/test_objective_scaling.py | 23 + 3 files changed, 29 insertions(+), 2848 deletions(-) delete mode 100644 test_cases/023-objective-scaling-optimality.json create mode 100644 tests/test_objective_scaling.py diff --git a/src/optimizer/optimizer.py b/src/optimizer/optimizer.py index 777067d06..7b8f94002 100644 --- a/src/optimizer/optimizer.py +++ b/src/optimizer/optimizer.py @@ -22,9 +22,12 @@ class OptimizationStrategy: 'attenuate_grid_peaks': ('imp', 'exp'), } -# factor the objective is scaled by before handing the model to the solver, see -# _setup_target_function(). Argmax neutral, it only moves the coefficients away from the -# solver's absolute tolerances. +# factor the assembled objective is multiplied by before the model goes to the solver. CBC judges +# improvements against absolute tolerances (~1e-7), and with prices given per Wh the raw objective +# coefficients land close to that bound, so real improvements get pruned as numerical noise. +# Scaling does not change the argmax, it only lifts the coefficients into a range the solver can +# resolve. The reported objective value is recalculated from the solution and stays in its +# original unit. OBJECTIVE_SCALE = 1e6 # grid energy variable and limit exceedance variable per leveled side @@ -367,12 +370,6 @@ def _setup_target_function(self): objective += self.variables['c'][i][t] * self.min_import_price * 5e-5 * (self.T - t) * bat.c_priority objective += self.variables['d'][i][t] * self.min_import_price * 5e-5 * (self.T - t) * bat.c_priority - # CBC judges improvements against absolute tolerances (~1e-7). Prices are given in - # currency per Wh, so the raw coefficients of the objective land close to that bound and - # real improvements get pruned as numerical noise. Scaling the whole objective does not - # change its argmax but lifts the coefficients into a range the solver can resolve, which - # both speeds up the search and avoids stopping on a suboptimal solution. The reported - # objective value is recalculated from the solution, so it stays in the original unit. self.problem += objective * OBJECTIVE_SCALE def _add_energy_balance_constraints(self): diff --git a/test_cases/023-objective-scaling-optimality.json b/test_cases/023-objective-scaling-optimality.json deleted file mode 100644 index eeae76ea8..000000000 --- a/test_cases/023-objective-scaling-optimality.json +++ /dev/null @@ -1,2839 +0,0 @@ -{ - "request": { - "batteries": [ - { - "c_max": 11040, - "c_min": 1380, - "charge_from_grid": true, - "d_max": 0, - "p_a": 0.0002896641, - "p_demand": [ - 59.416664, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345, - 345 - ], - "s_initial": 22225.25, - "s_max": 36000, - "s_min": 0 - }, - { - "c_max": 1200, - "c_min": 0, - "d_max": 800, - "p_a": 0.0002896641, - "s_initial": 2304, - "s_max": 3763.2, - "s_min": 384 - } - ], - "eta_c": 0.9, - "eta_d": 0.9, - "grid": {}, - "strategy": { - "charging_strategy": "none" - }, - "time_series": { - "dt": [ - 155, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900 - ], - "ft": [ - 112.921265, - 728.34064, - 801.0094, - 873.6781, - 938.9219, - 996.7406, - 1054.5593, - 1112.3782, - 1155.2063, - 1183.0437, - 1210.8812, - 1238.7188, - 1249.4453, - 1243.0609, - 1236.6765, - 1230.2922, - 1197.9265, - 1139.5797, - 1081.2328, - 1022.8859, - 949.3641, - 860.6672, - 771.97034, - 683.27344, - 580.7531, - 464.40936, - 348.0656, - 231.72188, - 151.85625, - 108.46875, - 65.08125, - 21.69375, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0.5203125, - 1.5609375, - 2.6015625, - 3.6421876, - 6.4734373, - 11.095312, - 15.717188, - 20.339062, - 27.392187, - 36.876564, - 46.36094, - 55.845314, - 64.126564, - 71.20469, - 78.282814, - 85.36094, - 91.67344, - 97.220314, - 102.76719, - 108.314064, - 111.785934, - 113.182816, - 114.57969, - 115.97656, - 116.13281, - 115.04844, - 113.964066, - 112.879684, - 108.57969, - 101.064064, - 93.54844, - 86.032814, - 76.55937, - 65.12813, - 53.696877, - 42.265625, - 33.020313, - 25.960938, - 18.901562, - 11.842188, - 7.2734375, - 5.1953125, - 3.1171875, - 1.0390625, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "gt": [ - 21.393555, - 141.79106, - 118.81549, - 99.2091, - 109.34505, - 132.05226, - 123.809944, - 141.81425, - 135.75327, - 106.92932, - 140.49687, - 126.39748, - 114.454895, - 114.83157, - 133.39836, - 127.19294, - 121.62753, - 131.93904, - 125.489586, - 120.30516, - 145.8974, - 111.00469, - 109.803246, - 115.55383, - 110.95339, - 143.56088, - 141.53888, - 155.29164, - 165.85475, - 114.378586, - 112.033646, - 144.18939, - 115.97164, - 135.61955, - 120.56148, - 118.6445, - 94.84965, - 91.41663, - 108.5017, - 114.15888, - 108.08978, - 99.23897, - 96.08394, - 87.73309, - 85.94274, - 85.82203, - 88.0076, - 104.134254, - 93.09057, - 91.94959, - 86.898, - 80.40401, - 76.58926, - 74.85362, - 68.42451, - 64.79879, - 60.614475, - 61.24875, - 63.063812, - 62.15554, - 61.571392, - 58.47286, - 57.82632, - 60.407665, - 60.250023, - 59.18935, - 58.422638, - 56.657635, - 55.188343, - 59.011417, - 59.9491, - 59.66825, - 58.85921, - 54.93606, - 56.355854, - 57.735176, - 60.74794, - 59.263706, - 57.673912, - 55.405136, - 57.71855, - 58.83158, - 66.15803, - 62.891605, - 62.198093, - 82.32632, - 99.87082, - 106.07729, - 87.39631, - 85.34917, - 110.29032, - 110.94921, - 106.05359, - 103.05663, - 112.38872, - 126.82367, - 124.22064, - 141.79106, - 118.81549, - 99.2091, - 109.34505, - 132.05226, - 123.809944, - 141.81425, - 135.75327, - 106.92932, - 140.49687, - 126.39748, - 114.454895, - 114.83157, - 133.39836, - 127.19294, - 121.62753, - 131.93904, - 125.489586, - 120.30516, - 145.8974, - 111.00469, - 109.803246, - 115.55383, - 110.95339, - 143.56088, - 141.53888, - 155.29164, - 165.85475, - 114.378586, - 112.033646, - 144.18939, - 115.97164, - 135.61955, - 120.56148, - 118.6445, - 94.84965, - 91.41663, - 108.5017, - 114.15888, - 108.08978, - 99.23897, - 96.08394, - 87.73309, - 85.94274, - 85.82203, - 88.0076, - 104.134254, - 93.09057, - 91.94959, - 86.898, - 80.40401, - 76.58926, - 74.85362, - 68.42451, - 64.79879, - 60.614475, - 61.24875, - 63.063812, - 62.15554, - 61.571392, - 58.47286, - 57.82632, - 60.407665, - 60.250023, - 59.18935, - 58.422638, - 56.657635, - 55.188343, - 59.011417, - 59.9491, - 59.66825, - 58.85921, - 54.93606, - 56.355854, - 57.735176, - 60.74794, - 59.263706, - 57.673912, - 55.405136, - 57.71855, - 58.83158, - 66.15803, - 62.891605, - 62.198093, - 82.32632, - 99.87082, - 106.07729 - ], - "p_E": [ - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012, - 0.00012 - ], - "p_N": [ - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251, - 0.0003251 - ] - } - }, - "expected_response": { - "status": "Optimal", - "objective_value": 1.4327495658487992, - "limit_violations": { - "grid_import_limit_exceeded": false, - "grid_export_limit_hit": false - }, - "batteries": [ - { - "charging_power": [ - 59.416664, - 345.0, - 345.0, - 345.0, - 345.0, - 345.0, - 345.0, - 970.56395, - 1019.453, - 991.75262, - 345.0, - 1112.3213, - 345.0, - 345.0, - 1103.2781, - 1103.0993, - 1076.299, - 1007.6407, - 955.74321, - 902.58074, - 803.4667, - 749.66251, - 345.0, - -2.6935452e-10, - -1.3966531e-10, - -7.48207e-11, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - "discharging_power": [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - "state_of_charge": [ - 22278.725, - 22589.225, - 22899.725, - 23210.225, - 23520.725, - 23831.225, - 24141.725, - 25015.233, - 25932.74, - 26825.318, - 27135.818, - 28136.907, - 28447.407, - 28757.907, - 29750.857, - 30743.646, - 31712.316, - 32619.192, - 33479.361, - 34291.684, - 35014.804, - 35689.5, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0, - 36000.0 - ] - }, - { - "charging_power": [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 138.37637, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 300.0, - 300.0, - 300.0, - 300.0, - 206.52672, - 76.43024, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 6.253496, - 0.0, - 0.0, - 1.677915, - 0.21687, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - "discharging_power": [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 13.9985, - 5.909836, - 46.952396, - 122.49564, - 115.97164, - 135.61955, - 120.56148, - 118.6445, - 94.84965, - 91.41663, - 108.5017, - 114.15888, - 108.08978, - 99.23897, - 96.08394, - 87.73309, - 85.94274, - 85.82203, - 88.0076, - 104.13425, - 93.09057, - 91.94959, - 86.898, - 80.40401, - 76.58926, - 74.85362, - 68.42451, - 64.79879, - 60.614475, - 61.24875, - 63.063812, - 62.15554, - 61.571392, - 58.47286, - 57.82632, - 60.407665, - 60.250023, - 14.528007, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 5.0653318, - 0.0, - 0.0, - 0.0, - 1.5347759, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - "state_of_charge": [ - 2304.0, - 2304.0, - 2304.0, - 2304.0, - 2304.0, - 2304.0, - 2304.0, - 2304.0, - 2304.0, - 2304.0, - 2304.0, - 2304.0, - 2428.5387, - 2428.5387, - 2428.5387, - 2428.5387, - 2428.5387, - 2428.5387, - 2428.5387, - 2428.5387, - 2428.5387, - 2428.5387, - 2698.5387, - 2968.5387, - 3238.5387, - 3508.5387, - 3694.4128, - 3763.2, - 3747.6461, - 3741.0796, - 3688.9103, - 3552.804, - 3423.9467, - 3273.2583, - 3139.3011, - 3007.4738, - 2902.0853, - 2800.5113, - 2679.9539, - 2553.1107, - 2433.0109, - 2322.7454, - 2215.9855, - 2118.5042, - 2023.0123, - 1927.6545, - 1829.8683, - 1714.1635, - 1610.7296, - 1508.5634, - 1412.01, - 1322.6722, - 1237.5731, - 1154.4024, - 1078.3751, - 1006.3765, - 939.02708, - 870.97291, - 800.90201, - 731.8403, - 663.42764, - 598.45779, - 534.20633, - 467.0867, - 400.14223, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 389.62815, - 384.0, - 384.0, - 385.51012, - 385.70531, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0, - 384.0 - ] - } - ], - "grid_import": [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 44.661343, - 58.422638, - 56.657635, - 55.188343, - 59.011417, - 59.9491, - 59.66825, - 58.85921, - 54.93606, - 56.355854, - 57.735176, - 60.74794, - 59.263706, - 57.673912, - 55.405136, - 57.71855, - 58.83158, - 66.15803, - 62.891605, - 61.67778, - 80.765382, - 97.269257, - 102.4351, - 80.922873, - 74.253858, - 94.573132, - 90.610148, - 78.661403, - 66.180066, - 66.02778, - 70.978356, - 60.094076, - 70.58637, - 40.532676, - 13.84816, - 17.67161, - 34.831946, - 21.042754, - 33.500186, - 23.967336, - 0.0, - 20.851848, - 10.42092, - 0.0, - 0.0, - 17.899518, - 14.313256, - 13.04784, - 30.874976, - 31.941146, - 34.272346, - 69.33803, - 45.87656, - 56.106369, - 73.288205, - 77.933077, - 117.59994, - 122.63732, - 143.44945, - 158.58131, - 109.18327, - 108.91646, - 143.15033, - 115.97164, - 135.61955, - 120.56148, - 118.6445, - 94.84965, - 91.41663, - 108.5017, - 114.15888, - 108.08978, - 99.23897, - 96.08394, - 87.73309, - 85.94274, - 85.82203, - 88.0076, - 104.13425, - 93.09057, - 91.94959, - 86.898, - 80.40401, - 76.58926, - 74.85362, - 68.42451, - 64.79879, - 60.614475, - 61.24875, - 63.063812, - 62.15554, - 61.571392, - 58.47286, - 57.82632, - 60.407665, - 60.250023, - 59.18935, - 58.422638, - 56.657635, - 55.188343, - 59.011417, - 59.9491, - 59.66825, - 58.85921, - 54.93606, - 56.355854, - 57.735176, - 60.74794, - 59.263706, - 57.673912, - 55.405136, - 57.71855, - 58.83158, - 66.15803, - 62.891605, - 62.198093, - 82.32632, - 99.87082, - 106.07729 - ], - "grid_export": [ - 32.111046, - 241.54958, - 337.19391, - 429.469, - 484.57685, - 519.68834, - 585.74936, - 0.0, - 0.0, - 84.36176, - 725.38433, - 0.0, - 651.61403, - 783.22933, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 17.167094, - 267.71961, - 169.79971, - 20.84848, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - "flow_direction": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "grid_import_overshoot": [], - "grid_export_overshoot": [] - } -} \ No newline at end of file diff --git a/tests/test_objective_scaling.py b/tests/test_objective_scaling.py new file mode 100644 index 000000000..0e65d75f0 --- /dev/null +++ b/tests/test_objective_scaling.py @@ -0,0 +1,23 @@ + +import json +import pathlib + +from optimizer.app import app + +# 021 solved without a charging strategy. Before the objective was scaled, the solver stopped +# here on a solution about 0.59% below the optimum, so this pins the value it has to reach. +CASE = pathlib.Path('test_cases/021-min-pv-use-case-with-weird-behavior.json') +EXPECTED_OBJECTIVE = 1.4327495658487992 + + +def test_optimum_is_not_cut_off_by_solver_tolerances(): + request = json.loads(CASE.read_text())["request"] + request["strategy"] = {"charging_strategy": "none"} + + response = app.test_client().post("/optimize/charge-schedule", json=request) + + assert response.status_code == 200, f"request returned with status {response.status_code}" + assert response.json["status"] == "Optimal" + # not an equality check: a better solution stays acceptable, a worse one does not + assert response.json["objective_value"] >= EXPECTED_OBJECTIVE * (1 - 1e-6), \ + f"objective value: {response.json['objective_value']}, expected at least: {EXPECTED_OBJECTIVE}"