Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
ee78216
Add GenerateRectilinearGrid
alexbenedicto May 9, 2025
cc8e2a5
Add ElementVolumes filter
alexbenedicto May 9, 2025
b88bff7
Add GenerateFractures filter
alexbenedicto May 12, 2025
d32ad33
Add CollocatedNodes filter
alexbenedicto May 13, 2025
bac1a83
Add SupportElements filter but without polyhedron checking due to lac…
alexbenedicto May 15, 2025
f180f8f
To revert
alexbenedicto May 23, 2025
f6bc7f2
Merge remote-tracking branch 'origin/main' into benedicto/feature/vtk…
alexbenedicto Jun 24, 2025
f14cc1b
Keep supported_elements like before merging
alexbenedicto Jun 24, 2025
2f367bb
Update already implemented filters to work after merge
alexbenedicto Jun 24, 2025
0b44584
Temporary commit
alexbenedicto Aug 1, 2025
a9c4f7a
Merge remote-tracking branch 'origin/main' into benedicto/feature/vtk…
alexbenedicto Aug 1, 2025
f68b38d
Add base class for all mesh doctor VTK filters
alexbenedicto Aug 4, 2025
9727b21
Update existing filters with new base class
alexbenedicto Aug 4, 2025
9516825
Fix init for GenerateRectilinearGrid
alexbenedicto Aug 5, 2025
b9d9a78
Add SelfIntersectingElements
alexbenedicto Aug 5, 2025
4838fce
Change __action to mesh_action function for better clarity
alexbenedicto Aug 5, 2025
e7a4134
Change base class names + add MeshDoctorChecks base
alexbenedicto Aug 6, 2025
41ce1a1
Remove MeshDoctorChecks class
alexbenedicto Aug 6, 2025
353abc5
Fix global variable assignation for MESH in supported_elements
alexbenedicto Aug 12, 2025
0009e51
Add AllChecks and MainChecks filters
alexbenedicto Aug 12, 2025
a67d3cb
yapf on mesh-doctor
alexbenedicto Aug 12, 2025
686ff68
Update __doc__ for each filter
alexbenedicto Aug 12, 2025
8a07761
Update .rst documentations
alexbenedicto Aug 12, 2025
ed9843c
Merge remote-tracking branch 'origin/main' into benedicto/feature/vtk…
alexbenedicto Aug 12, 2025
d81951e
Improve displayed results for supported_elements
alexbenedicto Aug 12, 2025
dfe85b2
yapf
alexbenedicto Aug 13, 2025
ce1ca67
Update vtkIO to be more robust, reduce duplication
alexbenedicto Aug 13, 2025
bfe2517
Update mesh_action to only be given vtkUnstructuredGrid
alexbenedicto Aug 14, 2025
f99e42f
Review implementations + yapf
alexbenedicto Aug 14, 2025
71496c6
Fix invalid variable names
alexbenedicto Aug 14, 2025
40abad6
yapf
alexbenedicto Aug 14, 2025
ab17743
Fix docs
alexbenedicto Aug 14, 2025
ab3ca8f
Merge remote-tracking branch 'origin/main' into benedicto/feature/vtk…
alexbenedicto Aug 25, 2025
415c49d
Replace MeshDoctorBase with MeshDoctorBaseFilter to remove vtk pipeline
alexbenedicto Aug 25, 2025
68439c9
Update all filters with new base class
alexbenedicto Aug 25, 2025
a4c4c3b
Reimplement to use applyFilter approach
alexbenedicto Aug 29, 2025
dd9cecb
Update documentation
alexbenedicto Aug 29, 2025
1ba9b08
Remove previous tests for filters
alexbenedicto Aug 30, 2025
88ccfce
Update test_generate_cube to include GenerateRectilinearGrid
alexbenedicto Sep 3, 2025
0894a8c
Update test_generate_fractures to include GenerateFractures
alexbenedicto Sep 3, 2025
f117435
Remove condition for writing output grid in standalone functions
alexbenedicto Sep 3, 2025
9edea27
Remove tempfile to use tmp_path functionality of pytest
alexbenedicto Sep 3, 2025
c6911ae
Add test_CollocatedNodes
alexbenedicto Sep 3, 2025
26fb43d
Add better input checking when init class
alexbenedicto Sep 3, 2025
b718e81
Add non-destructive behavior to input_mesh
alexbenedicto Sep 3, 2025
b5278ca
Add test_ElementVolumes
alexbenedicto Sep 3, 2025
93ce020
Add test_MeshDoctorFilterBase
alexbenedicto Sep 3, 2025
8824b00
Add NonCorformal tests
alexbenedicto Sep 3, 2025
1bf5fd6
Add test for SelfIntersectingElements
alexbenedicto Sep 5, 2025
d7d6e4c
Add tests for SupportedElements
alexbenedicto Sep 5, 2025
f5c5ec6
Add tests for Checks
alexbenedicto Sep 5, 2025
dbe1e3d
Better test mesh creation
alexbenedicto Sep 5, 2025
1e7dd4e
Reimplement vtkIO and test it
alexbenedicto Sep 8, 2025
f1a2410
Correct some comments
alexbenedicto Sep 15, 2025
10ec288
Add findUniqueCellCenterCellIds function
alexbenedicto Sep 15, 2025
e141022
yapf
alexbenedicto Sep 15, 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
2 changes: 2 additions & 0 deletions docs/geos-mesh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ GEOS Mesh tools

