Skip to content

Commit 16522a2

Browse files
committed
Modify test_rm3_decay to perform validation against reference file and plot validation results using GnuPlot
1 parent 1b81e26 commit 16522a2

5 files changed

Lines changed: 93 additions & 20 deletions

File tree

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,11 @@ target_include_directories(HydroChronoGUI
431431
"$<INSTALL_INTERFACE:include>"
432432
)
433433

434+
if(MSVC)
435+
target_compile_options(HydroChronoGUI PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/wd4996>) # deprecated function or class member
436+
target_compile_options(HydroChronoGUI PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/wd4458>) # declaration hides class member
437+
endif()
438+
434439
set_target_properties(HydroChronoGUI PROPERTIES POSITION_INDEPENDENT_CODE ON)
435440
target_link_libraries(HydroChronoGUI
436441
PUBLIC

data/reference_data/rm3/hc_ref_rm3_decay.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Time (s) Float Heave (m) Plate Heave (m)
1+
Time(s) Float_Heave(m) Plate_Heave(m)
22
0.01 -0.62000515 -21.29000007
33
0.02 -0.62002233 -21.29000032
44
0.03 -0.62005382 -21.29000078

tests/regression/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function(build_regression_test TEST_GROUP TEST_NAME MULTIPLE)
2222

2323
target_compile_definitions(${TEST_EXE}
2424
PRIVATE
25+
"REFERENCE_FILE_NAME=\"${FILE_REF}\""
2526
"RESULTS_DIR_NAME=\"${TEST_GROUP}\""
2627
"RESULTS_FILE_NAME=\"results_${TEST_NAME}\""
2728
)

tests/regression/rm3/test_rm3_decay.cpp

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@
66
#include <chrono/physics/ChBodyEasy.h>
77
#include <chrono/physics/ChSystemNSC.h>
88

9-
#include "chrono_postprocess/ChGnuPlot.h"
9+
#include <chrono/utils/ChUtils.h>
10+
11+
#include "../test_utils.h"
1012

1113
#include <chrono> // std::chrono::high_resolution_clock::now
1214
#include <iomanip> // std::setprecision
1315
#include <vector> // std::vector<double>
1416

1517
// Use the namespaces of Chrono
1618
using namespace chrono;
19+
using namespace chrono::utils;
1720

1821
int main(int argc, char* argv[]) {
1922
std::cout << "Chrono version: " << CHRONO_VERSION << "\n\n";
@@ -53,14 +56,8 @@ int main(int argc, char* argv[]) {
5356

5457
// Create user interface
5558
std::shared_ptr<hydroc::gui::UI> pui = hydroc::gui::CreateUI(visualizationOn);
56-
5759
hydroc::gui::UI& ui = *pui.get();
5860

59-
// some io/viz options
60-
std::vector<double> time_vector;
61-
std::vector<double> float_heave_position;
62-
std::vector<double> plate_heave_position;
63-
6461
// set up body from a mesh
6562
std::cout << "Attempting to open mesh file: " << body1_meshfame << std::endl;
6663
std::shared_ptr<ChBody> float_body1 = chrono_types::make_shared<ChBodyEasyMesh>( //
@@ -127,10 +124,10 @@ int main(int argc, char* argv[]) {
127124

128125
HydroForces hydroForces(bodies, h5fname, default_dont_add_waves);
129126

130-
//// Debug printing added mass matrix and system mass matrix
131-
// ChSparseMatrix M;
132-
// system.GetMassMatrix(&M);
133-
// std::cout << M << std::endl;
127+
// Result arrays
128+
std::vector<double> time_vector;
129+
std::vector<double> float_heave_position;
130+
std::vector<double> plate_heave_position;
134131

135132
// for profiling
136133
auto start = std::chrono::high_resolution_clock::now();
@@ -190,14 +187,39 @@ int main(int argc, char* argv[]) {
190187
}
191188
}
192189

190+
// Read reference data
191+
ChValidation::Headers col_headers;
192+
ChValidation::Data ref_data = ChValidation::ReadDataFile(REFERENCE_FILE_NAME, col_headers);
193+
ChAssertAlways(ref_data.size() == 3);
194+
195+
// Simulation data
196+
ChValidation::Data res_data = ChValidation::CreateData({time_vector, float_heave_position, plate_heave_position});
197+
198+
// Perform validation
199+
auto norm_type = ChValidation::NormType::RMS;
200+
double tolerance = 1e-8;
201+
ChValidation::DataVector error_norms;
202+
bool passed = ChValidation::Test(res_data, ref_data, ChValidation::NormType::RMS, tolerance, error_norms);
203+
204+
std::cout << "\nValidation";
205+
std::cout << "\n Reference file: " << REFERENCE_FILE_NAME;
206+
std::cout << "\n Data series: ";
207+
for (const auto& c : col_headers)
208+
std::cout << c << " ";
209+
std::cout << "\n Ref. data points: " << ref_data[0].size();
210+
std::cout << "\n Sim. data points: " << res_data[0].size();
211+
std::cout << "\n Validation norm: " << ChValidation::GetNormTypeAsString(norm_type);
212+
std::cout << "\n Tolerance: " << tolerance;
213+
std::cout << "\n " << (passed ? "Passed" : "Failed");
214+
std::cout << " [ ";
215+
for (const auto& nrm : error_norms)
216+
std::cout << nrm << " ";
217+
std::cout << "]" << std::endl;
218+
219+
// Plot simulation and reference results
193220
if (plotOn) {
194-
postprocess::ChGnuPlot gplot(out_dir + "/rm3_decay.gpl");
195-
gplot.SetGrid();
196-
gplot.SetLabelX("time (s)");
197-
gplot.SetLabelY("heave (m)");
198-
gplot.SetTitle("RM3 decay");
199-
gplot.Plot(time_vector, plate_heave_position, "", " with lines lt rgb '#FF5500' lw 2");
221+
PlotValidation(out_dir + "/rm3_decay.gpl", "RM3 decay", col_headers, ref_data, res_data, simulationDuration);
200222
}
201223

202-
return 0;
203-
}
224+
return !passed;
225+
}

tests/regression/test_utils.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#ifndef TEST_UTILS_H
2+
#define TEST_UTILS_H
3+
4+
#include <chrono/utils/ChValidation.h>
5+
#include <chrono_postprocess/ChGnuPlot.h>
6+
7+
void PlotValidation(const std::string& out_script,
8+
const std::string& title,
9+
const chrono::utils::ChValidation::Headers& headers,
10+
chrono::utils::ChValidation::Data& ref_data,
11+
chrono::utils::ChValidation::Data& res_data,
12+
double simulationDuration) {
13+
int n_plots = (int)res_data.size() - 1;
14+
15+
chrono::postprocess::ChGnuPlot gplot(out_script);
16+
gplot.SetCanvasSize(1200, 500 * n_plots);
17+
gplot.SetTitle("{/:Bold " + title + "}");
18+
gplot.SetCommand("set multiplot layout " + std::to_string(n_plots) + ", 1");
19+
20+
for (int i = 1; i <= n_plots; i++) {
21+
gplot.SetRangeX(0, simulationDuration);
22+
gplot.SetCommand("set xlabel '" + headers[0] + "' noenhanced");
23+
24+
gplot.SetCommand("set ylabel '" + headers[i] + "' noenhanced");
25+
gplot.Plot(ref_data[0], ref_data[i], "Reference", "with lines lt rgb '#0055FF' lw 4");
26+
gplot.Plot(res_data[0], res_data[i], "Simulation", "with lines lt rgb '#FF3300' lw 4 dashtype 2");
27+
28+
auto n_err = std::min(res_data[0].size(), ref_data[0].size());
29+
chrono::ChVectorDynamic<> t_err = ref_data[0].head(n_err);
30+
chrono::ChVectorDynamic<> err = ref_data[i].head(n_err) - res_data[i].head(n_err);
31+
if (err.norm() < 1e-4) {
32+
gplot.SetRangeY2(-0.01, +0.01);
33+
gplot.SetCommand("set y2tics -0.01 , 0.01, 0.01");
34+
}
35+
gplot.SetLabelY2("error");
36+
gplot.Plot(t_err, err, "Error (ref - sim)", "axes x1y2 with lines lt rgb '#44CC44' lw 4");
37+
38+
gplot.SetLegend("box lt -1 lw 1");
39+
gplot.SetGrid();
40+
41+
gplot.FlushPlots();
42+
}
43+
}
44+
45+
#endif

0 commit comments

Comments
 (0)