|
| 1 | +/********************************************************************* |
| 2 | + * @file added_mass.h |
| 3 | + * @brief ChLoadAddedMass: Chrono load for infinite-frequency added mass. |
| 4 | + * |
| 5 | + * STATUS: LEGACY IMPLEMENTATION -- retained for reference and as a |
| 6 | + * switchable alternative. The default added-mass path now uses |
| 7 | + * Chrono's built-in ChLoadHydrodynamics. |
| 8 | + * |
| 9 | + * To activate this implementation, define HYDROCHRONO_USE_LEGACY_ADDED_MASS |
| 10 | + * in hydro_system.h (see toggle comment near the top of that file). |
| 11 | + * |
| 12 | + * MAIN TYPES: |
| 13 | + * - ChLoadAddedMass: ChLoadCustomMultiple subclass that applies |
| 14 | + * added mass from HDF5 hydrodynamic data to Chrono bodies. |
| 15 | + * |
| 16 | + * ROLE: Chrono coupling layer. Provides a ChLoadCustomMultiple-based |
| 17 | + * approach to applying added mass forces to the Chrono simulation system. |
| 18 | + *********************************************************************/ |
| 19 | + |
| 20 | +#ifndef HYDROC_COUPLING_ADDED_MASS_H |
| 21 | +#define HYDROC_COUPLING_ADDED_MASS_H |
| 22 | + |
| 23 | +#include <chrono/core/ChMatrix.h> |
| 24 | +#include <chrono/physics/ChBody.h> |
| 25 | +#include <hydroc/io/h5_reader.h> |
| 26 | +#include <vector> |
| 27 | + |
| 28 | +#include <chrono/physics/ChLoad.h> |
| 29 | +#include <chrono/physics/ChSystem.h> |
| 30 | + |
| 31 | +// ============================================================================= |
| 32 | +class ChLoadAddedMass : public chrono::ChLoadCustomMultiple { |
| 33 | + public: |
| 34 | + /** |
| 35 | + * @brief Initializes body to have load applied to and added mass matrix from h5 file initialized object. |
| 36 | + * |
| 37 | + * Vector of bodies with hydro forces (and added mass) need to be listed in same order as they are added to the |
| 38 | + * system. Also need to be separate from any bodies without hydro forces (or added mass) and hydro bodies need to be |
| 39 | + * added to system before any bodies without hydro forces applied. |
| 40 | + * |
| 41 | + * @param body_info_struct HydroData::BodyInfo for each body with h5 information including added mass matrix |
| 42 | + * @param bodies vector of Project Chrono bodies to apply added mass to. Must be added to system in same order as in |
| 43 | + * this matrix. |
| 44 | + * @param system pointer to system containing the bodies, used for getting system mass matrix size at any time. |
| 45 | + */ |
| 46 | + ChLoadAddedMass(const std::vector<HydroData::BodyInfo>& body_info_struct, |
| 47 | + std::vector<std::shared_ptr<chrono::ChLoadable>>& bodies, |
| 48 | + chrono::ChSystem* system); |
| 49 | + |
| 50 | + /** |
| 51 | + * @brief "Virtual" copy constructor (covariant return type). Required from chrono inheritance. |
| 52 | + */ |
| 53 | + virtual ChLoadAddedMass* Clone() const override { return new ChLoadAddedMass(*this); } |
| 54 | + |
| 55 | + /** |
| 56 | + * @brief Compute Q, the generalized load. |
| 57 | + * |
| 58 | + * From Chrono documentation: |
| 59 | + * In this case, it computes the quadratic (centrifugal, gyroscopic) terms. |
| 60 | + * Signs are negative as Q assumed at right hand side, so Q= -Fgyro -Fcentrifugal |
| 61 | + * Called automatically at each Update(). |
| 62 | + * The M*a term is not added: to this end one could use LoadIntLoadResidual_Mv afterward. |
| 63 | + */ |
| 64 | + virtual void ComputeQ(chrono::ChState* state_x, ///< state position to evaluate Q |
| 65 | + chrono::ChStateDelta* state_w ///< state speed to evaluate Q |
| 66 | + ) override {} |
| 67 | + |
| 68 | + /** |
| 69 | + * @brief This is the function that sets the infinite added mass matrix every timestep. |
| 70 | + * |
| 71 | + * From Chrono docs: |
| 72 | + * Compute the K=-dQ/dx, R=-dQ/dv, M=-dQ/da Jacobians. |
| 73 | + * Implementation in a derived class should load the Jacobian matrices K, R, M in the structure 'm_jacobians'. |
| 74 | + * Note the sign that is flipped because we assume equations are written with Q moved to left-hand side. |
| 75 | + * |
| 76 | + * @param state_x state position to evaluate jacobians |
| 77 | + * @param state_w state speed to evaluate jacobians |
| 78 | + */ |
| 79 | + virtual void ComputeJacobian(chrono::ChState* state_x, chrono::ChStateDelta* state_w) override; |
| 80 | + |
| 81 | + /** |
| 82 | + * @brief Computes LoadIntLoadResidual_Mv for vector w, const c, and vector R. Also carried over from chrono |
| 83 | + * inheritance. |
| 84 | + * |
| 85 | + * Note R here is vector, and is not R gyroscopic damping matrix from ComputeJacobian. |
| 86 | + * Just for efficiency, override the default LoadIntLoadResidual_Mv, because we can do this in a simplified way. |
| 87 | + * |
| 88 | + * @param R result: the R residual, R += c*M*w |
| 89 | + * @param w the w vector |
| 90 | + * @param c a scaling factor |
| 91 | + */ |
| 92 | + virtual void LoadIntLoadResidual_Mv(chrono::ChVectorDynamic<>& R, |
| 93 | + const chrono::ChVectorDynamic<>& w, |
| 94 | + const double c) override; |
| 95 | + |
| 96 | + private: |
| 97 | + chrono::ChSystem* system; |
| 98 | + chrono::ChMatrixDynamic<double> infinite_added_mass; ///< added mass at infinite frequency in global coordinates |
| 99 | + chrono::ChMatrixDynamic<double> |
| 100 | + infinite_added_mass_system; ///< added mass at infinite frequency in global coordinates (system matrix) |
| 101 | + virtual bool IsStiff() override { return true; } // this to force the use of the inertial M, R and K matrices |
| 102 | +}; |
| 103 | + |
| 104 | +#endif // HYDROC_COUPLING_ADDED_MASS_H |
| 105 | + |
0 commit comments