Skip to content

Commit 1f83c7a

Browse files
committed
Migrate F3OF DT1 and DT2 tests from demos to new regression test suite & ensure consistent formatting
1 parent 3d1f277 commit 1f83c7a

8 files changed

Lines changed: 30817 additions & 3 deletions

File tree

tests/regression/CMakeLists.txt

Lines changed: 163 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,176 @@ if(TARGET sphere_decay_test)
7979
)
8080
endif()
8181

82-
# F3OF DT3 Regression Test
82+
# F3OF DT1 Regression Test
8383
# ========================
8484

8585
# Create executable in model-based directory
86-
add_executable(f3of_dt3_test)
86+
add_executable(f3of_dt1_test)
8787

8888
set(F3OF_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/f3of)
8989
set(F3OF_RELEASE_DIR ${CMAKE_BINARY_DIR}/tests/regression/Release/f3of)
9090
set(F3OF_RESULTS_DIR ${F3OF_RELEASE_DIR}/results)
9191

92+
# Use model-based source and let simulation create results automatically
93+
set_target_properties(f3of_dt1_test
94+
PROPERTIES
95+
RUNTIME_OUTPUT_DIRECTORY ${F3OF_RELEASE_DIR}
96+
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${F3OF_RELEASE_DIR}
97+
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${F3OF_RELEASE_DIR}
98+
)
99+
100+
target_sources(
101+
f3of_dt1_test
102+
PRIVATE
103+
${F3OF_SRC_DIR}/f3of_dt1_test.cpp
104+
)
105+
106+
if(HYDROCHRONO_ENABLE_IRRLICHT)
107+
target_compile_definitions(f3of_dt1_test
108+
PRIVATE
109+
HYDROCHRONO_HAVE_IRRLICHT=1
110+
"CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\""
111+
)
112+
endif()
113+
114+
target_include_directories(
115+
f3of_dt1_test
116+
PRIVATE
117+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src
118+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/gui
119+
)
120+
121+
target_link_libraries(
122+
f3of_dt1_test
123+
PRIVATE
124+
HydroChrono
125+
HydroChronoGUI
126+
)
127+
128+
# Register as CTest test
129+
if(TARGET f3of_dt1_test)
130+
# Copy test data to the output directory
131+
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data DESTINATION ${CMAKE_BINARY_DIR}/tests/regression/Release)
132+
133+
add_test(
134+
NAME f3of_dt1_regression
135+
COMMAND ${F3OF_RELEASE_DIR}/f3of_dt1_test.exe ${HYDROCHRONO_DATA_DIR} --nogui
136+
)
137+
138+
set_tests_properties(
139+
f3of_dt1_regression
140+
PROPERTIES
141+
LABELS "regression;f3of;dt1;decay;core"
142+
FIXTURES_SETUP f3of_dt1_regression_file
143+
WORKING_DIRECTORY ${F3OF_RELEASE_DIR}
144+
ENVIRONMENT "${TEST_ENVIRONMENT}"
145+
)
146+
147+
# Reference comparison test - use the new centralized reference data location
148+
set(FILE_RST ${F3OF_RESULTS_DIR}/CHRONO_F3OF_DT1_SURGE.txt)
149+
set(FILE_REF ${CMAKE_SOURCE_DIR}/tests/regression/reference_data/f3of/dt1/hydrochrono_f3of_dt1_surge.txt)
150+
151+
add_test(
152+
NAME f3of_dt1_regression_ref
153+
COMMAND python ${CMAKE_SOURCE_DIR}/tests/regression/f3of/compare_dt1.py
154+
)
155+
156+
set_tests_properties(
157+
f3of_dt1_regression_ref
158+
PROPERTIES
159+
LABELS "regression;f3of;dt1;decay;reference;core"
160+
FIXTURES_REQUIRED f3of_dt1_regression_file
161+
WORKING_DIRECTORY ${F3OF_RELEASE_DIR}
162+
ENVIRONMENT "PATH=${Python3_ROOT_DIR};$ENV{PATH};HYDROCHRONO_BUILD_DIR=${CMAKE_BINARY_DIR}"
163+
)
164+
endif()
165+
166+
# F3OF DT2 Regression Test
167+
# ========================
168+
169+
# Create executable in model-based directory
170+
add_executable(f3of_dt2_test)
171+
172+
# Use model-based source and let simulation create results automatically
173+
set_target_properties(f3of_dt2_test
174+
PROPERTIES
175+
RUNTIME_OUTPUT_DIRECTORY ${F3OF_RELEASE_DIR}
176+
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${F3OF_RELEASE_DIR}
177+
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${F3OF_RELEASE_DIR}
178+
)
179+
180+
target_sources(
181+
f3of_dt2_test
182+
PRIVATE
183+
${F3OF_SRC_DIR}/f3of_dt2_test.cpp
184+
)
185+
186+
if(HYDROCHRONO_ENABLE_IRRLICHT)
187+
target_compile_definitions(f3of_dt2_test
188+
PRIVATE
189+
HYDROCHRONO_HAVE_IRRLICHT=1
190+
"CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\""
191+
)
192+
endif()
193+
194+
target_include_directories(
195+
f3of_dt2_test
196+
PRIVATE
197+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src
198+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/gui
199+
)
200+
201+
target_link_libraries(
202+
f3of_dt2_test
203+
PRIVATE
204+
HydroChrono
205+
HydroChronoGUI
206+
)
207+
208+
# Register as CTest test
209+
if(TARGET f3of_dt2_test)
210+
# Copy test data to the output directory
211+
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data DESTINATION ${CMAKE_BINARY_DIR}/tests/regression/Release)
212+
213+
add_test(
214+
NAME f3of_dt2_regression
215+
COMMAND ${F3OF_RELEASE_DIR}/f3of_dt2_test.exe ${HYDROCHRONO_DATA_DIR} --nogui
216+
)
217+
218+
set_tests_properties(
219+
f3of_dt2_regression
220+
PROPERTIES
221+
LABELS "regression;f3of;dt2;decay;core"
222+
FIXTURES_SETUP f3of_dt2_regression_file
223+
WORKING_DIRECTORY ${F3OF_RELEASE_DIR}
224+
ENVIRONMENT "${TEST_ENVIRONMENT}"
225+
)
226+
227+
# Reference comparison test - use the new centralized reference data location
228+
set(FILE_RST ${F3OF_RESULTS_DIR}/CHRONO_F3OF_DT2_PITCH.txt)
229+
set(FILE_REF ${CMAKE_SOURCE_DIR}/tests/regression/reference_data/f3of/dt2/hydrochrono_f3of_dt2_pitch.txt)
230+
231+
add_test(
232+
NAME f3of_dt2_regression_ref
233+
COMMAND python ${CMAKE_SOURCE_DIR}/tests/regression/f3of/compare_dt2.py
234+
)
235+
236+
set_tests_properties(
237+
f3of_dt2_regression_ref
238+
PROPERTIES
239+
LABELS "regression;f3of;dt2;decay;reference;core"
240+
FIXTURES_REQUIRED f3of_dt2_regression_file
241+
WORKING_DIRECTORY ${F3OF_RELEASE_DIR}
242+
ENVIRONMENT "PATH=${Python3_ROOT_DIR};$ENV{PATH};HYDROCHRONO_BUILD_DIR=${CMAKE_BINARY_DIR}"
243+
)
244+
endif()
245+
246+
# F3OF DT3 Regression Test
247+
# ========================
248+
249+
# Create executable in model-based directory
250+
add_executable(f3of_dt3_test)
251+
92252
# Use model-based source and let simulation create results automatically
93253
set_target_properties(f3of_dt3_test
94254
PROPERTIES
@@ -146,7 +306,7 @@ if(TARGET f3of_dt3_test)
146306

147307
# Reference comparison test - use the new centralized reference data location
148308
set(FILE_RST ${F3OF_RESULTS_DIR}/f3of_dt3.txt)
149-
set(FILE_REF ${CMAKE_SOURCE_DIR}/tests/regression/reference_data/f3of/dt3/f3of_dt3_hc_data.txt)
309+
set(FILE_REF ${CMAKE_SOURCE_DIR}/tests/regression/reference_data/f3of/dt3/hydrochrono_f3of_dt3_flap_pitch.txt)
150310

151311
add_test(
152312
NAME f3of_dt3_regression_ref
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env python3
2+
"""
3+
F3OF DT1 Regression Test Comparison Script
4+
5+
This script compares HydroChrono results for F3OF DT1 (surge decay test)
6+
against reference data from the demos folder.
7+
"""
8+
9+
import sys
10+
import os
11+
from pathlib import Path
12+
import numpy as np
13+
14+
# Import the comparison template
15+
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
16+
from compare_template import create_comparison_plot
17+
18+
def main():
19+
# F3OF DT1 specific configuration
20+
test_name = "F3OF DT1 Surge Decay"
21+
executable_patterns = ["f3of_dt1_test", "f3of_dt1_test.exe"]
22+
23+
# Data files - use absolute paths
24+
hc_data_file = "results/CHRONO_F3OF_DT1_SURGE.txt"
25+
ref_data_file = os.path.join(os.path.dirname(__file__), "..", "reference_data", "f3of", "dt1", "hydrochrono_f3of_dt1_surge.txt")
26+
27+
# Check if files exist
28+
if not os.path.exists(hc_data_file):
29+
print(f"Error: Test data file not found: {hc_data_file}")
30+
sys.exit(1)
31+
32+
if not os.path.exists(ref_data_file):
33+
print(f"Error: Reference data file not found: {ref_data_file}")
34+
sys.exit(1)
35+
36+
try:
37+
# Load data for validation
38+
ref_data = np.loadtxt(ref_data_file, skiprows=1)
39+
test_data = np.loadtxt(hc_data_file, skiprows=1)
40+
41+
# Extract surge column (column 1) for comparison
42+
ref_surge_data = np.column_stack((ref_data[:, 0], ref_data[:, 1])) # time, surge
43+
test_surge_data = np.column_stack((test_data[:, 0], test_data[:, 1])) # time, surge
44+
45+
# Show where the plots will be saved
46+
test_file_path = Path(hc_data_file)
47+
plots_dir = test_file_path.parent / "plots"
48+
plots_dir.mkdir(parents=True, exist_ok=True)
49+
print(f"Plots will be saved to: {plots_dir}")
50+
51+
# Find the executable path
52+
executable_path = None
53+
if executable_patterns:
54+
from compare_template import find_executable
55+
executable_path = find_executable(test_file_path.parent, executable_patterns)
56+
57+
# Generate comparison plot
58+
def rel_to_root(path):
59+
try:
60+
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../..'))
61+
return os.path.relpath(path, project_root)
62+
except Exception:
63+
return str(path)
64+
65+
n1, n2 = create_comparison_plot(
66+
ref_surge_data, test_surge_data, test_name, plots_dir,
67+
ref_file_path=rel_to_root(ref_data_file),
68+
test_file_path=rel_to_root(hc_data_file),
69+
executable_path=rel_to_root(str(executable_path)) if executable_path else None,
70+
y_label="Base Surge (m)",
71+
executable_patterns=executable_patterns
72+
)
73+
74+
# Additional F3OF-specific validations
75+
76+
# Check base surge (column 1)
77+
diff_base_surge = np.linalg.norm(ref_data[:,1] - test_data[:,1]) / len(ref_data[:,1])
78+
if diff_base_surge > 1e-6:
79+
print(f"F3OF DT1 validation failed: Base surge difference {diff_base_surge:.2e} > 1e-6")
80+
sys.exit(1)
81+
82+
# Check base pitch (column 2) - should be zero for DT1
83+
diff_base_pitch = np.linalg.norm(ref_data[:,2] - test_data[:,2]) / len(ref_data[:,2])
84+
if diff_base_pitch > 1e-10:
85+
print(f"F3OF DT1 validation failed: Base pitch difference {diff_base_pitch:.2e} > 1e-10")
86+
sys.exit(1)
87+
88+
# Check flap fore pitch (column 3) - should be zero for DT1
89+
diff_flap_fore_pitch = np.linalg.norm(ref_data[:,3] - test_data[:,3]) / len(ref_data[:,3])
90+
if diff_flap_fore_pitch > 1e-10:
91+
print(f"F3OF DT1 validation failed: Flap fore pitch difference {diff_flap_fore_pitch:.2e} > 1e-10")
92+
sys.exit(1)
93+
94+
# Check flap aft pitch (column 4) - should be zero for DT1
95+
diff_flap_aft_pitch = np.linalg.norm(ref_data[:,4] - test_data[:,4]) / len(ref_data[:,4])
96+
if diff_flap_aft_pitch > 1e-10:
97+
print(f"F3OF DT1 validation failed: Flap aft pitch difference {diff_flap_aft_pitch:.2e} > 1e-10")
98+
sys.exit(1)
99+
100+
# Check template comparison results
101+
l2_threshold, linf_threshold = 1e-6, 1e-6
102+
if (n1 > l2_threshold or n2 > linf_threshold):
103+
print(f"F3OF DT1 TEST FAILED - L2 Norm: {n1:.2e}, L-infinity Norm: {n2:.2e}")
104+
sys.exit(1)
105+
else:
106+
print(f"F3OF DT1 TEST PASSED - L2 Norm: {n1:.2e}, L-infinity Norm: {n2:.2e}")
107+
print(f"Generated plot: {plots_dir}/{test_name.replace(' ', '_')}_comparison.png")
108+
109+
except Exception as e:
110+
print(f"Error during comparison: {e}")
111+
sys.exit(1)
112+
113+
if __name__ == "__main__":
114+
main()

0 commit comments

Comments
 (0)