Skip to content

Commit fe534f0

Browse files
committed
Add RM3 mooring demo with MoorDyn coupling
1 parent 8c1a04b commit fe534f0

6 files changed

Lines changed: 309 additions & 0 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
Mooring line data file for MoorDyn in libmoordyn.dll
2+
---------------------- LINE TYPES -----------------------------------------------------
3+
LineType Diam Mass/m EA BA/-zeta EI Cd Ca CdAx CaAx
4+
(-) (m) (kg/m) (N) (N-s/-) (N-m^2) (-) (-) (-) (-)
5+
Chain 0.144 126.0 583.376E6 -0.8 0 1.6 1.0 0.05 0.0
6+
---------------------------- BODIES -----------------------------------------------------
7+
ID Attachment X0 Y0 Z0 r0 p0 y0 Mass CG* I* Volume CdA* Ca
8+
(#) (-) (m) (m) (m) (deg) (deg) (deg) (kg) (m) (kg-m^2) (m^3) (m^2) (-)
9+
1 Coupled 0 0 -21.5 0 0 0 0.0 0 0 0 0 0
10+
---------------------- POINTS -----------------------------------------------------
11+
ID Attachment X Y Z Mass Volume CdA CA
12+
(#) (word/ID) (m) (m) (m) (kg) (mˆ3) (m^2) (-)
13+
1 Body1 -3.0 0 11.50 0 0 0 0
14+
2 Fixed -267.0 0 -70.00 0 0 0 0
15+
3 Body1 1.5 2.598 11.50 0 0 0 0
16+
4 Fixed 133.5 231.23 -70.00 0 0 0 0
17+
5 Body1 1.5 -2.598 11.50 0 0 0 0
18+
6 Fixed 133.5 -231.23 -70.00 0 0 0 0
19+
7 Free -40.0 0 -10.00 16755 33.510 12.566 1
20+
8 Free 20.0 34.642 -10.00 16755 33.510 12.566 1
21+
9 Free 20.0 -34.642 -10.00 16755 33.510 12.566 1
22+
---------------------- LINES -----------------------------------------------------
23+
ID LineType AttachA AttachB UnstrLen NumSegs LineOutputs
24+
(#) (-) (#) (#) (m) (-) (-)
25+
1 Chain 2 7 240.0 15 tp
26+
2 Chain 4 8 240.0 15 tp
27+
3 Chain 6 9 240.0 15 tp
28+
4 Chain 7 1 40.0 5 tp
29+
5 Chain 8 3 40.0 5 tp
30+
6 Chain 9 5 40.0 5 tp
31+
---------------------- SOLVER OPTIONS-----------------------------------------
32+
0.0005 dtM - time step to use in mooring integration
33+
0 WaveKin - wave kinematics flag (0=neglect, the only option currently supported)
34+
3.0e6 kBot - bottom stiffness
35+
3.0e5 cBot - bottom damping
36+
70 WtrDpth - water depth
37+
5.0 CdScaleIC - factor by which to scale drag coefficients during dynamic relaxation IC gen
38+
0.001 threshIC - threshold for IC con
39+
200.0 TmaxIC - max time for ic gen (s)
40+
2 writeLog - Write a log file
41+
0 WriteUnits - 0: do not write the units header on the output files
42+
1 disableOutTime - 1: do not write timesteps to command window
43+
-------------------------- OUTPUTS --------------------------------
44+
FairTen4
45+
FairTen5
46+
FairTen6
47+
--------------------- need this line ------------------
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
hydrodynamics:
2+
bodies:
3+
- name: body1
4+
h5_file: hydroData/rm3.h5
5+
6+
- name: body2
7+
h5_file: hydroData/rm3.h5
8+
9+
waves:
10+
type: still
11+
12+
moordyn:
13+
enabled: true
14+
input_file: mooring/lines_rm3.txt
15+
bodies: [body2]
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
chrono-version: 9.0
2+
3+
model:
4+
name: rm3_mooring_model
5+
angle_degrees: false
6+
7+
data_path:
8+
type: RELATIVE
9+
root: "."
10+
11+
bodies:
12+
- name: body1
13+
location: [0.0, 0.0, -0.72]
14+
mass: 725834
15+
fixed: false
16+
inertia:
17+
moments: [20907301.0, 21306090.66, 37085481.11]
18+
products: [0, 0, 0]
19+
com:
20+
location: [0, 0, 0]
21+
orientation: [0, 0, 0]
22+
visualization:
23+
model_file: geometry/float_cog.obj
24+
25+
- name: body2
26+
location: [0.0, 0.0, -21.5]
27+
mass: 886691
28+
fixed: false
29+
inertia:
30+
moments: [94419614.57, 94407091.24, 28542224.82]
31+
products: [0, 0, 0]
32+
com:
33+
location: [0, 0, 0]
34+
orientation: [0, 0, 0]
35+
visualization:
36+
model_file: geometry/plate_cog.obj
37+
38+
joints:
39+
- name: float_plate_joint
40+
type: PRISMATIC
41+
body1: body1
42+
body2: body2
43+
location: [0, 0, -0.72]
44+
axis: [0, 0, 1]
45+
46+
tsdas:
47+
- name: PTO
48+
type: TSDA
49+
body1: body1
50+
body2: body2
51+
point1: [0, 0, -0.72]
52+
point2: [0, 0, -21.5]
53+
spring_coefficient: 0
54+
damping_coefficient: 1200000
55+
free_length: 0.0
56+
visualization:
57+
type: SPRING
58+
radius: 0.3
59+
resolution: 80
60+
turns: 15
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
model_file: rm3_mooring.model.yaml
2+
simulation_file: rm3.simulation.yaml
3+
hydro_file: rm3_mooring.hydro.yaml
4+
output_directory: results/rm3_mooring

demos/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ build_demo(sphere sphere_irreg_waves)
3636
build_demo(sphere sphere_irreg_waves_eta_import)
3737
build_demo(rm3 rm3_decay)
3838
build_demo(rm3 rm3_reg_waves)
39+
if(HYDROCHRONO_ENABLE_MOORDYN)
40+
build_demo(rm3 rm3_mooring)
41+
endif()
3942
build_demo(oswec oswec_decay)
4043
build_demo(oswec oswec_reg_waves)
4144
build_demo(f3of f3of_dt1)

demos/rm3/demo_rm3_mooring.cpp

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#include <hydroc/gui/guihelper.h>
2+
#include <hydroc/helper.h>
3+
#include <hydroc/hydro_system.h>
4+
#include <hydroc/logging.h>
5+
6+
#ifdef HYDROCHRONO_HAVE_MOORDYN
7+
#include <hydroc/config/moordyn_config.h>
8+
#endif
9+
10+
#include <chrono/core/ChRealtimeStep.h>
11+
#include <chrono/physics/ChBodyEasy.h>
12+
#include <chrono/physics/ChSystemNSC.h>
13+
14+
#include <chrono>
15+
#include <iomanip>
16+
#include <vector>
17+
18+
using namespace chrono;
19+
20+
int main(int argc, char* argv[]) {
21+
std::cout << "Chrono version: " << CHRONO_VERSION << "\n\n";
22+
23+
bool profilingOn = true;
24+
bool saveDataOn = true;
25+
bool plotOn = true;
26+
bool visualizationOn = true;
27+
std::string data_dir;
28+
if (!hydroc::GetCLIArguments(argc, argv, "RM3 mooring demo", saveDataOn, profilingOn, plotOn, visualizationOn,
29+
data_dir))
30+
return 1;
31+
if (!hydroc::SetInitialEnvironment(data_dir)) return 1;
32+
33+
std::filesystem::path DATADIR(hydroc::getDataDir());
34+
std::cout << "Data directory: " << DATADIR << std::endl;
35+
36+
auto body1_meshfame =
37+
(DATADIR / "demos" / "rm3" / "geometry" / "float_cog.obj").lexically_normal().generic_string();
38+
auto body2_meshfame =
39+
(DATADIR / "demos" / "rm3" / "geometry" / "plate_cog.obj").lexically_normal().generic_string();
40+
auto h5fname = (DATADIR / "demos" / "rm3" / "hydroData" / "rm3.h5").lexically_normal().generic_string();
41+
42+
std::cout << " body1 mesh: " << body1_meshfame << std::endl;
43+
std::cout << " body2 mesh: " << body2_meshfame << std::endl;
44+
std::cout << " h5 file: " << h5fname << std::endl;
45+
46+
// System and solver
47+
ChSystemNSC system;
48+
system.SetGravitationalAcceleration(ChVector3d(0.0, 0.0, -9.81));
49+
double timestep = 0.01;
50+
system.SetTimestepperType(ChTimestepper::Type::HHT);
51+
system.SetSolverType(ChSolver::Type::SPARSE_LU);
52+
ChRealtimeStepTimer realtime_timer;
53+
double simulationDuration = 40.0;
54+
55+
std::shared_ptr<hydroc::gui::UI> pui = hydroc::gui::CreateUI(visualizationOn);
56+
hydroc::gui::UI& ui = *pui.get();
57+
58+
std::vector<double> time_vector;
59+
std::vector<double> float_heave_position;
60+
std::vector<double> float_drift_position;
61+
std::vector<double> plate_heave_position;
62+
63+
// Float body
64+
std::cout << "Loading float mesh: " << body1_meshfame << std::endl;
65+
std::shared_ptr<ChBody> float_body1 = chrono_types::make_shared<ChBodyEasyMesh>(
66+
body1_meshfame, 0, false, true, false);
67+
68+
system.Add(float_body1);
69+
float_body1->SetName("body1");
70+
float_body1->SetPos(ChVector3d(0, 0, -0.72));
71+
float_body1->SetMass(725834);
72+
float_body1->SetInertiaXX(ChVector3d(20907301.0, 21306090.66, 37085481.11));
73+
74+
auto red = chrono_types::make_shared<ChVisualMaterial>();
75+
red->SetDiffuseColor(ChColor(0.3f, 0.1f, 0.1f));
76+
float_body1->GetVisualShape(0)->SetMaterial(0, red);
77+
78+
// Plate body
79+
std::cout << "Loading plate mesh: " << body2_meshfame << std::endl;
80+
std::shared_ptr<ChBody> plate_body2 = chrono_types::make_shared<ChBodyEasyMesh>(
81+
body2_meshfame, 0, false, true, false);
82+
83+
system.Add(plate_body2);
84+
plate_body2->SetName("body2");
85+
plate_body2->SetPos(ChVector3d(0, 0, -21.29));
86+
plate_body2->SetMass(886691);
87+
plate_body2->SetInertiaXX(ChVector3d(94419614.57, 94407091.24, 28542224.82));
88+
89+
auto blue = chrono_types::make_shared<ChVisualMaterial>();
90+
blue->SetDiffuseColor(ChColor(0.3f, 0.1f, 0.6f));
91+
plate_body2->GetVisualShape(0)->SetMaterial(0, blue);
92+
93+
// Prismatic joint (vertical heave)
94+
auto prismatic = chrono_types::make_shared<ChLinkLockPrismatic>();
95+
prismatic->Initialize(float_body1, plate_body2, false, ChFramed(ChVector3d(0, 0, -0.72)),
96+
ChFramed(ChVector3d(0, 0, -21.29)));
97+
system.AddLink(prismatic);
98+
99+
// PTO damper
100+
auto prismatic_pto = chrono_types::make_shared<ChLinkTSDA>();
101+
prismatic_pto->Initialize(float_body1, plate_body2, false, ChVector3d(0, 0, -0.72), ChVector3d(0, 0, -21.29));
102+
prismatic_pto->SetDampingCoefficient(1200000.0);
103+
system.AddLink(prismatic_pto);
104+
105+
// Hydrodynamic forces
106+
std::vector<std::shared_ptr<ChBody>> bodies;
107+
bodies.push_back(float_body1);
108+
bodies.push_back(plate_body2);
109+
110+
auto my_hydro_inputs = std::make_shared<RegularWave>();
111+
my_hydro_inputs->regular_wave_amplitude_ = 1.0;
112+
my_hydro_inputs->regular_wave_omega_ = 2.10;
113+
114+
TestHydro hydro_forces(bodies, h5fname);
115+
116+
#ifdef HYDROCHRONO_HAVE_MOORDYN
117+
{
118+
auto moordyn_input =
119+
(DATADIR / "yaml" / "rm3" / "mooring" / "lines_rm3.txt").lexically_normal().generic_string();
120+
std::cout << " MoorDyn input: " << moordyn_input << std::endl;
121+
122+
MoorDynConfig md_cfg;
123+
md_cfg.enabled = true;
124+
md_cfg.input_file = moordyn_input;
125+
md_cfg.coupled_body_indices = {1}; // body2 (plate) = index 1
126+
hydro_forces.SetMoorDynConfig(md_cfg);
127+
}
128+
#endif
129+
130+
hydro_forces.AddWaves(my_hydro_inputs);
131+
132+
auto start = std::chrono::high_resolution_clock::now();
133+
134+
ui.Init(&system, "RM3 - Mooring Demo");
135+
ui.SetCamera(0, -50, -10, 0, 0, -10);
136+
ui.SetWaveModel(my_hydro_inputs);
137+
138+
while (system.GetChTime() <= simulationDuration) {
139+
if (ui.IsRunning(timestep) == false) break;
140+
141+
if (ui.simulationStarted) {
142+
system.DoStepDynamics(timestep);
143+
144+
time_vector.push_back(system.GetChTime());
145+
float_heave_position.push_back(float_body1->GetPos().z());
146+
float_drift_position.push_back(float_body1->GetPos().x());
147+
plate_heave_position.push_back(plate_body2->GetPos().z());
148+
}
149+
}
150+
151+
auto end = std::chrono::high_resolution_clock::now();
152+
unsigned duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
153+
154+
std::string out_dir = hydroc::getDemoOutDir();
155+
if (profilingOn || saveDataOn) {
156+
out_dir = out_dir + "/" + RESULTS_DIR_NAME;
157+
std::filesystem::create_directory(std::filesystem::path(out_dir));
158+
}
159+
160+
if (profilingOn) {
161+
std::ofstream profilingFile(out_dir + "/mooring_duration.txt");
162+
profilingFile << duration << " ms\n";
163+
profilingFile.close();
164+
}
165+
166+
if (saveDataOn) {
167+
std::ofstream outputFile(out_dir + "/mooring.txt");
168+
outputFile << std::left << std::setw(10) << "Time (s)" << std::right << std::setw(16) << "Float Heave (m)"
169+
<< std::right << std::setw(16) << "Plate Heave (m)" << std::right << std::setw(16)
170+
<< "Float Drift (x) (m)" << std::endl;
171+
for (size_t i = 0; i < time_vector.size(); ++i)
172+
outputFile << std::left << std::setw(10) << std::setprecision(2) << std::fixed << time_vector[i]
173+
<< std::right << std::setw(16) << std::setprecision(8) << std::fixed << float_heave_position[i]
174+
<< std::right << std::setw(16) << std::setprecision(8) << std::fixed << plate_heave_position[i]
175+
<< std::right << std::setw(16) << std::setprecision(8) << std::fixed << float_drift_position[i]
176+
<< std::endl;
177+
outputFile.close();
178+
}
179+
return 0;
180+
}

0 commit comments

Comments
 (0)