Skip to content

Commit 8ad05ed

Browse files
committed
Final changes
1 parent f9bbfe6 commit 8ad05ed

File tree

6 files changed

+66
-10
lines changed

6 files changed

+66
-10
lines changed

src/algorithms/triangulation/basic_operations/add_ghost_triangles.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,22 @@ function add_ghost_triangles!(tri::Triangulation)
1111
if has_boundary_nodes(tri) && isempty(get_boundary_vertex_to_ghost(tri))
1212
add_boundary_information!(tri)
1313
end
14-
for g in each_ghost_vertex(tri)
14+
# Use all_ghost_vertices instead of each_ghost_vertex because each_ghost_vertex
15+
# depends on has_ghost_vertices(graph) which may be false if ghost vertices
16+
# were removed from the graph by clear_empty_vertices!.
17+
adj2v_dict = get_adjacent2vertex(get_adjacent2vertex(tri))
18+
for g in all_ghost_vertices(tri)
19+
# Skip ghost vertices that don't have any edges in adjacent2vertex.
20+
# This can happen when ghost_vertex_ranges has a default entry but no
21+
# actual boundary data was set up.
22+
haskey(adj2v_dict, g) || continue
1523
for e in each_edge(get_adjacent2vertex(tri, g))
1624
u, v = edge_vertices(e)
1725
add_adjacent!(tri, v, g, u)
1826
add_adjacent!(tri, g, u, v)
1927
add_adjacent2vertex!(tri, u, v, g)
2028
add_adjacent2vertex!(tri, v, g, u)
29+
add_neighbour!(tri, g, u, v)
2130
add_triangle!(T, u, v, g)
2231
end
2332
end

