Skip to content

Commit 7c4f714

Browse files
committed
Enhance regression suite: migrate more tests, unify reference data, and improve plotting
- Migrated additional test cases (including sphere regular/irregular) into the regression suite for automated validation. - Standardized reference data file naming convention to use the `hc_ref_` prefix for all relevant tests (sphere, F3OF, etc.), improving clarity and consistency. - Updated and replaced outdated reference data files with results from the latest simulations to ensure up-to-date comparisons. - Fixed comparison scripts to search for result files in the build directory, resolving issues with missing or misplaced outputs. - Generated and saved comparison plots for all migrated tests, ensuring visual validation is available for regular, irregular, and decay cases. - Improved plot info panels: renamed "Simulation File" to "Latest File" and shortened file paths for better readability. - Added or updated comparison scripts (e.g., for F3OF DT3) to support new file locations and naming conventions. - Confirmed all regression tests pass and generate correct plots.
1 parent 1f83c7a commit 7c4f714

29 files changed

Lines changed: 563803 additions & 21 deletions

tests/regression/CMakeLists.txt

Lines changed: 246 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ if(TARGET f3of_dt1_test)
146146

147147
# Reference comparison test - use the new centralized reference data location
148148
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)
149+
set(FILE_REF ${CMAKE_SOURCE_DIR}/tests/regression/reference_data/f3of/dt1/hc_ref_f3of_dt1_surge.txt)
150150

151151
add_test(
152152
NAME f3of_dt1_regression_ref
@@ -226,7 +226,7 @@ if(TARGET f3of_dt2_test)
226226

227227
# Reference comparison test - use the new centralized reference data location
228228
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)
229+
set(FILE_REF ${CMAKE_SOURCE_DIR}/tests/regression/reference_data/f3of/dt2/hc_ref_f3of_dt2_pitch.txt)
230230

