Skip to content

cable_thermal_model

CableKey

Bases: BaseModel

Immutable identifier for a cable within a named circuit.

CablePosition

Bases: StrEnum

Enumeration of cable positions within a circuit.

BondingType

Bases: StrEnum

Bonding type of a cable circuit.

CircuitType

Bases: StrEnum

Circuit type of a cable configuration.

CircuitYReference

Bases: StrEnum

Y-axis reference position for circuit placement.

PipeInputSchema

Bases: BaseModel

Input schema defining pipe geometry and fill material.

StaticEnvAir

StaticEnvAir()

Bases: StaticEnv[FDCableInAir, CircuitInAirFromCableInputSchema, CircuitInAirFromCableConstructionalInputSchema, CircuitInAirFromCableIdInputSchema]

Class that builds a static environment for circuits in air.

Source code in cable_thermal_model/environment/static_env.py
63
64
65
66
67
68
69
70
71
72
def __init__(self) -> None:
    """Initialize the static environment with empty circuit and cable containers."""
    self.circuits: dict[str, CableCircuit] = {}
    self.circuit_cable_indices: dict[str, list[int]] = {}
    self.cables: dict[CableKey, PosCable] = {}
    self.number_of_cables: int = 0

    self.crossing_cables: bool = False

    self.n_phases: int = 3

add_circuit_from_cable

add_circuit_from_cable(
    circuit_input: CircuitInAirFromCableInputSchema,
)

Add the circuit to the environment based on a cable instance.

Convection parameters are added to the circuit.

Parameters:

Name Type Description Default
circuit_input CircuitInAirFromCableInputSchema

CircuitInputSchema containing the input parameters for the circuit in air, including a Cable instance.

required
References
  • NEN-IEC 60287-2-1 (2023) - [table 3]
Source code in cable_thermal_model/environment/static_env_air.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
def add_circuit_from_cable(
    self,
    circuit_input: CircuitInAirFromCableInputSchema,
):
    """Add the circuit to the environment based on a cable instance.

    Convection parameters are added to the circuit.

    Args:
        circuit_input: CircuitInputSchema containing the input parameters
            for the circuit in air, including a Cable instance.

    References:
        - NEN-IEC 60287-2-1 (2023) - [table 3]

    """
    if self.circuits:
        raise ValueError(
            "Environment already contains circuit(s). Cannot add multiple circuits to an air environment"
        )

    self.set_environment_convection_parameters(
        circuit_type=circuit_input.circuit_type,
        dist=circuit_input.dist,
        cable=circuit_input.cable,
        clipped_to_wall=circuit_input.clipped_to_wall,
    )

    return super().add_circuit_from_cable(circuit_input)

set_environment_convection_parameters

set_environment_convection_parameters(
    circuit_type: CircuitType | None,
    dist: float | None,
    cable: FDCableInAir,
    clipped_to_wall: bool,
)

Adds convection parameters to the cables.

Parameters:

Name Type Description Default
circuit_type CircuitType | None

Type of circuit, one of 'single', 'trefoil', 'linear'

required
dist float | None

Distance between cables, relevant for 'linear' circuits

required
cable FDCableInAir

FDCable instance

required
clipped_to_wall bool

Indicator if the circuit is clipped to a wall

required
References
  • NEN-IEC 60287-2-1 (2023) - [table 3]
Source code in cable_thermal_model/environment/static_env_air.py
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
def set_environment_convection_parameters(
    self,
    circuit_type: CircuitType | None,
    dist: float | None,
    cable: FDCableInAir,
    clipped_to_wall: bool,
):
    """Adds convection parameters to the cables.

    Args:
        circuit_type: Type of circuit, one of 'single', 'trefoil', 'linear'
        dist: Distance between cables, relevant for 'linear' circuits
        cable: FDCable instance
        clipped_to_wall: Indicator if the circuit is clipped to a wall

    References:
        - NEN-IEC 60287-2-1 (2023) - [table 3]

    """
    Z, E, Cg = self._get_convection_parameters(circuit_type, dist, cable, clipped_to_wall)

    cable.set_convection_parameters(Z=Z, E=E, Cg=Cg)

StaticEnvSoil

StaticEnvSoil()

Bases: StaticEnv[FDCable, CircuitInSoilFromCableInputSchema, CircuitInSoilFromCableConstructionalInputSchema, CircuitInSoilFromCableIdInputSchema]

Class that builds a static environment for circuits in soil.

Source code in cable_thermal_model/environment/static_env.py
63
64
65
66
67
68
69
70
71
72
def __init__(self) -> None:
    """Initialize the static environment with empty circuit and cable containers."""
    self.circuits: dict[str, CableCircuit] = {}
    self.circuit_cable_indices: dict[str, list[int]] = {}
    self.cables: dict[CableKey, PosCable] = {}
    self.number_of_cables: int = 0

    self.crossing_cables: bool = False

    self.n_phases: int = 3

