Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
bb2911e
Move SurfaceGeomechanicsFilter and refactor functions
paloma-martinez Sep 9, 2025
391aeea
Move and refactor plugin
paloma-martinez Sep 9, 2025
176b508
add geos-processing to install script
paloma-martinez Sep 10, 2025
cd83faf
Merge branch 'main' into pmartinez/refactor/moveSurfaceGeomechanics
paloma-martinez Sep 10, 2025
8b72f3f
Add more log
paloma-martinez Sep 12, 2025
5bd267c
Add documentation
paloma-martinez Sep 18, 2025
4277ebb
Filter cleaning
paloma-martinez Oct 3, 2025
2e71538
Documentation
paloma-martinez Oct 3, 2025
4bdc33c
Merge branch 'main' into pmartinez/refactor/moveSurfaceGeomechanics
paloma-martinez Oct 3, 2025
b6f9d85
Refactor the basis change computation
paloma-martinez Oct 15, 2025
37e3fd6
Merge branch 'main' into pmartinez/refactor/moveSurfaceGeomechanics
paloma-martinez Oct 15, 2025
9c10aea
Refactor of normal and tangential vectors computation
paloma-martinez Oct 21, 2025
b2d6447
Merge branch 'main' into pmartinez/refactor/moveSurfaceGeomechanics
paloma-martinez Oct 21, 2025
4643add
Replace and add tests for attribute to vector functions
paloma-martinez Oct 29, 2025
64494c8
Add tests and better error handling
paloma-martinez Oct 29, 2025
98a825b
Adding tests for SurfaceGeomechanics filter
paloma-martinez Oct 29, 2025
c87b243
Merge branch 'main' into pmartinez/refactor/moveSurfaceGeomechanics
paloma-martinez Oct 29, 2025
52bcd56
Fix
paloma-martinez Oct 29, 2025
d3e4fc6
typo
paloma-martinez Oct 29, 2025
badc7cd
Small modifications from Romain review
paloma-martinez Oct 30, 2025
335782c
Fix typing and error in getTangents function
paloma-martinez Oct 31, 2025
359ceb0
Fix tests following previous commit modifs
paloma-martinez Oct 31, 2025
27ae09d
SISO filter
paloma-martinez Oct 31, 2025
58e30e3
fix docstring
paloma-martinez Oct 31, 2025
c56b2de
fix the fix
paloma-martinez Oct 31, 2025
cdd923c
typing
paloma-martinez Oct 31, 2025
24e4c5b
typing
paloma-martinez Oct 31, 2025
a7f17e0
Merge branch 'main' into pmartinez/refactor/moveSurfaceGeomechanics
paloma-martinez Oct 31, 2025
7e7eca1
.
paloma-martinez Oct 31, 2025
9df9481
Merge branch 'pmartinez/refactor/moveSurfaceGeomechanics' of https://…
paloma-martinez Oct 31, 2025
dab09d0
Move GeosBlockMerge from geos-posp to geos-processing
RomainBaville Oct 31, 2025
7677e88
Remove PVPythonAlgorythmBase
RomainBaville Oct 31, 2025
a59d804
Update to the last version of the main
RomainBaville Oct 31, 2025
95072db
clean & refactor the code
RomainBaville Nov 3, 2025
7b94f10
Merge branch 'main' into RomainBaville/refactor/MoveGeosBlockMerge
RomainBaville Nov 3, 2025
c2ab8fb
Update import
RomainBaville Nov 3, 2025
c2df04e
Fix density name for fluid phase
RomainBaville Nov 4, 2025
eabc058
harmonized the code (logger, varriable name ...)
RomainBaville Nov 4, 2025
ab7bfcb
Clean the doc
RomainBaville Nov 4, 2025
789cd31
Update GeosBlockMerge calling
RomainBaville Nov 4, 2025
8f08be8
fix computePhaseNames
RomainBaville Nov 4, 2025
13ea5b5
fix convertBlockToSurface
RomainBaville Nov 4, 2025
7755639
fix ci
RomainBaville Nov 4, 2025
e23251b
Refactor plugin to allways extract and merge all the possible blocks
RomainBaville Nov 5, 2025
efc53be
fix timestep parsing
RomainBaville Nov 6, 2025
f2a98a0
fix computePhaseName
RomainBaville Nov 6, 2025
db03941
clean log
RomainBaville Nov 6, 2025
4a380b0
clean output
RomainBaville Nov 6, 2025
5761f7b
Update Geos Output array names
RomainBaville Nov 6, 2025
a955382
fix error
RomainBaville Nov 6, 2025
7c76c64
Apply Paloma suggestion
RomainBaville Nov 7, 2025
de12113
Update the doc and clean the interface
RomainBaville Nov 7, 2025
2dd0c9c
Move utils functions from the plugin to be generalisable
RomainBaville Nov 12, 2025
c8308dc
fix executive
RomainBaville Nov 12, 2025
3cc2be7
Clean the plugin outputs messages
RomainBaville Nov 12, 2025
62cc57d
Rename the plugin file
RomainBaville Nov 12, 2025
dddfed1
Remove old PVExtractAndMerge plugin
RomainBaville Nov 12, 2025
0569296
Update GEOS output attribute name
RomainBaville Nov 12, 2025
065f126
fix the doc
RomainBaville Nov 12, 2025
b6a7161
fix import
RomainBaville Nov 12, 2025
dbb2b44
Merge branch 'RomainBaville/refactor/MoveGeosBlockMerge' into RomainB…
RomainBaville Nov 12, 2025
0f5882a
fix yapf
RomainBaville Nov 13, 2025
f3ab71e
Rename the plugin name
RomainBaville Nov 13, 2025
bae6f34
Update the doc
RomainBaville Nov 13, 2025
596a2af
Refactor the plugin
RomainBaville Nov 13, 2025
8876ea8
Update friction angle unit to be coherent with surface geomechanics p…
RomainBaville Nov 13, 2025
3e741e9
Clean the log
RomainBaville Nov 13, 2025
7b54d8c
Remove old geomechanics workflow plugins
RomainBaville Nov 13, 2025
8a7b9a6
Update the doc
RomainBaville Nov 13, 2025
22f5a61
Merge branch 'RomainBaville/refactor/RefactorPVExtractMergeBlockPlugi…
RomainBaville Nov 13, 2025
f4c7bf5
Update the doc
RomainBaville Nov 13, 2025
e4c3349
clean vtk error logging
RomainBaville Nov 14, 2025
68a702e
Update docstring
RomainBaville Nov 14, 2025
83d74b9
Update to the last version of the main and fix conflict
RomainBaville Nov 17, 2025
c83ae6d
Merge branch 'RomainBaville/refactor/RefactorPVExtractMergeBlockPlugi…
RomainBaville Nov 17, 2025
c662dbc
Update to the last version of the main and fix conflicts
RomainBaville Nov 17, 2025
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
27 changes: 4 additions & 23 deletions docs/geos_pv_docs/processing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,36 +53,17 @@ PVGeosBlockExtractAndMerge plugin
.. automodule:: geos.pv.plugins.PVGeosBlockExtractAndMerge