231231
add_test(
232232
NAME f3of_dt2_regression_ref
@@ -306,7 +306,7 @@ if(TARGET f3of_dt3_test)
306306

307307
# Reference comparison test - use the new centralized reference data location
308308
set(FILE_RST ${F3OF_RESULTS_DIR}/f3of_dt3.txt)
309-
set(FILE_REF ${CMAKE_SOURCE_DIR}/tests/regression/reference_data/f3of/dt3/hydrochrono_f3of_dt3_flap_pitch.txt)
309+
set(FILE_REF ${CMAKE_SOURCE_DIR}/tests/regression/reference_data/f3of/dt3/hc_ref_f3of_dt3_flap_pitch.txt)
310310

311311
add_test(
312312
NAME f3of_dt3_regression_ref
@@ -321,4 +321,247 @@ if(TARGET f3of_dt3_test)
321321
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/regression/f3of
322322
ENVIRONMENT "PATH=${Python3_ROOT_DIR};$ENV{PATH};HYDROCHRONO_BUILD_DIR=${CMAKE_BINARY_DIR}"
323323
)
324+
endif()
325+
326+
# Sphere Regular Waves Regression Test
327+
# ===================================
328+
329+
# Create executable in model-based directory
330+
add_executable(sphere_reg_waves_test)
331+
332+
set(SPHERE_REG_WAVES_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sphere/reg_waves)
333+
set(SPHERE_REG_WAVES_RELEASE_DIR ${CMAKE_BINARY_DIR}/tests/regression/Release/sphere/reg_waves)
334+
set(SPHERE_REG_WAVES_RESULTS_DIR ${SPHERE_REG_WAVES_RELEASE_DIR}/results)
335+
336+
# Use model-based source and let simulation create results automatically
337+
set_target_properties(sphere_reg_waves_test
338+
PROPERTIES
339+
RUNTIME_OUTPUT_DIRECTORY ${SPHERE_REG_WAVES_RELEASE_DIR}
340+
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${SPHERE_REG_WAVES_RELEASE_DIR}
341+
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${SPHERE_REG_WAVES_RELEASE_DIR}
342+
)
343+
344+
target_sources(
345+
sphere_reg_waves_test
346+
PRIVATE
347+
${SPHERE_REG_WAVES_SRC_DIR}/sphere_reg_waves_test.cpp
348+
)
349+
350+
if(HYDROCHRONO_ENABLE_IRRLICHT)
351+
target_compile_definitions(sphere_reg_waves_test
352+
PRIVATE
353+
HYDROCHRONO_HAVE_IRRLICHT=1
354+
"CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\""
355+
)
356+
endif()
357+
358+
target_include_directories(
359+
sphere_reg_waves_test
360+
PRIVATE
361+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src
362+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/gui
363+
)
364+
365+
target_link_libraries(
366+
sphere_reg_waves_test
367+
PRIVATE
368+
HydroChrono
369+
HydroChronoGUI
370+
)
371+
372+
# Register as CTest test
373+
if(TARGET sphere_reg_waves_test)
374+
# Copy test data to the output directory
375+
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data DESTINATION ${CMAKE_BINARY_DIR}/tests/regression/Release)
376+
377+
add_test(
378+
NAME sphere_reg_waves_regression
379+
COMMAND ${SPHERE_REG_WAVES_RELEASE_DIR}/sphere_reg_waves_test.exe ${HYDROCHRONO_DATA_DIR} --nogui
380+
)
381+
382+
set_tests_properties(
383+
sphere_reg_waves_regression
384+
PROPERTIES
385+
LABELS "regression;sphere;reg_waves;core"
386+
FIXTURES_SETUP sphere_reg_waves_regression_file
387+
WORKING_DIRECTORY ${SPHERE_REG_WAVES_RELEASE_DIR}
388+
ENVIRONMENT "${TEST_ENVIRONMENT}"
389+
)
390+
391+
# Reference comparison test
392+
add_test(
393+
NAME sphere_reg_waves_regression_ref
394+
COMMAND python ${CMAKE_SOURCE_DIR}/tests/regression/sphere/reg_waves/compare.py
395+
)
396+
397+
set_tests_properties(
398+
sphere_reg_waves_regression_ref
399+
PROPERTIES
400+
LABELS "regression;sphere;reg_waves;reference;core"
401+
FIXTURES_REQUIRED sphere_reg_waves_regression_file
402+
WORKING_DIRECTORY ${SPHERE_REG_WAVES_RELEASE_DIR}
403+
ENVIRONMENT "PATH=${Python3_ROOT_DIR};$ENV{PATH};HYDROCHRONO_BUILD_DIR=${CMAKE_BINARY_DIR}"
404+
)
405+
endif()
406+
407+
# Sphere Irregular Waves Regression Test
408+
# =====================================
409+
410+
# Create executable in model-based directory
411+
add_executable(sphere_irreg_waves_test)
412+
413+
set(SPHERE_IRREG_WAVES_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sphere/irreg_waves)
414+
set(SPHERE_IRREG_WAVES_RELEASE_DIR ${CMAKE_BINARY_DIR}/tests/regression/Release/sphere/irreg_waves)
415+
set(SPHERE_IRREG_WAVES_RESULTS_DIR ${SPHERE_IRREG_WAVES_RELEASE_DIR}/results)
416+
417+
# Use model-based source and let simulation create results automatically
418+
set_target_properties(sphere_irreg_waves_test
419+
PROPERTIES
420+
RUNTIME_OUTPUT_DIRECTORY ${SPHERE_IRREG_WAVES_RELEASE_DIR}
421+
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${SPHERE_IRREG_WAVES_RELEASE_DIR}
422+
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${SPHERE_IRREG_WAVES_RELEASE_DIR}
423+
)
424+
425+
target_sources(
426+
sphere_irreg_waves_test
427+
PRIVATE
428+
${SPHERE_IRREG_WAVES_SRC_DIR}/sphere_irreg_waves_test.cpp
429+
)
430+
431+
if(HYDROCHRONO_ENABLE_IRRLICHT)
432+
target_compile_definitions(sphere_irreg_waves_test
433+
PRIVATE
434+
HYDROCHRONO_HAVE_IRRLICHT=1
435+
"CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\""
436+
)
437+
endif()
438+
439+
target_include_directories(
440+
sphere_irreg_waves_test
441+
PRIVATE
442+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src
443+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/gui
444+
)
445+
446+
target_link_libraries(
447+
sphere_irreg_waves_test
448+
PRIVATE
449+
HydroChrono
450+
HydroChronoGUI
451+
)
452+
453+
# Register as CTest test
454+
if(TARGET sphere_irreg_waves_test)
455+
# Copy test data to the output directory
456+
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data DESTINATION ${CMAKE_BINARY_DIR}/tests/regression/Release)
457+
458+
add_test(
459+
NAME sphere_irreg_waves_regression
460+
COMMAND ${SPHERE_IRREG_WAVES_RELEASE_DIR}/sphere_irreg_waves_test.exe ${HYDROCHRONO_DATA_DIR} --nogui
461+
)
462+
463+
set_tests_properties(
464+
sphere_irreg_waves_regression
465+
PROPERTIES
466+
LABELS "regression;sphere;irreg_waves;core"
467+
FIXTURES_SETUP sphere_irreg_waves_regression_file
468+
WORKING_DIRECTORY ${SPHERE_IRREG_WAVES_RELEASE_DIR}
469+
ENVIRONMENT "${TEST_ENVIRONMENT}"
470+
)
471+
472+
# Reference comparison test
473+
add_test(
474+
NAME sphere_irreg_waves_regression_ref
475+
COMMAND python ${CMAKE_SOURCE_DIR}/tests/regression/sphere/irreg_waves/compare.py
476+
)
477+
478+
set_tests_properties(
479+
sphere_irreg_waves_regression_ref
480+
PROPERTIES
481+
LABELS "regression;sphere;irreg_waves;reference;core"
482+
FIXTURES_REQUIRED sphere_irreg_waves_regression_file
483+
WORKING_DIRECTORY ${SPHERE_IRREG_WAVES_RELEASE_DIR}
484+
ENVIRONMENT "PATH=${Python3_ROOT_DIR};$ENV{PATH};HYDROCHRONO_BUILD_DIR=${CMAKE_BINARY_DIR}"
485+
)
486+
endif()
487+
488+
# Sphere Irregular Waves with ETA Import Regression Test
489+
# =====================================================
490+
491+
# Create executable in model-based directory
492+
add_executable(sphere_irreg_waves_eta_test)
493+
494+
set(SPHERE_IRREG_WAVES_ETA_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sphere/irreg_waves_eta)
495+
set(SPHERE_IRREG_WAVES_ETA_RELEASE_DIR ${CMAKE_BINARY_DIR}/tests/regression/Release/sphere/irreg_waves_eta)
496+
set(SPHERE_IRREG_WAVES_ETA_RESULTS_DIR ${SPHERE_IRREG_WAVES_ETA_RELEASE_DIR}/results)
497+
498+
# Use model-based source and let simulation create results automatically
499+
set_target_properties(sphere_irreg_waves_eta_test
500+
PROPERTIES
501+
RUNTIME_OUTPUT_DIRECTORY ${SPHERE_IRREG_WAVES_ETA_RELEASE_DIR}
502+
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${SPHERE_IRREG_WAVES_ETA_RELEASE_DIR}
503+
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${SPHERE_IRREG_WAVES_ETA_RELEASE_DIR}
504+
)
505+
506+
target_sources(
507+
sphere_irreg_waves_eta_test
508+
PRIVATE
509+
${SPHERE_IRREG_WAVES_ETA_SRC_DIR}/sphere_irreg_waves_eta_test.cpp
510+
)
511+
512+
if(HYDROCHRONO_ENABLE_IRRLICHT)
513+
target_compile_definitions(sphere_irreg_waves_eta_test
514+
PRIVATE
515+
HYDROCHRONO_HAVE_IRRLICHT=1
516+
"CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\""
517+
)
518+
endif()
519+
520+
target_include_directories(
521+
sphere_irreg_waves_eta_test
522+
PRIVATE
523+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src
524+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/gui
525+
)
526+
527+
target_link_libraries(
528+
sphere_irreg_waves_eta_test
529+
PRIVATE
530+
HydroChrono
531+
HydroChronoGUI
532+
)
533+
534+
# Register as CTest test
535+
if(TARGET sphere_irreg_waves_eta_test)
536+
# Copy test data to the output directory
537+
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data DESTINATION ${CMAKE_BINARY_DIR}/tests/regression/Release)
538+
539+
add_test(
540+
NAME sphere_irreg_waves_eta_regression
541+
COMMAND ${SPHERE_IRREG_WAVES_ETA_RELEASE_DIR}/sphere_irreg_waves_eta_test.exe ${HYDROCHRONO_DATA_DIR} --nogui
542+
)
543+
544+
set_tests_properties(
545+
sphere_irreg_waves_eta_regression
546+
PROPERTIES
547+
LABELS "regression;sphere;irreg_waves_eta;core"
548+
FIXTURES_SETUP sphere_irreg_waves_eta_regression_file
549+
WORKING_DIRECTORY ${SPHERE_IRREG_WAVES_ETA_RELEASE_DIR}
550+
ENVIRONMENT "${TEST_ENVIRONMENT}"
551+
)
552+
553+
# Reference comparison test
554+
add_test(
555+
NAME sphere_irreg_waves_eta_regression_ref
556+
COMMAND python ${CMAKE_SOURCE_DIR}/tests/regression/sphere/irreg_waves_eta/compare.py
557+
)
558+
559+
set_tests_properties(
560+
sphere_irreg_waves_eta_regression_ref
561+
PROPERTIES
562+
LABELS "regression;sphere;irreg_waves_eta;reference;core"
563+
FIXTURES_REQUIRED sphere_irreg_waves_eta_regression_file
564+
WORKING_DIRECTORY ${SPHERE_IRREG_WAVES_ETA_RELEASE_DIR}
565+
ENVIRONMENT "PATH=${Python3_ROOT_DIR};$ENV{PATH};HYDROCHRONO_BUILD_DIR=${CMAKE_BINARY_DIR}"
566+
)
324567
endif()

