linerate 2.1.2__tar.gz → 2.2.0__tar.gz
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.
- {linerate-2.1.2 → linerate-2.2.0}/PKG-INFO +1 -1
- {linerate-2.1.2 → linerate-2.2.0}/linerate/models/thermal_model.py +5 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/solver.py +20 -15
- {linerate-2.1.2 → linerate-2.2.0}/linerate.egg-info/PKG-INFO +1 -1
- {linerate-2.1.2 → linerate-2.2.0}/tests/test_solver.py +32 -0
- {linerate-2.1.2 → linerate-2.2.0}/.github/workflows/deploy.yml +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/.github/workflows/tests.yml +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/.gitignore +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/.pre-commit-config.yaml +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/LICENSE +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/README.md +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/Makefile +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/_static/css/custom.css +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/cigre207/convective_cooling.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/cigre207/solar_heating.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/cigre601/convective_cooling.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/cigre601/solar_heating.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/convective_cooling.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/dimensionless.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/ieee738/convective_cooling.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/ieee738/solar_heating.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/index.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/joule_heating.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/math.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/radiative_cooling.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/solar_angles.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/equations/solar_heating.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/model.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/solver.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api/types.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/api.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/bibliography.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/conf.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/figs/frontpage.png +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/index.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/make.bat +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/docs/refs.bib +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/examples/README.rst +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/examples/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/examples/plot_cigre.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/examples/plot_solar_heating_comparison.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/examples/plot_solar_radiation.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/cigre207/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/cigre207/ac_resistance.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/cigre207/convective_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/cigre207/solar_heating.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/cigre601/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/cigre601/convective_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/cigre601/py.typed +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/cigre601/solar_heating.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/convective_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/dimensionless.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/ieee738/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/ieee738/convective_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/ieee738/py.typed +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/ieee738/solar_heating.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/joule_heating.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/math.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/py.typed +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/radiative_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/solar_angles.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/equations/solar_heating.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/model.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/models/Cigre207.md +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/models/cigre207.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/models/cigre601.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/models/ieee738.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/py.typed +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/types.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate/units.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate.egg-info/SOURCES.txt +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate.egg-info/dependency_links.txt +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate.egg-info/requires.txt +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/linerate.egg-info/top_level.txt +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/pyproject.toml +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/renovate.json +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/setup.cfg +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/acceptance_tests/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/acceptance_tests/test_cigre_ampacity_cases.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/acceptance_tests/test_ieee_ampacity_cases.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/acceptance_tests/test_ratekit_ampacity_cases.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/acceptance_tests/test_thermal_model.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/conftest.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/cigre207/test_convective_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/cigre601/__init__.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/cigre601/test_convective_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/cigre601/test_solar_heating.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/ieee738/test_ieee_convective_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/ieee738/test_solar_heating.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/test_convective_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/test_dimensionless.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/test_joule_heating.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/test_math.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/test_radiative_cooling.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/test_solar_angles.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/equations/test_solar_heating.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/integration_tests/test_vectorization.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/tests/models/test_thermal_model.py +0 -0
- {linerate-2.1.2 → linerate-2.2.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: linerate
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Library for computing line ampacity ratings for overhead lines
|
|
5
5
|
Author-email: Statnett Datascience <Datascience.Drift@Statnett.no>, Yngve Mardal Moe <yngve.m.moe@gmail.com>
|
|
6
6
|
Requires-Python: >=3.9
|
|
@@ -198,6 +198,7 @@ class ThermalModel(ABC):
|
|
|
198
198
|
min_ampacity: Ampere = 0,
|
|
199
199
|
max_ampacity: Ampere = 5000,
|
|
200
200
|
tolerance: float = 1.0,
|
|
201
|
+
accept_invalid_values: bool = False,
|
|
201
202
|
) -> Ampere:
|
|
202
203
|
r"""Use the bisection method to compute the steady-state thermal rating (ampacity).
|
|
203
204
|
|
|
@@ -216,6 +217,9 @@ class ThermalModel(ABC):
|
|
|
216
217
|
bisection iterations will stop once the numerical ampacity uncertainty is below
|
|
217
218
|
:math:`\Delta I`. The bisection method will run for
|
|
218
219
|
:math:`\left\lceil\frac{I_\text{min} - I_\text{min}}{\Delta I}\right\rceil` iterations.
|
|
220
|
+
accept_invalid_values:
|
|
221
|
+
If True, np.nan is returned whenever the current cannot be found within the provided
|
|
222
|
+
search interval. If False, a ValueError will be raised instead.
|
|
219
223
|
|
|
220
224
|
Returns
|
|
221
225
|
-------
|
|
@@ -228,6 +232,7 @@ class ThermalModel(ABC):
|
|
|
228
232
|
min_ampacity=min_ampacity,
|
|
229
233
|
max_ampacity=max_ampacity,
|
|
230
234
|
tolerance=tolerance,
|
|
235
|
+
accept_invalid_values=accept_invalid_values,
|
|
231
236
|
)
|
|
232
237
|
n = self.span.num_conductors
|
|
233
238
|
return I * n
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from functools import partial
|
|
2
|
-
from typing import Callable
|
|
2
|
+
from typing import Callable
|
|
3
3
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@ def bisect(
|
|
|
13
13
|
xmin: FloatOrFloatArray,
|
|
14
14
|
xmax: FloatOrFloatArray,
|
|
15
15
|
tolerance: float,
|
|
16
|
-
|
|
16
|
+
accept_invalid_values: bool = False,
|
|
17
17
|
) -> FloatOrFloatArray:
|
|
18
18
|
r"""Compute the roots of a function using a vectorized bisection method.
|
|
19
19
|
|
|
@@ -32,10 +32,10 @@ def bisect(
|
|
|
32
32
|
bounded within an interval of size :math:`\Delta x` or less. The bisection method will
|
|
33
33
|
run for :math:`\left\lceil\frac{x_\max - x_\min}{\Delta x}\right\rceil`
|
|
34
34
|
iterations.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
:math:`\text{sign}(f(\mathbf{x}_\min)) = \text{sign}(f(\mathbf{x}_\max))
|
|
38
|
-
|
|
35
|
+
accept_invalid_values:
|
|
36
|
+
If True, np.nan is returned whenever
|
|
37
|
+
:math:`\text{sign}(f(\mathbf{x}_\min)) = \text{sign}(f(\mathbf{x}_\max))`
|
|
38
|
+
If False, a ValueError will be raised.
|
|
39
39
|
|
|
40
40
|
Returns
|
|
41
41
|
-------
|
|
@@ -44,7 +44,7 @@ def bisect(
|
|
|
44
44
|
there is a root :math:`x_i \in [\tilde{x}_i - 0.5 \Delta x, \tilde{x}_i + 0.5 \Delta x]`
|
|
45
45
|
so :math:`f_i(x_i) = 0`.
|
|
46
46
|
"""
|
|
47
|
-
_invalid_value = np.nan
|
|
47
|
+
_invalid_value = np.nan
|
|
48
48
|
|
|
49
49
|
if not np.all(np.isfinite(xmin)) or not np.all(np.isfinite(xmax)):
|
|
50
50
|
raise ValueError("xmin and xmax must be finite.")
|
|
@@ -54,14 +54,15 @@ def bisect(
|
|
|
54
54
|
f_right = f(xmax)
|
|
55
55
|
|
|
56
56
|
invalid_mask = np.sign(f_left) == np.sign(f_right)
|
|
57
|
-
if np.any(invalid_mask) and
|
|
57
|
+
if np.any(invalid_mask) and not accept_invalid_values:
|
|
58
58
|
raise ValueError(
|
|
59
59
|
"f(xmin) and f(xmax) have the same sign. Consider increasing the search interval."
|
|
60
60
|
)
|
|
61
61
|
elif isinstance(invalid_mask, bool) and invalid_mask:
|
|
62
62
|
return _invalid_value
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
nan_mask = np.isnan(f_left) | np.isnan(f_right)
|
|
65
|
+
while interval > tolerance and not np.all(nan_mask):
|
|
65
66
|
xmid = 0.5 * (xmax + xmin)
|
|
66
67
|
interval *= 0.5
|
|
67
68
|
f_mid = f(xmid)
|
|
@@ -72,7 +73,10 @@ def bisect(
|
|
|
72
73
|
f_left = np.where(mask, f_mid, f_left)
|
|
73
74
|
f_right = np.where(mask, f_right, f_mid)
|
|
74
75
|
|
|
76
|
+
nan_mask = np.isnan(f_left) | np.isnan(f_right)
|
|
77
|
+
|
|
75
78
|
out = np.where(invalid_mask, _invalid_value, 0.5 * (xmax + xmin))
|
|
79
|
+
out = np.where(nan_mask, np.nan, out)
|
|
76
80
|
return out
|
|
77
81
|
|
|
78
82
|
|
|
@@ -121,7 +125,7 @@ def compute_conductor_ampacity(
|
|
|
121
125
|
min_ampacity: Ampere = 0,
|
|
122
126
|
max_ampacity: Ampere = 5_000,
|
|
123
127
|
tolerance: float = 1, # Ampere
|
|
124
|
-
|
|
128
|
+
accept_invalid_values: bool = False,
|
|
125
129
|
) -> Ampere:
|
|
126
130
|
r"""Use the bisection method to compute the steady-state thermal rating (ampacity).
|
|
127
131
|
|
|
@@ -144,10 +148,9 @@ def compute_conductor_ampacity(
|
|
|
144
148
|
bisection iterations will stop once the numerical ampacity uncertainty is below
|
|
145
149
|
:math:`\Delta I`. The bisection method will run for
|
|
146
150
|
:math:`\left\lceil\frac{I_\text{max} - I_\text{min}}{\Delta I}\right\rceil` iterations.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
ampacities.
|
|
151
|
+
accept_invalid_values:
|
|
152
|
+
If True, np.nan is returned whenever the current cannot be found within the provided
|
|
153
|
+
search interval. If False, a ValueError will be raised instead.
|
|
151
154
|
|
|
152
155
|
Returns
|
|
153
156
|
-------
|
|
@@ -156,4 +159,6 @@ def compute_conductor_ampacity(
|
|
|
156
159
|
"""
|
|
157
160
|
f = partial(heat_balance, max_conductor_temperature)
|
|
158
161
|
|
|
159
|
-
return bisect(
|
|
162
|
+
return bisect(
|
|
163
|
+
f, min_ampacity, max_ampacity, tolerance, accept_invalid_values=accept_invalid_values
|
|
164
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: linerate
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Library for computing line ampacity ratings for overhead lines
|
|
5
5
|
Author-email: Statnett Datascience <Datascience.Drift@Statnett.no>, Yngve Mardal Moe <yngve.m.moe@gmail.com>
|
|
6
6
|
Requires-Python: >=3.9
|
|
@@ -87,3 +87,35 @@ def test_bisect_raises_valueerror_when_infinite_in_array_input():
|
|
|
87
87
|
xmax=np.array([10_000, 10_000]),
|
|
88
88
|
tolerance=1e-8,
|
|
89
89
|
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_bisect_returns_dtype_float_if_not_accept_invalid_values():
|
|
93
|
+
def heat_balance(currents: np.array):
|
|
94
|
+
A = currents
|
|
95
|
+
T = 90
|
|
96
|
+
res = (A - 100 * T) * (currents + 100 * T)
|
|
97
|
+
return res
|
|
98
|
+
|
|
99
|
+
solution = solver.bisect(
|
|
100
|
+
heat_balance,
|
|
101
|
+
xmin=np.array([0, 0]),
|
|
102
|
+
xmax=np.array([10_000, 10_000]),
|
|
103
|
+
tolerance=1e-8,
|
|
104
|
+
accept_invalid_values=False,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
assert solution.dtype == np.float64
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def test_bisect_return_nan_if_heat_balance_returns_nan():
|
|
111
|
+
def heat_balance(currents: np.array):
|
|
112
|
+
return np.ones_like(currents) * np.nan
|
|
113
|
+
|
|
114
|
+
solution = solver.bisect(
|
|
115
|
+
heat_balance,
|
|
116
|
+
xmin=np.array([0, 0]),
|
|
117
|
+
xmax=np.array([10_000, 10_000]),
|
|
118
|
+
tolerance=1e-8,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
np.testing.assert_array_equal(np.isnan(solution), np.full_like(solution, True, dtype=bool))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|