Skip to content

Commit f1f395b

Browse files
authored
First version of meshDoctor (#2091)
Current implementation can detect collocated nodes and generate vtk global ids. Still work in progress, it can also generate the fracture information needed by GEOSX.
1 parent a86aa2e commit f1f395b

18 files changed

+1283
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
COLLOCATES_NODES = "collocated_nodes"
2+
GENERATE_FRACTURES = "generate_fractures"
3+
GENERATE_GLOBAL_IDS = "generate_global_ids"
4+
5+
all_checks = dict()
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from collections import defaultdict
2+
from dataclasses import dataclass
3+
import logging
4+
from typing import Tuple
5+
6+
import numpy
7+
8+
from vtkmodules.vtkCommonCore import (
9+
reference,
10+
vtkPoints,
11+
)
12+
from vtkmodules.vtkCommonDataModel import (
13+
vtkIncrementalOctreePointLocator,
14+
)
15+
16+
from . import vtk_utils
17+
18+
19+
@dataclass(frozen=True)
20+
class Options:
21+
tolerance: float
22+
23+
24+
@dataclass(frozen=True)
25+
class Result:
26+
nodes_buckets: Tuple[Tuple[int]]
27+
28+
29+
def __check(mesh, options: Options) -> Result:
30+
points = mesh.GetPoints()
31+
32+
locator = vtkIncrementalOctreePointLocator()
33+
locator.SetTolerance(options.tolerance)
34+
output = vtkPoints()
35+
locator.InitPointInsertion(output, points.GetBounds())
36+
37+
# original ids to/from filtered ids.
38+
# original_to_filtered = numpy.ones(points.GetNumberOfPoints(), dtype=int) * -1
39+
filtered_to_original = numpy.ones(points.GetNumberOfPoints(), dtype=int) * -1
40+
41+
rejected_points = defaultdict(list)
42+
point_id = reference(0)
43+
for i in range(points.GetNumberOfPoints()):
44+
is_inserted = locator.InsertUniquePoint(points.GetPoint(i), point_id)
45+
if not is_inserted:
46+
# If it's not inserted, `point_id` contains the node that was already at that location.
47+
# But in that case, `point_id` is the new numbering in the destination points array.
48+
# 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.
49+
logging.debug(f"Point {i} at {points.GetPoint(i)} has been rejected, point {filtered_to_original[point_id.get()]} is already inserted.")
50+
rejected_points[point_id.get()].append(i)
51+
else:
52+
# If it's inserted, `point_id` contains the new index in the destination array.
53+
# We store this information to be able to connect the source and destination arrays.
54+
# original_to_filtered[i] = point_id.get()
55+
filtered_to_original[point_id.get()] = i
56+
57+
tmp = []
58+
for n, ns in rejected_points.items():
59+
tmp.append((n, *ns))
60+
61+
return Result(nodes_buckets=tmp)
62+
63+
64+
def check(vtk_input_file: str, options: Options) -> Result:
65+
mesh = vtk_utils.read_mesh(vtk_input_file)
66+
return __check(mesh, options)

0 commit comments

Comments
 (0)