Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/inputs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,15 @@ outputs are wanted. Eight output properties are currently possible:
- c – internal damping force at each segment
- s – strain of each segment
- d – rate of strain of each segment

- f – net node force
- W – weight at each node
- B – buoyancy force at each node
- P – dynamic pressure at each node
- X – transverse drag force at each node
- Y – tangential drag force at each node
- A – transverse fluid inertia force at each node
- a – tangential fluid inertia force at each node
- b – bottom contact force
For example, outputting node positions and segment tensions could be achieved by writing “pt” for
this last column. These outputs will go to a dedicated output file for each rod. For sending
values to the global output file, use the Outputs section instead.
Expand Down
158 changes: 91 additions & 67 deletions source/Line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "Util/Interp.hpp"
#include <tuple>
// #include <random>
#include <iomanip>

#ifdef USE_VTK
#include "Util/VTK_Util.hpp"
Expand All @@ -46,6 +47,10 @@
#include <vtkXMLPolyDataWriter.h>
#endif

// Formating constants for line files outputs (iomanip)
constexpr int WIDTH = 20; // Width for output
constexpr int PRECISION = 7; // Precision for output

using namespace std;

namespace moordyn {
Expand Down Expand Up @@ -302,80 +307,87 @@ Line::initialize()
// 1st line with the fields

// output time
*outfile << "Time"
<< "\t ";
*outfile << setw(10) << right
<< "Time";

// output positions
if (channels.find("p") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
*outfile << "Node" << i << "px \t Node" << i << "py \t Node"
<< i << "pz \t ";
*outfile << setw(WIDTH) << right << ("Node" + to_string((int)i) + "px")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "py")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "pz");
}
}
// output curvatures
if (channels.find("K") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
*outfile << "Node" << i << "Ku \t ";
*outfile << setw(WIDTH) << right << ("Node" + to_string((int)i) + "Ku");
}
}
// output velocities
if (channels.find("v") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
*outfile << "Node" << i << "vx \t Node" << i << "vy \t Node"
<< i << "vz \t ";
*outfile << setw(WIDTH) << right << ("Node" + to_string((int)i) + "vx")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "vy")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "vz");
}
}
// output wave velocities
if (channels.find("U") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
*outfile << "Node" << i << "Ux \t Node" << i << "Uy \t Node"
<< i << "Uz \t ";
*outfile << setw(WIDTH) << right << ("Node" + to_string((int)i) + "Ux")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "Uy")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "Uz");
}
}
// output hydro force
if (channels.find("D") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
*outfile << "Node" << i << "Dx \t Node" << i << "Dy \t Node"
<< i << "Dz \t ";
*outfile << setw(WIDTH) << right << ("Node" + to_string((int)i) + "Dx")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "Dy")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "Dz");
}
}
// output VIV lift force
if (channels.find("V") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
*outfile << "Node" << i << "Vx \t Node" << i << "Vy \t Node"
<< i << "Vz \t ";
*outfile << setw(WIDTH) << right << ("Node" + to_string((int)i) + "Vx")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "Vy")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "Vz");
}
}
// output segment tensions
if (channels.find("t") != string::npos) {
for (unsigned int i = 1; i <= N; i++) {
*outfile << "Seg" << i << "Te \t ";
*outfile << setw(WIDTH) << right << ("Seg" + to_string((int)i) + "Te");
}
}
// output internal damping force
if (channels.find("c") != string::npos) {
for (unsigned int i = 1; i <= N; i++) {
*outfile << "Seg" << i << "cx \t Seg" << i << "cy \t Seg" << i
<< "cz \t ";
*outfile << setw(WIDTH) << right << ("Seg" + to_string((int)i) + "cx")
<< setw(WIDTH) << right << ("Seg" + to_string((int)i) + "cy")
<< setw(WIDTH) << right << ("Seg" + to_string((int)i) + "cz");
}
}
// output segment strains
if (channels.find("s") != string::npos) {
for (unsigned int i = 1; i <= N; i++) {
*outfile << "Seg" << i << "St \t ";
*outfile << setw(WIDTH) << right << ("Seg" + to_string((int)i) + "St");
}
}
// output segment strain rates
if (channels.find("d") != string::npos) {
for (unsigned int i = 1; i <= N; i++) {
*outfile << "Seg" << i << "dSt \t ";
*outfile << setw(WIDTH) << right << ("Seg" + to_string((int)i) + "dSt");
}
}
// output seabed contact forces
if (channels.find("b") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
*outfile << "Node" << i << "bx \t Node" << i << "by \t Node"
<< i << "bz \t ";
*outfile << setw(WIDTH) << right << ("Node" + to_string((int)i) + "bx")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "by")
<< setw(WIDTH) << right << ("Node" + to_string((int)i) + "bz");
}
}

Expand All @@ -385,64 +397,75 @@ Line::initialize()
// 2nd line with the units

// output time
*outfile << "(s)"
<< "\t ";
*outfile << setw(10) << right
<< "(s)";

