Skip to content

Commit 87e4db2

Browse files
committed
Add support for run-time plotting in demos and tests.
- Modify utility GetCLIArguments function to also provide options `--plot` and `--no_plot`. - Enable run-time visualization and plotting by default. - Set `--no_gui --no_plot` when running tests through `ctest`. - Add optional plotting (using Chrono's ChGnuPlot) for all decay demos and tests.
1 parent c1bb209 commit 87e4db2

26 files changed

Lines changed: 319 additions & 167 deletions

demos/DeepCWind/demo_DeepCWind_decay.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
#include <hydroc/hydro_forces.h>
44

55
#include <chrono/core/ChRealtimeStep.h>
6-
#include <chrono/physics/ChSystemSMC.h>
76
#include <chrono/physics/ChBodyEasy.h>
7+
#include <chrono/physics/ChSystemSMC.h>
8+
9+
#include "chrono_postprocess/ChGnuPlot.h"
810

911
#include <chrono> // std::chrono::high_resolution_clock::now
1012
#include <iomanip> // std::setprecision
@@ -20,16 +22,19 @@ int main(int argc, char* argv[]) {
2022
// Parse CLI arguments and initialize environment
2123
bool profilingOn = true;
2224
bool saveDataOn = true;
25+
bool plotOn = true;
2326
bool visualizationOn = true;
2427
std::string data_dir;
25-
if (!hydroc::GetCLIArguments(argc, argv, "DeepC wind demo", saveDataOn, profilingOn, visualizationOn, data_dir))
28+
if (!hydroc::GetCLIArguments(argc, argv, "DeepC wind demo", saveDataOn, profilingOn, plotOn, visualizationOn,
29+
data_dir))
2630
return 1;
2731
if (!hydroc::SetInitialEnvironment(data_dir)) return 1;
2832

2933
std::filesystem::path DATADIR(hydroc::getDataDir());
3034

31-
auto body1_meshfame = (DATADIR / "demos" / "DeepCWind" / "geometry" / "deepcwind.obj").lexically_normal().generic_string();
32-
auto h5fname = (DATADIR / "demos" / "DeepCWind" / "hydroData" / "deepcwind.h5").lexically_normal().generic_string();
35+
auto body1_meshfame =
36+
(DATADIR / "demos" / "DeepCWind" / "geometry" / "deepcwind.obj").lexically_normal().generic_string();
37+
auto h5fname = (DATADIR / "demos" / "DeepCWind" / "hydroData" / "deepcwind.h5").lexically_normal().generic_string();
3338

3439
// system/solver settings
3540
ChSystemSMC system;
@@ -122,7 +127,7 @@ int main(int argc, char* argv[]) {
122127

123128
std::string out_dir = hydroc::getDemoOutDir();
124129
if (profilingOn || saveDataOn) {
125-
out_dir = out_dir + "/" + RESULTS_DIR_NAME;
130+
out_dir = out_dir + "/" + RESULTS_DIR_NAME;
126131
std::filesystem::create_directory(std::filesystem::path(out_dir));
127132
}
128133

@@ -144,5 +149,19 @@ int main(int argc, char* argv[]) {
144149
<< std::endl;
145150
outputFile.close();
146151
}
152+
153+
if (plotOn) {
154+
postprocess::ChGnuPlot gplot(out_dir + "/deepCWind_decay.gpl");
155+
gplot.SetGrid();
156+
gplot.SetLabelX("time (s)");
157+
gplot.SetLabelY("surge");
158+
gplot.SetLabelY2("pitch");
159+
gplot.SetCommand("set ytics 0.05 nomirror");
160+
gplot.SetCommand("set y2tics 0.05 nomirror");
161+
gplot.SetTitle("DeepCWind decay");
162+
gplot.Plot(time_vector, base_surge, "base surge", " with lines lt rgb '#FF5500' lw 2");
163+
gplot.Plot(time_vector, base_pitch, "base pitch", " axes x1y2 with lines lt rgb '#0055FF' lw 2");
164+
}
165+
147166
return 0;
148167
}

demos/f3of/demo_F3OF_DT1.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#include <hydroc/hydro_forces.h>
44

55
#include <chrono/core/ChRealtimeStep.h>
6-
#include <chrono/physics/ChSystemSMC.h>
76
#include <chrono/physics/ChBodyEasy.h>
7+
#include <chrono/physics/ChSystemSMC.h>
88

99
#include <chrono> // std::chrono::high_resolution_clock::now
1010
#include <iomanip> // std::setprecision
@@ -19,9 +19,11 @@ int main(int argc, char* argv[]) {
1919
// Parse CLI arguments and initialize environment
2020
bool profilingOn = true;
2121
bool saveDataOn = true;
22+
bool plotOn = true;
2223
bool visualizationOn = true;
2324
std::string data_dir;
24-
if (!hydroc::GetCLIArguments(argc, argv, "F3OF DT1 demo", saveDataOn, profilingOn, visualizationOn, data_dir))
25+
if (!hydroc::GetCLIArguments(argc, argv, "F3OF DT1 demo", saveDataOn, profilingOn, plotOn, visualizationOn,
26+
data_dir))
2527
return 1;
2628
if (!hydroc::SetInitialEnvironment(data_dir)) return 1;
2729

demos/f3of/demo_F3OF_DT2.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#include <hydroc/hydro_forces.h>
44

55
#include <chrono/core/ChRealtimeStep.h>
6-
#include <chrono/physics/ChSystemSMC.h>
76
#include <chrono/physics/ChBodyEasy.h>
7+
#include <chrono/physics/ChSystemSMC.h>
88

99
#include <chrono> // std::chrono::high_resolution_clock::now
1010
#include <iomanip> // std::setprecision
@@ -19,9 +19,11 @@ int main(int argc, char* argv[]) {
1919
// Parse CLI arguments and initialize environment
2020
bool profilingOn = true;
2121
bool saveDataOn = true;
22+
bool plotOn = true;
2223
bool visualizationOn = true;
2324
std::string data_dir;
24-
if (!hydroc::GetCLIArguments(argc, argv, "F3OF DT2 demo", saveDataOn, profilingOn, visualizationOn, data_dir))
25+
if (!hydroc::GetCLIArguments(argc, argv, "F3OF DT2 demo", saveDataOn, profilingOn, plotOn, visualizationOn,
26+
data_dir))
2527
return 1;
2628
if (!hydroc::SetInitialEnvironment(data_dir)) return 1;
2729

demos/f3of/demo_F3OF_DT3.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#include <hydroc/hydro_forces.h>
44

55
#include <chrono/core/ChRealtimeStep.h>
6-
#include <chrono/physics/ChSystemSMC.h>
76
#include <chrono/physics/ChBodyEasy.h>
7+
#include <chrono/physics/ChSystemSMC.h>
88

99
#include <chrono> // std::chrono::high_resolution_clock::now
1010
#include <iomanip> // std::setprecision
@@ -24,9 +24,11 @@ int main(int argc, char* argv[]) {
2424
// Parse CLI arguments and initialize environment
2525
bool profilingOn = true;
2626
bool saveDataOn = true;
27+
bool plotOn = true;
2728
bool visualizationOn = true;
2829
std::string data_dir;
29-
if (!hydroc::GetCLIArguments(argc, argv, "F3OF DT3 demo", saveDataOn, profilingOn, visualizationOn, data_dir))
30+
if (!hydroc::GetCLIArguments(argc, argv, "F3OF DT3 demo", saveDataOn, profilingOn, plotOn, visualizationOn,
31+
data_dir))
3032
return 1;
3133
if (!hydroc::SetInitialEnvironment(data_dir)) return 1;
3234

demos/oswec/demo_oswec_decay.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
#include <hydroc/hydro_forces.h>
44

55
#include <chrono/core/ChRealtimeStep.h>
6-
#include <chrono/physics/ChSystemNSC.h>
76
#include <chrono/physics/ChBodyEasy.h>
7+
#include <chrono/physics/ChSystemNSC.h>
8+
9+
#include "chrono_postprocess/ChGnuPlot.h"
810

911
#include <chrono> // std::chrono::high_resolution_clock::now
1012
#include <iomanip> // std::setprecision
@@ -65,9 +67,11 @@ int main(int argc, char* argv[]) {
6567
// Parse CLI arguments and initialize environment
6668
bool profilingOn = true;
6769
bool saveDataOn = true;
70+
bool plotOn = true;
6871
bool visualizationOn = true;
6972
std::string data_dir;
70-
if (!hydroc::GetCLIArguments(argc, argv, "OSWEC decay demo", saveDataOn, profilingOn, visualizationOn, data_dir))
73+
if (!hydroc::GetCLIArguments(argc, argv, "OSWEC decay demo", saveDataOn, profilingOn, plotOn, visualizationOn,
74+
data_dir))
7175
return 1;
7276
if (!hydroc::SetInitialEnvironment(data_dir)) return 1;
7377

@@ -235,5 +239,15 @@ int main(int argc, char* argv[]) {
235239
<< std::endl;
236240
outputFile.close();
237241
}
242+
243+
if (plotOn) {
244+
postprocess::ChGnuPlot gplot(out_dir + "/owsec_decay.gpl");
245+
gplot.SetGrid();
246+
gplot.SetLabelX("time (s)");
247+
gplot.SetLabelY("pitch (rad)");
248+
gplot.SetTitle("OSWEC decay");
249+
gplot.Plot(time_vector, flap_rot, "", " with lines lt rgb '#FF5500' lw 2");
250+
}
251+
238252
return 0;
239253
}

demos/oswec/demo_oswec_reg_waves.cpp

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#include <hydroc/hydro_forces.h>
44

55
#include <chrono/core/ChRealtimeStep.h>
6-
#include <chrono/physics/ChSystemNSC.h>
76
#include <chrono/physics/ChBodyEasy.h>
7+
#include <chrono/physics/ChSystemNSC.h>
88

99
#include <chrono> // std::chrono::high_resolution_clock::now
1010
#include <iomanip> // std::setprecision
@@ -59,31 +59,33 @@ std::array<double, 3> add_vectors(std::array<double, 3> v1, std::array<double, 3
5959
return {v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]};
6060
}
6161

62-
6362
int main(int argc, char* argv[]) {
64-
65-
std::vector<double> periods = {4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 18.5, 19.0, 19.25, 19.5, 20.0, 21.0, 22.0, 24.0};
63+
std::vector<double> periods = {4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0,
64+
18.5, 19.0, 19.25, 19.5, 20.0, 21.0, 22.0, 24.0};
6665
int reg_wave_num_max = periods.size();
6766

6867
for (int reg_wave_num = 1; reg_wave_num <= reg_wave_num_max; ++reg_wave_num) {
6968
std::cout << "Chrono version: " << CHRONO_VERSION << "\n\n";
7069

7170
// Parse CLI arguments and initialize environment
71+
bool plotOn = true;
7272
bool visualizationOn = true;
7373
bool profilingOn = true;
7474
bool saveDataOn = true;
7575
std::string data_dir;
76-
if (!hydroc::GetCLIArguments(argc, argv, "OSWEC regular waves demo", saveDataOn, profilingOn, visualizationOn,
77-
data_dir))
76+
if (!hydroc::GetCLIArguments(argc, argv, "OSWEC regular waves demo", saveDataOn, profilingOn, plotOn,
77+
visualizationOn, data_dir))
7878
return 1;
7979
if (!hydroc::SetInitialEnvironment(data_dir)) return 1;
8080

8181
// Get model file names
8282
std::filesystem::path DATADIR(hydroc::getDataDir());
8383

84-
auto body1_meshfname = (DATADIR / "demos" / "oswec" / "geometry" / "flap.obj").lexically_normal().generic_string();
85-
auto body2_meshfname = (DATADIR / "demos" / "oswec" / "geometry" / "base.obj").lexically_normal().generic_string();
86-
auto h5fname = (DATADIR / "demos" / "oswec" / "hydroData" / "oswec.h5").lexically_normal().generic_string();
84+
auto body1_meshfname =
85+
(DATADIR / "demos" / "oswec" / "geometry" / "flap.obj").lexically_normal().generic_string();
86+
auto body2_meshfname =
87+
(DATADIR / "demos" / "oswec" / "geometry" / "base.obj").lexically_normal().generic_string();
88+
auto h5fname = (DATADIR / "demos" / "oswec" / "hydroData" / "oswec.h5").lexically_normal().generic_string();
8789

8890
// system/solver settings
8991
ChSystemNSC system;
@@ -92,7 +94,7 @@ int main(int argc, char* argv[]) {
9294
double timestep = 0.03;
9395
// system.SetTimestepperType(ChTimestepper::Type::HHT);
9496
system.SetSolverType(ChSolver::Type::GMRES);
95-
// system.GetSolver()->AsIterative()->SetMaxIterations(300); // the higher, the easier to keep the constraints satisfied.
97+
// system.GetSolver()->AsIterative()->SetMaxIterations(300);
9698
ChRealtimeStepTimer realtime_timer;
9799
double simulationDuration = 1000.0;
98100

@@ -109,16 +111,16 @@ int main(int argc, char* argv[]) {
109111
std::array<double, 3> axis = {0, 1, 0};
110112
double angle_in_degrees = 0.0;
111113

112-
//std::array<double, 3> rotated_hinge_to_cg = rotate_vector_3d(hinge_to_cg, axis, angle_in_degrees);
114+
// std::array<double, 3> rotated_hinge_to_cg = rotate_vector_3d(hinge_to_cg, axis, angle_in_degrees);
113115

114-
//std::array<double, 3> new_cg = add_vectors(origin_to_hinge, rotated_hinge_to_cg);
116+
// std::array<double, 3> new_cg = add_vectors(origin_to_hinge, rotated_hinge_to_cg);
115117

116-
//std::cout << "The original vector is [" << hinge_to_cg[0] << ", " << hinge_to_cg[1] << ", " << hinge_to_cg[2]
117-
// << "]" << std::endl;
118-
//std::cout << "The rotated vector is [" << rotated_hinge_to_cg[0] << ", " << rotated_hinge_to_cg[1] << ", "
119-
// << rotated_hinge_to_cg[2] << "]" << std::endl;
120-
//std::cout << "The new vector is [" << new_cg[0] << ", " << new_cg[1] << ", " << new_cg[2] << "]"
121-
// << std::endl;
118+
// std::cout << "The original vector is [" << hinge_to_cg[0] << ", " << hinge_to_cg[1] << ", " << hinge_to_cg[2]
119+
// << "]" << std::endl;
120+
// std::cout << "The rotated vector is [" << rotated_hinge_to_cg[0] << ", " << rotated_hinge_to_cg[1] << ", "
121+
// << rotated_hinge_to_cg[2] << "]" << std::endl;
122+
// std::cout << "The new vector is [" << new_cg[0] << ", " << new_cg[1] << ", " << new_cg[2] << "]"
123+
// << std::endl;
122124

123125
// set up body from a mesh
124126
std::cout << "Attempting to open mesh file: " << body1_meshfname << std::endl;
@@ -141,7 +143,7 @@ int main(int argc, char* argv[]) {
141143
auto ang_rad = CH_PI / 18.0;
142144
// flap_body->SetPos(ChVector3d(new_cg[0], new_cg[1], new_cg[2]));
143145
flap_body->SetPos(ChVector3d(0.0, 0.0, -3.9));
144-
//flap_body->SetRot(QuatFromAngleY(ang_rad));
146+
// flap_body->SetRot(QuatFromAngleY(ang_rad));
145147
flap_body->SetMass(127000.0);
146148
flap_body->SetInertiaXX(ChVector3d(1.85e6, 1.85e6, 1.85e6));
147149
// notes: mass and inertia added to added mass and system mass correctly.
@@ -196,9 +198,9 @@ int main(int argc, char* argv[]) {
196198
bodies.push_back(flap_body);
197199
bodies.push_back(base_body);
198200

199-
auto my_hydro_inputs = std::make_shared<RegularWave>(static_cast<unsigned int>(bodies.size()));
201+
auto my_hydro_inputs = std::make_shared<RegularWave>(static_cast<unsigned int>(bodies.size()));
200202
my_hydro_inputs->regular_wave_amplitude_ = 0.01;
201-
my_hydro_inputs->regular_wave_omega_ = (2 * CH_PI)/(periods[reg_wave_num - 1]);
203+
my_hydro_inputs->regular_wave_omega_ = (2 * CH_PI) / (periods[reg_wave_num - 1]);
202204

203205
//// attach hydrodynamic forces to body
204206
/*std::vector<std::shared_ptr<ChBody>> bodies;
@@ -244,23 +246,22 @@ int main(int argc, char* argv[]) {
244246

245247
if (saveDataOn) {
246248
std::ofstream outputFile(out_dir + "/reg_waves_" + std::to_string(reg_wave_num) + ".txt");
247-
//outputFile << std::left << std::setw(10) << "Time (s)" << std::right << std::setw(16)
248-
// << "Flap Rotation y (radians)" << std::right << std::setw(16) << "Flap Rotation y (degrees)"
249-
// << std::endl;
250-
//for (int i = 0; i < time_vector.size(); ++i)
251-
// outputFile << std::left << std::setw(10) << std::setprecision(2) << std::fixed << time_vector[i]
252-
// << std::right << std::setw(16) << std::setprecision(4) << std::fixed << flap_rot[i]
253-
// << std::right << std::setw(16) << std::setprecision(4) << std::fixed
254-
// << flap_rot[i] * 360.0 / 6.28 << std::endl;
255-
//outputFile.close();
249+
// outputFile << std::left << std::setw(10) << "Time (s)" << std::right << std::setw(16)
250+
// << "Flap Rotation y (radians)" << std::right << std::setw(16) << "Flap Rotation y (degrees)"
251+
// << std::endl;
252+
// for (int i = 0; i < time_vector.size(); ++i)
253+
// outputFile << std::left << std::setw(10) << std::setprecision(2) << std::fixed << time_vector[i]
254+
// << std::right << std::setw(16) << std::setprecision(4) << std::fixed << flap_rot[i]
255+
// << std::right << std::setw(16) << std::setprecision(4) << std::fixed
256+
// << flap_rot[i] * 360.0 / 6.28 << std::endl;
257+
// outputFile.close();
256258

257259
outputFile.precision(10);
258260
outputFile.width(12);
259261
outputFile << "Wave #: \t" << reg_wave_num << "\n";
260262
outputFile << "Wave amplitude (m): \t" << my_hydro_inputs->regular_wave_amplitude_ << "\n";
261263
outputFile << "Wave omega (rad/s): \t" << my_hydro_inputs->regular_wave_omega_ << "\n";
262-
outputFile << std::left << std::setw(10) << "Time (s)" << std::right << std::setw(12)
263-
<< "Pitch (rads)"
264+
outputFile << std::left << std::setw(10) << "Time (s)" << std::right << std::setw(12) << "Pitch (rads)"
264265
<< std::endl;
265266
for (int i = 0; i < time_vector.size(); ++i)
266267
outputFile << std::left << std::setw(10) << std::setprecision(2) << std::fixed << time_vector[i]

demos/rm3/demo_rm3_decay.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
#include <hydroc/hydro_forces.h>
44

55
#include <chrono/core/ChRealtimeStep.h>
6-
#include <chrono/physics/ChSystemNSC.h>
76
#include <chrono/physics/ChBodyEasy.h>
7+
#include <chrono/physics/ChSystemNSC.h>
8+
9+
#include "chrono_postprocess/ChGnuPlot.h"
810

911
#include <chrono> // std::chrono::high_resolution_clock::now
1012
#include <iomanip> // std::setprecision
@@ -19,18 +21,22 @@ int main(int argc, char* argv[]) {
1921
// Parse CLI arguments and initialize environment
2022
bool profilingOn = true;
2123
bool saveDataOn = true;
24+
bool plotOn = true;
2225
bool visualizationOn = true;
2326
std::string data_dir;
24-
if (!hydroc::GetCLIArguments(argc, argv, "RM3 decay demo", saveDataOn, profilingOn, visualizationOn, data_dir))
27+
if (!hydroc::GetCLIArguments(argc, argv, "RM3 decay demo", saveDataOn, profilingOn, plotOn, visualizationOn,
28+
data_dir))
2529
return 1;
2630
if (!hydroc::SetInitialEnvironment(data_dir)) return 1;
2731

2832
// Get model file names
2933
std::filesystem::path DATADIR(hydroc::getDataDir());
3034

31-
auto body1_meshfame = (DATADIR / "demos" / "rm3" / "geometry" / "float_cog.obj").lexically_normal().generic_string();
32-
auto body2_meshfame = (DATADIR / "demos" / "rm3" / "geometry" / "plate_cog.obj").lexically_normal().generic_string();
33-
auto h5fname = (DATADIR / "demos" / "rm3" / "hydroData" / "rm3.h5").lexically_normal().generic_string();
35+
auto body1_meshfame =
36+
(DATADIR / "demos" / "rm3" / "geometry" / "float_cog.obj").lexically_normal().generic_string();
37+
auto body2_meshfame =
38+
(DATADIR / "demos" / "rm3" / "geometry" / "plate_cog.obj").lexically_normal().generic_string();
39+
auto h5fname = (DATADIR / "demos" / "rm3" / "hydroData" / "rm3.h5").lexically_normal().generic_string();
3440

3541
// system/solver settings
3642
ChSystemNSC system;
@@ -173,5 +179,15 @@ int main(int argc, char* argv[]) {
173179
<< std::endl;
174180
outputFile.close();
175181
}
182+
183+
if (plotOn) {
184+
postprocess::ChGnuPlot gplot(out_dir + "/rm3_decay.gpl");
185+
gplot.SetGrid();
186+
gplot.SetLabelX("time (s)");
187+
gplot.SetLabelY("heave (m)");
188+
gplot.SetTitle("RM3 decay");
189+
gplot.Plot(time_vector, plate_heave_position, "", " with lines lt rgb '#FF5500' lw 2");
190+
}
191+
176192
return 0;
177193
}

0 commit comments

Comments
 (0)