Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--
from thermohl.solver import HeatEquationType<!--
SPDX-FileCopyrightText: 2025 RTE (https://www.rte-france.com)

This Source Code Form is subject to the terms of the Mozilla Public
Expand Down Expand Up @@ -138,8 +138,9 @@ surface temperature (°C) of a conductor in steady-state regime along with the c

```python
from thermohl import solver
from thermohl.solver.enums.heat_equation_type import HeatEquationType

slvr = solver.ieee(dic=None, heateq='1t')
slvr = solver.ieee(dic=None, heat_equation=HeatEquationType.WITH_ONE_TEMPERATURE)
temp = slvr.steady_temperature()
```

Expand All @@ -161,8 +162,9 @@ distinct ampacities (and the lower the ambient temperature, the higher the ampac
```python
import numpy as np
from thermohl import solver
from thermohl.solver.enums.heat_equation_type import HeatEquationType

slvr = solver.ieee(dict(Ta=np.array([0., 15., 30.])), heateq='1t')
slvr = solver.ieee(dict(Ta=np.array([0., 15., 30.])), heat_equation=HeatEquationType.WITH_ONE_TEMPERATURE)
Tmax = 80.
imax = slvr.steady_intensity(Tmax)
```
Expand Down
11 changes: 8 additions & 3 deletions examples/example_solver_intensity.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
import pandas as pd

from thermohl import solver
from thermohl.solver.enums.power_type import PowerType
from thermohl.solver.enums.variable_type import VariableType


def test_solve(dct, Trep, tol=1.0e-06, mxi=64):
"""Given an input dictionnary, a default tolerance and a maximum number of
"""Given an input dictionary, a default tolerance and a maximum number of
iterations, compute the surface temperature for the four available models.
Print compute time, Return a DataFrame with both input and computed
temperature."""
Expand Down Expand Up @@ -83,9 +85,12 @@ def test_solve(dct, Trep, tol=1.0e-06, mxi=64):
slv = d["model"]
df = slv.steady_intensity(Trep, tol=tol, maxiter=mxi, return_power=True)
df["pb"] = (
df["P_joule"] + df["P_solar"] - df["P_convection"] - df["P_radiation"]
df[PowerType.JOULE]
+ df[PowerType.SOLAR]
- df[PowerType.CONVECTION]
- df[PowerType.RADIATION]
)
slv.dc["transit"] = df["I_max"].values
slv.dc[VariableType.TRANSIT] = df["I_max"].values
df["TIrep"] = slv.steady_temperature(return_power=False)["T_surf"]

ax[0, i].hist(df["pb"], bins=100)
Expand Down
17 changes: 12 additions & 5 deletions examples/example_transient.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import numpy as np

from thermohl import solver
from thermohl.solver.enums.solver_type import SolverType
from thermohl.solver.enums.variable_type import VariableType

if __name__ == "__main__":
import matplotlib
Expand Down Expand Up @@ -53,7 +55,12 @@
plt.show()

# dict with all 4 solvers
kys = ["cigre", "ieee", "rte", "rtem"]
kys = [
SolverType.SOLVER_CIGRE,
SolverType.SOLVER_IEEE,
SolverType.SOLVER_RTE,
SolverType.SOLVER_OLLA,
]
slv = dict(
cigre=solver.cigre(dct),
ieee=solver.ieee(dct),
Expand All @@ -64,9 +71,9 @@
plt.figure()
for i, key in enumerate(slv):
elm = slv[key]
elm.dc["transit"] = transit
elm.dc[VariableType.TRANSIT] = transit
df = elm.steady_temperature()
elm.dc["transit"] = np.nan
elm.dc[VariableType.TRANSIT] = np.nan
cl = "C%d" % (i % 10,)
T1 = df["T_surf"].values
T2 = elm.transient_temperature(t, T0=np.array(T1[0]), transit=transit)["T_surf"]
Expand All @@ -82,9 +89,9 @@
# only rte but with core temp
plt.figure()
elm = slv["rte"]
elm.dc["transit"] = transit
elm.dc[VariableType.TRANSIT] = transit
df = elm.steady_temperature(return_avg=True, return_core=True)
elm.dc["transit"] = np.nan
elm.dc[VariableType.TRANSIT] = np.nan
cl = "C0"
dg = elm.transient_temperature(
t, T0=T1[0], transit=transit, return_avg=True, return_core=True
Expand Down
13 changes: 10 additions & 3 deletions examples/example_transient2.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import numpy as np

from thermohl import solver
from thermohl.solver.enums.solver_type import SolverType
from thermohl.solver.enums.variable_type import VariableType

if __name__ == "__main__":
import matplotlib
Expand Down Expand Up @@ -54,7 +56,12 @@
plt.show()

# dict with all 4 solvers
kys = ["cigre", "ieee", "rte", "rtem"]
kys = [
SolverType.SOLVER_CIGRE,
SolverType.SOLVER_IEEE,
SolverType.SOLVER_RTE,
SolverType.SOLVER_OLLA,
]
slv = dict(
cigre=solver.cigre(dct),
ieee=solver.ieee(dct),
Expand All @@ -65,10 +72,10 @@
plt.figure()
for i, key in enumerate(slv):
elm = slv[key]
elm.dc["transit"] = transit[:, 1]
elm.dc[VariableType.TRANSIT] = transit[:, 1]
elm.dc["Ta"] = elm.dc["Ta"][1]
df = elm.steady_temperature()
elm.dc["transit"] = np.nan
elm.dc[VariableType.TRANSIT] = np.nan
elm.dc["Ta"] = dct["Ta"]
cl = "C%d" % (i % 10,)
T1 = df["T_surf"].values
Expand Down
150 changes: 89 additions & 61 deletions src/thermohl/solver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
from thermohl.power import olla as ollap

from thermohl.solver.base import Args, Solver
from thermohl.solver.enums.heat_equation_type import HeatEquationType
from thermohl.solver.slv1d import Solver1D
from thermohl.solver.slv1t import Solver1T
from thermohl.solver.slv3t import Solver3T
from thermohl.solver.slv3t_legacy import Solver3TL
from thermohl.solver.enums.solver_type import SolverType

concreteSolverType = Union[
Type[Solver1T], Type[Solver3T], Type[Solver3TL], Type[Solver1D]
Expand All @@ -30,95 +32,121 @@ def default_values() -> Dict[str, Any]:


def _factory(
dic: Optional[Dict[str, Any]] = None, heateq: str = "1t", model: str = "ieee"
dic: Optional[Dict[str, Any]] = None,
heat_equation: HeatEquationType = HeatEquationType.WITH_ONE_TEMPERATURE,
model: SolverType = SolverType.SOLVER_IEEE,
) -> Solver:
solver = create_solver_from_heat_equation(heat_equation)

solver_modules = {
SolverType.SOLVER_CIGRE: cigrep,
SolverType.SOLVER_IEEE: ieeep,
SolverType.SOLVER_OLLA: ollap,
SolverType.SOLVER_RTE: rtep,
}

if model not in solver_modules:
raise ValueError(f"Unsupported solver model: {model}")

module = solver_modules[model]
return solver(
dic,
module.JouleHeating,
module.SolarHeating,
module.ConvectiveCooling,
module.RadiativeCooling,
)


def create_solver_from_heat_equation(
heat_equation: HeatEquationType,
) -> concreteSolverType:
heat_equations_solvers = {
HeatEquationType.WITH_ONE_TEMPERATURE: Solver1T,
HeatEquationType.WITH_THREE_TEMPERATURES: Solver3T,
HeatEquationType.WITH_THREE_TEMPERATURES_LEGACY: Solver3TL,
HeatEquationType.WITH_1D: Solver1D,
}

if heat_equation not in heat_equations_solvers:
raise ValueError(f"Invalid HeatEquation value {heat_equation.value}")

return heat_equations_solvers[heat_equation]


def __solver_model(
dic: Optional[Dict[str, Any]] = None,
heat_equation: HeatEquationType = HeatEquationType.WITH_ONE_TEMPERATURE,
model: SolverType = SolverType.SOLVER_CIGRE,
) -> Solver:
"""Get a Solver using a given model and heat equation.

Args:
dic (dict | None): Input values. The default is None.
heat_equation (HeatEquationType): Input heat equation.
model (SolverType): Solver model to use.

"""
return _factory(dic, heat_equation=heat_equation, model=model)


def cigre(
dic: Optional[Dict[str, Any]] = None,
heat_equation: HeatEquationType = HeatEquationType.WITH_ONE_TEMPERATURE,
) -> Solver:
solver: concreteSolverType
if heateq == "1t":
solver = Solver1T
elif heateq == "3t":
solver = Solver3T
elif heateq == "3tl":
solver = Solver3TL
elif heateq == "1d":
solver = Solver1D
else:
raise ValueError()

if model == "cigre":
return solver(
dic,
cigrep.JouleHeating,
cigrep.SolarHeating,
cigrep.ConvectiveCooling,
cigrep.RadiativeCooling,
)
elif model == "ieee":
return solver(
dic,
ieeep.JouleHeating,
ieeep.SolarHeating,
ieeep.ConvectiveCooling,
ieeep.RadiativeCooling,
)
elif model == "olla":
return solver(
dic,
ollap.JouleHeating,
ollap.SolarHeating,
ollap.ConvectiveCooling,
ollap.RadiativeCooling,
)
elif model == "rte":
return solver(
dic,
rtep.JouleHeating,
rtep.SolarHeating,
rtep.ConvectiveCooling,
rtep.RadiativeCooling,
)
else:
raise ValueError()


def cigre(dic: Optional[Dict[str, Any]] = None, heateq: str = "1t") -> Solver:
"""Get a Solver using CIGRE models.

Args:
dic (dict | None): Input values. The default is None.
heateq (str): Input heat equation.
heat_equation (HeatEquationType): Input heat equation.

"""
return _factory(dic, heateq=heateq, model="cigre")
return __solver_model(
dic=dic, heat_equation=heat_equation, model=SolverType.SOLVER_CIGRE
)


def ieee(dic: Optional[Dict[str, Any]] = None, heateq: str = "1t") -> Solver:
def ieee(
dic: Optional[Dict[str, Any]] = None,
heat_equation: HeatEquationType = HeatEquationType.WITH_ONE_TEMPERATURE,
) -> Solver:
"""Get a Solver using IEEE models.

Args:
dic (dict | None): Input values. The default is None.
heateq (str): Input heat equation.
heat_equation (HeatEquationType): Input heat equation.

"""
return _factory(dic, heateq=heateq, model="ieee")
return __solver_model(
dic, heat_equation=heat_equation, model=SolverType.SOLVER_IEEE
)


def olla(dic: Optional[Dict[str, Any]] = None, heateq: str = "1t") -> Solver:
def olla(
dic: Optional[Dict[str, Any]] = None,
heat_equation: HeatEquationType = HeatEquationType.WITH_ONE_TEMPERATURE,
) -> Solver:
"""Get a Solver using RTE-olla models.

Args:
dic (dict | None): Input values. The default is None.
heateq (str): Input heat equation.
heat_equation (HeatEquationType): Input heat equation.

"""
return _factory(dic, heateq=heateq, model="olla")
return __solver_model(
dic, heat_equation=heat_equation, model=SolverType.SOLVER_OLLA
)


def rte(dic: Optional[Dict[str, Any]] = None, heateq: str = "1t") -> Solver:
def rte(
dic: Optional[Dict[str, Any]] = None,
heat_equation: HeatEquationType = HeatEquationType.WITH_ONE_TEMPERATURE,
) -> Solver:
"""Get a Solver using RTE models.

Args:
dic (dict | None): Input values. The default is None.
heateq (str): Input heat equation.
heat_equation (HeatEquationType): Input heat equation.

"""
return _factory(dic, heateq=heateq, model="rte")
return __solver_model(dic, heat_equation=heat_equation, model=SolverType.SOLVER_RTE)
38 changes: 11 additions & 27 deletions src/thermohl/solver/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
numberArrayLike,
)
from thermohl.power import PowerTerm
from thermohl.solver.enums.power_type import PowerType


class _DEFPARAM:
Expand Down Expand Up @@ -189,33 +190,6 @@ class Solver(ABC):
__init__ function.
"""

class Names:
pjle = "P_joule"
psol = "P_solar"
pcnv = "P_convection"
prad = "P_radiation"
ppre = "P_precipitation"
err = "err"
surf = "surf"
avg = "avg"
core = "core"
time = "time"
transit = "transit"
temp = "t"
tsurf = "t_surf"
tavg = "t_avg"
tcore = "t_core"

@staticmethod
def powers() -> tuple[str, str, str, str, str]:
return (
Solver.Names.pjle,
Solver.Names.psol,
Solver.Names.pcnv,
Solver.Names.prad,
Solver.Names.ppre,
)

def __init__(
self,
dic: Optional[dict[str, Any]] = None,
Expand Down Expand Up @@ -266,6 +240,16 @@ def balance(self, T: floatArrayLike) -> floatArrayLike:
- self.pc.value(T)
)

@staticmethod
def powers() -> tuple[PowerType, PowerType, PowerType, PowerType, PowerType]:
return (
PowerType.JOULE,
PowerType.SOLAR,
PowerType.CONVECTION,
PowerType.RADIATION,
PowerType.RAIN,
)

@abstractmethod
def steady_temperature(self) -> pd.DataFrame:
raise NotImplementedError
Expand Down
Empty file.
Loading