linerate 2.2.0__tar.gz → 3.0.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.2.0 → linerate-3.0.0}/.github/workflows/tests.yml +3 -3
- {linerate-2.2.0 → linerate-3.0.0}/.pre-commit-config.yaml +4 -0
- {linerate-2.2.0 → linerate-3.0.0}/PKG-INFO +1 -1
- {linerate-2.2.0 → linerate-3.0.0}/examples/plot_solar_heating_comparison.py +4 -1
- {linerate-2.2.0 → linerate-3.0.0}/examples/plot_solar_radiation.py +14 -11
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/ieee738/convective_cooling.py +1 -1
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/solar_angles.py +12 -6
- {linerate-2.2.0 → linerate-3.0.0}/linerate/models/cigre207.py +6 -9
- {linerate-2.2.0 → linerate-3.0.0}/linerate/models/cigre601.py +66 -43
- {linerate-2.2.0 → linerate-3.0.0}/linerate/models/ieee738.py +6 -12
- {linerate-2.2.0 → linerate-3.0.0}/linerate/models/thermal_model.py +13 -22
- {linerate-2.2.0 → linerate-3.0.0}/linerate/solver.py +3 -1
- {linerate-2.2.0 → linerate-3.0.0}/linerate/types.py +9 -12
- {linerate-2.2.0 → linerate-3.0.0}/linerate/units.py +2 -1
- {linerate-2.2.0 → linerate-3.0.0}/linerate.egg-info/PKG-INFO +1 -1
- {linerate-2.2.0 → linerate-3.0.0}/linerate.egg-info/SOURCES.txt +1 -0
- {linerate-2.2.0 → linerate-3.0.0}/pyproject.toml +6 -0
- linerate-3.0.0/tests/acceptance_tests/test_cigre_ampacity_cases.py +117 -0
- linerate-3.0.0/tests/acceptance_tests/test_ieee_ampacity_cases.py +89 -0
- linerate-3.0.0/tests/acceptance_tests/test_ratekit_ampacity_cases.py +118 -0
- {linerate-2.2.0 → linerate-3.0.0}/tests/acceptance_tests/test_thermal_model.py +12 -11
- linerate-3.0.0/tests/conftest.py +102 -0
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/cigre601/test_convective_cooling.py +68 -37
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/cigre601/test_solar_heating.py +27 -22
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/ieee738/test_ieee_convective_cooling.py +23 -16
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/ieee738/test_solar_heating.py +13 -8
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/test_convective_cooling.py +6 -5
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/test_dimensionless.py +29 -11
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/test_joule_heating.py +25 -10
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/test_math.py +6 -9
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/test_radiative_cooling.py +13 -6
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/test_solar_angles.py +14 -9
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/test_solar_heating.py +6 -3
- {linerate-2.2.0 → linerate-3.0.0}/tests/integration_tests/test_vectorization.py +11 -8
- linerate-3.0.0/tests/models/test_cigre601_with_solar_radiation.py +49 -0
- {linerate-2.2.0 → linerate-3.0.0}/tests/models/test_thermal_model.py +5 -1
- {linerate-2.2.0 → linerate-3.0.0}/tests/test_solver.py +30 -38
- {linerate-2.2.0 → linerate-3.0.0}/uv.lock +40 -1
- linerate-2.2.0/tests/acceptance_tests/test_cigre_ampacity_cases.py +0 -115
- linerate-2.2.0/tests/acceptance_tests/test_ieee_ampacity_cases.py +0 -87
- linerate-2.2.0/tests/acceptance_tests/test_ratekit_ampacity_cases.py +0 -115
- linerate-2.2.0/tests/conftest.py +0 -88
- {linerate-2.2.0 → linerate-3.0.0}/.github/workflows/deploy.yml +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/.gitignore +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/LICENSE +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/README.md +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/Makefile +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/_static/css/custom.css +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/cigre207/convective_cooling.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/cigre207/solar_heating.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/cigre601/convective_cooling.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/cigre601/solar_heating.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/convective_cooling.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/dimensionless.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/ieee738/convective_cooling.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/ieee738/solar_heating.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/index.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/joule_heating.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/math.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/radiative_cooling.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/solar_angles.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/equations/solar_heating.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/model.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/solver.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api/types.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/api.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/bibliography.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/conf.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/figs/frontpage.png +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/index.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/make.bat +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/docs/refs.bib +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/examples/README.rst +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/examples/__init__.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/examples/plot_cigre.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/__init__.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/__init__.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/cigre207/__init__.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/cigre207/ac_resistance.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/cigre207/convective_cooling.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/cigre207/solar_heating.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/cigre601/__init__.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/cigre601/convective_cooling.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/cigre601/py.typed +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/cigre601/solar_heating.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/convective_cooling.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/dimensionless.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/ieee738/__init__.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/ieee738/py.typed +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/ieee738/solar_heating.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/joule_heating.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/math.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/py.typed +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/radiative_cooling.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/equations/solar_heating.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/model.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/models/Cigre207.md +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate/py.typed +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate.egg-info/dependency_links.txt +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate.egg-info/requires.txt +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/linerate.egg-info/top_level.txt +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/renovate.json +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/setup.cfg +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/tests/__init__.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/tests/acceptance_tests/__init__.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/__init__.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/cigre207/test_convective_cooling.py +0 -0
- {linerate-2.2.0 → linerate-3.0.0}/tests/equations/cigre601/__init__.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: Lint and
|
|
2
|
+
name: Lint, type check and test
|
|
3
3
|
|
|
4
4
|
on: [push, pull_request]
|
|
5
5
|
|
|
6
6
|
jobs:
|
|
7
|
-
lint:
|
|
7
|
+
lint-and-type-check:
|
|
8
8
|
runs-on: ubuntu-latest
|
|
9
9
|
strategy:
|
|
10
10
|
matrix:
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v6
|
|
18
18
|
with:
|
|
19
19
|
python-version: ${{ matrix.python-version }}
|
|
20
|
-
- name: Run linting
|
|
20
|
+
- name: Run linting and type checking
|
|
21
21
|
run: |
|
|
22
22
|
uv run --frozen pre-commit run --all-files
|
|
23
23
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: linerate
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.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
|
|
@@ -73,7 +73,10 @@ for k, v in vals_with_range.items():
|
|
|
73
73
|
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
74
74
|
|
|
75
75
|
P_s_cigre = solar_heating.compute_solar_heating(alpha_s, I_T, D)
|
|
76
|
+
assert isinstance(P_s_cigre, np.ndarray)
|
|
77
|
+
|
|
76
78
|
P_s_ieee = ieee738.solar_heating.compute_solar_heating(alpha_s, Q_se, cos_theta, D)
|
|
79
|
+
assert isinstance(P_s_ieee, np.ndarray)
|
|
77
80
|
|
|
78
81
|
###############################################################################
|
|
79
82
|
# Create visualisation
|
|
@@ -92,7 +95,7 @@ for k, v in vals_with_range.items():
|
|
|
92
95
|
)
|
|
93
96
|
elif k == "sin_H_s":
|
|
94
97
|
plt.xlabel("Solar altitude [$^\\circ$]")
|
|
95
|
-
plt.xticks(ticks=[0, 1 / 3, 2 / 3, 1], labels=[0, 30, 60, 90])
|
|
98
|
+
plt.xticks(ticks=[0, 1 / 3, 2 / 3, 1], labels=["0", "30", "60", "90"])
|
|
96
99
|
plt.title(
|
|
97
100
|
r"Solar heating calculated using the CIGRE-601 and the IEEE-736 standards."
|
|
98
101
|
"\n"
|
|
@@ -11,7 +11,6 @@ the difference between the solar azimuth and the span azimuth (or bearing),
|
|
|
11
11
|
# Imports and utilities
|
|
12
12
|
# ^^^^^^^^^^^^^^^^^^^^^
|
|
13
13
|
|
|
14
|
-
import matplotlib.cm as cm
|
|
15
14
|
import matplotlib.pyplot as plt
|
|
16
15
|
import numpy as np
|
|
17
16
|
|
|
@@ -45,9 +44,12 @@ I_d = cigre601.solar_heating.compute_diffuse_sky_radiation(I_B, sin_H_s)
|
|
|
45
44
|
I_T_F0 = cigre601.solar_heating.compute_global_radiation_intensity(
|
|
46
45
|
I_B, I_d, albedo=0.0, sin_angle_of_sun_on_line=sin_eta, sin_solar_altitude=sin_H_s
|
|
47
46
|
)
|
|
47
|
+
assert isinstance(I_T_F0, np.ndarray)
|
|
48
|
+
|
|
48
49
|
I_T_F = cigre601.solar_heating.compute_global_radiation_intensity(
|
|
49
50
|
I_B, I_d, albedo=albedo, sin_angle_of_sun_on_line=sin_eta, sin_solar_altitude=sin_H_s
|
|
50
51
|
)
|
|
52
|
+
assert isinstance(I_T_F, np.ndarray)
|
|
51
53
|
|
|
52
54
|
###############################################################################
|
|
53
55
|
# Create visualisation
|
|
@@ -57,19 +59,20 @@ I_T_F = cigre601.solar_heating.compute_global_radiation_intensity(
|
|
|
57
59
|
|
|
58
60
|
# Setup figure and axes
|
|
59
61
|
fig = plt.figure(figsize=(11, 1.9))
|
|
60
|
-
axes = [fig.add_axes(
|
|
62
|
+
axes = [fig.add_axes((0.07, 0.27, 0.19, 0.7))]
|
|
61
63
|
axes += [
|
|
62
|
-
fig.add_axes(
|
|
63
|
-
fig.add_axes(
|
|
64
|
-
fig.add_axes(
|
|
64
|
+
fig.add_axes((0.30, 0.27, 0.18, 0.7), sharey=axes[0]),
|
|
65
|
+
fig.add_axes((0.53, 0.27, 0.18, 0.7), sharey=axes[0]),
|
|
66
|
+
fig.add_axes((0.76, 0.27, 0.18, 0.7), sharey=axes[0]),
|
|
65
67
|
]
|
|
66
|
-
cbar_ax = fig.add_axes(
|
|
68
|
+
cbar_ax = fig.add_axes((0.955, 0.27, 0.015, 0.7))
|
|
67
69
|
|
|
68
70
|
# Add plots
|
|
69
71
|
axes[0].plot(np.degrees(solar_altitude), I_B, color="k")
|
|
70
72
|
axes[1].plot(np.degrees(solar_altitude), I_d, color="k")
|
|
73
|
+
cmap = plt.get_cmap("cividis")
|
|
71
74
|
for i, d_gamma in enumerate(azimuth_difference.ravel()):
|
|
72
|
-
color =
|
|
75
|
+
color = cmap(d_gamma / azimuth_difference.max())
|
|
73
76
|
d_gamma = np.degrees(d_gamma)
|
|
74
77
|
axes[2].plot(np.degrees(solar_altitude), I_T_F0[:, i], color=color)
|
|
75
78
|
axes[3].plot(np.degrees(solar_altitude), I_T_F[:, i], color=color)
|
|
@@ -84,7 +87,7 @@ for ax in axes:
|
|
|
84
87
|
# Setup y-axes to be shared
|
|
85
88
|
ax.set_ylim(0, I_T_F.max() * 1.05)
|
|
86
89
|
ax.set_yticks([0, 500, 1000, 1360]) # Include tick for solar constant
|
|
87
|
-
ax.set_yticklabels([0, 500, 1000, "$G_{SC}$"])
|
|
90
|
+
ax.set_yticklabels(["0", "500", "1000", "$G_{SC}$"])
|
|
88
91
|
ax.axhline(1360, color="k", linestyle="--") # Add dashed line for solar constant
|
|
89
92
|
|
|
90
93
|
|
|
@@ -96,8 +99,8 @@ axes[3].tick_params(labelleft=False)
|
|
|
96
99
|
# Setup labels
|
|
97
100
|
axes[0].set_ylabel(r"$I_B~[\mathrm{W}~\mathrm{m}^{-1}]$", labelpad=-1)
|
|
98
101
|
axes[1].set_ylabel(r"$I_d~[\mathrm{W}~\mathrm{m}^{-1}]$")
|
|
99
|
-
axes[2].set_ylabel("$F=0$\n$I_T~[\mathrm{W}~\mathrm{m}^{-1}]$") # noqa
|
|
100
|
-
axes[3].set_ylabel(
|
|
102
|
+
axes[2].set_ylabel(r"$F=0$\n$I_T~[\mathrm{W}~\mathrm{m}^{-1}]$") # noqa
|
|
103
|
+
axes[3].set_ylabel(rf"$F={albedo}$\n$I_T~[\mathrm{{W}}~\mathrm{{m}}^{{-1}}]$") # noqa
|
|
101
104
|
|
|
102
105
|
# Colorbar
|
|
103
106
|
cbar_ax.imshow(azimuth_difference.T, aspect="auto", cmap="cividis")
|
|
@@ -105,7 +108,7 @@ cbar_ax.yaxis.set_label_position("right")
|
|
|
105
108
|
cbar_ax.set_ylabel(r"$\left|\gamma_c - \gamma_s\right|~[^\circ]$", labelpad=-10)
|
|
106
109
|
cbar_ax.yaxis.tick_right()
|
|
107
110
|
cbar_ax.set_yticks(cbar_ax.get_ylim())
|
|
108
|
-
cbar_ax.set_yticklabels([0, 90])
|
|
111
|
+
cbar_ax.set_yticklabels(["0", "90"])
|
|
109
112
|
cbar_ax.set_xticks([])
|
|
110
113
|
|
|
111
114
|
plt.show()
|
|
@@ -190,7 +190,7 @@ def compute_forced_convection( # q_c1 or q_c2
|
|
|
190
190
|
q_c1 = K_angle * (1.01 + 1.35 * N_Re**0.52) * k_f * (T_s - T_a)
|
|
191
191
|
q_c2 = K_angle * 0.754 * N_Re**0.6 * k_f * (T_s - T_a)
|
|
192
192
|
|
|
193
|
-
if
|
|
193
|
+
if isinstance(q_c1, np.ndarray) and isinstance(q_c2, np.ndarray):
|
|
194
194
|
q_cf = []
|
|
195
195
|
for i in range(len(q_c1)):
|
|
196
196
|
if q_c1[i] > q_c2[i]:
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from numba import vectorize
|
|
3
|
+
|
|
3
4
|
from linerate.equations import math
|
|
4
5
|
|
|
5
|
-
from ..units import Date, Degrees, Radian, Unitless
|
|
6
6
|
from ..types import Span
|
|
7
|
+
from ..units import Date, Degrees, Radian, Unitless
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def _get_day_of_year(when: Date) -> Unitless:
|
|
10
11
|
YearResolutionType = np.datetime64(1, "Y")
|
|
11
12
|
DayResolutionType = np.datetime64(1, "D")
|
|
12
13
|
|
|
13
|
-
return (when.astype(DayResolutionType) - when.astype(YearResolutionType)).astype(float) + 1
|
|
14
|
+
return (when.astype(DayResolutionType) - when.astype(YearResolutionType)).astype(float) + 1.0
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def _get_hour_of_day(when: Date) -> Unitless:
|
|
@@ -55,9 +56,11 @@ def compute_hour_angle_relative_to_noon(when: Date, longitude: Degrees) -> Radia
|
|
|
55
56
|
utc_minute = _get_minute_of_hour(when)
|
|
56
57
|
pi = np.pi
|
|
57
58
|
# We add longitude/15 since 15 degrees of longitude increases solar hour by 1
|
|
58
|
-
|
|
59
|
+
hour_angle = np.mod((-12 + utc_hour + utc_minute / 60 + longitude / 15), 24) * (
|
|
59
60
|
pi / 12
|
|
60
61
|
) # pi/12 is 15 degrees
|
|
62
|
+
# Shift to [-pi, pi] range to ensure negative values before noon
|
|
63
|
+
return np.where(hour_angle >= pi, hour_angle - 2 * pi, hour_angle)
|
|
61
64
|
|
|
62
65
|
|
|
63
66
|
def compute_solar_declination(
|
|
@@ -123,13 +126,16 @@ def _compute_solar_azimuth_constant(
|
|
|
123
126
|
if -pi <= omega < 0:
|
|
124
127
|
if chi >= 0:
|
|
125
128
|
C = 0
|
|
126
|
-
|
|
129
|
+
else:
|
|
127
130
|
C = pi
|
|
128
131
|
elif 0 <= omega < pi:
|
|
129
132
|
if chi >= 0:
|
|
130
133
|
C = pi
|
|
131
|
-
|
|
134
|
+
else:
|
|
132
135
|
C = 2 * pi
|
|
136
|
+
else:
|
|
137
|
+
raise ValueError(f"Hour angle {omega} out of range [-π, π)")
|
|
138
|
+
|
|
133
139
|
return C
|
|
134
140
|
|
|
135
141
|
|
|
@@ -138,7 +144,7 @@ def compute_solar_azimuth_constant(
|
|
|
138
144
|
) -> Radian:
|
|
139
145
|
r"""Compute the solar azimuth constant.
|
|
140
146
|
|
|
141
|
-
Table 2 on page 18 of:cite:p:`ieee738`.
|
|
147
|
+
Table 2 on page 18 of :cite:p:`ieee738`.
|
|
142
148
|
|
|
143
149
|
Parameters
|
|
144
150
|
----------
|
|
@@ -35,9 +35,7 @@ class Cigre207(ThermalModel):
|
|
|
35
35
|
)
|
|
36
36
|
|
|
37
37
|
@_copy_method_docstring(ThermalModel)
|
|
38
|
-
def compute_solar_heating(
|
|
39
|
-
self, conductor_temperature: Celsius, current: Ampere
|
|
40
|
-
) -> WattPerMeter:
|
|
38
|
+
def compute_solar_heating(self) -> WattPerMeter:
|
|
41
39
|
alpha_s = self.span.conductor.solar_absorptivity
|
|
42
40
|
phi = self.span.latitude
|
|
43
41
|
gamma_c = self.span.conductor_azimuth
|
|
@@ -60,7 +58,7 @@ class Cigre207(ThermalModel):
|
|
|
60
58
|
)
|
|
61
59
|
if self.include_diffuse_radiation:
|
|
62
60
|
I_d = cigre207.solar_heating.compute_diffuse_sky_radiation(I_B, sin_H_s)
|
|
63
|
-
F = self.
|
|
61
|
+
F = self.weather.ground_albedo
|
|
64
62
|
else:
|
|
65
63
|
I_d = 0
|
|
66
64
|
F = 0
|
|
@@ -74,9 +72,7 @@ class Cigre207(ThermalModel):
|
|
|
74
72
|
)
|
|
75
73
|
|
|
76
74
|
@_copy_method_docstring(ThermalModel)
|
|
77
|
-
def compute_convective_cooling(
|
|
78
|
-
self, conductor_temperature: Celsius, current: Ampere
|
|
79
|
-
) -> WattPerMeter:
|
|
75
|
+
def compute_convective_cooling(self, conductor_temperature: Celsius) -> WattPerMeter:
|
|
80
76
|
D = self.span.conductor.conductor_diameter
|
|
81
77
|
d = self.span.conductor.outer_layer_strand_diameter
|
|
82
78
|
V = self.weather.wind_speed
|
|
@@ -126,10 +122,11 @@ class Cigre207(ThermalModel):
|
|
|
126
122
|
|
|
127
123
|
@_copy_method_docstring(ThermalModel)
|
|
128
124
|
def compute_radiative_cooling(
|
|
129
|
-
self,
|
|
125
|
+
self,
|
|
126
|
+
conductor_temperature: Celsius,
|
|
130
127
|
) -> WattPerMeter:
|
|
131
128
|
return super().compute_radiative_cooling(
|
|
132
|
-
conductor_temperature=conductor_temperature,
|
|
129
|
+
conductor_temperature=conductor_temperature,
|
|
133
130
|
)
|
|
134
131
|
|
|
135
132
|
@_copy_method_docstring(ThermalModel)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from numbers import Real
|
|
2
|
-
|
|
3
1
|
import numpy as np
|
|
4
2
|
|
|
5
3
|
from linerate.equations import (
|
|
@@ -11,24 +9,27 @@ from linerate.equations import (
|
|
|
11
9
|
solar_heating,
|
|
12
10
|
)
|
|
13
11
|
from linerate.models.thermal_model import ThermalModel, _copy_method_docstring
|
|
14
|
-
from linerate.types import Span, Weather, WeatherWithSolarRadiation
|
|
12
|
+
from linerate.types import BaseWeather, Span, Weather, WeatherWithSolarRadiation
|
|
15
13
|
from linerate.units import (
|
|
16
14
|
Ampere,
|
|
17
15
|
Celsius,
|
|
18
16
|
Date,
|
|
19
17
|
JoulePerKilogramPerKelvin,
|
|
20
18
|
OhmPerMeter,
|
|
19
|
+
Unitless,
|
|
21
20
|
WattPerMeter,
|
|
22
21
|
)
|
|
23
22
|
|
|
24
23
|
|
|
25
|
-
class
|
|
24
|
+
class BaseCigre601(ThermalModel):
|
|
25
|
+
DEFAULT_MAX_REYNOLDS_NUMBER = 4000.0 # Max value of the angle correction in CIGRE601
|
|
26
|
+
|
|
26
27
|
def __init__(
|
|
27
28
|
self,
|
|
28
29
|
span: Span,
|
|
29
|
-
weather:
|
|
30
|
+
weather: BaseWeather,
|
|
30
31
|
time: Date,
|
|
31
|
-
max_reynolds_number:
|
|
32
|
+
max_reynolds_number: Unitless = DEFAULT_MAX_REYNOLDS_NUMBER,
|
|
32
33
|
):
|
|
33
34
|
super().__init__(span, weather)
|
|
34
35
|
self.time = time
|
|
@@ -48,36 +49,10 @@ class Cigre601(ThermalModel):
|
|
|
48
49
|
conductor_temperature=conductor_temperature, current=current
|
|
49
50
|
)
|
|
50
51
|
|
|
51
|
-
@_copy_method_docstring(ThermalModel)
|
|
52
|
-
def compute_solar_heating(
|
|
53
|
-
self, conductor_temperature: Celsius, current: Ampere
|
|
54
|
-
) -> WattPerMeter:
|
|
55
|
-
alpha_s = self.span.conductor.solar_absorptivity
|
|
56
|
-
F = self.weather.ground_albedo
|
|
57
|
-
y = self.span.conductor_altitude
|
|
58
|
-
N_s = self.weather.clearness_ratio
|
|
59
|
-
D = self.span.conductor.conductor_diameter
|
|
60
|
-
|
|
61
|
-
sin_H_s = solar_angles.compute_sin_solar_altitude_for_span(self.span, self.time)
|
|
62
|
-
|
|
63
|
-
sin_eta = solar_angles.compute_sin_solar_effective_incidence_angle_for_span(
|
|
64
|
-
self.span, self.time, sin_H_s
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
I_B = cigre601.solar_heating.compute_direct_solar_radiation(sin_H_s, N_s, y)
|
|
68
|
-
I_d = cigre601.solar_heating.compute_diffuse_sky_radiation(I_B, sin_H_s)
|
|
69
|
-
I_T = cigre601.solar_heating.compute_global_radiation_intensity(
|
|
70
|
-
I_B, I_d, F, sin_eta, sin_H_s
|
|
71
|
-
)
|
|
72
|
-
return solar_heating.compute_solar_heating(
|
|
73
|
-
alpha_s,
|
|
74
|
-
I_T,
|
|
75
|
-
D,
|
|
76
|
-
)
|
|
77
|
-
|
|
78
52
|
@_copy_method_docstring(ThermalModel)
|
|
79
53
|
def compute_convective_cooling(
|
|
80
|
-
self,
|
|
54
|
+
self,
|
|
55
|
+
conductor_temperature: Celsius,
|
|
81
56
|
) -> WattPerMeter:
|
|
82
57
|
D = self.span.conductor.conductor_diameter
|
|
83
58
|
d = self.span.conductor.outer_layer_strand_diameter
|
|
@@ -133,10 +108,11 @@ class Cigre601(ThermalModel):
|
|
|
133
108
|
|
|
134
109
|
@_copy_method_docstring(ThermalModel)
|
|
135
110
|
def compute_radiative_cooling(
|
|
136
|
-
self,
|
|
111
|
+
self,
|
|
112
|
+
conductor_temperature: Celsius,
|
|
137
113
|
) -> WattPerMeter:
|
|
138
114
|
return super().compute_radiative_cooling(
|
|
139
|
-
conductor_temperature=conductor_temperature,
|
|
115
|
+
conductor_temperature=conductor_temperature,
|
|
140
116
|
)
|
|
141
117
|
|
|
142
118
|
def compute_temperature_gradient(
|
|
@@ -169,17 +145,64 @@ class Cigre601(ThermalModel):
|
|
|
169
145
|
)
|
|
170
146
|
|
|
171
147
|
|
|
172
|
-
class
|
|
173
|
-
"""Extension of the
|
|
148
|
+
class Cigre601(BaseCigre601):
|
|
149
|
+
"""Extension of the BaseCigre601 model that uses the solar radiation parametrisation in CIGRE601."""
|
|
150
|
+
|
|
151
|
+
def __init__(
|
|
152
|
+
self,
|
|
153
|
+
span: Span,
|
|
154
|
+
weather: Weather,
|
|
155
|
+
time: Date,
|
|
156
|
+
max_reynolds_number: Unitless = BaseCigre601.DEFAULT_MAX_REYNOLDS_NUMBER,
|
|
157
|
+
):
|
|
158
|
+
self.span = span
|
|
159
|
+
self.weather = weather
|
|
160
|
+
self.time = time
|
|
161
|
+
self.max_reynolds_number = max_reynolds_number
|
|
162
|
+
|
|
163
|
+
@_copy_method_docstring(ThermalModel)
|
|
164
|
+
def compute_solar_heating(self) -> WattPerMeter:
|
|
165
|
+
alpha_s = self.span.conductor.solar_absorptivity
|
|
166
|
+
F = self.weather.ground_albedo
|
|
167
|
+
y = self.span.conductor_altitude
|
|
168
|
+
N_s = self.weather.clearness_ratio
|
|
169
|
+
D = self.span.conductor.conductor_diameter
|
|
170
|
+
|
|
171
|
+
sin_H_s = solar_angles.compute_sin_solar_altitude_for_span(self.span, self.time)
|
|
172
|
+
|
|
173
|
+
sin_eta = solar_angles.compute_sin_solar_effective_incidence_angle_for_span(
|
|
174
|
+
self.span, self.time, sin_H_s
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
I_B = cigre601.solar_heating.compute_direct_solar_radiation(sin_H_s, N_s, y)
|
|
178
|
+
I_d = cigre601.solar_heating.compute_diffuse_sky_radiation(I_B, sin_H_s)
|
|
179
|
+
I_T = cigre601.solar_heating.compute_global_radiation_intensity(
|
|
180
|
+
I_B, I_d, F, sin_eta, sin_H_s
|
|
181
|
+
)
|
|
182
|
+
return solar_heating.compute_solar_heating(
|
|
183
|
+
alpha_s,
|
|
184
|
+
I_T,
|
|
185
|
+
D,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class Cigre601WithSolarRadiation(BaseCigre601):
|
|
190
|
+
"""Extension of the BaseCigre601 model that accepts external solar radiation data for direct and diffuse solar
|
|
174
191
|
radiation."""
|
|
175
192
|
|
|
176
|
-
def __init__(
|
|
177
|
-
|
|
193
|
+
def __init__(
|
|
194
|
+
self,
|
|
195
|
+
span: Span,
|
|
196
|
+
weather: WeatherWithSolarRadiation,
|
|
197
|
+
time: Date,
|
|
198
|
+
max_reynolds_number: Unitless = BaseCigre601.DEFAULT_MAX_REYNOLDS_NUMBER,
|
|
199
|
+
):
|
|
200
|
+
self.span = span
|
|
178
201
|
self.weather = weather
|
|
202
|
+
self.time = time
|
|
203
|
+
self.max_reynolds_number = max_reynolds_number
|
|
179
204
|
|
|
180
|
-
def compute_solar_heating(
|
|
181
|
-
self, conductor_temperature: Celsius, current: Ampere
|
|
182
|
-
) -> WattPerMeter:
|
|
205
|
+
def compute_solar_heating(self) -> WattPerMeter:
|
|
183
206
|
alpha_s = self.span.conductor.solar_absorptivity
|
|
184
207
|
F = self.weather.ground_albedo
|
|
185
208
|
D = self.span.conductor.conductor_diameter
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
from numbers import Real
|
|
2
|
-
|
|
3
1
|
import numpy as np
|
|
4
2
|
|
|
5
3
|
from linerate.equations import dimensionless, ieee738, math, solar_angles
|
|
6
4
|
from linerate.models.thermal_model import ThermalModel, _copy_method_docstring
|
|
7
5
|
from linerate.types import Span, Weather
|
|
8
|
-
from linerate.units import Ampere, Celsius, Date, OhmPerMeter, WattPerMeter
|
|
6
|
+
from linerate.units import Ampere, Celsius, Date, OhmPerMeter, Unitless, WattPerMeter
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
class IEEE738(ThermalModel):
|
|
@@ -14,7 +12,7 @@ class IEEE738(ThermalModel):
|
|
|
14
12
|
span: Span,
|
|
15
13
|
weather: Weather,
|
|
16
14
|
time: Date,
|
|
17
|
-
max_reynolds_number:
|
|
15
|
+
max_reynolds_number: Unitless = 50_000.0, # Max Reynolds number for forced convection
|
|
18
16
|
):
|
|
19
17
|
super().__init__(span, weather)
|
|
20
18
|
self.time = time
|
|
@@ -36,7 +34,7 @@ class IEEE738(ThermalModel):
|
|
|
36
34
|
|
|
37
35
|
@_copy_method_docstring(ThermalModel)
|
|
38
36
|
def compute_solar_heating(
|
|
39
|
-
self,
|
|
37
|
+
self,
|
|
40
38
|
) -> WattPerMeter:
|
|
41
39
|
alpha_s = self.span.conductor.solar_absorptivity # alpha in IEEE
|
|
42
40
|
phi = self.span.latitude # Lat in IEEE
|
|
@@ -58,9 +56,7 @@ class IEEE738(ThermalModel):
|
|
|
58
56
|
return ieee738.solar_heating.compute_solar_heating(alpha_s, Q_se, cos_theta, D)
|
|
59
57
|
|
|
60
58
|
@_copy_method_docstring(ThermalModel)
|
|
61
|
-
def compute_convective_cooling(
|
|
62
|
-
self, conductor_temperature: Celsius, current: Ampere
|
|
63
|
-
) -> WattPerMeter:
|
|
59
|
+
def compute_convective_cooling(self, conductor_temperature: Celsius) -> WattPerMeter:
|
|
64
60
|
D = self.span.conductor.conductor_diameter # D_0 in IEEE
|
|
65
61
|
y = self.span.conductor_altitude # H_e in IEEE
|
|
66
62
|
V = self.weather.wind_speed # V_w in IEEE
|
|
@@ -85,9 +81,7 @@ class IEEE738(ThermalModel):
|
|
|
85
81
|
return ieee738.convective_cooling.compute_convective_cooling(q_cf, q_cn)
|
|
86
82
|
|
|
87
83
|
@_copy_method_docstring(ThermalModel)
|
|
88
|
-
def compute_radiative_cooling(
|
|
89
|
-
self, conductor_temperature: Celsius, current: Ampere
|
|
90
|
-
) -> WattPerMeter:
|
|
84
|
+
def compute_radiative_cooling(self, conductor_temperature: Celsius) -> WattPerMeter:
|
|
91
85
|
return super().compute_radiative_cooling(
|
|
92
|
-
conductor_temperature=conductor_temperature,
|
|
86
|
+
conductor_temperature=conductor_temperature,
|
|
93
87
|
)
|
|
@@ -3,7 +3,7 @@ from typing import Dict
|
|
|
3
3
|
|
|
4
4
|
from linerate import solver
|
|
5
5
|
from linerate.equations import joule_heating, radiative_cooling
|
|
6
|
-
from linerate.types import
|
|
6
|
+
from linerate.types import BaseWeather, Span
|
|
7
7
|
from linerate.units import Ampere, Celsius, OhmPerMeter, WattPerMeter
|
|
8
8
|
|
|
9
9
|
|
|
@@ -19,7 +19,7 @@ class ThermalModel(ABC):
|
|
|
19
19
|
"""Abstract class for a minimal conductor thermal model."""
|
|
20
20
|
|
|
21
21
|
@abstractmethod
|
|
22
|
-
def __init__(self, span: Span, weather:
|
|
22
|
+
def __init__(self, span: Span, weather: BaseWeather):
|
|
23
23
|
self.span = span
|
|
24
24
|
self.weather = weather
|
|
25
25
|
|
|
@@ -84,17 +84,10 @@ class ThermalModel(ABC):
|
|
|
84
84
|
|
|
85
85
|
@abstractmethod
|
|
86
86
|
def compute_solar_heating(
|
|
87
|
-
self,
|
|
87
|
+
self,
|
|
88
88
|
) -> WattPerMeter:
|
|
89
89
|
r"""Compute the solar heating, :math:`P_S~\left[\text{W}~\text{m}^{-1}\right]`.
|
|
90
90
|
|
|
91
|
-
Parameters
|
|
92
|
-
----------
|
|
93
|
-
conductor_temperature:
|
|
94
|
-
:math:`T_\text{av}~\left[^\circ\text{C}\right]`. The average conductor temperature.
|
|
95
|
-
current:
|
|
96
|
-
:math:`I~\left[\text{A}\right]`. The current.
|
|
97
|
-
|
|
98
91
|
Returns
|
|
99
92
|
-------
|
|
100
93
|
Union[float, float64, ndarray[Any, dtype[float64]]]
|
|
@@ -104,7 +97,8 @@ class ThermalModel(ABC):
|
|
|
104
97
|
|
|
105
98
|
@abstractmethod
|
|
106
99
|
def compute_convective_cooling(
|
|
107
|
-
self,
|
|
100
|
+
self,
|
|
101
|
+
conductor_temperature: Celsius,
|
|
108
102
|
) -> WattPerMeter:
|
|
109
103
|
r"""Compute the convective cooling, :math:`P_c~\left[\text{W}~\text{m}^{-1}\right]`.
|
|
110
104
|
|
|
@@ -112,8 +106,6 @@ class ThermalModel(ABC):
|
|
|
112
106
|
----------
|
|
113
107
|
conductor_temperature:
|
|
114
108
|
:math:`T_\text{av}~\left[^\circ\text{C}\right]`. The average conductor temperature.
|
|
115
|
-
current:
|
|
116
|
-
:math:`I~\left[\text{A}\right]`. The current.
|
|
117
109
|
|
|
118
110
|
Returns
|
|
119
111
|
-------
|
|
@@ -124,7 +116,8 @@ class ThermalModel(ABC):
|
|
|
124
116
|
|
|
125
117
|
@abstractmethod
|
|
126
118
|
def compute_radiative_cooling(
|
|
127
|
-
self,
|
|
119
|
+
self,
|
|
120
|
+
conductor_temperature: Celsius,
|
|
128
121
|
) -> WattPerMeter:
|
|
129
122
|
r"""Compute the radiative cooling, :math:`P_r~\left[\text{W}~\text{m}^{-1}\right]`.
|
|
130
123
|
|
|
@@ -132,8 +125,6 @@ class ThermalModel(ABC):
|
|
|
132
125
|
----------
|
|
133
126
|
conductor_temperature:
|
|
134
127
|
:math:`T_\text{av}~\left[^\circ\text{C}\right]`. The average conductor temperature.
|
|
135
|
-
current:
|
|
136
|
-
:math:`I~\left[\text{A}\right]`. The current.
|
|
137
128
|
|
|
138
129
|
Returns
|
|
139
130
|
-------
|
|
@@ -163,9 +154,9 @@ class ThermalModel(ABC):
|
|
|
163
154
|
:math:`P_J + P_s - P_c - P_r~\left[\text{W}~\text{m}^{-1}\right]`. The heat balance.
|
|
164
155
|
"""
|
|
165
156
|
P_j = self.compute_joule_heating(conductor_temperature, current)
|
|
166
|
-
P_s = self.compute_solar_heating(
|
|
167
|
-
P_c = self.compute_convective_cooling(conductor_temperature
|
|
168
|
-
P_r = self.compute_radiative_cooling(conductor_temperature
|
|
157
|
+
P_s = self.compute_solar_heating()
|
|
158
|
+
P_c = self.compute_convective_cooling(conductor_temperature)
|
|
159
|
+
P_r = self.compute_radiative_cooling(conductor_temperature)
|
|
169
160
|
return P_j + P_s - P_c - P_r
|
|
170
161
|
|
|
171
162
|
def compute_info(
|
|
@@ -186,10 +177,10 @@ class ThermalModel(ABC):
|
|
|
186
177
|
A dictionary with the magnitude of the different heating and cooling effects.
|
|
187
178
|
"""
|
|
188
179
|
return {
|
|
189
|
-
"convective_cooling": self.compute_convective_cooling(conductor_temperature
|
|
190
|
-
"radiative_cooling": self.compute_radiative_cooling(conductor_temperature
|
|
180
|
+
"convective_cooling": self.compute_convective_cooling(conductor_temperature),
|
|
181
|
+
"radiative_cooling": self.compute_radiative_cooling(conductor_temperature),
|
|
191
182
|
"joule_heating": self.compute_joule_heating(conductor_temperature, current),
|
|
192
|
-
"solar_heating": self.compute_solar_heating(
|
|
183
|
+
"solar_heating": self.compute_solar_heating(),
|
|
193
184
|
}
|
|
194
185
|
|
|
195
186
|
def compute_steady_state_ampacity(
|
|
@@ -114,7 +114,9 @@ def compute_conductor_temperature(
|
|
|
114
114
|
Union[float, float64, ndarray[Any, dtype[float64]]]
|
|
115
115
|
:math:`I~\left[\text{A}\right]`. The thermal rating.
|
|
116
116
|
"""
|
|
117
|
-
|
|
117
|
+
|
|
118
|
+
def f(conductor_temperature: Celsius) -> WattPerMeter:
|
|
119
|
+
return heat_balance(conductor_temperature, current)
|
|
118
120
|
|
|
119
121
|
return bisect(f, min_temperature, max_temperature, tolerance)
|
|
120
122
|
|
|
@@ -163,8 +163,8 @@ class Span:
|
|
|
163
163
|
return 0.5 * (self.start_tower.altitude + self.end_tower.altitude)
|
|
164
164
|
|
|
165
165
|
|
|
166
|
-
@dataclass
|
|
167
|
-
class
|
|
166
|
+
@dataclass
|
|
167
|
+
class BaseWeather:
|
|
168
168
|
#: :math:`T_a~\left[^\circ C\right]`. The ambient air temperature.
|
|
169
169
|
air_temperature: Celsius
|
|
170
170
|
#: :math:`\delta~\left[\text{radian}\right]`. Wind direction east of north.
|
|
@@ -173,24 +173,21 @@ class Weather:
|
|
|
173
173
|
wind_speed: MeterPerSecond
|
|
174
174
|
#: :math:`F`. The ground albedo.
|
|
175
175
|
ground_albedo: Unitless
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@dataclass
|
|
179
|
+
class Weather(BaseWeather):
|
|
176
180
|
#: :math:`N_s`. The clearness ratio (or clearness number in
|
|
177
181
|
#: :cite:p:`sharma1965interrelationships,cigre207`).
|
|
178
182
|
clearness_ratio: Unitless = 1
|
|
179
183
|
|
|
180
184
|
|
|
181
185
|
@dataclass
|
|
182
|
-
class WeatherWithSolarRadiation(
|
|
186
|
+
class WeatherWithSolarRadiation(BaseWeather):
|
|
183
187
|
"""Extension of the Weather class to accept solar radiation timeseries."""
|
|
184
188
|
|
|
185
189
|
#: :math:`I_d~\left[\text{W}~\text{m}^{-2}\right]`. The diffuse radiation intensity.
|
|
186
|
-
diffuse_radiation_intensity: WattPerSquareMeter
|
|
190
|
+
diffuse_radiation_intensity: WattPerSquareMeter
|
|
187
191
|
#: :math:`I_B~\left[\text{W}~\text{m}^{-2}\right]`. The direct radiation intensity on a surface normal to the
|
|
188
192
|
# sun's beam.
|
|
189
|
-
direct_radiation_intensity: WattPerSquareMeter
|
|
190
|
-
|
|
191
|
-
def __post_init__(self):
|
|
192
|
-
if (self.diffuse_radiation_intensity is None) or (self.direct_radiation_intensity is None):
|
|
193
|
-
raise ValueError(
|
|
194
|
-
"Both 'diffuse_radiation_intensity' and 'direct_radiation_intensity' must be provided. For weather"
|
|
195
|
-
" data without solar radiation, use the 'Weather' class instead.",
|
|
196
|
-
)
|
|
193
|
+
direct_radiation_intensity: WattPerSquareMeter
|
|
@@ -8,10 +8,11 @@ except ImportError: # Python version <3.9
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import numpy.typing as npt
|
|
10
10
|
|
|
11
|
-
FloatOrFloatArray = Union[float, np.
|
|
11
|
+
FloatOrFloatArray = Union[float, np.floating, npt.NDArray[np.floating]]
|
|
12
12
|
BoolOrBoolArray = Union[bool, np.bool_, npt.NDArray[np.bool_]]
|
|
13
13
|
|
|
14
14
|
OhmPerMeter = Annotated[FloatOrFloatArray, "Ω/m"]
|
|
15
|
+
OhmPerMeterPerCelsius = Annotated[FloatOrFloatArray, "Ω/(m °C)"]
|
|
15
16
|
Ampere = Annotated[FloatOrFloatArray, "A"]
|
|
16
17
|
Radian = Annotated[FloatOrFloatArray, "rad"]
|
|
17
18
|
Degrees = Annotated[FloatOrFloatArray, "°"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: linerate
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.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
|
|
@@ -98,4 +98,5 @@ tests/equations/cigre601/test_solar_heating.py
|
|
|
98
98
|
tests/equations/ieee738/test_ieee_convective_cooling.py
|
|
99
99
|
tests/equations/ieee738/test_solar_heating.py
|
|
100
100
|
tests/integration_tests/test_vectorization.py
|
|
101
|
+
tests/models/test_cigre601_with_solar_radiation.py
|
|
101
102
|
tests/models/test_thermal_model.py
|
|
@@ -24,6 +24,8 @@ dev = [
|
|
|
24
24
|
"pytest==8.4.2",
|
|
25
25
|
"pytest-cov==7.0.0",
|
|
26
26
|
"pytest-randomly==4.0.1",
|
|
27
|
+
"pyright[nodejs]",
|
|
28
|
+
"matplotlib>=3.9.4",
|
|
27
29
|
]
|
|
28
30
|
docs = [
|
|
29
31
|
"sphinx",
|
|
@@ -94,3 +96,7 @@ filterwarnings = [
|
|
|
94
96
|
[build-system]
|
|
95
97
|
requires = ["setuptools>=64", "setuptools-scm>=8"]
|
|
96
98
|
build-backend = "setuptools.build_meta"
|
|
99
|
+
|
|
100
|
+
[tool.pyright]
|
|
101
|
+
venvPath = "."
|
|
102
|
+
venv = ".venv"
|