./geos_mesh_docs/doctor

./geos_mesh_docs/doctor_filters

./geos_mesh_docs/converter

./geos_mesh_docs/io
Expand Down
61 changes: 54 additions & 7 deletions docs/geos_mesh_docs/doctor.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Mesh Doctor
---------------
-----------

``mesh-doctor`` is a ``python`` executable that can be used through the command line to perform various checks, validations, and tiny fixes to the ``vtk`` mesh that are meant to be used in ``geos``.
``mesh-doctor`` is organized as a collection of modules with their dedicated sets of options.
The current page will introduce those modules, but the details and all the arguments can be retrieved by using the ``--help`` option for each module.
| ``mesh-doctor`` is a ``python`` executable that can be used through the command line to perform various checks, validations, and tiny fixes to the ``vtkUnstructuredGrid`` mesh that are meant to be used in ``geos``.
``mesh-doctor`` is organized as a collection of modules with their dedicated sets of options.
| The current page will introduce those modules, but the details and all the arguments can be retrieved by using the ``--help`` option for each module.

Prerequisites
^^^^^^^^^^^^^
Expand Down Expand Up @@ -310,8 +310,55 @@ It will also verify that the ``VTK_POLYHEDRON`` cells can effectively get conver
.. code-block::

$ mesh-doctor supported_elements --help
usage: mesh_doctor.py supported_elements [-h] [--chunck_size 1] [--nproc 8]
usage: mesh_doctor.py supported_elements [-h] [--chunk_size 1] [--nproc 8]
options:
-h, --help show this help message and exit
--chunck_size 1 [int]: Defaults chunk size for parallel processing to 1
--nproc 8 [int]: Number of threads used for parallel processing. Defaults to your CPU count 8.
--chunk_size 1 [int]: Defaults chunk size for parallel processing to 1
--nproc 8 [int]: Number of threads used for parallel processing. Defaults to your CPU count 8.


Why only use vtkUnstructuredGrid?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| The mesh doctor is designed specifically for unstructured meshes used in GEOS.
| All input files are expected to be ``.vtu`` (VTK Unstructured Grid) format.
| What about other formats?

VTK Hierarchy
"""""""""""""

Supposedly, other grid types that are part of the following VTK hierarchy could be used::

vtkDataObject
└── vtkDataSet
└── vtkCartesianGrid
└── vtkRectilinearGrid
└── vtkImageData
└── vtkStructuredPoints
└── vtkUniformGrid
└── vtkPointSet
└── vtkExplicitStructuredGrid
└── vtkPolyData
└── vtkStructuredGrid
└── vtkUnstructuredGrid

And when looking at specific methods used in mesh-doctor, it could suggest that other formats could be used:

* Points access: ``mesh.GetPoints()`` - Available in all vtkPointSet subclasses ✓
* Cell iteration: ``mesh.GetNumberOfCells()``, ``mesh.GetCell()`` - Available in all vtkDataSet subclasses ✓
* Cell types: ``mesh.GetCellType()`` - Available in all vtkDataSet subclasses ✓
* Cell/Point data: ``mesh.GetCellData()``, ``mesh.GetPointData()`` - Available in all vtkDataSet subclasses ✓

VTK Filter Compatibility
""""""""""""""""""""""""

| ``vtkCellSizeFilter``, ``vtkMeshQuality``, and other VTK filters used in the actions expect ``vtkDataSet`` or its subclasses
``vtkUnstructuredGrid`` is compatible with all VTK filters used.
| ``vtkPolyData`` has a different data structure, not suitable for 3D volumetric meshes.

