3#define _USE_MATH_DEFINES
8#include "chrono/physics/ChSystem.h"
9#include "chrono/physics/ChSystemSMC.h"
10#include "chrono/physics/ChLoadContainer.h"
11#include "chrono/physics/ChLinkMate.h"
12#include "chrono/physics/ChBodyEasy.h"
13#include "chrono/physics/ChContactMaterial.h"
14#include "chrono/physics/ChContactMaterialSMC.h"
15#include "chrono/fea/ChElementBeamANCF_3333.h"
16#include "chrono/fea/ChElementCableANCF.h"
17#include "chrono/fea/ChElementBeamEuler.h"
18#include "chrono/fea/ChBeamSection.h"
19#include "chrono/fea/ChMesh.h"
20#include "chrono/fea/ChLinkNodeNode.h"
21#include "chrono/fea/ChLinkNodeFrame.h"
22#include "chrono/fea/ChLinkNodeSlopeFrame.h"
23#include "chrono/fea/ChLoadsBeam.h"
24#include "chrono/fea/ChContactSurfaceNodeCloud.h"
25#include "chrono/timestepper/ChTimestepper.h"
37 ChVectorN<double, 12> m_GenForceVec0;
38 virtual void SetupInitial(ChSystem* system)
override {
54 for (
int i = 0; i < 2; i++) {
55 m_element_dof += (i == 0 ? GetNodeA() : GetNodeB())->GetNumCoordsPosLevel();
57 m_full_dof = (m_element_dof == 2 * 6);
59 m_mapping_dof.resize(m_element_dof);
61 for (
int i = 0; i < 2; i++) {
62 auto node = (i == 0 ? GetNodeA() : GetNodeB());
63 for (
unsigned int j = 0; j < node->GetNumCoordsPosLevel(); j++)
64 m_mapping_dof(dof++) = i * 6 + j;
71 this->mass = this->length * GetDensity();
75 ChVectorDynamic<> FVector0(12);
77 m_GenForceVec0.setZero();
78 ComputeInternalForces(FVector0);
79 m_GenForceVec0 = FVector0;
107template <
typename Tag,
typename Tag::type Member>
113 using type = ChQuaternion<> chrono::fea::ChElementBeamEuler::*;
117 &chrono::fea::ChElementBeamEuler::q_element_ref_rot>;
125 virtual void SetupInitial(ChSystem* system)
override {
126 assert(GetSection());
131 this->mass = this->length * GetDensity();
135 auto node0 = GetNodeA();
136 auto node1 = GetNodeB();
137 ChVector3d mXele = node1->GetX0().GetPos() - node0->GetX0().GetPos();
142 ChVector3d myele = (node0->GetX0().GetRotMat().GetAxisY()
143 + node1->GetX0().GetRotMat().GetAxisY()).GetNormalized();
144 A0.SetFromAxisX(mXele, myele);
161 ComputeStiffnessMatrix();
169 ComputeGeometricStiffnessMatrix();
180 ChLoaderUdistributed(mloadable) {
181 Fa = ChVector3d(0.,0.,0.);
182 Fb = ChVector3d(0.,0.,0.);
189 ChVectorDynamic<>& F,
190 ChVectorDynamic<>* state_x,
191 ChVectorDynamic<>* state_w
193 double Fy_max = 0.005;
194 ChVector3d force =
Fa*abs(-1+
U)/2.+
Fb*(1+
U)/2.;
199 void SetF(ChVector3d Fa_in, ChVector3d Fb_in) {
236 std::vector<std::shared_ptr<ChNodeFEAxyzD>>
nodes;
237 std::vector<std::shared_ptr<ChNodeFEAxyzDD>>
nodesDD;
240 std::vector<std::shared_ptr<ChNodeFEAxyzrot>>
nodesRot;
278 void setIyy(
double Iyy_in);
292 std::vector<std::shared_ptr<cppCable>>
cables;
294 std::vector<double>
d;
296 std::vector<double>
E;
298 std::vector<std::shared_ptr<ChNodeFEAxyzD>>
nodes;
299 std::vector<std::shared_ptr<ChNodeFEAxyzDD>>
nodesDD;
300 std::vector<std::shared_ptr<ChNodeFEAxyzrot>>
nodesRot;
318 std::shared_ptr<ChMesh>
mesh,
319 std::vector<double>
length,
321 std::vector<double>
d,
322 std::vector<double>
rho,
323 std::vector<double>
E,
346 std::shared_ptr<ChMesh>
mesh,
347 std::vector<double>
length,
349 std::vector<double>
d,
350 std::vector<double>
rho,
351 std::vector<double>
E,
366 std::shared_ptr<cppCable> segment;
368 for (
int i = 0; i <
length.size(); ++i) {
369 segment = std::make_shared<cppCable>(
system,
378 cables.push_back(segment);
386 for (
int i = 0; i <
cables.size(); ++i) {
388 cables[i]->buildNodes(
true);
390 cables[i]->nodesRot.begin(),
391 cables[i]->nodesRot.end());
396 cables[i]->buildNodes(
false);
399 cables[i]->buildNodes(
true);
413 for (
int i = 0; i <
cables.size(); ++i) {
415 cables[i]->buildElements(
false);
424 cables[i]->buildElements(
true);
447 for (
int i = 0; i <
cables.size(); ++i) {
449 cables[i]->buildMesh(
false);
452 cables[i]->buildMesh(
true);
457 auto con1 = chrono_types::make_shared<ChLinkMateSpherical>();
458 auto nodeA =
cables[i]->nodesRot.front();
459 auto nodeB =
cables[i-1]->nodesRot.back();
460 con1->Initialize(nodeA, nodeB,
false, nodeA->GetPos(), nodeA->GetPos());
464 auto con1 = chrono_types::make_shared<ChLinkNodeNode>();
465 auto nodeA =
cables[i]->nodes.front();
466 auto nodeB =
cables[i-1]->nodes.back();
467 con1->Initialize(nodeA, nodeB);
498 int node_nb_prev = node_nb;
499 for (
int i = 0; i <
cables.size(); ++i) {
501 node_nb +=
cables[i]->nodesRot.size();
504 node_nb +=
cables[i]->nodes.size();
508 cables[i]->setFluidAccelerationAtNodes(fluid_acc);
509 node_nb_prev = node_nb;
516 int node_nb_prev = node_nb;
517 for (
int i = 0; i <
cables.size(); ++i) {
519 node_nb +=
cables[i]->nodesRot.size();
522 node_nb +=
cables[i]->nodes.size();
524 std::vector<ChVector3d> fluid_vel(
fluid_velocity.begin()+node_nb_prev,
526 cables[i]->setFluidVelocityAtNodes(fluid_vel);
527 node_nb_prev = node_nb;
534 int node_nb_prev = 0;
535 for (
int i = 0; i <
cables.size(); ++i) {
537 node_nb +=
cables[i]->nodesRot.size();
540 node_nb +=
cables[i]->nodes.size();
542 std::vector<double> fluid_dens(
fluid_density.begin()+node_nb_prev,
544 cables[i]->setFluidDensityAtNodes(fluid_dens);
545 node_nb_prev = node_nb;
551 for (
int i = 0; i <
cables.size(); ++i) {
552 cables[i]->setDragForce();
557 for (
int i = 0; i <
cables.size(); ++i) {
558 cables[i]->setAddedMassForce();
563 for (
int i = 0; i <
cables.size(); ++i) {
570 auto force = ChVector3d();
571 auto torque = ChVector3d();
580 auto mat2 = ChMatrixDynamic<>();
589 std::vector<std::shared_ptr<ChVector3d>> nodal_positions;
590 for (
int i = 0; i <
nodes.size(); ++i) {
591 auto pos =
nodes[i]->GetPos();
595 auto nodal_position = chrono_types::make_shared<ChVector3d>(x, y,
z);
596 nodal_positions.push_back(nodal_position);
598 return nodal_positions;
603 auto constraint = chrono_types::make_shared<ChLinkMateSpherical>();
610 auto constraint = chrono_types::make_shared<ChLinkNodeFrame>();
611 constraint->Initialize(
nodes.back(), body);
620 auto constraint = chrono_types::make_shared<ChLinkMateSpherical>();
627 auto constraint = chrono_types::make_shared<ChLinkNodeFrame>();
628 constraint->Initialize(
nodes.front(), body);
642 auto contact_cloud = chrono_types::make_shared<ChContactSurfaceNodeCloud>(
contact_material);
644 mesh->AddContactSurface(contact_cloud);
647 for (
int i = 0; i <
cables.size(); ++i) {
648 cables[i]->addNodestoContactCloud(contact_cloud);
655 std::shared_ptr<ChMesh>
mesh,
683 for (
int i = 0; i <
nb_elems; i++) {
733 std::shared_ptr<ChNodeFEAxyzrot> node;
735 ChVector3d ref = ChVector3d(1.,0.,0.);
736 ChQuaternion<> frame_quat;
737 for (
int i = 0; i <
mvecs.size() - 1; ++i) {
740 double ang = acos(dir^ref);
743 frame_quat.SetFromAngleAxis(ang, axis);
744 node = chrono_types::make_shared<ChNodeFEAxyzrot>(ChFrame<>(
mvecs[i],
747 std::shared_ptr<ChVector3d> drag0 = chrono_types::make_shared<ChVector3d>(0.,0.,0.);
748 std::shared_ptr<ChVector3d> am0 = chrono_types::make_shared<ChVector3d>(0.,0.,0.);
752 if (last_node ==
true) {
769 double ang = acos(dir^ref);
772 frame_quat.SetFromAngleAxis(ang, axis);
773 node = chrono_types::make_shared<ChNodeFEAxyzrot>(ChFrame<>(
mvecs[
mvecs.size()-1],
778 std::shared_ptr<ChVector3d> drag0 = chrono_types::make_shared<ChVector3d>(0.,0.,0.);
779 std::shared_ptr<ChVector3d> am0 = chrono_types::make_shared<ChVector3d>(0.,0.,0.);
793 std::shared_ptr<ChNodeFEAxyzD> node;
795 ChCoordsys<> coordsys;
796 for (
int i = 0; i <
mvecs.size() - 1; ++i) {
799 node = chrono_types::make_shared<ChNodeFEAxyzD>(
mvecs[i], dir);
800 nodes.push_back(node);
801 std::shared_ptr<ChVector3d> drag0 = chrono_types::make_shared<ChVector3d>(0.,0.,0.);
802 std::shared_ptr<ChVector3d> am0 = chrono_types::make_shared<ChVector3d>(0.,0.,0.);
806 if (last_node ==
true) {
809 node = chrono_types::make_shared<ChNodeFEAxyzD>(
mvecs[
mvecs.size()-1], dir);
810 nodes.push_back(node);
813 std::shared_ptr<ChVector3d> drag0 = chrono_types::make_shared<ChVector3d>(0.,0.,0.);
814 std::shared_ptr<ChVector3d> am0 = chrono_types::make_shared<ChVector3d>(0.,0.,0.);
834 auto loadcontainer = chrono_types::make_shared<ChLoadContainer>();
835 system->Add(loadcontainer);
836 mesh->SetAutomaticGravity(
false);
843 for (
int i = 0; i <
nb_elems; ++i) {
844 auto element = chrono_types::make_shared<ChElementCableANCFmod>();
845 auto load_distributed = chrono_types::make_shared<ChLoadBeamWrenchDistributed>(element);
846 auto load = chrono_types::make_shared<ChLoadBeamWrench>(element);
847 auto gravity = chrono_types::make_shared<ChLoaderGravity>(element);
848 gravity->SetGravitationalAcceleration(
system->GetGravitationalAcceleration());
849 std::shared_ptr<ChLoad> loadtri(
new ChLoad(gravity));
850 auto load_volumetric = chrono_types::make_shared<ChLoad>(gravity);
859 loadcontainer->Add(load_volumetric);
871 if (set_lastnodes ==
true) {
879 auto loadcontainer = chrono_types::make_shared<ChLoadContainer>();
880 system->Add(loadcontainer);
881 mesh->SetAutomaticGravity(
false);
887 for (
int i = 0; i <
nodesRot.size() - 1; ++i) {
888 auto element = chrono_types::make_shared<ChElementBeamEulermod>();
889 auto load_distributed = chrono_types::make_shared<ChLoadBeamWrenchDistributed>(element);
890 auto load = chrono_types::make_shared<ChLoadBeamWrench>(element);
891 auto gravity = chrono_types::make_shared<ChLoaderGravity>(element);
892 gravity->SetGravitationalAcceleration(
system->GetGravitationalAcceleration());
893 std::shared_ptr<ChLoad> loadtri(
new ChLoad(gravity));
894 auto load_volumetric = chrono_types::make_shared<ChLoad>(gravity);
903 loadcontainer->Add(load_volumetric);
915 if (set_lastnodes ==
true) {
940 if (add_lastnode ==
true) {
956 if (add_lastnode ==
true) {
1006 for (
int i = 0; i <
nb_nodes; ++i) {
1008 t_dir =
nodes[i]->GetSlope1();
1009 u_ch =
nodes[i]->GetPosDt();
1012 t_dir =
nodesRot[i]->GetRot().GetVector();
1019 u_prot = ChVector3d(ux_prot, uy_prot, uz_prot);
1020 u_rel = u_prot - u_ch;
1023 double dot = u_rel^t_dir;
1026 Fd_a = 0.5*rho_f*
Cd_axial*M_PI*
d*Va.Length()*Va;
1052 for (
int i = 0; i <
nb_nodes; ++i) {
1054 t_dir =
nodes[i]->GetSlope1();
1055 a_ch =
nodes[i]->GetPosDt2();
1058 t_dir =
nodesRot[i]->GetRot().GetVector();
1065 a_prot = ChVector3d(ax_prot, ay_prot, az_prot);
1066 a_rel = a_prot - a_ch;
1068 double dot = a_rel^t_dir;
1073 Fm_f = rho_f*M_PI*
d*
d/4.*a_prot;
1074 Fm = Fm_a + Fm_n + Fm_f;
1080 for (
int i = 0; i <
nb_nodes-1; ++i) {
1081 ChVector3d Fa = ChVector3d(0.,0.,0.);
1082 ChVector3d Fb = ChVector3d(0.,0.,0.);
1094 if (
mesh->GetAutomaticGravity() ==
true) {
1105 for (
int i = 0; i <
nb_nodes-1; ++i) {
1110 cloud->AddNode(
nodes[i],
d);
1116 std::shared_ptr<ChMesh> mesh,
1117 std::vector<double> length,
1118 std::vector<int> nb_elems,
1119 std::vector<double> d,
1120 std::vector<double> rho,
1121 std::vector<double> E,
1122 std::string beam_type)
1139 auto con1 = chrono_types::make_shared<ChLinkNodeNode>();
1140 auto nodeA = cable1->
nodes[node1];
1141 auto nodeB = cable2->
nodes[node2];
1142 con1->Initialize(nodeA, nodeB);
1143 cable1->
system->Add(con1);
1150 auto con1 = chrono_types::make_shared<ChLinkMateSpherical>();
1151 auto nodeA = cable1->
nodesRot[node1];
1152 auto nodeB = cable2->
nodesRot[node2];
1153 con1->Initialize(nodeA, nodeB,
false, nodeA->GetPos(), nodeA->GetPos());
1154 cable1->
system->Add(con1);
cppMultiSegmentedCable * newMoorings(std::shared_ptr< ChSystem > system, std::shared_ptr< ChMesh > mesh, std::vector< double > length, std::vector< int > nb_elems, std::vector< double > d, std::vector< double > rho, std::vector< double > E, std::string beam_type)
void cppAttachNodeToNodeFEAxyzrot(cppMultiSegmentedCable *cable1, int node1, cppMultiSegmentedCable *cable2, int node2)
ChQuaternion & q_element_ref_rot_of(chrono::fea::ChElementBeamEuler &el)
void cppAttachNodeToNodeFEAxyzD(cppMultiSegmentedCable *cable1, int node1, cppMultiSegmentedCable *cable2, int node2)
void SetF(ChVector3d Fa_in, ChVector3d Fb_in)
virtual int GetIntegrationPointsU()
MyLoaderTriangular(std::shared_ptr< ChLoadableU > mloadable)
virtual void ComputeF(const double U, ChVectorDynamic<> &F, ChVectorDynamic<> *state_x, ChVectorDynamic<> *state_w)
void buildNodesBeamEuler(bool last_node)
std::vector< std::shared_ptr< ChNodeFEAxyzrot > > nodesRot
std::vector< std::shared_ptr< ChLoad > > elems_loads_triangular
void buildMeshBeamEuler(bool add_lastnode)
std::vector< std::shared_ptr< ChElementCableANCF > > elemsCableANCF
std::vector< ChVector3d > mvecs
std::vector< ChVector3d > fluid_velocity
void buildNodes(bool last_node)
cppCable(std::shared_ptr< ChSystem > system, std::shared_ptr< ChMesh > mesh, double length, int nb_elems, double d, double rho, double E, double L0, std::string beam_type)
std::vector< double > length_per_elem
std::vector< std::shared_ptr< ChElementBeamEuler > > elemsBeamEuler
std::vector< std::shared_ptr< ChVector3d > > forces_addedmass
std::shared_ptr< ChMesh > mesh
std::vector< std::shared_ptr< ChElementCableANCF > > elems_cable
std::vector< std::shared_ptr< ChNodeFEAxyzD > > nodes
std::vector< std::shared_ptr< ChLoad > > elems_loads_volumetric
std::vector< ChVector3d > mdirs
void setIyy(double Iyy_in)
std::vector< std::shared_ptr< ChVector3d > > forces_drag
void setAddedMassCoefficients(double axial, double normal)
void buildElementsBeamEuler(bool set_lastnodes)
void buildElementsCableANCF(bool set_lastnodes)
void setDragCoefficients(double axial, double normal)
std::vector< ChVector3d > fluid_acceleration
void buildMeshCableANCF(bool add_lastnode)
std::vector< double > fluid_density
void addNodestoContactCloud(std::shared_ptr< ChContactSurfaceNodeCloud > cloud)
std::vector< std::shared_ptr< ChNodeFEAxyzDD > > nodesDD
std::vector< ChVector3d > mvecs_middle
std::vector< double > elems_length
std::shared_ptr< ChBeamSectionAdvanced > msection_advanced
std::shared_ptr< ChSystem > system
void setFluidVelocityAtNodes(std::vector< ChVector3d > vel)
std::vector< double > nodes_density
void setRestLengthPerElement(std::vector< double > length_array)
void setFluidAccelerationAtNodes(std::vector< ChVector3d > acc)
void buildMesh(bool add_lastnode)
void setFluidDensityAtNodes(std::vector< double > vof)
std::vector< std::shared_ptr< ChVector3d > > getNodalPositions()
void buildElements(bool set_lastnodes)
void buildNodesCableANCF(bool last_node)
std::shared_ptr< ChBeamSectionCable > msection_cable
std::vector< ChVector3d > mvecs_tangents
void setFluidAccelerationAtNodes(std::vector< ChVector3d > vel)
std::vector< int > nb_nodes
std::shared_ptr< ChContactMaterialSMC > mysurfmaterial
std::vector< double > rho
void attachFrontNodeToBody(std::shared_ptr< ChBody > body)
cppMultiSegmentedCable(std::shared_ptr< ChSystem > system, std::shared_ptr< ChMesh > mesh, std::vector< double > length, std::vector< int > nb_nodes, std::vector< double > d, std::vector< double > rho, std::vector< double > E, std::string beam_type)
std::vector< std::shared_ptr< ChVector3d > > getNodalPositions()
std::vector< int > nb_elems
std::vector< std::shared_ptr< ChNodeFEAxyzrot > > nodesRot
std::shared_ptr< ChBody > body_front
std::vector< ChVector3d > fluid_acceleration
std::vector< std::shared_ptr< cppCable > > cables
std::shared_ptr< ChBody > fairleadd
std::vector< std::shared_ptr< ChNodeFEAxyzD > > nodes
std::shared_ptr< ChLinkBase > constraint_back
void setFluidVelocityAtNodes(std::vector< ChVector3d > vel)
std::shared_ptr< ChLinkNodeFrame > fairlead2
ChVector3d getTensionElement(int i, double eta)
std::vector< std::shared_ptr< ChElementCableANCF > > elemsCableANCF
void attachBackNodeToBody(std::shared_ptr< ChBody > body)
std::shared_ptr< ChSystem > system
std::vector< std::shared_ptr< ChNodeFEAxyzDD > > nodesDD
std::vector< std::shared_ptr< ChVector3d > > forces_drag
std::shared_ptr< ChBody > body_back
std::vector< double > fluid_density
std::vector< double > length
void updateAddedMassForces()
std::vector< std::shared_ptr< ChVector3d > > forces_addedmass
std::shared_ptr< ChMesh > mesh
void setContactMaterial(std::shared_ptr< ChContactMaterialSMC > material)
std::vector< ChVector3d > mvecs
std::shared_ptr< ChLinkBase > constraint_front
std::vector< ChVector3d > fluid_velocity
void setFluidDensityAtNodes(std::vector< double > dens)
std::shared_ptr< ChContactMaterialSMC > contact_material
std::vector< std::shared_ptr< ChElementBeamEuler > > elemsBeamEuler
void vel(double rS, double norm_v, double r, double theta, double *vR, double *vTHETA)
ChQuaternion<> chrono::fea::ChElementBeamEuler::* type
friend type chronoPrivateMemberThief(ChElementBeamEuler_q_element_ref_rot_tag)
friend Tag::type chronoPrivateMemberThief(Tag)