rtc-tools 2.8.0a1__py3-none-any.whl → 2.8.0a2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rtc-tools might be problematic. Click here for more details.
- {rtc_tools-2.8.0a1.dist-info → rtc_tools-2.8.0a2.dist-info}/METADATA +5 -7
- {rtc_tools-2.8.0a1.dist-info → rtc_tools-2.8.0a2.dist-info}/RECORD +9 -9
- {rtc_tools-2.8.0a1.dist-info → rtc_tools-2.8.0a2.dist-info}/licenses/AUTHORS +3 -0
- rtctools/_internal/casadi_helpers.py +22 -4
- rtctools/optimization/collocated_integrated_optimization_problem.py +47 -5
- {rtc_tools-2.8.0a1.dist-info → rtc_tools-2.8.0a2.dist-info}/WHEEL +0 -0
- {rtc_tools-2.8.0a1.dist-info → rtc_tools-2.8.0a2.dist-info}/entry_points.txt +0 -0
- {rtc_tools-2.8.0a1.dist-info → rtc_tools-2.8.0a2.dist-info}/licenses/COPYING +0 -0
- {rtc_tools-2.8.0a1.dist-info → rtc_tools-2.8.0a2.dist-info}/licenses/COPYING.LESSER +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rtc-tools
|
|
3
|
-
Version: 2.8.
|
|
3
|
+
Version: 2.8.0a2
|
|
4
4
|
Summary: Toolbox for control and optimization of water systems.
|
|
5
5
|
Project-URL: Homepage, https://oss.deltares.nl/web/rtc-tools/home
|
|
6
6
|
Project-URL: Download, http://github.com/deltares/rtc-tools/
|
|
@@ -191,10 +191,10 @@ Requires-Python: >=3.9
|
|
|
191
191
|
Requires-Dist: casadi!=3.6.6,<3.8,>=3.6.3
|
|
192
192
|
Requires-Dist: defusedxml>=0.7.0
|
|
193
193
|
Requires-Dist: importlib-metadata>=5.0.0; python_version < '3.10'
|
|
194
|
-
Requires-Dist: numpy>=1.
|
|
194
|
+
Requires-Dist: numpy>=1.20.0
|
|
195
195
|
Requires-Dist: pymoca==0.9.*,>=0.9.1
|
|
196
196
|
Requires-Dist: rtc-tools-channel-flow>=1.2.0
|
|
197
|
-
Requires-Dist: scipy>=1.
|
|
197
|
+
Requires-Dist: scipy>=1.6.0
|
|
198
198
|
Provides-Extra: all
|
|
199
199
|
Requires-Dist: netcdf4; extra == 'all'
|
|
200
200
|
Provides-Extra: netcdf
|
|
@@ -219,13 +219,11 @@ RTC-Tools offers the following functionalities:
|
|
|
219
219
|
|
|
220
220
|
- **Model building using extensible libraries**: Build complex system models using extensible libraries of model components. Modelers can also implement their custom modeling components, for instance, using the [Modelica language](https://modelica.org/language/) or Python script.
|
|
221
221
|
|
|
222
|
-
RTC-Tools can be used with the following libraries and packages for specific applications
|
|
222
|
+
RTC-Tools can be used with the following libraries and packages for specific applications. Please note that this list is not exhaustive. Users can also create libraries for other types of applications.
|
|
223
223
|
- [rtc-tools-channel-flow](https://gitlab.com/deltares/rtc-tools-channel-flow): water system models
|
|
224
224
|
- [rtc-tools-hydraulic-structures](https://gitlab.com/deltares/rtc-tools-channel-flow): hydraulic assets, such as weirs and pumps
|
|
225
225
|
- [rtc-tools-heat-network](https://github.com/Nieuwe-Warmte-Nu/rtc-tools-heat-network): heat networks
|
|
226
|
-
|
|
227
|
-
Please note that this list is not exhaustive. Users can also create libraries for other types of applications.
|
|
228
|
-
|
|
226
|
+
|
|
229
227
|
- **Running simulations**: Simulate a given model.
|
|
230
228
|
|
|
231
229
|
- **Specifying and solving optimization problems**: Define optimization goals, constraints and decision variables to specify the optimization problem for a given model. RTC-Tools supports both open-source solvers (CBC, HiGHS, Ipopt) and commercial solvers (Gurobi, CPLEX) for solving several types of optimization problems:
|
|
@@ -5,7 +5,7 @@ rtctools/version.py,sha256=xvbTWTq6B21t4hw5bi2hdOVaIBeDBQtqEEHe0kxYZsc,1995
|
|
|
5
5
|
rtctools/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
rtctools/_internal/alias_tools.py,sha256=XuQSAhhFuVtwn0yrAObZWIKPsSF4j2axXRtEmitIFPs,5310
|
|
7
7
|
rtctools/_internal/caching.py,sha256=p4gqSL7kCI7Hff-KjMEP7mhJCQSiU_lYm2MR7E18gBM,905
|
|
8
|
-
rtctools/_internal/casadi_helpers.py,sha256=
|
|
8
|
+
rtctools/_internal/casadi_helpers.py,sha256=vN1H7D_6otY6stVD0Dw2b2UapCJ6T2r8QuscNT8OJOw,2309
|
|
9
9
|
rtctools/_internal/debug_check_helpers.py,sha256=UgQTEPw4PyR7MbYLewSSWQqTwQj7xr5yUBk820O9Kk4,1084
|
|
10
10
|
rtctools/_internal/ensemble_bounds_decorator.py,sha256=-eMSvkgKQ0Ew3EBDzsikQjIOlEP_iZOpbGGuX8R0F_A,2917
|
|
11
11
|
rtctools/data/__init__.py,sha256=EllgSmCdrlvQZSd1VilvjPaeYJGhY9ErPiQtedmuFoA,157
|
|
@@ -19,7 +19,7 @@ rtctools/data/interpolation/bspline.py,sha256=qevB842XWCH3fWlWMBqKMy1mw37ust-0Yt
|
|
|
19
19
|
rtctools/data/interpolation/bspline1d.py,sha256=HAh7m5xLBuiFKzMzuYEqZX_GmCPChKjV7ynTS6iRZOc,6166
|
|
20
20
|
rtctools/data/interpolation/bspline2d.py,sha256=ScmX0fPDxbUVtj3pbUE0L7UJocqroD_6fUT-4cvdRMc,1693
|
|
21
21
|
rtctools/optimization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
rtctools/optimization/collocated_integrated_optimization_problem.py,sha256=
|
|
22
|
+
rtctools/optimization/collocated_integrated_optimization_problem.py,sha256=eiBh9kxbD7W-KgG44rwOhygKD6yJqAFvCisZIJRK7No,135509
|
|
23
23
|
rtctools/optimization/control_tree_mixin.py,sha256=6OMvjT5rFvvXU3_O6Uwz8xvBQpRH9d5z4mMOtOQ4-a4,9036
|
|
24
24
|
rtctools/optimization/csv_lookup_table_mixin.py,sha256=TUYAT-u-mzH6HLP0iJHnLBVqV5tWnhYAqDC4Aj17MJg,17399
|
|
25
25
|
rtctools/optimization/csv_mixin.py,sha256=_6iPVK_EJ8PxnukepzkhFtidceucsozRML_DDEycYik,12453
|
|
@@ -43,10 +43,10 @@ rtctools/simulation/csv_mixin.py,sha256=rGDUFPsqGHmF0_dWdXeWzWzMpkPmwCNweTBVrwSh
|
|
|
43
43
|
rtctools/simulation/io_mixin.py,sha256=WIKOQxr3fS-aNbgjet9iWoUayuD22zLIYmqlWEqxXHo,6215
|
|
44
44
|
rtctools/simulation/pi_mixin.py,sha256=_TU2DrK2MQqVsyrHBD9W4SDEuot9dYmgTDNiXkDAJfk,9833
|
|
45
45
|
rtctools/simulation/simulation_problem.py,sha256=v5Lk2x-yuVb5s7ne5fFgxONxGniLHTyTR0XRzYRl1fw,50005
|
|
46
|
-
rtc_tools-2.8.
|
|
47
|
-
rtc_tools-2.8.
|
|
48
|
-
rtc_tools-2.8.
|
|
49
|
-
rtc_tools-2.8.
|
|
50
|
-
rtc_tools-2.8.
|
|
51
|
-
rtc_tools-2.8.
|
|
52
|
-
rtc_tools-2.8.
|
|
46
|
+
rtc_tools-2.8.0a2.dist-info/METADATA,sha256=nKu420Qtu40T8fhGyBihzZD3UEx_ZZmL9ewiN6B468c,15035
|
|
47
|
+
rtc_tools-2.8.0a2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
48
|
+
rtc_tools-2.8.0a2.dist-info/entry_points.txt,sha256=DVS8sWf3b9ph9h8srEr6zmQ7ZKGwblwgZgGPZg-jRNQ,150
|
|
49
|
+
rtc_tools-2.8.0a2.dist-info/licenses/AUTHORS,sha256=al_VX-S8aXSvAt0PNBikE_KWq0ovofK54qTW_JLr9TA,201
|
|
50
|
+
rtc_tools-2.8.0a2.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
51
|
+
rtc_tools-2.8.0a2.dist-info/licenses/COPYING.LESSER,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
52
|
+
rtc_tools-2.8.0a2.dist-info/RECORD,,
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from typing import Union
|
|
2
3
|
|
|
3
4
|
import casadi as ca
|
|
4
5
|
|
|
5
6
|
logger = logging.getLogger("rtctools")
|
|
6
7
|
|
|
8
|
+
# Limit the number of times we try to substitute in external functions, e.g. in
|
|
9
|
+
# case of infinite recursion. Generally unlikely that we will hit this limit for
|
|
10
|
+
# any reasonable use case.
|
|
11
|
+
MAX_SUBSTITUTE_DEPTH = 10
|
|
12
|
+
|
|
7
13
|
|
|
8
14
|
def is_affine(expr, symbols):
|
|
9
15
|
try:
|
|
@@ -37,12 +43,24 @@ def reduce_matvec(e, v):
|
|
|
37
43
|
return ca.reshape(ca.mtimes(A, v), e.shape)
|
|
38
44
|
|
|
39
45
|
|
|
40
|
-
def substitute_in_external(
|
|
41
|
-
|
|
46
|
+
def substitute_in_external(
|
|
47
|
+
expr: list[ca.MX], symbols: list[ca.MX], values: list[Union[ca.MX, ca.DM, float]]
|
|
48
|
+
):
|
|
49
|
+
# We expect expr to be a list of (at most) length 1
|
|
50
|
+
assert len(expr) <= 1
|
|
51
|
+
|
|
52
|
+
if not expr or len(symbols) == 0 or all(isinstance(x, ca.DM) for x in expr):
|
|
42
53
|
return expr
|
|
54
|
+
elif not expr:
|
|
55
|
+
return []
|
|
43
56
|
else:
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
for _ in range(MAX_SUBSTITUTE_DEPTH):
|
|
58
|
+
f = ca.Function("f", symbols, expr).expand()
|
|
59
|
+
expr = f.call(values, True, False)
|
|
60
|
+
if expr[0].is_constant():
|
|
61
|
+
break
|
|
62
|
+
|
|
63
|
+
return expr
|
|
46
64
|
|
|
47
65
|
|
|
48
66
|
def interpolate(ts, xs, t, equidistant, mode=0):
|
|
@@ -45,11 +45,17 @@ class CollocatedIntegratedOptimizationProblem(OptimizationProblem, metaclass=ABC
|
|
|
45
45
|
|
|
46
46
|
:cvar check_collocation_linearity:
|
|
47
47
|
If ``True``, check whether collocation constraints are linear. Default is ``True``.
|
|
48
|
+
:cvar inline_delay_expressions:
|
|
49
|
+
If ``True``, delay expressions are inlined into constraints and objectives instead of
|
|
50
|
+
being added as separate equality constraints. Default is ``False``.
|
|
48
51
|
"""
|
|
49
52
|
|
|
50
53
|
#: Check whether the collocation constraints are linear
|
|
51
54
|
check_collocation_linearity = True
|
|
52
55
|
|
|
56
|
+
#: Inline delay expressions instead of adding them as separate equality constraints
|
|
57
|
+
inline_delay_expressions = False
|
|
58
|
+
|
|
53
59
|
#: Whether or not the collocation constraints are linear (affine)
|
|
54
60
|
linear_collocation = None
|
|
55
61
|
|
|
@@ -386,7 +392,9 @@ class CollocatedIntegratedOptimizationProblem(OptimizationProblem, metaclass=ABC
|
|
|
386
392
|
):
|
|
387
393
|
parameter_values = nullvertcat(*parameter_values)
|
|
388
394
|
[parameter_values] = substitute_in_external(
|
|
389
|
-
[parameter_values],
|
|
395
|
+
[parameter_values],
|
|
396
|
+
self.dae_variables["parameters"],
|
|
397
|
+
ca.vertsplit(parameter_values),
|
|
390
398
|
)
|
|
391
399
|
else:
|
|
392
400
|
parameter_values = nullvertcat(*parameter_values)
|
|
@@ -1789,6 +1797,12 @@ class CollocatedIntegratedOptimizationProblem(OptimizationProblem, metaclass=ABC
|
|
|
1789
1797
|
+ [constant_inputs[v.name()] for v in self.dae_variables["constant_inputs"]]
|
|
1790
1798
|
)
|
|
1791
1799
|
|
|
1800
|
+
# If inlining delay expressions, prepare for the single call to ca.substitute()
|
|
1801
|
+
# at the end
|
|
1802
|
+
if self.inline_delay_expressions:
|
|
1803
|
+
delayed_feedback_variable_replacement = ca.MX.zeros(X.numel())
|
|
1804
|
+
delayed_feedback_variable_replacement[:] = X
|
|
1805
|
+
|
|
1792
1806
|
for i in range(len(delayed_feedback_expressions)):
|
|
1793
1807
|
in_variable_name = delayed_feedback_states[i]
|
|
1794
1808
|
expression = delayed_feedback_expressions[i]
|
|
@@ -1855,10 +1869,38 @@ class CollocatedIntegratedOptimizationProblem(OptimizationProblem, metaclass=ABC
|
|
|
1855
1869
|
|
|
1856
1870
|
nominal = nominal_delayed_feedback[i]
|
|
1857
1871
|
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1872
|
+
if self.inline_delay_expressions:
|
|
1873
|
+
# Get the indices for the delayed feedback variable in the optimization
|
|
1874
|
+
# vector
|
|
1875
|
+
indices = self.__indices[ensemble_member][in_canonical]
|
|
1876
|
+
|
|
1877
|
+
# Insert replacement values into appropriate slot
|
|
1878
|
+
delayed_feedback_variable_replacement[indices] = (
|
|
1879
|
+
x_out_delayed / in_nominal / in_sign
|
|
1880
|
+
)
|
|
1881
|
+
|
|
1882
|
+
# Equate delayed feedback variable to zero so that the numerical solver can
|
|
1883
|
+
# remove it from the problem.
|
|
1884
|
+
#
|
|
1885
|
+
# Note: The alternative approach would be to shrink self.solver_input=X,
|
|
1886
|
+
# self.__indices, and any other variables that directly or indirectly
|
|
1887
|
+
# depend on the size and order of 'X'. This would be a complex operation,
|
|
1888
|
+
# which would however be redundant for solvers that (like Ipopt) already
|
|
1889
|
+
# automatically detect and remove variables where lbx==ubx.
|
|
1890
|
+
lbx[indices] = 0.0
|
|
1891
|
+
ubx[indices] = 0.0
|
|
1892
|
+
else:
|
|
1893
|
+
# Default behavior: add delay expressions as equality constraints
|
|
1894
|
+
g.append((x_in - x_out_delayed) / nominal)
|
|
1895
|
+
zeros = np.zeros(n_collocation_times)
|
|
1896
|
+
lbg.extend(zeros)
|
|
1897
|
+
ubg.extend(zeros)
|
|
1898
|
+
|
|
1899
|
+
# If inlining delay expressions, carry out the single call to ca.substitute()
|
|
1900
|
+
# A single call is more efficient as it constructs a single ca.Function internally,
|
|
1901
|
+
# rather than one for each element of the list.
|
|
1902
|
+
if self.inline_delay_expressions:
|
|
1903
|
+
g = [ca.substitute(ca.vertcat(*g), X, delayed_feedback_variable_replacement)]
|
|
1862
1904
|
|
|
1863
1905
|
# Objective
|
|
1864
1906
|
f_member = self.objective(ensemble_member)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|