CableLayer

Bases: StrEnum

Enum class for possible cable layer types. Values derived from those used in the old Cable init.

soil_layers classmethod

soil_layers() -> list[CableLayer]

Return a list of all soil layers.

Source code in cable_thermal_model/model/cables/enum_classes_cable.py
213
214
215
216
@classmethod
def soil_layers(cls) -> list[CableLayer]:
    """Return a list of all soil layers."""
    return [layer for layer in cls if layer.name.startswith("Soil")]

PipeFillType

Bases: StrEnum

Enum class for possible types of material filling the pipe surrounding a cable.

StateAir

Bases: State

StateAir has no added attributes on top of State.

However, we want to make sure there is only one circuit (check for a unique circuit_name).

validate_single_circuit

validate_single_circuit()

Ensure that all cable representations in StateAir belong to the same circuit.

Source code in cable_thermal_model/model/schemas/state_schemas.py
104
105
106
107
108
109
110
@model_validator(mode="after")
def validate_single_circuit(self):
    """Ensure that all cable representations in StateAir belong to the same circuit."""
    circuit_names = {cable_key.circuit_name for cable_key in self.cable_representations}
    if len(circuit_names) > 1:
        raise ValueError(f"StateAir should only contain one circuit, but found multiple: {circuit_names}")
    return self

ModelFactory

Factory class for creating model instances based on the environment.

create_model staticmethod

create_model(
    static_env: StaticEnvAir,
    scenario: DataFrame[ScenarioSchemaAir],
) -> ModelAir
create_model(
    static_env: StaticEnvSoil,
    scenario: DataFrame[ScenarioSchemaSoil],
) -> ModelSoil
create_model(
    static_env: StaticEnv,
    scenario: DataFrame[ScenarioSchemaAir]
    | DataFrame[ScenarioSchemaSoil],
) -> Model

Create a model instance based on the environment type.

Parameters:

Name Type Description Default
static_env StaticEnv

Static environment configuration for the model.

required
scenario DataFrame[ScenarioSchemaAir] | DataFrame[ScenarioSchemaSoil]

Scenario data used by the model.

required

Returns:

Name Type Description
Model Model

An instance of ModelAir or ModelSoil.

Raises:

Type Description
ValueError

If static_env is not a supported environment type.

Source code in cable_thermal_model/model/model_factory.py
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@staticmethod
def create_model(
    static_env: StaticEnv,
    scenario: DataFrame[ScenarioSchemaAir] | DataFrame[ScenarioSchemaSoil],
) -> Model:
    """Create a model instance based on the environment type.

    Args:
        static_env (StaticEnv): Static environment configuration for the model.
        scenario (DataFrame[ScenarioSchemaAir] | DataFrame[ScenarioSchemaSoil]):
            Scenario data used by the model.

    Returns:
        Model: An instance of ModelAir or ModelSoil.

    Raises:
        ValueError: If static_env is not a supported environment type.
    """
    if isinstance(static_env, StaticEnvAir):
        return ModelAir(static_env=static_env, scenario=cast(DataFrame[ScenarioSchemaAir], scenario))
    elif isinstance(static_env, StaticEnvSoil):
        return ModelSoil(static_env=static_env, scenario=cast(DataFrame[ScenarioSchemaSoil], scenario))
    else:
        raise ValueError(
            f"Unsupported static environment type: {type(static_env).__name__}. "
            f"Expected {StaticEnvAir.__name__} or {StaticEnvSoil.__name__}."
        )

StateSoil

Bases: State

Extends upon the base State class. Includes additional attribute mutual_heating_solutions and validation thereof.

Attributes:

Name Type Description
mutual_heating_solutions dict[CableKey, ndarray]

dict[CableKey, np.ndarray] A dictionary containing the temperature increase inside a cable due to mutual heating from other cables in the environment. This is stored as a dict with CableKey as key and an array of temperature increases per grid point as value.

validate_mutual_heating_solutions

validate_mutual_heating_solutions()

Validate that mutual_heating_solutions keys match the cable representation keys.

Source code in cable_thermal_model/model/schemas/state_schemas.py
84
85
86
87
88
89
90
91
92
93
94
95
@model_validator(mode="after")
def validate_mutual_heating_solutions(self):
    """Validate that mutual_heating_solutions keys match the cable representation keys."""
    found_keys = set(self.mutual_heating_solutions.keys())
    expected_keys = {cable.name for cable in self.cable_representations}
    if found_keys != expected_keys:
        raise ValueError(
            "CableKeys of mutual_heating_solutions should match with "
            "the CableKeys in the cable representations. "
            f"Found keys: {found_keys}, expected keys: {expected_keys}"
        )
    return self