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 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

To use mesh-doctor, you need to have installed the mandatory packages using the following commands (in this order):

python -m pip install --upgrade ./geos-utils
python -m pip install --upgrade ./geos-mesh
python -m pip install --upgrade ./mesh-doctor

Once done, you can call mesh-doctor in your command line as presented in the rest of this documentation.

Modules

To list all the modules available through mesh-doctor, you can simply use the --help option, which will list all available modules as well as a quick summary.

$ mesh-doctor --help
usage: mesh-doctor [-h] [-v] [-q]
                   {allChecks,collocatedNodes,elementVolumes,fixElementsOrderings,generateCube,generateFractures,generateGlobalIds,mainChecks,nonConformal,selfIntersectingElements,supportedElements}
                   ...

Inspects meshes for GEOS.

positional arguments:
  {allChecks,collocatedNodes,elementVolumes,fixElementsOrderings,generateCube,generateFractures,generateGlobalIds,mainChecks,nonConformal,selfIntersectingElements,supportedElements}
        Modules
    allChecks
        Perform one or multiple mesh-doctor checks from the complete set available.
    collocatedNodes
        Checks if nodes are collocated.
    elementVolumes
        Checks if the volumes of the elements are greater than "minVolume".
    fixElementsOrderings
        Reorders the support nodes for the given cell types.
    generateCube
        Generate a cube and its fields.
    generateFractures
        Splits the mesh to generate the faults and fractures.
    generateGlobalIds
        Adds globals ids for points and cells.
    mainChecks
        Perform a curated set of main mesh-doctor checks.
    nonConformal
        Detects non conformal elements. [EXPERIMENTAL]
    selfIntersectingElements
        Checks if the faces of the elements are self intersecting.
    supportedElements
        Check that all the elements of the mesh are supported by GEOSX.

options:
  -h, --help
        show this help message and exit
  -v    Use -v 'INFO', -vv for 'DEBUG'. Defaults to 'WARNING'.
  -q    Use -q to reduce the verbosity of the output.

Note that checks are dynamically loaded.
An option may be missing because of an unloaded module.
Increase verbosity (-v, -vv) to get full information.

Then, if you are interested in a specific module, you can ask for its documentation using the mesh-doctor module_name --help pattern. For example

$ mesh-doctor collocatedNodes --help
usage: mesh-doctor collocatedNodes [-h] -i VTU_MESH_FILE --tolerance 0.0

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process.
  --tolerance 0.0       [float]: The absolute distance between two nodes for
                        them to be considered collocated.

Finally, to execute a specific module, you can use the following pattern:

mesh-doctor module_name -i /path/to/input.vtu --output /path/to/output.vtu [module_options]

mesh-doctor loads its module dynamically. If a module can’t be loaded, mesh-doctor will proceed and try to load other modules. If you see a message like

[1970-04-14 03:07:15,625][WARNING] Could not load module "collocatedNodes": No module named 'vtkmodules'

then most likely mesh-doctor could not load the collocatedNodes module, because the vtk python package was not found. Thereafter, the documentation for module collocatedNodes will not be displayed. You can solve this issue by installing the dependencies of mesh-doctor defined in its requirements.txt file (python -m pip install -r requirements.txt).

Here is a list and brief description of all the modules available.

allChecks and mainChecks

mesh-doctor modules are called actions and they can be split into 2 different categories: check actions that will give you a feedback on a .vtu mesh that you would like to use in GEOS. operate actions that will either create a new mesh or modify an existing mesh.

allChecks aims at applying every single check action in one single command. The available list is of check is: collocatedNodes, elementVolumes, nonConformal, selfIntersectingElements, supportedElements.

mainChecks does only the fastest checks collocatedNodes, elementVolumes and selfIntersectingElements that can quickly highlight some issues to deal with before investigating the other checks.

Both allChecks and mainChecks have the same keywords and can be operated in the same way. The example below shows the case of allChecks, but it can be swapped for mainChecks.

$ mesh-doctor allChecks --help
usage: mesh-doctor allChecks [-h] -i VTU_MESH_FILE
                             [--checksToPerform CHECKSTOPERFORM]
                             [--setParameters SETPARAMETERS]

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process. (default:
                        None)
  --checksToPerform CHECKSTOPERFORM
                        Comma-separated list of checks to perform. If empty,
                        all of the following are run by default:
                        ['collocatedNodes', 'elementVolumes', 'nonConformal',
                        'selfIntersectingElements', 'supportedElements'].
                        Available choices: ['collocatedNodes',
                        'elementVolumes', 'nonConformal',
                        'selfIntersectingElements', 'supportedElements'].
                        Example: --checksToPerform
                        collocatedNodes,elementVolumes (default: )
  --setParameters SETPARAMETERS
                        Comma-separated list of parameters to override
                        defaults (e.g., 'param_name:value'). Default
                        parameters are: For collocatedNodes: tolerance:0.0.
                        For elementVolumes: minVolume:0.0. For nonConformal:
                        angleTolerance:10.0, pointTolerance:0.0,
                        faceTolerance:0.0. For selfIntersectingElements:
                        minDistance:2.220446049250313e-16. For
                        supportedElements: chunkSize:1, nproc:2. Example:
                        --setParameters parameter_name:10.5,other_param:25
                        (default: )