Specific Operations Require vtkUnstructuredGrid
"""""""""""""""""""""""""""""""""""""""""""""""

* ``GetCellNeighbors()`` - Only available in vtkUnstructuredGrid
* ``GetFaceStream()`` - Only available in vtkUnstructuredGrid (for polyhedron support)
* ``GetDistinctCellTypesArray()`` - Only available in vtkUnstructuredGrid
19 changes: 19 additions & 0 deletions docs/geos_mesh_docs/doctor_filters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
VTK Filters
===========

In addition to the command-line interface, mesh-doctor functionality is also available as VTK filters for programmatic use in Python. These filters provide the same mesh validation and processing capabilities but can be integrated directly into Python workflows and visualization pipelines.

The VTK filters offer several advantages:

* **Integration**: Easy integration with existing VTK/ParaView workflows
* **Scripting**: Programmatic access for batch processing and automation
* **Visualization**: Direct output suitable for ParaView visualization
* **Flexibility**: Configurable parameters and output options
* **Chaining**: Ability to combine multiple filters in processing pipelines

For detailed documentation on available filters, their parameters, and usage examples, see:

.. toctree::
:maxdepth: 1

filters/index
18 changes: 18 additions & 0 deletions docs/geos_mesh_docs/filters/Checks.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
AllChecks and MainChecks Filters
================================

.. automodule:: geos.mesh.doctor.filters.Checks
:members:
:undoc-members:
:show-inheritance:

See Also
--------

* :doc:`CollocatedNodes <CollocatedNodes>` - Individual collocated nodes check
* :doc:`ElementVolumes <ElementVolumes>` - Individual element volume check
* :doc:`NonConformal <NonConformal>` - Individual non-conformal interface check
* :doc:`SelfIntersectingElements <SelfIntersectingElements>` - Individual self-intersection check
* :doc:`SupportedElements <SupportedElements>` - Individual supported elements check


50 changes: 50 additions & 0 deletions docs/geos_mesh_docs/filters/CollocatedNodes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
CollocatedNodes Filter
======================

.. automodule:: geos.mesh.doctor.filters.CollocatedNodes
:members:
:undoc-members:
:show-inheritance:

Understanding the Results
-------------------------

**Collocated Node Buckets**

Each bucket is a tuple containing node indices that are within the specified tolerance of each other:

.. code-block:: python

# Example result: [(0, 15, 23), (7, 42), (100, 101, 102, 103)]
# This means:
# - Nodes 0, 15, and 23 are collocated
# - Nodes 7 and 42 are collocated
# - Nodes 100, 101, 102, and 103 are collocated

**Wrong Support Elements**

Cell element IDs where the same node appears multiple times in the element's connectivity. This usually indicates:

* Degenerate elements
* Mesh generation errors
* Topology problems

Common Use Cases
----------------

* **Mesh Quality Assessment**: Identify potential mesh issues before simulation
* **Mesh Preprocessing**: Clean up meshes by detecting node duplicates
* **Debugging**: Understand why meshes might have connectivity problems
* **Validation**: Ensure mesh meets quality standards for specific applications

I/O
---

* **Input**: vtkUnstructuredGrid
* **Output**: vtkUnstructuredGrid with optional arrays marking problematic elements
* **Additional Data**: When painting is enabled, adds "WrongSupportElements" array to cell data

See Also
--------

* :doc:`AllChecks and MainChecks <Checks>` - Includes collocated nodes check among others
63 changes: 63 additions & 0 deletions docs/geos_mesh_docs/filters/ElementVolumes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
ElementVolumes Filter
=====================

.. automodule:: geos.mesh.doctor.filters.ElementVolumes
:members:
:undoc-members:
:show-inheritance:

Understanding Volume Issues
---------------------------

**Negative Volumes**

Indicate elements with inverted geometry:

* **Tetrahedra**: Nodes ordered incorrectly (clockwise instead of counter-clockwise)
* **Hexahedra**: Faces oriented inward instead of outward
* **Other elements**: Similar orientation/ordering issues

**Zero Volumes**

Indicate degenerate elements:

* **Collapsed elements**: All nodes lie in the same plane (3D) or line (2D)
* **Duplicate nodes**: Multiple nodes at the same location within the element
* **Extreme aspect ratios**: Elements stretched to near-zero thickness

**Impact on Simulations**

Elements with non-positive volumes can cause:

* Numerical instabilities
* Convergence problems
* Incorrect physical results
* Solver failures

Common Fixes
------------

**For Negative Volumes:**

1. **Reorder nodes**: Correct the connectivity order
2. **Flip elements**: Use mesh repair tools
3. **Regenerate mesh**: If issues are widespread

**For Zero Volumes:**

1. **Remove degenerate elements**: Delete problematic cells
2. **Merge collocated nodes**: Fix duplicate node issues
3. **Improve mesh quality**: Regenerate with better settings

I/O
---

* **Input**: vtkUnstructuredGrid
* **Output**: vtkUnstructuredGrid with volume information added as cell data
* **Volume Array**: "Volume" array added to cell data containing computed volumes
* **Additional Data**: When returnNegativeZeroVolumes is enabled, provides detailed problematic element information

See Also
--------

* :doc:`AllChecks and MainChecks <Checks>` - Includes element volumes check among others
78 changes: 78 additions & 0 deletions docs/geos_mesh_docs/filters/GenerateFractures.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
GenerateFractures Filter
========================

.. automodule:: geos.mesh.doctor.filters.GenerateFractures
:members:
:undoc-members:
:show-inheritance:

Fracture Policies
-----------------

**Field Fractures Policy (field)**

| Obtained by setting ``--policy field``.
|
| Creates fractures by using internal interfaces between cells regions.
| These interfaces corresponds to a change in the values of a CellData array stored in your mesh.
| Suppose you have a CellData array named "Regions" with 3 different values indicating geological layers. 1 is caprock, 2 is reservoir, and 3 is underburden as represented here (below is a 2D representation along Z for simplicity):
|
| 111111111111111111
| 111111222222222222
| 222222222223333333
| 333333333333333333
|
| In this example, I define the interface between reservoir and caprock as a fracture, and the interface between reservoir and underburden as another fracture.
| So when specifying your field values as ``--values 1,2:2,3``, the filter will create a fracture along the interface between these two regions. The result will be a new mesh with the fracture represented as a separate entity. The nodes will be split along these interfaces, allowing for discontinuities in the mesh:
|
| 111111111111111111
| 111111------------
| ------222222222222
| 22222222222+++++++
| +++++++++++3333333
| 333333333333333333
|
| with ``----`` representing the first fracture and ``+++++++`` representing the second fracture.

**Internal Fractures Policy (internal_surfaces)**

| Obtained by setting ``--policy internal_surfaces``.
|
| Creates fractures by using tagged 2D cells that are identified as a fracture.
| In VTK, ``2D cells`` are refering to ``VTK_TRIANGLE`` or ``VTK_QUAD`` cell types.
| These 2D cells should be part of the input mesh and tagged with a specific CellData array value.
| Suppose you have a CellData array named "isFault" with 3 different values to tag fractures. 0 is for all non fault cells, 1 is fault1, and 2 is fault2 as represented here (below is a 2D representation along Z for simplicity):
|
| 000000000000000000
| 000000111111111111
| 111111000000000000
| 000000000002222222
| 222222222220000000
| 000000000000000000
|
| So when specifying your field values as ``--values 1:2``, the filter will create one fracture for each cells tagged with 1 and 2.

Understanding Fracture Generation
---------------------------------

**Process**

1. **Identification**: Find interfaces between cells with different field values
2. **Node Duplication**: Create separate nodes for each side of the fracture
3. **Mesh Splitting**: Update connectivity to use duplicated nodes
4. **Fracture Extraction**: Generate separate meshes for fracture surfaces

**Output Structure**

* **Split Mesh**: Original mesh with fractures as discontinuities
* **Fracture Meshes**: Individual surface meshes for each fracture

I/O
---

* **Input**: vtkUnstructuredGrid with fracture identification field or tagged 2D cells
* **Outputs**:

* Split mesh with fractures as discontinuities
* Individual fracture surface meshes
* **File Output**: Automatic writing of fracture meshes to specified directory
14 changes: 14 additions & 0 deletions docs/geos_mesh_docs/filters/GenerateRectilinearGrid.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
GenerateRectilinearGrid Filter
==============================

.. automodule:: geos.mesh.doctor.filters.GenerateRectilinearGrid
:members:
:undoc-members:
:show-inheritance:

I/O
---

* **Input**: Not needed
* **Output**: vtkUnstructuredGrid
* **Additional Data**: New fields on points or cells if user requests them.
14 changes: 14 additions & 0 deletions docs/geos_mesh_docs/filters/MeshDoctorFilterBase.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
MeshDoctorFilterBase
====================

.. automodule:: geos.mesh.doctor.filters.MeshDoctorFilterBase
:members:
:undoc-members:
:show-inheritance:

See Also
--------

* :doc:`AllChecks and MainChecks <Checks>` - Comprehensive mesh quality assessment using MeshDoctorFilterBase
* :doc:`GenerateRectilinearGrid <GenerateRectilinearGrid>` - Grid generation using MeshDoctorGeneratorBase
* :doc:`GenerateFractures <GenerateFractures>` - Fracture mesh generation using MeshDoctorFilterBase
Loading