Geomechanics workflows
++++++++++++++++++++++++


PVGeomechanicsWorkflowVolume plugin
---------------------------------------------

.. automodule:: geos.pv.plugins.PVGeomechanicsWorkflowVolume


PVGeomechanicsWorkflowVolumeSurface plugin
----------------------------------------------------

.. automodule:: geos.pv.plugins.PVGeomechanicsWorkflowVolumeSurface


PVGeomechanicsWorkflowVolumeSurfaceWell plugin
--------------------------------------------------------

.. automodule:: geos.pv.plugins.PVGeomechanicsWorkflowVolumeSurfaceWell


PVGeomechanicsWorkflowVolumeWell plugin
-------------------------------------------------
PVGeomechanicsWorkflow plugin
------------------------------

.. automodule:: geos.pv.plugins.PVGeomechanicsWorkflowVolumeWell
.. automodule:: geos.pv.plugins.PVGeomechanicsWorkflow


PVGeomechanicsCalculator plugin
---------------------------------------

.. automodule:: geos.pv.plugins.PVGeomechanicsCalculator
.. automodule:: geos.pv.plugins.PVGeomechanicsCalculator
104 changes: 61 additions & 43 deletions geos-mesh/src/geos/mesh/utils/genericHelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,17 @@ def triangulateMesh(
Returns:
vtkUnstructuredGrid: Triangulated mesh
"""
vtkErrorLogger: Logger
if logger is None:
logger = getLogger( "Triangulate", True )
# Creation of a child logger to deal with VTKErrors without polluting parent logger
vtkErrorLogger: Logger = getLogger( f"{logger.name}.vtkErrorLogger", True )
vtkErrorLogger.propagate = False
vtkErrorLogger = getLogger( "Triangulate Mesh vtkError Logger", True )
else:
vtkErrorLogger = logging.getLogger( f"{ logger.name } vtkError Logger" )
vtkErrorLogger.setLevel( logging.INFO )
vtkErrorLogger.addHandler( logger.handlers[ 0 ] )
vtkErrorLogger.propagate = False

vtkLogger.SetStderrVerbosity( vtkLogger.VERBOSITY_ERROR )

vtkErrorLogger.addFilter( RegexExceptionFilter() ) # will raise VTKError if captured VTK Error
vtkErrorLogger.setLevel( logging.DEBUG )

with VTKCaptureLog() as capturedLog:
triangulateMeshFilter: vtkDataSetTriangleFilter = vtkDataSetTriangleFilter()
Expand All @@ -81,7 +82,8 @@ def triangulateMesh(
capturedLog.seek( 0 )
captured = capturedLog.read().decode()

vtkErrorLogger.debug( captured.strip() )
if captured != "":
vtkErrorLogger.error( captured.strip() )

triangulatedMesh: vtkUnstructuredGrid = triangulateMeshFilter.GetOutput()

Expand All @@ -107,16 +109,17 @@ def convertUnstructuredGridToPolyData(
Returns:
vtkPolyData: Extracted surface
"""
vtkErrorLogger: Logger
if logger is None:
logger = getLogger( "ConvertVtkUnstructuredGridToVtkPolyData.", True )
# Creation of a child logger to deal with VTKErrors without polluting parent logger
vtkErrorLogger: Logger = getLogger( f"{logger.name}.vtkErrorLogger", True )
vtkErrorLogger.propagate = False
vtkErrorLogger = getLogger( "Convert vtkUnstructuredGrid To vtkPolyData vtkError Logger", True )
else:
vtkErrorLogger = logging.getLogger( f"{ logger.name } vtkError Logger" )
vtkErrorLogger.setLevel( logging.INFO )
vtkErrorLogger.addHandler( logger.handlers[ 0 ] )
vtkErrorLogger.propagate = False

vtkLogger.SetStderrVerbosity( vtkLogger.VERBOSITY_ERROR )

vtkErrorLogger.addFilter( RegexExceptionFilter() ) # will raise VTKError if captured VTK Error
vtkErrorLogger.setLevel( logging.DEBUG )

with VTKCaptureLog() as capturedLog:
extractSurfaceFilter: vtkDataSetSurfaceFilter = vtkDataSetSurfaceFilter()
Expand All @@ -131,7 +134,8 @@ def convertUnstructuredGridToPolyData(
capturedLog.seek( 0 )
captured = capturedLog.read().decode()

vtkErrorLogger.debug( captured.strip() )
if captured != "":
vtkErrorLogger.error( captured.strip() )

extractedSurface: vtkPolyData = extractSurfaceFilter.GetOutput()

Expand Down Expand Up @@ -460,8 +464,8 @@ def getTangentsVectors( surface: vtkPolyData ) -> Tuple[ npt.NDArray[ np.float64
try:
tangents1 = vtk_to_numpy( vtkTangents )
except AttributeError as err:
print( "No tangential attribute found in the mesh. Use the computeTangents function beforehand." )
raise VTKError( err ) from err
context: str = f"No tangential attribute found in the mesh. Use the computeTangents function beforehand.\n{ err }"
raise VTKError( context ) from err
else:
# Compute second tangential component
normals: npt.NDArray[ np.float64 ] = getNormalVectors( surface )
Expand All @@ -471,22 +475,30 @@ def getTangentsVectors( surface: vtkPolyData ) -> Tuple[ npt.NDArray[ np.float64
return ( tangents1, tangents2 )


def getLocalBasisVectors( surface: vtkPolyData ) -> npt.NDArray[ np.float64 ]:
def getLocalBasisVectors(
surface: vtkPolyData,
logger: Union[ Logger, None ] = None,
) -> npt.NDArray[ np.float64 ]:
"""Return the local basis vectors for all cells of the input surface.

Args:
surface(vtkPolydata): The input surface.
logger (Union[Logger, None], optional): A logger to manage the output messages.
Defaults to None, an internal logger is used.

Returns:
npt.NDArray[np.float64]: Array with normal, tangential 1 and tangential 2 vectors.
"""
if logger is None:
logger = getLogger( "getLocalBasisVectors", True )

try:
normals: npt.NDArray[ np.float64 ] = getNormalVectors( surface )
surfaceWithNormals: vtkPolyData = surface
# ValueError raised if no normals found in the mesh
except ValueError:
# In that case, the normals are computed.
surfaceWithNormals = computeNormals( surface )
surfaceWithNormals = computeNormals( surface, logger )
normals = getNormalVectors( surfaceWithNormals )

# Tangents require normals to be present in the mesh
Expand All @@ -495,7 +507,7 @@ def getLocalBasisVectors( surface: vtkPolyData ) -> npt.NDArray[ np.float64 ]:
npt.NDArray[ np.float64 ] ] = getTangentsVectors( surfaceWithNormals )
# If no tangents is present in the mesh, they are computed on that surface
except VTKError:
surfaceWithTangents: vtkPolyData = computeTangents( surfaceWithNormals )
surfaceWithTangents: vtkPolyData = computeTangents( surfaceWithNormals, logger )
tangents = getTangentsVectors( surfaceWithTangents )

return np.array( ( normals, *tangents ) )
Expand All @@ -515,16 +527,17 @@ def computeNormals(
Returns:
vtkPolyData: The surface with normal attribute.
"""
vtkErrorLogger: Logger
if logger is None:
logger = getLogger( "computeSurfaceNormals" )
# Creation of a child logger to deal with VTKErrors without polluting parent logger
vtkErrorLogger: Logger = getLogger( f"{logger.name}.vtkErrorLogger" )
vtkErrorLogger.propagate = False
vtkErrorLogger = getLogger( "Compute Surface Normals vtkError Logger", True )
else:
vtkErrorLogger = logging.getLogger( f"{ logger.name } vtkError Logger" )
vtkErrorLogger.setLevel( logging.INFO )
vtkErrorLogger.addHandler( logger.handlers[ 0 ] )
vtkErrorLogger.propagate = False

vtkLogger.SetStderrVerbosity( vtkLogger.VERBOSITY_ERROR )

vtkErrorLogger.addFilter( RegexExceptionFilter() ) # will raise VTKError if captured VTK Error
vtkErrorLogger.setLevel( logging.DEBUG )

with VTKCaptureLog() as capturedLog:
normalFilter: vtkPolyDataNormals = vtkPolyDataNormals()
Expand All @@ -536,7 +549,8 @@ def computeNormals(
capturedLog.seek( 0 )
captured = capturedLog.read().decode()

vtkErrorLogger.debug( captured.strip() )
if captured != "":
vtkErrorLogger.error( captured.strip() )

outputSurface = normalFilter.GetOutput()

Expand All @@ -562,22 +576,23 @@ def computeTangents(
Returns:
vtkPolyData: The surface with tangent attribute
"""
# need to compute texture coordinates required for tangent calculation
surface1: vtkPolyData = computeSurfaceTextureCoordinates( triangulatedSurface )
# Need to compute texture coordinates required for tangent calculation
surface1: vtkPolyData = computeSurfaceTextureCoordinates( triangulatedSurface, logger )

# TODO: triangulate the surface before computation of the tangents if needed.

# compute tangents
# Compute tangents
vtkErrorLogger: Logger
if logger is None:
logger = getLogger( "computeSurfaceTangents" )
# Creation of a child logger to deal with VTKErrors without polluting parent logger
vtkErrorLogger: Logger = getLogger( f"{logger.name}.vtkErrorLogger" )
vtkErrorLogger.propagate = False
vtkErrorLogger = getLogger( "Compute Surface Tangents vtkError Logger", True )
else:
vtkErrorLogger = logging.getLogger( f"{ logger.name } vtkError Logger" )
vtkErrorLogger.setLevel( logging.INFO )
vtkErrorLogger.addHandler( logger.handlers[ 0 ] )
vtkErrorLogger.propagate = False

vtkLogger.SetStderrVerbosity( vtkLogger.VERBOSITY_ERROR )

vtkErrorLogger.addFilter( RegexExceptionFilter() ) # will raise VTKError if captured VTK Error
vtkErrorLogger.setLevel( logging.DEBUG )

with VTKCaptureLog() as capturedLog:

Expand All @@ -591,7 +606,8 @@ def computeTangents(
capturedLog.seek( 0 )
captured = capturedLog.read().decode()

vtkErrorLogger.debug( captured.strip() )
if captured != "":
vtkErrorLogger.error( captured.strip() )

if surfaceOut is None:
raise VTKError( "Something went wrong in VTK calculation." )
Expand Down Expand Up @@ -623,16 +639,17 @@ def computeSurfaceTextureCoordinates(
vtkPolyData: The input surface with generated texture map.
"""
# Need to compute texture coordinates required for tangent calculation
vtkErrorLogger: Logger
if logger is None:
logger = getLogger( "computeSurfaceTextureCoordinates" )
# Creation of a child logger to deal with VTKErrors without polluting parent logger
vtkErrorLogger: Logger = getLogger( f"{logger.name}.vtkErrorLogger" )
vtkErrorLogger.propagate = False
vtkErrorLogger = getLogger( "Compute Surface Texture Coordinates vtkError Logger", True )
else:
vtkErrorLogger = logging.getLogger( f"{ logger.name } vtkError Logger" )
vtkErrorLogger.setLevel( logging.INFO )
vtkErrorLogger.addHandler( logger.handlers[ 0 ] )
vtkErrorLogger.propagate = False

vtkLogger.SetStderrVerbosity( vtkLogger.VERBOSITY_ERROR )

vtkErrorLogger.addFilter( RegexExceptionFilter() ) # will raise VTKError if captured VTK Error
vtkErrorLogger.setLevel( logging.DEBUG )

with VTKCaptureLog() as capturedLog:

Expand All @@ -644,6 +661,7 @@ def computeSurfaceTextureCoordinates(
capturedLog.seek( 0 )
captured = capturedLog.read().decode()

vtkErrorLogger.debug( captured.strip() )
if captured != "":
vtkErrorLogger.error( captured.strip() )

return textureFilter.GetOutput()
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
mesh: vtkUnstructuredGrid
computeAdvancedProperties: bool # optional, defaults to False
speHandler: bool # optional, defaults to False
loggerName: str # Defaults to "Geomechanics Calculator"

# Instantiate the filter
geomechanicsCalculatorFilter: GeomechanicsCalculator = GeomechanicsCalculator( mesh, computeAdvancedProperties, speHandler )
Expand Down Expand Up @@ -693,7 +694,7 @@ def __init__(
computeAdvancedProperties (bool, optional): True to compute advanced geomechanics properties, False otherwise.
Defaults to False.
loggerName (str, optional): Name of the filter logger.
Defaults to "Geomechanics Calculator"
Defaults to "Geomechanics Calculator".
speHandler (bool, optional): True to use a specific handler, False to use the internal handler.
Defaults to False.
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
extractFault: bool # Defaults to False
extractWell: bool # Defaults to False
speHandler: bool # Defaults to False
loggerName: str # Defaults to "Geos Block Extractor"

# Instantiate the filter
geosBlockExtractor: GeosBlockExtractor = GeosBlockExtractor( geosMesh, extractFault, extractWell, speHandler )
Expand All @@ -56,8 +57,6 @@
geosDomainExtracted = geosBlockExtractor.extractedGeosDomain.well # For well domain
"""

loggerTitle: str = "Geos Block Extractor"


class GeosExtractDomainBlock( vtkExtractBlock ):

Expand Down Expand Up @@ -149,6 +148,7 @@ def __init__(
extractFault: bool = False,
extractWell: bool = False,
speHandler: bool = False,
loggerName: str = "Geos Block Extractor",
) -> None:
"""Blocks from the ElementRegions from a GEOS output multiBlockDataset mesh.

Expand All @@ -160,6 +160,8 @@ def __init__(
Defaults to False.
speHandler (bool, optional): True to use a specific handler, False to use the internal handler.
Defaults to False.
loggerName (str, optional): Name of the filter logger.
Defaults to "Geos Block Extractor".
"""
self.geosMesh: vtkMultiBlockDataSet = geosMesh
self.extractedGeosDomain = self.ExtractedGeosDomain()
Expand All @@ -173,9 +175,9 @@ def __init__(
# Logger.
self.logger: Logger
if not speHandler:
self.logger = getLogger( loggerTitle, True )
self.logger = getLogger( loggerName, True )
else:
self.logger = logging.getLogger( loggerTitle )
self.logger = logging.getLogger( loggerName )
self.logger.setLevel( logging.INFO )

def setLoggerHandler( self: Self, handler: logging.Handler ) -> None:
Expand All @@ -201,15 +203,18 @@ def applyFilter( self: Self ) -> None:
extractGeosDomain: GeosExtractDomainBlock = GeosExtractDomainBlock()
extractGeosDomain.SetInputData( self.geosMesh )

domainNames: list = []
for domain in self.domainToExtract:
extractGeosDomain.RemoveAllIndices()
extractGeosDomain.AddGeosDomainName( domain )
extractGeosDomain.Update()
self.extractedGeosDomain.setExtractedDomain( domain, extractGeosDomain.GetOutput() )
domainNames.append( domain.value )

self.logger.info( f"The GEOS domain { domainNames } have been extracted." )
self.logger.info( f"The filter { self.logger.name } succeeded." )

self.logger.info( "The filter succeeded." )
except ( ValueError, TypeError ) as e:
self.logger.error( f"The filter { self.logger.name } failed.\n{ e }." )

except ValueError as ve:
self.logger.error( f"The filter failed.\n{ ve }." )
except TypeError as te:
self.logger.error( f"The filter failed.\n{ te }." )
return
Loading