Skip to content

deformation

DeformationRte

DeformationRte(
    tension_mean: ndarray,
    cable_length: ndarray,
    cable_section_area: float64,
    linear_weight: float64,
    young_modulus: float64,
    dilatation_coefficient: float64,
    temperature_reference: float64,
    polynomial_conductor: Polynomial,
    sagging_temperature: ndarray,
    max_stress: ndarray | None = None,
    **_,
)

Bases: IDeformation

This class implements the deformation model used by RTE.

Source code in src/mechaphlowers/core/models/cable/deformation.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def __init__(
    self,
    tension_mean: np.ndarray,
    cable_length: np.ndarray,
    cable_section_area: np.float64,
    linear_weight: np.float64,
    young_modulus: np.float64,
    dilatation_coefficient: np.float64,
    temperature_reference: np.float64,
    polynomial_conductor: Poly,
    sagging_temperature: np.ndarray,
    max_stress: np.ndarray | None = None,
    **_,
):
    self.tension_mean = tension_mean
    self.cable_length = cable_length
    self.cable_section_area = cable_section_area
    self.linear_weight = linear_weight
    self.young_modulus = young_modulus
    self.dilatation_coefficient = dilatation_coefficient
    self.temp_ref = temperature_reference
    self.polynomial_conductor = polynomial_conductor
    self.current_temperature = sagging_temperature
    self.is_polynomial = polynomial_conductor.trim().degree() >= 2

    if max_stress is None:
        self.max_stress = np.full(self.cable_length.shape, 0)
    else:
        self.max_stress = max_stress

epsilon_mecha_polynomial

epsilon_mecha_polynomial() -> ndarray

Computes epsilon when the stress-strain relation is polynomial

Source code in src/mechaphlowers/core/models/cable/deformation.py
136
137
138
139
140
141
142
143
144
145
146
def epsilon_mecha_polynomial(self) -> np.ndarray:
    """Computes epsilon when the stress-strain relation is polynomial"""
    T_mean = self.tension_mean
    E = self.young_modulus
    S = self.cable_section_area

    sigma = T_mean / S
    if self.polynomial_conductor is None:
        raise ValueError("polynomial_conductor is not defined")
    epsilon_plastic = self.epsilon_plastic()
    return epsilon_plastic + sigma / E

epsilon_plastic

epsilon_plastic() -> ndarray

Computes elastic permanent strain.

Source code in src/mechaphlowers/core/models/cable/deformation.py
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
def epsilon_plastic(self) -> np.ndarray:
    """Computes elastic permanent strain."""
    T_mean = self.tension_mean
    E = self.young_modulus
    S = self.cable_section_area
    max_stress = self.max_stress

    sigma = T_mean / S
    if max_stress is None:
        max_stress = np.full(T_mean.shape, 0)
    # epsilon plastic is based on the highest value between sigma and max_stress
    highest_constraint = np.fmax(sigma, max_stress)
    equation_solution = self.resolve_stress_strain_equation(
        highest_constraint
    )
    equation_solution -= highest_constraint / E
    return equation_solution

find_smallest_real_positive_root

find_smallest_real_positive_root(
    poly_to_resolve: ndarray,
) -> ndarray

Find the smallest root that is real and positive for each polynomial

Parameters:

Name Type Description Default

poly_to_resolve

ndarray

array of polynomials to solve

required

Raises:

Type Description
ValueError

if no real positive root has been found for at least one polynomial.

Returns:

Type Description
ndarray

np.ndarray: array of the roots (one per polynomial)

Source code in src/mechaphlowers/core/models/cable/deformation.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def find_smallest_real_positive_root(
    self,
    poly_to_resolve: np.ndarray,
) -> np.ndarray:
    """Find the smallest root that is real and positive for each polynomial

    Args:
            poly_to_resolve (np.ndarray): array of polynomials to solve

    Raises:
            ValueError: if no real positive root has been found for at least one polynomial.

    Returns:
            np.ndarray: array of the roots (one per polynomial)
    """
    # Can cause performance issues
    all_roots = [poly.roots() for poly in poly_to_resolve]

    all_roots_stacked = np.stack(all_roots)
    keep_solution_condition = np.logical_and(
        abs(all_roots_stacked.imag) < IMAGINARY_THRESHOLD,
        0.0 <= all_roots_stacked,
    )
    # Replace roots that are not real nor positive by np.inf
    real_positive_roots = np.where(
        keep_solution_condition, all_roots_stacked, np.inf
    )
    real_smallest_root = real_positive_roots.min(axis=1).real
    if np.inf in real_smallest_root:
        raise ConvergenceError(
            "No solution found for at least one span",
            origin="deformation_model",
        )
    return real_smallest_root

