1+ #!/usr/bin/env python3
2+ """
3+ OSWEC Decay Regression Test Comparison
4+
5+ This script compares the OSWEC decay test results with reference data and generates
6+ comparison plots using the standardized template.
7+
8+ Usage:
9+ python compare_decay.py <reference_file> <test_file>
10+ """
11+
12+ import sys
13+ import os
14+ from pathlib import Path
15+ import numpy as np
16+
17+ # Import the comparison template
18+ sys .path .append (os .path .join (os .path .dirname (__file__ ), '../utilities' ))
19+ from compare_template import run_multi_column_comparison
20+
21+ 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" , "oswec" , "decay" , "hc_ref_oswec_decay.txt" )
25+
26+ # Find the result file
27+ build_dir = os .environ .get ('HYDROCHRONO_BUILD_DIR' , 'C:/code/HydroChrono/build' )
28+ test_file = os .path .join (build_dir , "bin" , "tests" , "regression" , "oswec" , "results" , "CHRONO_OSWEC_DECAY.txt" )
29+ elif len (sys .argv ) == 3 :
30+ ref_file = sys .argv [1 ]
31+ test_file = sys .argv [2 ]
32+ else :
33+ print ("Usage: python compare_decay.py <reference_file> <test_file>" )
34+ print (" or: python compare_decay.py default" )
35+ sys .exit (1 )
36+
37+ # OSWEC Decay specific configuration
38+ test_name = "OSWEC Decay Test"
39+ executable_patterns = ["oswec_decay_test" , "oswec_decay_test.exe" ]
40+
41+ # Define the columns to plot and their configurations
42+ test_configs = [
43+ {
44+ 'column_index' : 1 , # Flap Pitch (radians)
45+ 'test_name' : f"{ test_name } - Flap Pitch" ,
46+ 'y_label' : "Flap Pitch (radians)" ,
47+ 'validation_tolerance' : (1e-4 , 0.02 ) # OSWEC-specific tolerance
48+ }
49+ ]
50+
51+ try :
52+ # Load data for additional OSWEC-specific validations
53+ ref_data = np .loadtxt (ref_file , skiprows = 1 )
54+ test_data = np .loadtxt (test_file , skiprows = 1 )
55+
56+ # Show where the plots will be saved
57+ test_file_path = Path (test_file )
58+ plots_dir = test_file_path .parent / "plots"
59+ plots_dir .mkdir (parents = True , exist_ok = True )
60+ print (f"Plots will be saved to: { plots_dir } " )
61+
62+ # Create temporary files with interpolated data to match time steps
63+ import tempfile
64+
65+ # Interpolate reference data to match test data time steps
66+ nval = test_data .shape [0 ]
67+ x = np .linspace (test_data [0 , 0 ], test_data [nval - 1 , 0 ], nval )
68+
69+ # Interpolate the flap pitch data (column 1 in reference, column 1 in test)
70+ flapPitchRef = np .interp (x , ref_data [:,0 ], ref_data [:,1 ])
71+
72+ # Create interpolated reference data
73+ ref_data_interp = np .column_stack ((x , flapPitchRef ))
74+
75+ # Create temporary files with interpolated data
76+ with tempfile .NamedTemporaryFile (mode = 'w' , suffix = '.txt' , delete = False ) as temp_ref :
77+ np .savetxt (temp_ref .name , ref_data_interp , fmt = '%.6f' )
78+
79+ with tempfile .NamedTemporaryFile (mode = 'w' , suffix = '.txt' , delete = False ) as temp_test :
80+ # Use only time and flap pitch columns from test data
81+ test_data_interp = np .column_stack ((test_data [:,0 ], test_data [:,1 ]))
82+ np .savetxt (temp_test .name , test_data_interp , fmt = '%.6f' )
83+
84+ try :
85+ # Run the multi-column comparison using the template with interpolated data
86+ # Override the plots directory to ensure it's saved in the correct location
87+ import sys as sys_module
88+ sys_module .path .append (os .path .join (os .path .dirname (__file__ ), '..' ))
89+ from compare_template import create_comparison_plot , format_path
90+
91+ # Manually create the comparison plot to control the output directory
92+ for config in test_configs :
93+ column_index = config ['column_index' ]
94+ test_name = config ['test_name' ]
95+ y_label = config ['y_label' ]
96+
97+ # Create data arrays for this column
98+ ref_col_data = np .column_stack ((ref_data_interp [:, 0 ], ref_data_interp [:, column_index ]))
99+ test_col_data = np .column_stack ((test_data_interp [:, 0 ], test_data_interp [:, column_index ]))
100+
101+ # Create the plot in the correct directory
102+ create_comparison_plot (
103+ ref_col_data , test_col_data , test_name , plots_dir ,
104+ ref_file_path = format_path (ref_file ),
105+ test_file_path = format_path (test_file ),
106+ y_label = y_label ,
107+ executable_patterns = executable_patterns
108+ )
109+
110+ # Create dummy results for compatibility
111+ results = [(0.0 , 0.0 , True )] * len (test_configs )
112+ finally :
113+ # Clean up temporary files
114+ os .unlink (temp_ref .name )
115+ os .unlink (temp_test .name )
116+
117+ # Additional OSWEC-specific validations (from the original script)
118+ nval = test_data .shape [0 ]
119+
120+ # Resample refData to testData sampling rate
121+ x = np .linspace (test_data [0 , 0 ], test_data [nval - 1 , 0 ], nval )
122+ flapPitchRef = np .interp (x , ref_data [:,0 ], ref_data [:,1 ])
123+ flapPitchTest = np .interp (x , test_data [:,0 ], test_data [:,1 ])
124+ flapPitchComp = flapPitchRef - flapPitchTest
125+
126+ # Frobenius norm - Flap pitch
127+ flapPitchn1 = np .linalg .norm (flapPitchComp )/ nval
128+ # infinity norm - Flap pitch
129+ flapPitchn2 = np .linalg .norm (flapPitchComp , np .inf )
130+
131+ if (flapPitchn1 > 1e-4 or flapPitchn2 > 0.02 ):
132+ print (f"OSWEC validation failed: Flap pitch difference { flapPitchn1 :.2e} > 1e-4 or { flapPitchn2 :.2e} > 0.02" )
133+ sys .exit (1 )
134+
135+ # Check if all template comparisons passed
136+ all_passed = all (result [2 ] for result in results )
137+
138+ if all_passed :
139+ print ("OSWEC DECAY TEST PASSED - All comparisons within tolerance" )
140+ print (f"Generated plots:" )
141+ for config in test_configs :
142+ plot_name = config ['test_name' ].lower ().replace (' ' , '_' ).replace ('-' , '_' )
143+ print (f" - { config ['test_name' ]} : { plots_dir } /{ plot_name } _comparison.png" )
144+ else :
145+ print ("OSWEC DECAY TEST FAILED - Some comparisons outside tolerance" )
146+ sys .exit (1 )
147+
148+ except Exception as e :
149+ print (f"Error during comparison: { e } " )
150+ sys .exit (1 )
151+
152+ if __name__ == "__main__" :
153+ main ()
0 commit comments