collocatedNodes

Displays the neighboring nodes that are closer to each other than a prescribed threshold. It is not uncommon to define multiple nodes for the exact same position, which will typically be an issue for geos and should be fixed.

$ mesh-doctor collocatedNodes --help
usage: mesh-doctor collocatedNodes [-h] -i VTU_MESH_FILE --tolerance 0.0

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process.
  --tolerance 0.0       [float]: The absolute distance between two nodes for
                        them to be considered collocated.

elementVolumes

Computes the volumes of all the cells and displays the ones that are below a prescribed threshold. Cells with negative volumes will typically be an issue for geos and should be fixed.

$ mesh-doctor elementVolumes --help
usage: mesh-doctor elementVolumes [-h] -i VTU_MESH_FILE --minVolume 0.0

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process.
  --minVolume 0.0       [float]: The minimum acceptable volume. Defaults to
                        0.0.

fixElementsOrderings

It sometimes happens that an exported mesh does not abide by the vtk orderings. The fixElementsOrderings module can rearrange the nodes of given types of elements. This can be convenient if you cannot regenerate the mesh.

$ mesh-doctor fixElementsOrderings --help
usage: mesh-doctor fixElementsOrderings [-h] -i VTU_MESH_FILE
                                        [--Hexahedron 1,6,5,4,7,0,2,3]
                                        [--Prism5 8,2,0,7,6,9,5,1,4,3]
                                        [--Prism6 11,2,8,10,5,0,9,7,6,1,4,3]
                                        [--Pyramid 3,4,0,2,1]
                                        [--Tetrahedron 2,0,3,1]
                                        [--Voxel 1,6,5,4,7,0,2,3]
                                        [--Wedge 3,5,4,0,2,1] --output OUTPUT
                                        [--data-mode binary, ascii]

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process.
  --Hexahedron 1,6,5,4,7,0,2,3
                        [list of integers]: node permutation for "Hexahedron".
  --Prism5 8,2,0,7,6,9,5,1,4,3
                        [list of integers]: node permutation for "Prism5".
  --Prism6 11,2,8,10,5,0,9,7,6,1,4,3
                        [list of integers]: node permutation for "Prism6".
  --Pyramid 3,4,0,2,1   [list of integers]: node permutation for "Pyramid".
  --Tetrahedron 2,0,3,1
                        [list of integers]: node permutation for
                        "Tetrahedron".
  --Voxel 1,6,5,4,7,0,2,3
                        [list of integers]: node permutation for "Voxel".
  --Wedge 3,5,4,0,2,1   [list of integers]: node permutation for "Wedge".
  --output OUTPUT       [string]: The vtk output file destination.
  --data-mode binary, ascii
                        [string]: For ".vtu" output format, the data mode can
                        be binary or ascii. Defaults to binary.

generateCube

This module conveniently generates cubic meshes in vtk. It can also generate fields with simple values. This tool can also be useful to generate a trial mesh that will later be refined or customized.

$ mesh-doctor generateCube --help
usage: mesh-doctor generateCube [-h] [-i VTU_MESH_FILE] [--x 0:1.5:3]
                                [--y 0:5:10] [--z 0:1] [--nx 2:2] [--ny 1:1]
                                [--nz 4]
                                [--fields name:support:dim [name:support:dim ...]]
                                [--cells] [--no-cells] [--points]
                                [--no-points] --output OUTPUT
                                [--data-mode binary, ascii]

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process. (optional)
  --x 0:1.5:3           [list of floats]: X coordinates of the points.
  --y 0:5:10            [list of floats]: Y coordinates of the points.
  --z 0:1               [list of floats]: Z coordinates of the points.
  --nx 2:2              [list of integers]: Number of elements in the X
                        direction.
  --ny 1:1              [list of integers]: Number of elements in the Y
                        direction.
  --nz 4                [list of integers]: Number of elements in the Z
                        direction.
  --fields name:support:dim [name:support:dim ...]
                        Create fields on CELLS or POINTS, with given dimension
                        (typically 1 or 3).
  --cells               [bool]: Generate global ids for cells. Defaults to
                        true.
  --no-cells            [bool]: Don't generate global ids for cells.
  --points              [bool]: Generate global ids for points. Defaults to
                        true.
  --no-points           [bool]: Don't generate global ids for points.
  --output OUTPUT       [string]: The vtk output file destination.
  --data-mode binary, ascii
                        [string]: For ".vtu" output format, the data mode can
                        be binary or ascii. Defaults to binary.

Exceptionally, this module does not require an input vtk mesh because its purpose is to generate a new one. The command to use would be something like:

mesh-doctor generateCube --output cube.vtu --x 0:10 --y 0:10 --z 0:10 --nx 10 --ny 15 --nz 20 --cells --nopoints

generateFractures

For a conformal fracture to be defined in a mesh, geos requires the mesh to be split at the faces where the fracture gets across the mesh. The generateFractures module will split the mesh and generate the multi-block vtk files.

