Mercurial > repos > public > sbplib_julia
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 |