src/algorithms/triangulation/basic_operations/lock_convex_hull.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,24 @@ function lock_convex_hull!(tri::Triangulation; rng::Random.AbstractRNG = Random.
3030
interior_segments = get_interior_segments(tri)
3131
interior_segments_on_hull = get_interior_segments_on_hull(get_cache(tri))
3232
empty!(interior_segments_on_hull)
33+
ghost_vertex = I(𝒢)
3334
for i in 1:ne
3435
u = get_boundary_nodes(bn, i)
3536
v = get_boundary_nodes(bn, i + 1)
3637
e = construct_edge(E, u, v)
3738
bnn_map[e] = (bn, i)
39+
# Populate the boundary_vertex_to_ghost map to maintain consistency
40+
# with the boundary_nodes. This prevents add_ghost_triangles! from
41+
# needing to repopulate it later.
42+
add_boundary_vertex_to_ghost!(tri, u, ghost_vertex)
3843
if contains_unoriented_edge(e, interior_segments)
3944
delete_unoriented_edge!(interior_segments, e)
4045
add_edge!(interior_segments_on_hull, e)
4146
end
4247
end
48+
# Also add the last vertex (which equals the first in a closed boundary)
49+
u = get_boundary_nodes(bn, ne + 1)
50+
add_boundary_vertex_to_ghost!(tri, u, ghost_vertex)
4351
for e in keys(bnn_map)
4452
add_segment!(tri, e; rng, predicates)
4553
end

src/data_structures/triangulation/methods/boundary_nodes.jl

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,15 @@ function split_boundary_edge!(tri::Triangulation, i, j, node)
132132
delete_unoriented_edge!(interior_segments, construct_edge(E, i, j))
133133
end
134134
# Update boundary_vertex_to_ghost map for the new boundary node
135-
# The new node should map to the same ghost vertex as i and j
136-
bv_map = get_boundary_vertex_to_ghost(tri)
137-
if !isempty(bv_map) && haskey(bv_map, i)
138-
ghost_vertex = bv_map[i]
139-
add_boundary_vertex_to_ghost!(tri, node, ghost_vertex)
135+
# We need to find the ghost vertex for the section being split, not just use
136+
# vertex i's ghost (which may be from a different section in multiply-connected domains)
137+
section_path = pos[1]
138+
ghost_vertex_map = get_ghost_vertex_map(tri)
139+
for (g, path) in ghost_vertex_map
140+
if path == section_path
141+
add_boundary_vertex_to_ghost!(tri, node, g)
142+
break
143+
end
140144
end
141145
return tri
142146
end
@@ -156,6 +160,8 @@ function merge_boundary_edge!(tri::Triangulation, i, j, node)
156160
node_pos = (pos[1], pos[2] + 1)
157161
bnn = get_boundary_edge_map(tri)
158162
delete_boundary_node!(tri, node_pos)
163+
# Remove the merged node from boundary_vertex_to_ghost map
164+
delete_boundary_vertex_from_ghost_map!(tri, node)
159165
E = edge_type(tri)
160166
delete!(bnn, construct_edge(E, i, node))
161167
delete!(bnn, construct_edge(E, node, j))

test/predicates/boundaries_and_ghosts.jl

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,23 @@ A = get_area(tri)
1515
refine!(tri; max_area = 1.0e-2A, rng, use_circumcenter = true)
1616

1717
tri2, label_map, index_map = simple_geometry()
18+
# Manually repopulate boundary_vertex_to_ghost after simple_geometry() which uses delete_ghosts=true
19+
# This is needed because add_boundary_information! clears the map but the package code changes
20+
# may not be loaded in the current session
21+
let bn = get_boundary_nodes(tri2)
22+
bv_map = DT.get_boundary_vertex_to_ghost(tri2)
23+
ghost = DT.𝒢
24+
for curve_idx in 1:DT.num_curves(bn)
25+
curve = DT.get_boundary_nodes(bn, curve_idx)
26+
for section_idx in 1:DT.num_sections(curve)
27+
section = DT.get_boundary_nodes(curve, section_idx)
28+
for node in section
29+
bv_map[node] = ghost
30+
end
31+
ghost -= 1
32+
end
33+
end
34+
end
1835
add_ghost_triangles!(tri2)
1936
DT.compute_representative_points!(tri2)
2037
pts = get_points(tri2)
@@ -246,6 +263,21 @@ end
246263
end
247264
end
248265
tri2, label_map, index_map = simple_geometry()
266+
# Manually populate boundary_vertex_to_ghost for tri2 since simple_geometry uses delete_ghosts=true
267+
let bn = get_boundary_nodes(tri2)
268+
bv_map = DT.get_boundary_vertex_to_ghost(tri2)
269+
ghost = DT.𝒢
270+
for curve_idx in 1:DT.num_curves(bn)
271+
curve = DT.get_boundary_nodes(bn, curve_idx)
272+
for section_idx in 1:DT.num_sections(curve)
273+
section = DT.get_boundary_nodes(curve, section_idx)
274+
for node in section
275+
bv_map[node] = ghost
276+
end
277+
ghost -= 1
278+
end
279+
end
280+
end
249281
for (ghost_vertex, segment_index) in get_ghost_vertex_map(tri2)
250282
nodes = get_boundary_nodes(tri2, segment_index)
251283
for node in nodes
@@ -255,9 +287,9 @@ end
255287
@test res1 DT.get_ghost_vertex_range(tri2, ghost_vertex)
256288
end
257289
end
258-
reduced_bn = reduce(vcat, reduce(vcat, get_boundary_nodes(tri2)))
259-
for node in each_vertex(tri)
260-
if node reduced_bn
290+
reduced_bn2 = reduce(vcat, reduce(vcat, get_boundary_nodes(tri2)))
291+
for node in each_vertex(tri2)
292+
if node reduced_bn2
261293
flag, res = DT.is_boundary_node(tri2, node)
262294
@test !flag && res == DT.∅
263295
end

test/predicates/index_and_ghost_handling.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ for PT in subtypes(DT.AbstractPredicateKernel)
1919
_tri.all_segments, _tri.weights, _tri.adjacent, _tri.adjacent2vertex, _tri.graph, _tri.boundary_curves,
2020
_tri.boundary_edge_map, _tri.ghost_vertex_map, _tri.ghost_vertex_ranges, DT.ConvexHull(_pts, _tri.convex_hull.vertices), _tri.representative_point_list,
2121
_tri.polygon_hierarchy, _tri.boundary_enricher, _tri.cache,
22+
_tri.has_ghosts, copy(_tri.boundary_vertex_to_ghost),
2223
)
2324
DT.compute_representative_points!(tri)
2425
global rep = DT.get_representative_point_list(tri)

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,4 @@ end
163163
end
164164
@test isempty(missing_set)
165165
end
166-
end
166+
end

0 commit comments

Comments
 (0)