tests/regression/compare_template.py

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,35 @@
102102
}
103103

104104
def format_path(path):
105-
"""Format file paths for display by making them relative to current directory"""
105+
"""Format file paths for display by making them relative to current directory and removing HydroChrono prefix"""
106106
if path is None:
107107
return "Not specified"
108108
try:
109+
# First make it relative to current directory
109110
rel_path = os.path.relpath(path, os.getcwd())
110-
return rel_path if len(rel_path) < len(path) else path
111+
if len(rel_path) >= len(path):
112+
rel_path = path
113+
114+
# Remove "HydroChrono" from the beginning of the path if present
115+
if rel_path.startswith("HydroChrono/"):
116+
rel_path = rel_path[12:] # Remove "HydroChrono/"
117+
elif rel_path.startswith("HydroChrono\\"):
118+
rel_path = rel_path[12:] # Remove "HydroChrono\"
119+
120+
return rel_path
111121
except (ValueError, OSError):
112-
return str(path)
122+
# If relative path fails, try to remove HydroChrono from absolute path
123+
path_str = str(path)
124+
if "HydroChrono" in path_str:
125+
# Find the position after "HydroChrono" and remove it
126+
hydrochrono_pos = path_str.find("HydroChrono")
127+
if hydrochrono_pos != -1:
128+
# Remove "HydroChrono" and the following slash/backslash
129+
remaining = path_str[hydrochrono_pos + 12:] # 12 = len("HydroChrono")
130+
if remaining.startswith("/") or remaining.startswith("\\"):
131+
remaining = remaining[1:]
132+
return remaining
133+
return path_str
113134