// output positions
if (channels.find("p") != string::npos) {
for (unsigned int i = 0; i <= 3 * N + 2; i++)
*outfile << "(m) \t";
*outfile << setw(WIDTH) << right
<< "(m)";
}
// output curvatures?
if (channels.find("K") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
*outfile << "(1/m) \t ";
*outfile << setw(WIDTH) << right
<< "(1/m)";
}
}
// output velocities?
if (channels.find("v") != string::npos) {
for (unsigned int i = 0; i <= 3 * N + 2; i++)
*outfile << "(m/s) \t";
*outfile << setw(WIDTH) << right
<< "(m/s)";
}
// output wave velocities?
if (channels.find("U") != string::npos) {
for (unsigned int i = 0; i <= 3 * N + 2; i++)
*outfile << "(m/s) \t";
*outfile << setw(WIDTH) << right
<< "(m/s)";
}
// output hydro force
if (channels.find("D") != string::npos) {
for (unsigned int i = 0; i <= 3 * N + 2; i++)
*outfile << "(N) \t";
*outfile << setw(WIDTH) << right
<< "(N)";
}
// output VIV force
if (channels.find("V") != string::npos) {
for (unsigned int i = 0; i <= 3 * N + 2; i++)
*outfile << "(N) \t";
*outfile << setw(WIDTH) << right
<< "(N)";
}
// output segment tensions?
if (channels.find("t") != string::npos) {
for (unsigned int i = 0; i < N; i++)
*outfile << "(N) \t";
*outfile << setw(WIDTH) << right
<< "(N)";
}
// output internal damping force?
if (channels.find("c") != string::npos) {
for (unsigned int i = 0; i < 3 * N; i++)
*outfile << "(N) \t";
*outfile << setw(WIDTH) << right
<< "(N)";
}
// output segment strains?
if (channels.find("s") != string::npos) {
for (unsigned int i = 0; i < N; i++)
*outfile << "(-) \t";
*outfile << setw(WIDTH) << right
<< "(-)";
}
// output segment strain rates?
if (channels.find("d") != string::npos) {
for (unsigned int i = 0; i < N; i++)
*outfile << "(-/s) \t";
*outfile << setw(WIDTH) << right
<< "(-/s)";
}
// output seabed contact force?
if (channels.find("b") != string::npos) {
for (unsigned int i = 0; i <= 3 * N + 2; i++)
*outfile << "(N) \t";
*outfile << setw(WIDTH) << right
<< "(N)";
}

*outfile << "\n";
Expand Down Expand Up @@ -1554,66 +1577,73 @@ Line::Output(real time)
// Flags changed to just be one character (case sensitive) per output flag.
// To match FASTv8 version.

// Helper to format and write a single value
auto write_val = [&](real val) {
*outfile << std::setw(WIDTH)
<< std::right
<< std::scientific
<< std::setprecision(PRECISION)
<< val;
};

if (outfile) // if not a null pointer (indicating no output)
{
if (!outfile->is_open()) {
LOGWRN << "Unable to write to output file " << endl;
return;
}
// Loops through the nodes
auto write_vec_array = [&](const std::vector<vec>& arr) {
for (unsigned int i = 0; i <= N; i++)
for (unsigned int J = 0; J < 3; J++){
write_val(arr[i][J]);}

};
// Loops through the nodes for scalars
auto write_scalar_array = [&](const std::vector<real>& arr) {
for (unsigned int i = 0; i <= N; i++)
write_val(arr[i]);
};
// output time
*outfile << time << "\t ";
*outfile << setw(10) << right << fixed << setprecision(4)
<< time;

// output positions?
// if (find(channels.begin(), channels.end(), "position") !=
// channels.end())
if (channels.find("p") != string::npos) {
for (unsigned int i = 0; i <= N; i++) // loop through nodes
{
for (unsigned int J = 0; J < 3; J++)
*outfile << r[i][J] << "\t ";
}
write_vec_array(r); // position
}

// output curvatures?
if (channels.find("K") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
*outfile << Kurv[i] << "\t ";
}
write_scalar_array(Kurv);
}
// output velocities?
if (channels.find("v") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
for (int J = 0; J < 3; J++)
*outfile << rd[i][J] << "\t ";
}
write_vec_array(rd);
}
// output wave velocities?
if (channels.find("U") != string::npos) {
auto [_z, U, _ud, _pdyn] = waves->getWaveKinLine(lineId);
for (unsigned int i = 0; i <= N; i++) {
for (int J = 0; J < 3; J++)
*outfile << U[i][J] << "\t ";
}
write_vec_array(U);
}
// output hydro drag force?
if (channels.find("D") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
for (int J = 0; J < 3; J++)
*outfile << Dp[i][J] + Dq[i][J] + Ap[i][J] + Aq[i][J]
<< "\t ";
write_val(Dp[i][J] + Dq[i][J] + Ap[i][J] + Aq[i][J]);
}
}

// output VIV force (only CF for now)
if (channels.find("V") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
for (int J = 0; J < 3; J++)
*outfile << Lf[i][J] << "\t ";
}
write_vec_array(Lf);
}
// output segment tensions?
if (channels.find("t") != string::npos) {
for (unsigned int i = 0; i < N; i++) {
*outfile << T[i].norm() << "\t ";
write_val(T[i].norm());
// >>> preparation below for switching to outputs at nodes
// <<< note that tension of end nodes will need weight and
// buoyancy adjustment
Expand All @@ -1627,29 +1657,23 @@ Line::Output(real time)
}
// output internal damping force?
if (channels.find("c") != string::npos) {
for (unsigned int i = 0; i < N; i++) {
for (int J = 0; J < 3; J++)
*outfile << Td[i][J] << "\t ";
}
write_vec_array(Td); // internal damping force
}
// output segment strains?
if (channels.find("s") != string::npos) {
for (unsigned int i = 0; i < N; i++) {
*outfile << lstr[i] / l[i] - 1.0 << "\t ";
write_val(lstr[i] / l[i] - 1.0);
}
}
// output segment strain rates?
if (channels.find("d") != string::npos) {
for (unsigned int i = 0; i < N; i++) {
*outfile << ldstr[i] / l[i] << "\t ";
write_val(ldstr[i] / l[i]);
}
}
// output seabed contact forces?
if (channels.find("b") != string::npos) {
for (unsigned int i = 0; i <= N; i++) {
for (int J = 0; J < 3; J++)
*outfile << B[i][J] << "\t ";
}
write_vec_array(B);
}

*outfile << "\n";
Expand Down
Loading
Loading