1+
2+ using Test
3+ using VortexStepMethod
4+ using VortexStepMethod: create_interpolations, find_circle_center_and_radius, calculate_inertia_tensor, calculate_com, read_faces
5+ using LinearAlgebra
6+
7+ @testset " KiteGeometry Tests" begin
8+ # Test data
9+ test_obj_path = joinpath (@__DIR__ , " data" , " test.obj" )
10+
11+ @testset " OBJ File Reading" begin
12+ # Create minimal test OBJ file
13+ test_vertices = """
14+ v 0.0 0.0 0.0
15+ v 1.0 0.0 0.0
16+ v 0.0 1.0 0.0
17+ f 1 2 3
18+ """
19+ write (test_obj_path, test_vertices)
20+
21+ vertices, faces = read_faces (test_obj_path)
22+
23+ @test length (vertices) == 3
24+ @test length (faces) == 1
25+ @test vertices[1 ] ≈ [0.0 , 0.0 , 0.0 ]
26+ @test vertices[2 ] ≈ [1.0 , 0.0 , 0.0 ]
27+ @test vertices[3 ] ≈ [0.0 , 1.0 , 0.0 ]
28+ @test faces[1 ] == [1 , 2 , 3 ]
29+ end
30+
31+ @testset " Center of Mass Calculation" begin
32+ vertices = [[0.0 , 0.0 , 0.0 ], [1.0 , 0.0 , 0.0 ], [0.0 , 1.0 , 0.0 ]]
33+ faces = [[1 , 2 , 3 ]]
34+
35+ com = calculate_com (vertices, faces)
36+ expected_com = [1 / 3 , 1 / 3 , 0.0 ]
37+
38+ @test isapprox (com, expected_com, rtol= 1e-5 )
39+ end
40+
41+ @testset " Inertia Tensor Calculation" begin
42+ vertices = [[0.0 , 0.0 , 0.0 ], [1.0 , 0.0 , 0.0 ], [0.0 , 1.0 , 0.0 ]]
43+ faces = [[1 , 2 , 3 ]]
44+ mass = 1.0
45+ com = [1 / 3 , 1 / 3 , 0.0 ]
46+
47+ I = calculate_inertia_tensor (vertices, faces, mass, com)
48+
49+ # Test properties of inertia tensor
50+ @test size (I) == (3 ,3 )
51+ @test isapprox (I, I' , rtol= 1e-10 ) # Symmetric
52+ @test all (diag (I) .≥ 0 ) # Non-negative diagonal
53+ end
54+
55+ @testset " Circle Fitting" begin
56+ # Create simple curved wing vertices
57+ r = 5.0
58+ z_center = 2.0
59+ vertices = []
60+ for θ in range (- π/ 4 , π/ 4 , length= 100 )
61+ push! (vertices, [0.0 , r* sin (θ), z_center + r* cos (θ)])
62+ end
63+
64+ z, radius, gamma_tip = find_circle_center_and_radius (vertices)
65+
66+ @test isapprox (z, z_center, rtol= 1e-2 )
67+ @test isapprox (radius, r, rtol= 1e-2 )
68+ @test gamma_tip ≈ - π/ 4 rtol= 1e-2
69+ end
70+
71+ @testset " Interpolation Creation" begin
72+ vertices = []
73+ r = 5.0
74+ z_center = 2.0
75+ for θ in range (- π/ 4 , π/ 4 , length= 10 )
76+ push! (vertices, [0.0 , r* sin (θ), z_center + r* cos (θ)])
77+ push! (vertices, [1.0 , r* sin (θ), z_center + r* cos (θ)])
78+ end
79+
80+ le_interp, te_interp, area_interp, gammas, max_xs, min_xs =
81+ create_interpolations (vertices, z_center, r, π/ 4 )
82+
83+ # Test interpolation at middle point
84+ @test le_interp (0.0 ) ≈ 0.0 rtol= 1e-2
85+ @test te_interp (0.0 ) ≈ 1.0 rtol= 1e-2
86+ end
87+
88+ @testset " KiteWing Construction" begin
89+ # Create minimal test wing
90+ wing = KiteWing (test_obj_path)
91+
92+ @test wing. n_panels == 54 # Default value
93+ @test wing. spanwise_panel_distribution == " linear"
94+ @test wing. spanwise_direction ≈ [0.0 , 1.0 , 0.0 ]
95+ @test isempty (wing. sections)
96+ @test wing. mass ≈ 1.0
97+ @test length (wing. center_of_mass) == 3
98+ @test typeof (wing. le_interp) <: Function
99+ @test typeof (wing. te_interp) <: Function
100+ @test typeof (wing. area_interp) <: Function
101+ end
102+
103+ @testset " Section Addition" begin
104+ wing = KiteWing (test_obj_path)
105+ gamma = 0.0
106+ aero_input = " inviscid"
107+
108+ add_section! (wing, gamma, aero_input)
109+
110+ @test length (wing. sections) == 1
111+ @test wing. sections[1 ]. aero_input == aero_input
112+ end
113+
114+ rm (test_obj_path)
115+ end
0 commit comments