resolve_stress_strain_equation

resolve_stress_strain_equation(
    highest_constraint: ndarray,
) -> ndarray

Solves \(\sigma = Polynomial(\varepsilon)\)

Source code in src/mechaphlowers/core/models/cable/deformation.py
166
167
168
169
170
171
172
173
174
def resolve_stress_strain_equation(
    self, highest_constraint: np.ndarray
) -> np.ndarray:
    """Solves $\\sigma = Polynomial(\\varepsilon)$"""
    polynomial = self.polynomial_conductor

    polynom_array = np.full(highest_constraint.shape, polynomial)
    poly_to_resolve = polynom_array - highest_constraint
    return self.find_smallest_real_positive_root(poly_to_resolve)

IDeformation

IDeformation(
    tension_mean: ndarray,
    cable_length: ndarray,
    cable_section_area: float64,
    linear_weight: float64,
    young_modulus: float64,
    dilatation_coefficient: float64,
    temperature_reference: float64,
    polynomial_conductor: Polynomial,
    sagging_temperature: ndarray,
    max_stress: ndarray | None = None,
    **_,
)

Bases: ABC

This abstract class is a base class for models to compute relative cable deformations.

Source code in src/mechaphlowers/core/models/cable/deformation.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def __init__(
    self,
    tension_mean: np.ndarray,
    cable_length: np.ndarray,
    cable_section_area: np.float64,
    linear_weight: np.float64,
    young_modulus: np.float64,
    dilatation_coefficient: np.float64,
    temperature_reference: np.float64,
    polynomial_conductor: Poly,
    sagging_temperature: np.ndarray,
    max_stress: np.ndarray | None = None,
    **_,
):
    self.tension_mean = tension_mean
    self.cable_length = cable_length
    self.cable_section_area = cable_section_area
    self.linear_weight = linear_weight
    self.young_modulus = young_modulus
    self.dilatation_coefficient = dilatation_coefficient
    self.temp_ref = temperature_reference
    self.polynomial_conductor = polynomial_conductor
    self.current_temperature = sagging_temperature
    self.is_polynomial = polynomial_conductor.trim().degree() >= 2

    if max_stress is None:
        self.max_stress = np.full(self.cable_length.shape, 0)
    else:
        self.max_stress = max_stress

L_0 abstractmethod

L_0() -> ndarray

Unstressed cable length, at a chosen reference temperature, whrer temperature_reference = 0°C

Source code in src/mechaphlowers/core/models/cable/deformation.py
74
75
76
@abstractmethod
def L_0(self) -> np.ndarray:
    """Unstressed cable length, at a chosen reference temperature, whrer temperature_reference = 0°C"""

L_ref abstractmethod

L_ref() -> ndarray

Unstressed cable length, at a chosen reference temperature, compared to the temperature reference

Source code in src/mechaphlowers/core/models/cable/deformation.py
70
71
72
@abstractmethod
def L_ref(self) -> np.ndarray:
    """Unstressed cable length, at a chosen reference temperature, compared to the temperature reference"""

epsilon abstractmethod

epsilon() -> ndarray

Total relative strain of the cable.

Source code in src/mechaphlowers/core/models/cable/deformation.py
78
79
80
@abstractmethod
def epsilon(self) -> np.ndarray:
    """Total relative strain of the cable."""

epsilon_mecha abstractmethod

epsilon_mecha() -> ndarray

Mechanical part of the relative strain of the cable.

Source code in src/mechaphlowers/core/models/cable/deformation.py
82
83
84
@abstractmethod
def epsilon_mecha(self) -> np.ndarray:
    """Mechanical part of the relative strain  of the cable."""

epsilon_therm abstractmethod

epsilon_therm() -> ndarray

Thermal part of the relative deformation of the cable, compared to a temperature_reference.

Source code in src/mechaphlowers/core/models/cable/deformation.py
86
87
88
@abstractmethod
def epsilon_therm(self) -> np.ndarray:
    """Thermal part of the relative deformation of the cable, compared to a temperature_reference."""

epsilon_therm_0 abstractmethod

epsilon_therm_0() -> ndarray

Thermal part of the relative deformation of the cable, where temperature_reference = 0.

Source code in src/mechaphlowers/core/models/cable/deformation.py
90
91
92
@abstractmethod
def epsilon_therm_0(self) -> np.ndarray:
    """Thermal part of the relative deformation of the cable, where temperature_reference = 0."""