Skip to content

Commit c9b4b44

Browse files
feat: Perform all mesh-doctor checks at once (#100)
* Change folder named "checks" for "actions" to be less ambiguous about mesh-doctor available features. * Improve logging functionality across main mesh-doctor scripts * all_checks and main_checks feature added * Update tests * Update documentation * Add RESULTS log level to Logger * Improve message output from certain checks + add description of parameters used when doing checks
1 parent 8b51ff9 commit c9b4b44

51 files changed

Lines changed: 1199 additions & 499 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/geos-mesh.rst

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
GEOS Mesh tools
22
====================
33

4+
**geos-mesh** is a Python package that contains several tools and utilities to handle processing and quality checks of meshes.
5+
46
.. toctree::
5-
:maxdepth: 5
7+
:maxdepth: 1
68
:caption: Contents:
79

8-
./geos_mesh_docs/home.rst
10+
./geos_mesh_docs/doctor
11+
12+
./geos_mesh_docs/converter
13+
14+
./geos_mesh_docs/io
15+
16+
./geos_mesh_docs/model
17+
18+
./geos_mesh_docs/processing
19+
20+
./geos_mesh_docs/stats
921

10-
./geos_mesh_docs/modules.rst
22+
./geos_mesh_docs/utils

docs/geos_mesh_docs/doctor.rst

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,29 @@ Mesh Doctor
55
``mesh-doctor`` is organized as a collection of modules with their dedicated sets of options.
66
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.
77

8+
Prerequisites
9+
^^^^^^^^^^^^^
10+
11+
To use mesh-doctor, you first need to have installed the ``geos-mesh`` package using the following command:
12+
13+
.. code-block:: bash
14+
15+
python -m pip install --upgrade ./geos-mesh
16+
17+
Once done, you can call ``mesh-doctor`` in your command line as presented in the rest of this documentation.
18+
819
Modules
920
^^^^^^^
1021

1122
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.
1223

1324
.. code-block::
1425
15-
$ python src/geos/mesh/doctor/mesh_doctor.py --help
26+
$ mesh-doctor --help
1627
usage: mesh_doctor.py [-h] [-v] [-q] -i VTK_MESH_FILE
1728
{collocated_nodes,element_volumes,fix_elements_orderings,generate_cube,generate_fractures,generate_global_ids,non_conformal,self_intersecting_elements,supported_elements}
1829
...
19-
2030
Inspects meshes for GEOSX.
21-
2231
positional arguments:
2332
{collocated_nodes,element_volumes,fix_elements_orderings,generate_cube,generate_fractures,generate_global_ids,non_conformal,self_intersecting_elements,supported_elements}
2433
Modules
@@ -40,14 +49,12 @@ To list all the modules available through ``mesh-doctor``, you can simply use th
4049
Checks if the faces of the elements are self intersecting.
4150
supported_elements
4251
Check that all the elements of the mesh are supported by GEOSX.
43-
4452
options:
4553
-h, --help
4654
show this help message and exit
4755
-v Use -v 'INFO', -vv for 'DEBUG'. Defaults to 'WARNING'.
4856
-q Use -q to reduce the verbosity of the output.
4957
-i VTK_MESH_FILE, --vtk-input-file VTK_MESH_FILE
50-
5158
Note that checks are dynamically loaded.
5259
An option may be missing because of an unloaded module.
5360
Increase verbosity (-v, -vv) to get full information.
@@ -57,9 +64,8 @@ For example
5764

5865
.. code-block::
5966
60-
$ python src/geos/mesh/doctor/mesh_doctor.py collocated_nodes --help
67+
$ mesh-doctor collocated_nodes --help
6168
usage: mesh_doctor.py collocated_nodes [-h] --tolerance TOLERANCE
62-
6369
options:
6470
-h, --help show this help message and exit
6571
--tolerance TOLERANCE [float]: The absolute distance between two nodes for them to be considered collocated.
@@ -78,6 +84,42 @@ You can solve this issue by installing the dependencies of ``mesh-doctor`` defin
7884

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

87+
``all_checks`` and ``main_checks``
88+
""""""""""""""""""""""""""""""""""
89+
90+
``mesh-doctor`` modules are called ``actions`` and they can be split into 2 different categories:
91+
``check actions`` that will give you a feedback on a .vtu mesh that you would like to use in GEOS.
92+
``operate actions`` that will either create a new mesh or modify an existing mesh.
93+
94+
``all_checks`` aims at applying every single ``check`` action in one single command. The available list is of check is:
95+
``collocated_nodes``, ``element_volumes``, ``non_conformal``, ``self_intersecting_elements``, ``supported_elements``.
96+
97+
``main_checks`` does only the fastest checks ``collocated_nodes``, ``element_volumes`` and ``self_intersecting_elements``
98+
that can quickly highlight some issues to deal with before investigating the other checks.
99+
100+
Both ``all_checks`` and ``main_checks`` have the same keywords and can be operated in the same way. The example below shows
101+
the case of ``all_checks``, but it can be swapped for ``main_checks``.
102+
103+
.. code-block::
104+
105+
$ mesh-doctor all_checks --help
106+
usage: mesh-doctor all_checks [-h] [--checks_to_perform CHECKS_TO_PERFORM] [--set_parameters SET_PARAMETERS]
107+
108+
options:
109+
-h, --help show this help message and exit
110+
--checks_to_perform CHECKS_TO_PERFORM
111+
Comma-separated list of mesh-doctor checks to perform.
112+
If no input was given, all of the following checks will be executed by default: ['collocated_nodes', 'element_volumes', 'self_intersecting_elements'].
113+
The available choices for checks are ['collocated_nodes', 'element_volumes', 'non_conformal', 'self_intersecting_elements', 'supported_elements'].
114+
If you want to choose only certain of them, you can name them individually.
115+
Example: --checks_to_perform collocated_nodes,element_volumes (default: )
116+
--set_parameters SET_PARAMETERS
117+
Comma-separated list of parameters to set for the checks (e.g., 'param_name:value'). These parameters override the defaults.
118+
Default parameters are: For collocated_nodes: tolerance:0.0. For element_volumes: min_volume:0.0.
119+
For non_conformal: angle_tolerance:10.0, point_tolerance:0.0, face_tolerance:0.0.
120+
For self_intersecting_elements: min_distance:2.220446049250313e-16. For supported_elements: chunk_size:1, nproc:8.
121+
Example: --set_parameters parameter_name:10.5,other_param:25 (default: )
122+
81123
``collocated_nodes``
82124
""""""""""""""""""""
83125

@@ -86,9 +128,8 @@ It is not uncommon to define multiple nodes for the exact same position, which w
86128

87129
.. code-block::
88130
89-
$ python src/geos/mesh/doctor/mesh_doctor.py collocated_nodes --help
131+
$ mesh-doctor collocated_nodes --help
90132
usage: mesh_doctor.py collocated_nodes [-h] --tolerance TOLERANCE
91-
92133
options:
93134
-h, --help show this help message and exit
94135
--tolerance TOLERANCE [float]: The absolute distance between two nodes for them to be considered collocated.
@@ -101,9 +142,8 @@ Cells with negative volumes will typically be an issue for ``geos`` and should b
101142

102143
.. code-block::
103144
104-
$ python src/geos/mesh/doctor/mesh_doctor.py element_volumes --help
145+
$ mesh-doctor element_volumes --help
105146
usage: mesh_doctor.py element_volumes [-h] --min 0.0
106-
107147
options:
108148
-h, --help show this help message and exit
109149
--min 0.0 [float]: The minimum acceptable volume. Defaults to 0.0.
@@ -117,12 +157,11 @@ This can be convenient if you cannot regenerate the mesh.
117157

118158
.. code-block::
119159
120-
$ python src/geos/mesh/doctor/mesh_doctor.py fix_elements_orderings --help
160+
$ mesh-doctor fix_elements_orderings --help
121161
usage: mesh_doctor.py fix_elements_orderings [-h] [--Hexahedron 1,6,5,4,7,0,2,3] [--Prism5 8,2,0,7,6,9,5,1,4,3]
122162
[--Prism6 11,2,8,10,5,0,9,7,6,1,4,3] [--Pyramid 3,4,0,2,1]
123163
[--Tetrahedron 2,0,3,1] [--Voxel 1,6,5,4,7,0,2,3]
124164
[--Wedge 3,5,4,0,2,1] --output OUTPUT [--data-mode binary, ascii]
125-
126165
options:
127166
-h, --help show this help message and exit
128167
--Hexahedron 1,6,5,4,7,0,2,3
@@ -148,11 +187,10 @@ This tool can also be useful to generate a trial mesh that will later be refined
148187

149188
.. code-block::
150189
151-
$ python src/geos/mesh/doctor/mesh_doctor.py generate_cube --help
190+
$ mesh-doctor generate_cube --help
152191
usage: mesh_doctor.py generate_cube [-h] [--x 0:1.5:3] [--y 0:5:10] [--z 0:1] [--nx 2:2] [--ny 1:1] [--nz 4]
153192
[--fields name:support:dim [name:support:dim ...]] [--cells] [--no-cells]
154193
[--points] [--no-points] --output OUTPUT [--data-mode binary, ascii]
155-
156194
options:
157195
-h, --help show this help message and exit
158196
--x 0:1.5:3 [list of floats]: X coordinates of the points.
@@ -179,10 +217,9 @@ The ``generate_fractures`` module will split the mesh and generate the multi-blo
179217

180218
.. code-block::
181219
182-
$ python src/geos/mesh/doctor/mesh_doctor.py generate_fractures --help
220+
$ mesh-doctor generate_fractures --help
183221
usage: mesh_doctor.py generate_fractures [-h] --policy field, internal_surfaces [--name NAME] [--values VALUES] --output OUTPUT
184222
[--data-mode binary, ascii] [--fractures_output_dir FRACTURES_OUTPUT_DIR]
185-
186223
options:
187224
-h, --help show this help message and exit
188225
--policy field, internal_surfaces
@@ -210,10 +247,9 @@ The ``generate_global_ids`` can generate `global ids` for the imported ``vtk`` m
210247

211248
.. code-block::
212249
213-
$ python src/geos/mesh/doctor/mesh_doctor.py generate_global_ids --help
250+
$ mesh-doctor generate_global_ids --help
214251
usage: mesh_doctor.py generate_global_ids [-h] [--cells] [--no-cells] [--points] [--no-points] --output OUTPUT
215252
[--data-mode binary, ascii]
216-
217253
options:
218254
-h, --help show this help message and exit
219255
--cells [bool]: Generate global ids for cells. Defaults to true.
@@ -234,10 +270,9 @@ This module can be a bit time consuming.
234270

235271
.. code-block::
236272
237-
$ python src/geos/mesh/doctor/mesh_doctor.py non_conformal --help
273+
$ mesh-doctor non_conformal --help
238274
usage: mesh_doctor.py non_conformal [-h] [--angle_tolerance 10.0] [--point_tolerance POINT_TOLERANCE]
239275
[--face_tolerance FACE_TOLERANCE]
240-
241276
options:
242277
-h, --help show this help message and exit
243278
--angle_tolerance 10.0 [float]: angle tolerance in degrees. Defaults to 10.0
@@ -254,9 +289,8 @@ This module will display the elements that have faces intersecting.
254289

255290
.. code-block::
256291
257-
$ python src/geos/mesh/doctor/mesh_doctor.py self_intersecting_elements --help
292+
$ mesh-doctor self_intersecting_elements --help
258293
usage: mesh_doctor.py self_intersecting_elements [-h] [--min 2.220446049250313e-16]
259-
260294
options:
261295
-h, --help show this help message and exit
262296
--min 2.220446049250313e-16
@@ -275,9 +309,8 @@ It will also verify that the ``VTK_POLYHEDRON`` cells can effectively get conver
275309

276310
.. code-block::
277311
278-
$ python src/geos/mesh/doctor/mesh_doctor.py supported_elements --help
312+
$ mesh-doctor supported_elements --help
279313
usage: mesh_doctor.py supported_elements [-h] [--chunck_size 1] [--nproc 8]
280-
281314
options:
282315
-h, --help show this help message and exit
283316
--chunck_size 1 [int]: Defaults chunk size for parallel processing to 1

docs/geos_mesh_docs/home.rst

Lines changed: 0 additions & 4 deletions
This file was deleted.

docs/geos_mesh_docs/modules.rst

Lines changed: 0 additions & 20 deletions
This file was deleted.
File renamed without changes.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from dataclasses import dataclass
2+
from geos.mesh.doctor.register import __load_module_action
3+
from geos.mesh.doctor.parsing.cli_parsing import setup_logger
4+
5+
6+
@dataclass( frozen=True )
7+
class Options:
8+
checks_to_perform: list[ str ]
9+
checks_options: dict[ str, any ]
10+
check_displays: dict[ str, any ]
11+
12+
13+
@dataclass( frozen=True )
14+
class Result:
15+
check_results: dict[ str, any ]
16+
17+
18+
def action( vtk_input_file: str, options: Options ) -> list[ Result ]:
19+
check_results: dict[ str, any ] = dict()
20+
for check_name in options.checks_to_perform:
21+
check_action = __load_module_action( check_name )
22+
setup_logger.info( f"Performing check '{check_name}'." )
23+
option = options.checks_options[ check_name ]
24+
check_result = check_action( vtk_input_file, option )
25+
check_results[ check_name ] = check_result
26+
return Result( check_results=check_results )

geos-mesh/src/geos/mesh/doctor/checks/check_fractures.py renamed to geos-mesh/src/geos/mesh/doctor/actions/check_fractures.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import logging
21
import numpy
32
from dataclasses import dataclass
43
from tqdm import tqdm
@@ -7,7 +6,8 @@
76
from vtkmodules.vtkCommonCore import vtkPoints
87
from vtkmodules.vtkIOXML import vtkXMLMultiBlockDataReader
98
from vtkmodules.util.numpy_support import vtk_to_numpy
10-
from geos.mesh.doctor.checks.generate_fractures import Coordinates3D
9+
from geos.mesh.doctor.actions.generate_fractures import Coordinates3D
10+
from geos.mesh.doctor.parsing.cli_parsing import setup_logger
1111
from geos.mesh.utils.genericHelpers import vtk_iter
1212

1313

@@ -113,11 +113,11 @@ def __check_neighbors( matrix: vtkUnstructuredGrid, fracture: vtkUnstructuredGri
113113
if f in fracture_faces:
114114
found += 1
115115
if found != 2:
116-
logging.warning( f"Something went wrong since we should have found 2 fractures faces (we found {found})" +
117-
f" for collocated nodes {cns}." )
116+
setup_logger.warning( "Something went wrong since we should have found 2 fractures faces (we found" +
117+
f" {found}) for collocated nodes {cns}." )
118118

119119

120-
def __check( vtk_input_file: str, options: Options ) -> Result:
120+
def __action( vtk_input_file: str, options: Options ) -> Result:
121121
matrix, fracture = __read_multiblock( vtk_input_file, options.matrix_name, options.fracture_name )
122122
matrix_points: vtkPoints = matrix.GetPoints()
123123
fracture_points: vtkPoints = fracture.GetPoints()
@@ -148,9 +148,9 @@ def __check( vtk_input_file: str, options: Options ) -> Result:
148148
return Result( errors=errors )
149149

150150

151-
def check( vtk_input_file: str, options: Options ) -> Result:
151+
def action( vtk_input_file: str, options: Options ) -> Result:
152152
try:
153-
return __check( vtk_input_file, options )
153+
return __action( vtk_input_file, options )
154154
except BaseException as e:
155-
logging.error( e )
155+
setup_logger.error( e )
156156
return Result( errors=() )

geos-mesh/src/geos/mesh/doctor/checks/collocated_nodes.py renamed to geos-mesh/src/geos/mesh/doctor/actions/collocated_nodes.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from collections import defaultdict
22
from dataclasses import dataclass
3-
import logging
43
import numpy
54
from typing import Collection, Iterable
65
from vtkmodules.vtkCommonCore import reference, vtkPoints
76
from vtkmodules.vtkCommonDataModel import vtkIncrementalOctreePointLocator
7+
from geos.mesh.doctor.parsing.cli_parsing import setup_logger
88
from geos.mesh.io.vtkIO import read_mesh
99

1010

@@ -19,7 +19,7 @@ class Result:
1919
wrong_support_elements: Collection[ int ] # Element indices with support node indices appearing more than once.
2020

2121

22-
def __check( mesh, options: Options ) -> Result:
22+
def __action( mesh, options: Options ) -> Result:
2323
points = mesh.GetPoints()
2424

2525
locator = vtkIncrementalOctreePointLocator()
@@ -38,7 +38,7 @@ def __check( mesh, options: Options ) -> Result:
3838
# If it's not inserted, `point_id` contains the node that was already at that location.
3939
# But in that case, `point_id` is the new numbering in the destination points array.
4040
# It's more useful for the user to get the old index in the original mesh, so he can look for it in his data.
41-
logging.debug(
41+
setup_logger.debug(
4242
f"Point {i} at {points.GetPoint(i)} has been rejected, point {filtered_to_original[point_id.get()]} is already inserted."
4343
)
4444
rejected_points[ point_id.get() ].append( i )
@@ -63,6 +63,6 @@ def __check( mesh, options: Options ) -> Result:
6363
return Result( nodes_buckets=tmp, wrong_support_elements=wrong_support_elements )
6464

6565

66-
def check( vtk_input_file: str, options: Options ) -> Result:
66+
def action( vtk_input_file: str, options: Options ) -> Result:
6767
mesh = read_mesh( vtk_input_file )
68-
return __check( mesh, options )
68+
return __action( mesh, options )

0 commit comments

Comments
 (0)