Skip to content

Commit 5836af1

Browse files
committed
return a DistMeshResults struct
1 parent 424c29e commit 5836af1

File tree

3 files changed

+44
-32
lines changed

3 files changed

+44
-32
lines changed

src/distmeshnd.jl

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ function distmesh(fdist::Function,
3535
distmesh(fdist, fh, h, setup, o, w, fp, Val(stats), VT)
3636
end
3737

38+
39+
struct DistMeshResult{PT, TT, STATS}
40+
points::Vector{PT}
41+
tetrahedra::Vector{TT}
42+
stats::STATS
43+
end
44+
3845
function distmesh(fdist::Function,
3946
fh,
4047
h::Number,
@@ -71,14 +78,16 @@ function distmesh(fdist::Function,
7178
facecenteredcubic!(fdist, p, pt_dists, h, setup.iso, origin, widths, VertType)
7279
end
7380

81+
# Result struct for holding points, simplices, and iteration statistics
82+
result = DistMeshResult(p, GeometryBasics.SimplexFace{4,Int32}[], DistMeshStatistics())
83+
7484
# initialize arrays
7585
pair_set = Set{Tuple{Int32,Int32}}() # set used for ensure we have a unique set of edges
7686
pair = Tuple{Int32,Int32}[] # edge indices (Int32 since we use Tetgen)
7787
dp = zeros(VertType, length(p)) # displacement at each node
7888
bars = VertType[] # the vector of each edge
7989
L = eltype(VertType)[] # vector length of each edge
8090
L0 = non_uniform ? eltype(VertType)[] : nothing # desired edge length computed by dh (edge length function)
81-
t = GeometryBasics.SimplexFace{4,Int32}[] # tetrahedra indices from delaunay triangulation
8291
maxmove = typemax(eltype(VertType)) # stores an iteration max movement for retriangulation
8392

8493
# arrays for tracking quality metrics
@@ -87,7 +96,6 @@ function distmesh(fdist::Function,
8796
qualities = eltype(VertType)[]
8897

8998
# information on each iteration
90-
statsdata = DistMeshStatistics()
9199
lcount = 0 # iteration counter
92100
triangulationcount = 0 # triangulation counter
93101

@@ -102,9 +110,9 @@ function distmesh(fdist::Function,
102110

103111
# compute a new delaunay triangulation
104112
# we use the default random insertion method
105-
delaunayn!(fdist, p, t, geps, false)
113+
delaunayn!(fdist, result, geps, false)
106114

107-
tet_to_edges!(pair, pair_set, t) # Describe each edge by a unique pair of nodes
115+
tet_to_edges!(pair, pair_set, result.tetrahedra) # Describe each edge by a unique pair of nodes
108116

109117
# resize arrays for new pair counts
110118
resize!(bars, length(pair))
@@ -114,14 +122,14 @@ function distmesh(fdist::Function,
114122
# if the points were sorted we need to update the distance cache
115123
if setup.sort && iszero(triangulationcount % setup.sort_interval)
116124
for i in eachindex(p)
117-
pt_dists[i] = fdist(p[i])
125+
pt_dists[i] = fdist(result.points[i])
118126
end
119127
end
120128
triangulationcount += 1
121-
stats && push!(statsdata.retriangulations, lcount)
129+
stats && push!(result.stats.retriangulations, lcount)
122130
end
123131

124-
compute_displacements!(fh, dp, pair, L, L0, bars, p, setup, VertType)
132+
compute_displacements!(fh, dp, pair, L, L0, bars, result.points, setup, VertType)
125133

126134
# Zero out forces on fix points
127135
if have_fixed
@@ -144,7 +152,7 @@ function distmesh(fdist::Function,
144152
# complex distance functions and large node counts
145153
move = sqrt(sum((p[i]-p0).^2)) # compute movement from the displacement
146154
d_est = pt_dists[i] + move # apply the movement to our cache point
147-
d = d_est < -geps ? d_est : fdist(p[i]) # determine if we need correct or approximate distance
155+
d = d_est < -geps ? d_est : fdist(result.points[i]) # determine if we need correct or approximate distance
148156
pt_dists[i] = d # store distance
149157

150158
if d < -geps
@@ -167,20 +175,20 @@ function distmesh(fdist::Function,
167175

168176
# save iteration stats
169177
if stats
170-
push!(statsdata.maxmove,maxmove)
171-
push!(statsdata.maxdp,maxdp)
172-
triangle_qualities!(tris,triset,qualities,p,t)
178+
push!(result.stats.maxmove,maxmove)
179+
push!(result.stats.maxdp,maxdp)
180+
triangle_qualities!(tris,triset,qualities,result.points,result.tetrahedra)
173181
sort!(qualities) # sort for median calc and robust summation
174182
mine, maxe = extrema(qualities)
175-
push!(statsdata.average_qual, sum(qualities)/length(qualities))
176-
push!(statsdata.median_qual, qualities[round(Int,length(qualities)/2)])
177-
push!(statsdata.minimum_qual, mine)
178-
push!(statsdata.maximum_qual, maxe)
183+
push!(result.stats.average_qual, sum(qualities)/length(qualities))
184+
push!(result.stats.median_qual, qualities[round(Int,length(qualities)/2)])
185+
push!(result.stats.minimum_qual, mine)
186+
push!(result.stats.maximum_qual, maxe)
179187
end
180188

181189
# Termination criterion
182190
if maxdp<setup.ptol*h
183-
return p, t, statsdata
191+
return result
184192
end
185193
end
186194
end

src/tetgen.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ function delaunayn_nosort(points)
1515
tetio
1616
end
1717

18-
function delaunayn!(fdist, p, t, geps, sorted_pts)
18+
function delaunayn!(fdist, result::DistMeshResult, geps, sorted_pts)
19+
t = result.tetrahedra
20+
p = result.points
1921
triangulation = sorted_pts ? delaunayn_nosort(p) : delaunayn(p)
2022
t_d = triangulation.tetrahedra
2123
resize!(t, length(t_d))

test/runtests.jl

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,30 +65,32 @@ end
6565

6666
@testset "distmesh 3D" begin
6767
d(p) = sqrt(sum(p.^2))-1
68-
p,t,_ = distmesh(d,HUniform(),0.2)
69-
@test length(p) == 485
70-
@test length(t) == 2207
68+
result = distmesh(d,HUniform(),0.2)
69+
@test length(result.points) == 485
70+
@test length(result.tetrahedra) == 2207
7171

72-
p,t,_ = distmesh(d,HUniform(),0.2, DistMeshSetup(distribution=:packed))
73-
@test length(p) == 742
74-
@test length(t) == 3472
72+
result = distmesh(d,HUniform(),0.2, DistMeshSetup(distribution=:packed))
73+
@test length(result.points) == 742
74+
@test length(result.tetrahedra) == 3472
7575

7676
# test stats is not messing
77-
p,t,s = distmesh(d,HUniform(),0.2, stats=true)
78-
@test length(p) == 485
79-
@test length(t) == 2207
77+
result = distmesh(d,HUniform(),0.2, stats=true)
78+
@test length(result.points) == 485
79+
@test length(result.tetrahedra) == 2207
8080

81-
p,t,s = distmesh(d,HUniform(),0.4, stats=true)
82-
@test length(p) == 56
83-
@test length(t) == 186
84-
for fn in fieldnames(typeof(s))
85-
@test isapprox(getproperty(s,fn), getproperty(stat_04,fn))
81+
result = distmesh(d,HUniform(),0.4, stats=true)
82+
@test length(result.points) == 56
83+
@test length(result.tetrahedra) == 186
84+
for fn in fieldnames(typeof(result.stats))
85+
@test isapprox(getproperty(result.stats,fn), getproperty(stat_04,fn))
8686
end
8787
end
8888

8989
@testset "dihedral metrics" begin
9090
d(p) = sqrt(sum(p.^2))-1
91-
p,t,_ = distmesh(d,HUniform(),0.2)
91+
result = distmesh(d,HUniform(),0.2)
92+
p = result.points
93+
t = result.tetrahedra
9294
all_angs = DistMesh.dihedral_angles(p,t)
9395
min_angs = DistMesh.min_dihedral_angles(p,t)
9496
ax = extrema(all_angs)

0 commit comments

Comments
 (0)