|
1 | 1 | #!/usr/bin/env python3 |
2 | 2 | """ |
3 | | -F3OF DT3 Regression Test Comparison |
| 3 | +F3OF DT3 Regression Test Comparison Script |
4 | 4 |
|
5 | | -This script compares the F3OF DT3 test results with reference data and generates |
6 | | -comparison plots for flap fore pitch and flap aft pitch using the standardized template. |
7 | | -
|
8 | | -Usage: |
9 | | - python compare_dt3.py <reference_file> <test_file> |
| 5 | +This script compares HydroChrono results for F3OF DT3 (flap pitch decay test) |
| 6 | +against reference data from the demos folder. |
10 | 7 | """ |
11 | 8 |
|
12 | 9 | import sys |
|
15 | 12 | import numpy as np |
16 | 13 |
|
17 | 14 | # Import the comparison template |
18 | | -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) |
| 15 | +sys.path.append(os.path.join(os.path.dirname(__file__), '../utilities')) |
19 | 16 | from compare_template import run_multi_column_comparison |
20 | 17 |
|
21 | 18 | def main(): |
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 | | - |
26 | | - # Look for result file in build directory |
27 | | - build_dir = os.environ.get('HYDROCHRONO_BUILD_DIR', 'C:/code/HydroChrono/build') |
28 | | - test_file = os.path.join(build_dir, "tests", "regression", "Release", "f3of", "results", "f3of_dt3.txt") |
29 | | - |
30 | | - # Fallback to local results directory if build file not found |
31 | | - if not os.path.exists(test_file): |
32 | | - test_file = os.path.join("results", "f3of_dt3.txt") |
33 | | - elif len(sys.argv) == 3: |
34 | | - ref_file = sys.argv[1] |
35 | | - test_file = sys.argv[2] |
36 | | - else: |
37 | | - print("Usage: python compare_dt3.py <reference_file> <test_file>") |
38 | | - print(" or: python compare_dt3.py default") |
39 | | - sys.exit(1) |
40 | | - |
41 | 19 | # F3OF DT3 specific configuration |
42 | | - test_name = "F3OF DT3 Decay Test" |
| 20 | + test_name = "F3OF DT3 Flap Pitch Decay" |
43 | 21 | executable_patterns = ["f3of_dt3_test", "f3of_dt3_test.exe"] |
44 | | - |
45 | | - # Define the columns to plot and their configurations |
46 | | - test_configs = [ |
47 | | - { |
48 | | - 'column_index': 3, # Flap Fore Pitch |
49 | | - 'test_name': f"{test_name} - Flap Fore Pitch", |
50 | | - 'y_label': "Flap Fore Pitch (radians)", |
51 | | - 'validation_tolerance': (1e-6, 1e-6) # F3OF-specific tolerance |
52 | | - }, |
53 | | - { |
54 | | - 'column_index': 4, # Flap Aft Pitch |
55 | | - 'test_name': f"{test_name} - Flap Aft Pitch", |
56 | | - 'y_label': "Flap Aft Pitch (radians)", |
57 | | - 'validation_tolerance': (1e-6, 1e-6) # F3OF-specific tolerance |
58 | | - } |
59 | | - ] |
60 | | - |
| 22 | + |
| 23 | + # Find the result file |
| 24 | + build_dir = os.environ.get('HYDROCHRONO_BUILD_DIR', os.path.join(os.path.dirname(__file__), '..', '..', '..', 'build')) |
| 25 | + hc_data_file = os.path.join(build_dir, "bin", "tests", "regression", "f3of", "results", "CHRONO_F3OF_DT3_FLAP_PITCH.txt") |
| 26 | + |
| 27 | + ref_data_file = os.path.join(os.path.dirname(__file__), "..", "reference_data", "f3of", "dt3", "hc_ref_f3of_dt3_flap_pitch.txt") |
| 28 | + |
| 29 | + # Check if files exist |
| 30 | + if not os.path.exists(hc_data_file): |
| 31 | + print(f"Error: Test data file not found: {hc_data_file}") |
| 32 | + sys.exit(1) |
| 33 | + |
| 34 | + if not os.path.exists(ref_data_file): |
| 35 | + print(f"Error: Reference data file not found: {ref_data_file}") |
| 36 | + sys.exit(1) |
| 37 | + |
61 | 38 | try: |
62 | | - # Load data for additional F3OF-specific validations |
63 | | - ref_data = np.loadtxt(ref_file, skiprows=1) |
64 | | - test_data = np.loadtxt(test_file, skiprows=1) |
65 | | - |
| 39 | + # Load data for validation |
| 40 | + ref_data = np.loadtxt(ref_data_file, skiprows=1) |
| 41 | + test_data = np.loadtxt(hc_data_file, skiprows=1) |
| 42 | + |
66 | 43 | # Show where the plots will be saved |
67 | | - test_file_path = Path(test_file) |
| 44 | + test_file_path = Path(hc_data_file) |
68 | 45 | plots_dir = test_file_path.parent / "plots" |
69 | 46 | plots_dir.mkdir(parents=True, exist_ok=True) |
70 | 47 | print(f"Plots will be saved to: {plots_dir}") |
71 | 48 |
|
| 49 | + # Find the executable path |
| 50 | + executable_path = None |
| 51 | + if executable_patterns: |
| 52 | + from compare_template import find_executable |
| 53 | + executable_path = find_executable(test_file_path.parent, executable_patterns) |
| 54 | + |
| 55 | + # Define the columns to plot and their configurations |
| 56 | + test_configs = [ |
| 57 | + { |
| 58 | + 'column_index': 3, # Flap Fore Pitch |
| 59 | + 'test_name': f"{test_name} - Flap Fore Pitch", |
| 60 | + 'y_label': "Flap Fore Pitch (radians)", |
| 61 | + 'validation_tolerance': (1e-6, 1e-6) |
| 62 | + }, |
| 63 | + { |
| 64 | + 'column_index': 4, # Flap Aft Pitch |
| 65 | + 'test_name': f"{test_name} - Flap Aft Pitch", |
| 66 | + 'y_label': "Flap Aft Pitch (radians)", |
| 67 | + 'validation_tolerance': (1e-6, 1e-6) |
| 68 | + } |
| 69 | + ] |
| 70 | + |
72 | 71 | # Run the multi-column comparison using the template |
73 | 72 | results = run_multi_column_comparison( |
74 | | - ref_file, test_file, test_configs, |
| 73 | + ref_data_file, hc_data_file, test_configs, |
75 | 74 | executable_patterns=executable_patterns |
76 | 75 | ) |
77 | | - |
| 76 | + |
78 | 77 | # Additional F3OF-specific validations (from the original script) |
79 | | - |
80 | 78 | # Check base surge (column 1) |
81 | 79 | diff_base_surge = np.linalg.norm(ref_data[:,1] - test_data[:,1]) / len(ref_data[:,1]) |
82 | 80 | if diff_base_surge > 1e-6: |
83 | | - print(f"F3OF validation failed: Base surge difference {diff_base_surge:.2e} > 1e-6") |
| 81 | + print(f"F3OF DT3 validation failed: Base surge difference {diff_base_surge:.2e} > 1e-6") |
84 | 82 | sys.exit(1) |
85 | | - |
| 83 | + |
86 | 84 | # Check base pitch (column 2) - more stringent tolerance |
87 | 85 | diff_base_pitch = np.linalg.norm(ref_data[:,2] - test_data[:,2]) / len(ref_data[:,2]) |
88 | 86 | if diff_base_pitch > 1e-10: |
89 | | - print(f"F3OF validation failed: Base pitch difference {diff_base_pitch:.2e} > 1e-10") |
| 87 | + print(f"F3OF DT3 validation failed: Base pitch difference {diff_base_pitch:.2e} > 1e-10") |
90 | 88 | sys.exit(1) |
91 | | - |
| 89 | + |
92 | 90 | # Check flap fore pitch (column 3) |
93 | 91 | diff_flap_fore_pitch = np.linalg.norm(ref_data[:,3] - test_data[:,3]) / len(ref_data[:,3]) |
94 | 92 | if diff_flap_fore_pitch > 1e-6: |
95 | | - print(f"F3OF validation failed: Flap fore pitch difference {diff_flap_fore_pitch:.2e} > 1e-6") |
| 93 | + print(f"F3OF DT3 validation failed: Flap fore pitch difference {diff_flap_fore_pitch:.2e} > 1e-6") |
96 | 94 | sys.exit(1) |
97 | | - |
| 95 | + |
98 | 96 | # Check flap aft pitch (column 4) |
99 | 97 | diff_flap_aft_pitch = np.linalg.norm(ref_data[:,4] - test_data[:,4]) / len(ref_data[:,4]) |
100 | 98 | if diff_flap_aft_pitch > 1e-6: |
101 | | - print(f"F3OF validation failed: Flap aft pitch difference {diff_flap_aft_pitch:.2e} > 1e-6") |
| 99 | + print(f"F3OF DT3 validation failed: Flap aft pitch difference {diff_flap_aft_pitch:.2e} > 1e-6") |
102 | 100 | sys.exit(1) |
103 | | - |
| 101 | + |
104 | 102 | # Check if all template comparisons passed |
105 | 103 | all_passed = all(result[2] for result in results) |
106 | | - |
| 104 | + |
107 | 105 | if all_passed: |
108 | 106 | print("F3OF DT3 TEST PASSED - All comparisons within tolerance") |
109 | 107 | print(f"Generated plots:") |
110 | 108 | for config in test_configs: |
111 | | - plot_name = config['test_name'].replace(' ', '_') |
112 | | - print(f" - {config['test_name']}: {plots_dir}/{plot_name}_comparison.png") |
| 109 | + plot_name = config['test_name'].lower().replace(' ', '_').replace('-', '_') |
| 110 | + print(f" - {plots_dir}/{plot_name}_comparison.png") |
113 | 111 | else: |
114 | 112 | print("F3OF DT3 TEST FAILED - Some comparisons outside tolerance") |
115 | 113 | sys.exit(1) |
116 | | - |
| 114 | + |
117 | 115 | except Exception as e: |
118 | 116 | print(f"Error during comparison: {e}") |
119 | 117 | sys.exit(1) |
|
0 commit comments