comparison test/Grids/geometry_test.jl @ 2079:118c09b168f5 default tip

Merge feature/grids/geometry_functions
author Jonatan Werpers <jonatan@werpers.com>
date Wed, 18 Feb 2026 21:33:00 +0100
parents c36812de3f2d
children
comparison
equal deleted inserted replaced
2067:a8ea4f94f3c4 2079:118c09b168f5
1 using Diffinitive.Grids
2 using Diffinitive.Grids: Line, LineSegment, linesegments, polygon_edges, Circle, TransfiniteInterpolationSurface, check_transfiniteinterpolation, arc, Arc
3 using StaticArrays
4
5 @testset "Line" begin
6 @testset "Constructors" begin
7 @test Line([1,2],[2,3]) isa Line{SVector{2,Int}}
8 @test Line((1,2),(2,3)) isa Line{SVector{2,Int}}
9 @test Line(@SVector[1,2],[2,3]) isa Line{SVector{2,Int}}
10 @test Line(@SVector[1,2],@SVector[2,3]) isa Line{SVector{2,Int}}
11
12 @test Line([1,2],[2.,3]) isa Line{SVector{2,Float64}}
13 @test Line(@SVector[1,2.],@SVector[2,3]) isa Line{SVector{2,Float64}}
14 @test Line((1,2.),(2,3)) isa Line{SVector{2,Float64}}
15 end
16
17 @testset "Evaluation" begin
18 l = Line([1,2],[2,3])
19
20 @test l(0) == [1,2]
21 @test l(1) == [1,2] + [2,3]
22 @test l(1/2) == [1,2] + [2,3]/2
23 end
24
25 @testset "Grids.jacobian" begin
26 l = Line([1,2],[2,3])
27
28 @test Grids.jacobian(l,0) == [2,3]
29 @test Grids.jacobian(l,1) == [2,3]
30 @test Grids.jacobian(l,1/2) == [2,3]
31 end
32 end
33
34 @testset "LineSegment" begin
35 @testset "Constructors" begin
36 @test LineSegment([1,2],[2,3]) isa LineSegment{SVector{2,Int}}
37 @test LineSegment((1,2),(2,3)) isa LineSegment{SVector{2,Int}}
38 @test LineSegment(@SVector[1,2],[2,3]) isa LineSegment{SVector{2,Int}}
39 @test LineSegment(@SVector[1,2],@SVector[2,3]) isa LineSegment{SVector{2,Int}}
40
41 @test LineSegment([1,2],[2.,3]) isa LineSegment{SVector{2,Float64}}
42 @test LineSegment(@SVector[1,2.],@SVector[2,3]) isa LineSegment{SVector{2,Float64}}
43 @test LineSegment((1,2.),(2,3)) isa LineSegment{SVector{2,Float64}}
44 end
45
46 @testset "Evaluation" begin
47 l = LineSegment([1,2],[2,3])
48
49 @test l(0) == [1,2]
50 @test l(1) == [2,3]
51 @test l(1/2) == [1,2]/2 + [2,3]/2
52 end
53
54 @testset "Grids.jacobian" begin
55 a, b = [1,2], [2,3]
56 l = LineSegment(a,b)
57 d = b-a
58
59 @test Grids.jacobian(l,0) == d
60 @test Grids.jacobian(l,1) == d
61 @test Grids.jacobian(l,1/2) == d
62 end
63 end
64
65 @testset "linesegments" begin
66 a,b,c,d = [1,1],[2,2],[3,3],[4,4]
67 @test linesegments(a,b) == [
68 LineSegment(a,b),
69 ]
70
71 @test linesegments(a,b,c) == [
72 LineSegment(a,b),
73 LineSegment(b,c),
74 ]
75
76 @test linesegments(a,b,c,d) == [
77 LineSegment(a,b),
78 LineSegment(b,c),
79 LineSegment(c,d),
80 ]
81 end
82
83 @testset "polygon_edges" begin
84 a,b,c,d = [1,1],[2,2],[3,3],[4,4]
85 @test polygon_edges(a,b) == [
86 LineSegment(a,b),
87 LineSegment(b,a),
88 ]
89
90 @test polygon_edges(a,b,c) == [
91 LineSegment(a,b),
92 LineSegment(b,c),
93 LineSegment(c,a),
94 ]
95
96 @test polygon_edges(a,b,c,d) == [
97 LineSegment(a,b),
98 LineSegment(b,c),
99 LineSegment(c,d),
100 LineSegment(d,a),
101 ]
102 end
103
104 @testset "Circle" begin
105 @testset "Constructors" begin
106 @test Circle([1,2], 1) isa Circle{SVector{2,Int},Int}
107 @test Circle([1,2], 1.) isa Circle{SVector{2,Int},Float64}
108 @test Circle([1,2.], 1.) isa Circle{SVector{2,Float64},Float64}
109 @test Circle([1,2.], 1) isa Circle{SVector{2,Float64},Int}
110 @test Circle((1,2.), 1.) isa Circle{SVector{2,Float64},Float64}
111 @test Circle((1,2), 1.) isa Circle{SVector{2,Int},Float64}
112 @test Circle((1.,2), 1) isa Circle{SVector{2,Float64},Int}
113 @test Circle((1,2), 1) isa Circle{SVector{2,Int},Int}
114 @test Circle(@SVector[1,2], 1.) isa Circle{SVector{2,Int},Float64}
115 @test Circle(@SVector[1,2.], 1.) isa Circle{SVector{2,Float64},Float64}
116 end
117
118 @testset "Evaluation" begin
119 c = Circle([0,0], 1)
120 @test c(0) ≈ [1,0]
121 @test c(π/2) ≈ [0,1]
122 @test c(π) ≈ [-1,0]
123 @test c(3π/2) ≈ [0,-1]
124 @test c(π/4) ≈ [1/√(2),1/√(2)]
125
126 c = Circle([0,0], 2)
127 @test c(0) ≈ [2,0]
128 @test c(π/2) ≈ [0,2]
129 @test c(π) ≈ [-2,0]
130 @test c(3π/2) ≈ [0,-2]
131 @test c(π/4) ≈ [√(2),√(2)]
132 end
133
134 @testset "Grids.jacobian" begin
135 c = Circle([0,0], 1)
136 @test Grids.jacobian(c, 0) ≈ [0,1]
137 @test Grids.jacobian(c, π/2) ≈ [-1,0]
138 @test Grids.jacobian(c, π) ≈ [0,-1]
139 @test Grids.jacobian(c, 3π/2) ≈ [1,0]
140 @test Grids.jacobian(c, π/4) ≈ [-1/√(2),1/√(2)]
141
142 c = Circle([0,0], 2)
143 @test Grids.jacobian(c, 0) ≈ [0,2]
144 @test Grids.jacobian(c, π/2) ≈ [-2,0]
145 @test Grids.jacobian(c, π) ≈ [0,-2]
146 @test Grids.jacobian(c, 3π/2) ≈ [2,0]
147 @test Grids.jacobian(c, π/4) ≈ [-√(2),√(2)]
148
149 c = Circle([-1,1], 1)
150 @test Grids.jacobian(c, 0) ≈ [0,1]
151 @test Grids.jacobian(c, π/2) ≈ [-1,0]
152 @test Grids.jacobian(c, π) ≈ [0,-1]
153 @test Grids.jacobian(c, 3π/2) ≈ [1,0]
154 @test Grids.jacobian(c, π/4) ≈ [-1/√(2),1/√(2)]
155
156 c = Circle([-1,1], 2)
157 @test Grids.jacobian(c, 0) ≈ [0,2]
158 @test Grids.jacobian(c, π/2) ≈ [-2,0]
159 @test Grids.jacobian(c, π) ≈ [0,-2]
160 @test Grids.jacobian(c, 3π/2) ≈ [2,0]
161 @test Grids.jacobian(c, π/4) ≈ [-√(2),√(2)]
162 end
163 end
164
165 @testset "Arc" begin
166 @test Arc(Circle([0,0], 1), 0, 1) isa Arc{SVector{2,Int}, Int}
167 @test Arc(Circle([0,0], 1.), 0, 1) isa Arc{SVector{2,Int}, Float64}
168 @test Arc(Circle([1., 1.], 1), 0., 1.) isa Arc{SVector{2,Float64}, Float64}
169 @test Arc(Circle([1., 1.], 1), 0, 1) isa Arc{SVector{2,Float64}, Int}
170 @test Arc(Circle([1., 1.], 1), 0, 1.) isa Arc{SVector{2,Float64}, Float64}
171
172 a = Arc(Circle([0,0], 1), 0, π/2)
173 @test a(0) ≈ [1,0]
174 @test a(1/3) ≈ [√(3)/2,1/2]
175 @test a(1/2) ≈ [1/√(2),1/√(2)]
176 @test a(2/3) ≈ [1/2, √(3)/2]
177 @test a(1) ≈ [0,1]
178
179 @testset "Grids.jacobian" begin
180 c = Circle([0,0], 1)
181
182 @testset "Matched to circle" begin
183 a = Arc(c, 0, 1)
184 @testset for t ∈ range(0,1,8)
185 @test jacobian(a,t) ≈ jacobian(c,t)
186 end
187 end
188
189 @testset "Full circle" begin
190 a = Arc(c, 0, 2π)
191 @testset for t ∈ range(0,1,8)
192 @test jacobian(a,t) ≈ 2π*jacobian(c,t)
193 end
194 end
195
196 @testset "Other" begin
197 a = Arc(c, π/3, 5π/4)
198 @testset for t ∈ range(0,1,8)
199 @test jacobian(a,t) ≈ 11π/12*jacobian(c,t)
200 end
201 end
202 end
203 end
204
205 @testset "arc" begin
206 @testset "Half circles around [0.5, 0.0]" begin
207 a = [0,0]
208 b = [1,0]
209
210 A = arc(a,b,1/2)
211 @test A(0) ≈ a atol=1e-15
212 @test A(1) ≈ b
213 @test A(0.5) ≈ [0.5, -0.5]
214
215 A = arc(a,b,-1/2)
216 @test A(0) ≈ a atol=1e-15
217 @test A(1) ≈ b
218 @test A(0.5) ≈ [0.5, 0.5]
219 end
220
221 @testset "Unit arc" begin
222 A = arc([1,0],[0,1],1)
223 @test A(0) ≈ [1,0]
224 @test A(1) ≈ [0,1]
225 @testset for t ∈ range(0,1,13)
226 @test A(t) ≈ [cos(t*π/2), sin(t*π/2)]
227 end
228 end
229
230 @testset "Inverted unit arc" begin
231 A = arc([1,0],[0,1],-1)
232 @test A(0) ≈ [1,0]
233 @test A(1) ≈ [0,1]
234 @testset "Inverted unit arc t=$t" for t ∈ range(0,1,13)
235 @test A(t) ≈ [1+cos(-π/2 - t*π/2), 1+sin(-π/2 - t*π/2)]
236 end
237 end
238
239 @testset "Quarters of unit circle" begin
240 unitvec(θ) = [cos(θ), sin(θ)]
241 @testset "θ ∈ ($(i)π/4, $(i+2)π/4)" for i ∈ range(0, step=1, length=8)
242 θ = i*π/4
243 @testset let θ₀ = θ, θ₁ = θ+π/2, r = 1
244 A = arc(unitvec(θ₀), unitvec(θ₁), r)
245 @test A(0) ≈ unitvec(θ)
246 @test A(1/3) ≈ unitvec(θ+π/6)
247 @test A(1/2) ≈ unitvec(θ+π/4)
248 @test A(2/3) ≈ unitvec(θ+π/3)
249 @test A(1) ≈ unitvec(θ+π/2)
250 end
251
252 @testset let θ₀ = θ+π/2, θ₁ = θ, r = -1
253 A = arc(unitvec(θ₀), unitvec(θ₁), r)
254 @test A(0) ≈ unitvec(θ+π/2)
255 @test A(1/3) ≈ unitvec(θ+π/3)
256 @test A(1/2) ≈ unitvec(θ+π/4)
257 @test A(2/3) ≈ unitvec(θ+π/6)
258 @test A(1) ≈ unitvec(θ)
259 end
260 end
261 end
262
263 @test_throws DomainError arc([-1,0], [1,0], 0.7)
264 end
265
266 @testset "TransfiniteInterpolationSurface" begin
267 @testset "Constructors" begin
268 @test TransfiniteInterpolationSurface(t->[1,2], t->[2,1], t->[0,0], t->[1,1]) isa TransfiniteInterpolationSurface
269
270 cs = polygon_edges([0,0],[1,0],[1,1],[0,1])
271 @test TransfiniteInterpolationSurface(cs...) isa TransfiniteInterpolationSurface
272 end
273
274 @testset "Evaluation" begin
275 cs = polygon_edges([0,0],[1,0],[1,1],[0,1])
276 ti = TransfiniteInterpolationSurface(cs...)
277
278 @test ti(0,0) == [0,0]
279 @test ti([0,0]) == [0,0]
280 @test ti(1,0) == [1,0]
281 @test ti([1,0]) == [1,0]
282 @test ti(1,1) == [1,1]
283 @test ti([1,1]) == [1,1]
284 @test ti(0,1) == [0,1]
285 @test ti([0,1]) == [0,1]
286
287 @test ti(1/2, 0) == [1/2, 0]
288 @test ti(1/2, 1) == [1/2, 1]
289 @test ti(0,1/2) == [0,1/2]
290 @test ti(1,1/2) == [1,1/2]
291
292
293 a, b, c, d = [1,0],[2,1/4],[2.5,1],[-1/3,1]
294 cs = polygon_edges(a,b,c,d)
295 ti = TransfiniteInterpolationSurface(cs...)
296
297 @test ti(0,0) == a
298 @test ti(1,0) == b
299 @test ti(1,1) == c
300 @test ti(0,1) == d
301
302 @test ti(1/2, 0) == (a+b)/2
303 @test ti(1/2, 1) == (c+d)/2
304 @test ti(0, 1/2) == (a+d)/2
305 @test ti(1, 1/2) == (b+c)/2
306
307 a, b, c, d = [0,0],[1,1/2],[1,3/2],[0,1]
308 ti = TransfiniteInterpolationSurface(
309 t->@SVector[t, t^2/2],
310 LineSegment(b,c),
311 LineSegment(c,d),
312 LineSegment(d,a),
313 )
314
315 @test ti(0,0) == a
316 @test ti(1,0) == b
317 @test ti(1,1) == c
318 @test ti(0,1) == d
319
320 @test ti(1/2, 0) == [1/2, 1/8]
321 @test ti(1/2, 1) == (c+d)/2
322 @test ti(0, 1/2) == (a+d)/2
323 @test ti(1, 1/2) == (b+c)/2
324
325 @testset "Out of domain error" begin
326 @test_throws DomainError ti(-0.1, 0)
327 @test_throws DomainError ti(1.1, 0)
328 @test_throws DomainError ti(0, -0.1)
329 @test_throws DomainError ti(0, 1.1)
330 @test_throws DomainError ti(1.1, -0.1)
331 end
332 end
333
334 @testset "check_transfiniteinterpolation" begin
335 cs = polygon_edges([0,0],[1,0],[1,1],[0,1])
336 ti = TransfiniteInterpolationSurface(cs...)
337
338 @test check_transfiniteinterpolation(ti) == nothing
339 @test check_transfiniteinterpolation(Bool, ti) == true
340
341 bad_sides = [
342 LineSegment([0,0],[1/2,0]),
343 LineSegment([1,0],[1,1/2]),
344 LineSegment([1,1],[0,1/2]),
345 LineSegment([0,1],[0,1/2]),
346 ]
347
348 s1 = TransfiniteInterpolationSurface(bad_sides[1],cs[2],cs[3],cs[4])
349 s2 = TransfiniteInterpolationSurface(cs[1],bad_sides[2],cs[3],cs[4])
350 s3 = TransfiniteInterpolationSurface(cs[1],cs[2],bad_sides[3],cs[4])
351 s4 = TransfiniteInterpolationSurface(cs[1],cs[2],cs[3],bad_sides[4])
352
353 @test check_transfiniteinterpolation(Bool, s1) == false
354 @test check_transfiniteinterpolation(Bool, s2) == false
355 @test check_transfiniteinterpolation(Bool, s3) == false
356 @test check_transfiniteinterpolation(Bool, s4) == false
357
358 @test_throws ArgumentError check_transfiniteinterpolation(s1)
359 @test_throws ArgumentError check_transfiniteinterpolation(s2)
360 @test_throws ArgumentError check_transfiniteinterpolation(s3)
361 @test_throws ArgumentError check_transfiniteinterpolation(s4)
362 end
363
364 @testset "Grids.jacobian" begin
365 cs = polygon_edges([0,0],[1,0],[1,1],[0,1])
366 ti = TransfiniteInterpolationSurface(cs...)
367
368 @test Grids.jacobian(ti, [0,0]) isa SMatrix
369
370 @test Grids.jacobian(ti, [0,0]) == [1 0; 0 1]
371 @test Grids.jacobian(ti, [1,0]) == [1 0; 0 1]
372 @test Grids.jacobian(ti, [1,1]) == [1 0; 0 1]
373 @test Grids.jacobian(ti, [0,1]) == [1 0; 0 1]
374
375 @test Grids.jacobian(ti, [1/2, 0]) == [1 0; 0 1]
376 @test Grids.jacobian(ti, [1/2, 1]) == [1 0; 0 1]
377 @test Grids.jacobian(ti, [0,1/2]) == [1 0; 0 1]
378 @test Grids.jacobian(ti, [1,1/2]) == [1 0; 0 1]
379
380
381 a, b, c, d = [1,0],[2,1/4],[2.5,1],[-1/3,1]
382 cs = polygon_edges(a,b,c,d)
383 ti = TransfiniteInterpolationSurface(cs...)
384
385 @test Grids.jacobian(ti, [0,0]) == [b-a d-a]
386 @test Grids.jacobian(ti, [1,0]) == [b-a c-b]
387 @test Grids.jacobian(ti, [1,1]) == [c-d c-b]
388 @test Grids.jacobian(ti, [0,1]) == [c-d d-a]
389
390
391 mid(x,y) = (x+y)/2
392 @test Grids.jacobian(ti, [1/2, 0]) ≈ [b-a mid(c,d)-mid(a,b)]
393 @test Grids.jacobian(ti, [1/2, 1]) ≈ [c-d mid(c,d)-mid(a,b)]
394 @test Grids.jacobian(ti, [0, 1/2]) ≈ [mid(b,c)-mid(a,d) d-a]
395 @test Grids.jacobian(ti, [1, 1/2]) ≈ [mid(b,c)-mid(a,d) c-b]
396
397 @testset "Out of domain error" begin
398 @test_throws DomainError Grids.jacobian(ti, [-0.1, 0])
399 @test_throws DomainError Grids.jacobian(ti, [1.1, 0])
400 @test_throws DomainError Grids.jacobian(ti, [0, -0.1])
401 @test_throws DomainError Grids.jacobian(ti, [0, 1.1])
402 @test_throws DomainError Grids.jacobian(ti, [1.1, -0.1])
403 end
404 end
405 end