From 774c87f8b7b6023af0eb875837342a6e3c9a7521 Mon Sep 17 00:00:00 2001 From: Jose Luis Cercos-Pita Date: Wed, 19 Nov 2025 09:07:43 +0100 Subject: [PATCH] fix(core): Explicit names for the elastic models --- source/Line.cpp | 37 ++++++++++++++++++------------------- source/Line.hpp | 45 ++++++++++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/source/Line.cpp b/source/Line.cpp index 206dfeca..cc766b93 100644 --- a/source/Line.cpp +++ b/source/Line.cpp @@ -152,7 +152,7 @@ Line::setup(int number_in, d = props->d; A = pi / 4. * d * d; rho = props->w / A; - ElasticMod = props->ElasticMod; + ElasticMod = (elastic_model)props->ElasticMod; EA = props->EA; EA_D = props->EA_D; alphaMBL = props->alphaMBL; @@ -242,7 +242,7 @@ Line::setup(int number_in, // segments) (1 = fully submerged, 0 = out of water) // viscoelastic things - if (ElasticMod > 1) { + if (ElasticMod != ELASTIC_CONSTANT) { dl_1.assign( N, 0.0); // segment stretch attributed to static stiffness portion [m] @@ -615,7 +615,7 @@ Line::initialize() // the segment. This is required here to initalize the state as non-zero, // which avoids an initial transient where the segment goes from unstretched // to stretched in one time step. - if (ElasticMod > 1) { + if (ElasticMod != ELASTIC_CONSTANT) { for (unsigned int i = 0; i < N; i++) { lstr[i] = unitvector(qs[i], r[i], r[i + 1]); dl_1[i] = lstr[i] - l[i]; // delta l of the segment @@ -790,24 +790,24 @@ Line::setState(const InstanceStateVarView state) // Error check for number of columns (if VIV and Visco need row.size() = 8, // if VIV xor Visco need row.size() = 7, if not VIV need row.size() = 6) - if ((state.row(0).size() != 8 && Cl > 0 && ElasticMod > 1) || - (state.row(0).size() != 7 && ((Cl > 0) ^ (ElasticMod > 1))) || - (state.row(0).size() != 6 && Cl == 0 && ElasticMod == 1)) { + if ((state.row(0).size() != 8 && Cl > 0 && ElasticMod != ELASTIC_CONSTANT) || + (state.row(0).size() != 7 && ((Cl > 0) ^ (ElasticMod != ELASTIC_CONSTANT))) || + (state.row(0).size() != 6 && Cl == 0 && ElasticMod == ELASTIC_CONSTANT)) { LOGERR << "Invalid state.row size for Line " << number << endl; throw moordyn::mem_error("Invalid state.row size"); } // Error check for number of rows (if visco need N rows, if normal need N-1 // rows) - if ((state.rows() != N && ElasticMod > 1) || - (state.rows() != N - 1 && ElasticMod == 1)) { + if ((state.rows() != N && ElasticMod != ELASTIC_CONSTANT) || + (state.rows() != N - 1 && ElasticMod == ELASTIC_CONSTANT)) { LOGERR << "Invalid number of rows in state matrix for Line " << number << endl; throw moordyn::mem_error("Invalid number of rows in state matrix"); } // If using the viscoelastic model, interate N rows, else iterate N-1 rows. - for (unsigned int i = 0; i < (ElasticMod > 1 ? N : N - 1); i++) { + for (unsigned int i = 0; i < (ElasticMod != ELASTIC_CONSTANT ? N : N - 1); i++) { // node number is i+1 // segment number is i if (i < N - 1) { // only assign the internal nodes @@ -815,7 +815,7 @@ Line::setState(const InstanceStateVarView state) rd[i + 1] = state.row(i).segment<3>(3); } - if (ElasticMod > 1) + if (ElasticMod != ELASTIC_CONSTANT) dl_1[i] = state.row(i) .tail<1>()[0]; // [0] needed becasue tail<1> returns a one @@ -826,7 +826,7 @@ Line::setState(const InstanceStateVarView state) !(IC_gen)) { // not needed in IC_gen. Initializes as distribution on // 0-2pi. State is initialized by init function in this // code, which sets phi to range 0-2pi - if (ElasticMod > 1) + if (ElasticMod != ELASTIC_CONSTANT) phi[i + 1] = state.row(i) .tail<2>()[0]; // if both VIV and viscoelastic second to @@ -1010,7 +1010,7 @@ Line::getStateDeriv(InstanceStateVarView drdt) // V[i] = A * l[i]; // volume attributed to segment // Calculate segment stiffness - if (ElasticMod == 1) { + if (ElasticMod == ELASTIC_CONSTANT) { // line tension if (nEApoints > 0) EA = getNonlinearEA(lstr[i], l[i]); @@ -1028,18 +1028,17 @@ Line::getStateDeriv(InstanceStateVarView drdt) BA = getNonlinearBA(ldstr[i], l[i]); Td[i] = BA * ldstr[i] / l[i] * qs[i]; - } else if ( - ElasticMod > - 1) { // viscoelastic model from - // https://asmedigitalcollection.asme.org/OMAE/proceedings/IOWTC2023/87578/V001T01A029/1195018 + } else { + // viscoelastic model from + // https://asmedigitalcollection.asme.org/OMAE/proceedings/IOWTC2023/87578/V001T01A029/1195018 // note that dl_1[i] is the same as Line%dl_1 in MD-F. This is the // deltaL of the first static spring k1. - if (ElasticMod == 2) { + if (ElasticMod == ELASTIC_VISCO_CTE) { // constant dynamic stiffness EA_2 = EA_D; - } else if (ElasticMod == 3) { + } else if (ElasticMod == ELASTIC_VISCO_MEAN) { if (dl_1[i] >= 0.0) // spring k1 is in tension // Mean load dependent dynamic stiffness: from combining // eqn. 2 and eqn. 10 from original MD viscoelastic paper, @@ -1468,7 +1467,7 @@ Line::getStateDeriv(InstanceStateVarView drdt) // Update state derivative for VIV. i-1 indexing because this is // only called for internal nodes (i.e. node 1 maps to row 0 in the // state deriv matrix). - if (ElasticMod > 1) + if (ElasticMod != ELASTIC_CONSTANT) drdt.row(i - 1).tail<2>()[0] = phi_dot[i]; // second to last element if visco model else diff --git a/source/Line.hpp b/source/Line.hpp index 9661c789..70cf74b2 100644 --- a/source/Line.hpp +++ b/source/Line.hpp @@ -85,6 +85,18 @@ class DECLDIR Line final ~Line(); private: + /// @brief Elasticity models + typedef enum + { + /// Constant EA + ELASTIC_CONSTANT = 1, + /// viscoelastic model with constant dynamic stiffness + ELASTIC_VISCO_CTE = 2, + /// mean load dependent dynamic stiffness + ELASTIC_VISCO_MEAN = 3, + } elastic_model; + + /** @brief Get the non-linear stiffness. This is interpolated from a * curve provided in the input file. * @param l_stretched The actual length of the segment @@ -142,9 +154,8 @@ class DECLDIR Line final moordyn::real d; /// line density (kg/m^3) moordyn::real rho; - /// Elasticity model flag (1: constant EA, 2: viscoelastic model with - /// constant dynamic stiffness, 3: mean load depenedent dynamic stiffness) - unsigned int ElasticMod; + /// Elasticity model flag. See ::elastic_model + elastic_model ElasticMod; /// line normal/static elasticity modulus * crosssectional area [N] moordyn::real EA; /// constant line dynamic stiffness modulus * area for viscoelastic stuff @@ -158,8 +169,8 @@ class DECLDIR Line final moordyn::real vbeta; /// stiffness of spring 2 in viscoelastic model (dynamic stiffness). This is /// the spring in series with the parallel spring-dashpot. if ElasticMod = - /// 2, EA_2 = EA_D. If ElasticMod = 3, EA_2 is load dependent dynamic - /// stiffness. + /// ELASTIC_VISCO_CTE, EA_2 = EA_D. If ElasticMod = ELASTIC_VISCO_MEAN, EA_2 + /// is load dependent dynamic stiffness. moordyn::real EA_2; /// segment stretch attributed to static stiffness portion [m] (deltaL_1) std::vector dl_1; @@ -435,17 +446,17 @@ class DECLDIR Line final // Line::setState but flipped) ------ Error check for number of columns // (if VIV and Visco need row.size() = 8, if VIV xor Visco need // row.size() = 7, if not VIV need row.size() = 6) - if ((state.row(0).size() != 8 && Cl > 0 && ElasticMod > 1) || - (state.row(0).size() != 7 && ((Cl > 0) ^ (ElasticMod > 1))) || - (state.row(0).size() != 6 && Cl == 0 && ElasticMod == 1)) { + if ((state.row(0).size() != 8 && Cl > 0 && ElasticMod != ELASTIC_CONSTANT) || + (state.row(0).size() != 7 && ((Cl > 0) ^ (ElasticMod != ELASTIC_CONSTANT))) || + (state.row(0).size() != 6 && Cl == 0 && ElasticMod == ELASTIC_CONSTANT)) { LOGERR << "Invalid state.row size for Line " << number << endl; throw moordyn::mem_error("Invalid state.row size"); } // Error check for number of rows (if visco need N rows, if normal need // N-1 rows) - if ((state.rows() != N && ElasticMod > 1) || - (state.rows() != N - 1 && ElasticMod == 1)) { + if ((state.rows() != N && ElasticMod != ELASTIC_CONSTANT) || + (state.rows() != N - 1 && ElasticMod == ELASTIC_CONSTANT)) { LOGERR << "Invalid number of rows in state matrix for Line " << number << endl; throw moordyn::mem_error("Invalid number of rows in state matrix"); @@ -453,20 +464,20 @@ class DECLDIR Line final // If using the viscoelastic model, iterate N rows, else iterate N-1 // rows. - for (unsigned int i = 0; i < (ElasticMod > 1 ? N : N - 1); i++) { + for (unsigned int i = 0; i < (ElasticMod != ELASTIC_CONSTANT ? N : N - 1); i++) { // node number is i+1 // segment number is i state.row(i).head<3>() = r[i + 1]; state.row(i).segment<3>(3) = rd[i + 1]; - if (ElasticMod > 1) + if (ElasticMod != ELASTIC_CONSTANT) state.row(i).tail<1>()[0] = dl_1[i]; // [0] needed becasue tail<1> returns a one element // vector. Viscoelastic state is always the last // element in the row if (Cl > 0) { - if (ElasticMod > 1) + if (ElasticMod != ELASTIC_CONSTANT) state.row(i).tail<2>()[0] = phi[i + 1]; // if both VIV and viscoelastic second to // last element in the row @@ -561,7 +572,7 @@ class DECLDIR Line final */ inline void setConstantEA(moordyn::real EA_in) { - if (ElasticMod > 1) { + if (ElasticMod != ELASTIC_CONSTANT) { LOGERR << "Cannot set constant EA for viscoelastic model" << endl; throw moordyn::invalid_value_error( "Cannot set constant EA for viscoelastic model"); @@ -1014,7 +1025,7 @@ class DECLDIR Line final */ inline const size_t stateN() const { - if (ElasticMod > 1) + if (ElasticMod != ELASTIC_CONSTANT) return getN(); // N rows for viscoelastic case else return getN() - 1; // N-1 rows for other cases @@ -1032,10 +1043,10 @@ class DECLDIR Line final */ inline const size_t stateDims() const { - if (Cl > 0 && ElasticMod > 1) + if (Cl > 0 && ElasticMod != ELASTIC_CONSTANT) return 8; // 3 for position, 3 for velocity, 1 for VIV phase, 1 for // viscoelasticity - else if ((Cl > 0) ^ (ElasticMod > 1)) + else if ((Cl > 0) ^ (ElasticMod != ELASTIC_CONSTANT)) return 7; // 3 for position, 3 for velocity, 1 for VIV phase or // viscoelasticity else