# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies.
# SPDX-FileContributor: Alexandre Benedicto
import os
from typing import Any
import numpy as np
import numpy.typing as npt
from geos_posp.processing.MohrCircle import MohrCircle
from geos_posp.processing.MohrCoulomb import MohrCoulomb
from geos_posp.visu.mohrCircles import (
MOHR_CIRCLE_ANALYSIS_MAIN,
MOHR_CIRCLE_PATH,
)
__doc__ = """
functionsMohrCircle module provides a set of utilities to instanciate Mohr's
circles and Mohr-Coulomb failure envelope.
"""
[docs]
def buildPythonViewScript(
dir_path: str,
mohrCircles: list[MohrCircle],
rockCohesion: float,
frictionAngle: float,
userChoices: dict[str, Any],
) -> str:
"""Builds the Python script used to launch the Python View.
The script is returned as a string to be then injected in the Python
View.
Args:
dir_path (str): directory path
mohrCircles (list[MohrCircle]): list of MohrCircle objects
rockCohesion (float): rock cohesion (Pa)
frictionAngle (float): friction angle (rad)
userChoices (dict[str, Any]): dictionnary of user plot parameters
Returns:
str: Complete Python View script.
"""
pathPythonViewScript: str = os.path.join(
dir_path, MOHR_CIRCLE_PATH, MOHR_CIRCLE_ANALYSIS_MAIN
)
mohrCircleParams: list[tuple[str, float, float, float]] = [
(mohrCircle.getCircleId(), *(mohrCircle.getPrincipalComponents()))
for mohrCircle in mohrCircles
]
script: str = ""
script += f"mohrCircleParams = {mohrCircleParams}\n"
script += f"rockCohesion = {rockCohesion}\n"
script += f"frictionAngle = {frictionAngle}\n"
script += f"userChoices = {userChoices}\n\n\n"
with open(pathPythonViewScript) as file:
fileContents = file.read()
script += fileContents
return script
[docs]
def findAnnotateTuples(
mohrCircle: MohrCircle,
) -> tuple[str, str, tuple[float, float], tuple[float, float]]:
"""Get the values and location of min and max normal stress or Mohr's circle.
Args:
mohrCircle (MohrCircle): input Mohr's circle
maxTau (float): max shear stress
Returns:
tuple[str, str, tuple[float, float], tuple[float, float]]: labels and
location of labels.
"""
p3, p2, p1 = mohrCircle.getPrincipalComponents()
xMaxDisplay: str = f"{p1:.2E}"
xMinDisplay: str = f"{p3:.2E}"
yPosition: float = 0.0
xyMax: tuple[float, float] = (p1, yPosition)
xyMin: tuple[float, float] = (p3, yPosition)
return (xMaxDisplay, xMinDisplay, xyMax, xyMin)
[docs]
def getMohrCircleId(cellId: str, timeStep: str) -> str:
"""Get Mohr's circle ID from cell id and time step.
Args:
cellId (str): cell ID
timeStep (str): time step.
Returns:
str: Mohr's circle ID
"""
return f"Cell_{cellId}@{timeStep}"
[docs]
def createMohrCircleAtTimeStep(
stressArray: npt.NDArray[np.float64],
cellIds: list[str],
timeStep: str,
convention: bool,
) -> list[MohrCircle]:
"""Create MohrCircle object(s) at a given time step for all cell ids.
Args:
stressArray (npt.NDArray[np.float64]): stress numpy array
cellIds (list[str]): list of cell ids
timeStep (str): time step
convention (bool): convention used for compression.
* False is Geos convention (compression is negative)
* True is usual convention (compression is positive)
Returns:
list[MohrCircle]: list of MohrCircle objects.
"""
assert stressArray.shape[1] == 6, "Stress vector must be of size 6."
mohrCircles: list[MohrCircle] = []
sign: float = 1.0 if convention else -1.0
for i, cellId in enumerate(cellIds):
ide: str = getMohrCircleId(cellId, timeStep)
mohrCircle: MohrCircle = MohrCircle(ide)
mohrCircle.computePrincipalComponents(stressArray[i] * sign)
mohrCircles.append(mohrCircle)
return mohrCircles
[docs]
def createMohrCirclesFromPrincipalComponents(
mohrCircleParams: list[tuple[str, float, float, float]]
) -> list[MohrCircle]:
"""Create Mohr's circle objects from principal components.
Args:
mohrCircleParams (list[tuple[str, float, float, float]]): list of Mohr's
circle parameters
Returns:
list[MohrCircle]: list of Mohr's circle objects.
"""
mohrCircles: list[MohrCircle] = []
for circleId, p3, p2, p1 in mohrCircleParams:
mohrCircle: MohrCircle = MohrCircle(circleId)
mohrCircle.setPrincipalComponents(p3, p2, p1)
mohrCircles.append(mohrCircle)
return mohrCircles
[docs]
def createMohrCoulombEnvelope(rockCohesion: float, frictionAngle: float) -> MohrCoulomb:
"""Create MohrCoulomb object from user parameters.
Args:
rockCohesion (float): rock cohesion (Pa).
frictionAngle (float): friction angle in radian.
Returns:
MohrCoulomb: MohrCoulomb object.
"""
return MohrCoulomb(rockCohesion, frictionAngle)