$ mesh-doctor generateFractures --help
usage: mesh-doctor generateFractures [-h] -i VTU_MESH_FILE --policy field,
                                     internalSurfaces [--name NAME]
                                     [--values VALUES] --output OUTPUT
                                     [--data-mode binary, ascii]
                                     [--fracturesOutputDir FRACTURESOUTPUTDIR]
                                     [--fracturesDataMode binary, ascii]

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process.
  --policy field, internalSurfaces
                        [string]: The criterion to define the surfaces that
                        will be changed into fracture zones. Possible values
                        are "field, internalSurfaces"
  --name NAME           [string]: If the "field" policy is selected, defines
                        which field will be considered to define the
                        fractures. If the "internalSurfaces" policy is
                        selected, defines the name of the attribute will be
                        considered to identify the fractures.
  --values VALUES       [list of comma separated integers]: If the "field"
                        policy is selected, which changes of the field will be
                        considered as a fracture. If the "internalSurfaces"
                        policy is selected, list of the fracture attributes.
                        You can create multiple fractures by separating the
                        values with ':' like shown in this example. --values
                        10,12:13,14,16,18:22 will create 3 fractures
                        identified respectively with the values (10,12),
                        (13,14,16,18) and (22). If no ':' is found, all values
                        specified will be assumed to create only 1 single
                        fracture.
  --output OUTPUT       [string]: The vtk output file destination.
  --data-mode binary, ascii
                        [string]: For ".vtu" output format, the data mode can
                        be binary or ascii. Defaults to binary.
  --fracturesOutputDir FRACTURESOUTPUTDIR
                        [string]: The output directory for the fractures
                        meshes that will be generated from the mesh.
  --fracturesDataMode binary, ascii
                        [string]: For ".vtu" output format, the data mode can
                        be binary or ascii. Defaults to binary.

generateGlobalIds

When running geos in parallel, global ids can be used to refer to data across multiple ranks. The generateGlobalIds can generate global ids for the imported vtk mesh.

$ mesh-doctor generateGlobalIds --help
usage: mesh-doctor generateGlobalIds [-h] -i VTU_MESH_FILE [--cells]
                                     [--no-cells] [--points] [--no-points]
                                     --output OUTPUT
                                     [--data-mode binary, ascii]

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process.
  --cells               [bool]: Generate global ids for cells. Defaults to
                        true.
  --no-cells            [bool]: Don't generate global ids for cells.
  --points              [bool]: Generate global ids for points. Defaults to
                        true.
  --no-points           [bool]: Don't generate global ids for points.
  --output OUTPUT       [string]: The vtk output file destination.
  --data-mode binary, ascii
                        [string]: For ".vtu" output format, the data mode can
                        be binary or ascii. Defaults to binary.

nonConformal

This module will detect elements which are close enough (there’s a user defined threshold) but which are not in front of each other (another threshold can be defined). Close enough can be defined in terms or proximity of the nodes and faces of the elements. The angle between two faces can also be precribed. This module can be a bit time consuming.

$ mesh-doctor nonConformal --help
usage: mesh-doctor nonConformal [-h] -i VTU_MESH_FILE [--angleTolerance 10.0]
                                [--pointTolerance 0.0] [--faceTolerance 0.0]

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process.
  --angleTolerance 10.0
                        [float]: angle tolerance in degrees. Defaults to 10.0
  --pointTolerance 0.0  [float]: tolerance for two points to be considered
                        collocated. Defaults to 0.0
  --faceTolerance 0.0   [float]: tolerance for two faces to be considered
                        "touching". Defaults to 0.0

selfIntersectingElements

Some meshes can have cells that auto-intersect. This module will display the elements that have faces intersecting.

$ mesh-doctor selfIntersectingElements --help
usage: mesh-doctor selfIntersectingElements [-h] -i VTU_MESH_FILE
                                            [--minDistance 2.220446049250313e-16]

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process.
  --minDistance 2.220446049250313e-16
                        [float]: The minimum distance in the computation.
                        Defaults to your machine precision
                        2.220446049250313e-16.

supportedElements

geos supports a specific set of elements. Let’s cite the standard elements like tetrahedra, wedges, pyramids or hexahedra. But also prismes up to 11 faces. geos also supports the generic VTK_POLYHEDRON/42 elements, which are converted on the fly into one of the elements just described.

The supportedElements check will validate that no unsupported element is included in the input mesh. It will also verify that the VTK_POLYHEDRON cells can effectively get converted into a supported type of element.

$ mesh-doctor supportedElements --help
usage: mesh-doctor supportedElements [-h] -i VTU_MESH_FILE [--chunkSize 1]
                                     [--nproc 2]

options:
  -h, --help            show this help message and exit
  -i VTU_MESH_FILE, --vtu-input-file VTU_MESH_FILE
                        [string]: The VTU mesh file to process.
  --chunkSize 1         [int]: Defaults chunk size for parallel processing to
                        1
  --nproc 2             [int]: Number of threads used for parallel processing.
                        Defaults to your CPU count 2.

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