114135
def get_cmake_cache_path():
115136
"""Return the canonical path to CMakeCache.txt in the build directory."""
@@ -370,7 +391,7 @@ def create_comparison_plot(ref_data, test_data, test_name, output_dir,
370391
f"Test Information\n\n"
371392
f"Model/Executable: {model_name}\n"
372393
f"Reference File: {format_path(ref_file_path)}\n"
373-
f"Simulation File: {format_path(test_file_path)}\n"
394+
f"Latest File: {format_path(test_file_path)}\n"
374395
f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
375396
)
376397
create_text_panel(fig, LAYOUT['panels']['test_info'], info_content)
@@ -484,8 +505,23 @@ def run_comparison(ref_file, test_file, test_name=None, y_label="Value",
484505

485506
# Load data with error handling
486507
try:
487-
refData = np.loadtxt(ref_file, skiprows=1)
488-
testData = np.loadtxt(test_file, skiprows=1)
508+
# Try to detect the number of header lines by looking for the first numeric line
509+
def find_data_start(filename):
510+
with open(filename, 'r') as f:
511+
for i, line in enumerate(f):
512+
# Check if line contains numeric data (time value)
513+
try:
514+
float(line.split()[0])
515+
return i
516+
except (ValueError, IndexError):
517+
continue
518+
return 0 # Default to 0 if no numeric line found
519+
520+
ref_skiprows = find_data_start(ref_file)
521+
test_skiprows = find_data_start(test_file)
522+
523+
refData = np.loadtxt(ref_file, skiprows=ref_skiprows)
524+
testData = np.loadtxt(test_file, skiprows=test_skiprows)
489525
except (OSError, IOError, ValueError) as e:
490526
print(f"Error loading data files: {e}")
491527
sys.exit(1)
@@ -690,10 +726,10 @@ def rel_to_root(path):
690726
def main():
691727
if len(sys.argv) != 3:
692728
print("Usage: python compare.py <reference_file> <test_file>")
693-
sys.exit(1)
694-
695-
ref_file = sys.argv[1]
696-
test_file = sys.argv[2]
729+
sys.exit(1)
730+
731+
ref_file = sys.argv[1]
732+
test_file = sys.argv[2]
697733
698734
# Test-specific configuration
699735
test_name = "Example Multi-Column Test"

tests/regression/f3of/compare.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,18 @@
1919
from compare_template import run_multi_column_comparison
2020

2121
def main():
22-
if len(sys.argv) != 3:
22+
if len(sys.argv) == 1 or (len(sys.argv) == 3 and sys.argv[1] == 'default'):
23+
# Use default reference and result file locations
24+
ref_file = os.path.join(os.path.dirname(__file__), "..", "reference_data", "f3of", "dt3", "hc_ref_f3of_dt3_flap_pitch.txt")
25+
test_file = os.path.join("results", "f3of_dt3.txt")
26+
elif len(sys.argv) == 3:
27+
ref_file = sys.argv[1]
28+
test_file = sys.argv[2]
29+
else:
2330
print("Usage: python compare.py <reference_file> <test_file>")
31+
print(" or: python compare.py default")
2432
sys.exit(1)
2533

26-
ref_file = sys.argv[1]
27-
test_file = sys.argv[2]
28-
2934
# F3OF DT3 specific configuration
3035
test_name = "F3OF DT3 Decay Test"
3136
executable_patterns = ["f3of_dt3_test", "f3of_dt3_test.exe"]
@@ -56,7 +61,7 @@ def main():
5661
plots_dir = test_file_path.parent / "plots"
5762
plots_dir.mkdir(parents=True, exist_ok=True)
5863
print(f"Plots will be saved to: {plots_dir}")
59-
64+
6065
# Run the multi-column comparison using the template
6166
results = run_multi_column_comparison(
6267
ref_file, test_file, test_configs,

0 commit comments

Comments
 (0)