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/fea/ChElementBeamANCF_3333.h"
14 #include "chrono/fea/ChElementCableANCF.h"
15 #include "chrono/fea/ChElementBeamEuler.h"
16 #include "chrono/fea/ChBeamSection.h"
17 #include "chrono/fea/ChMesh.h"
18 #include "chrono/fea/ChLinkPointPoint.h"
19 #include "chrono/fea/ChLinkPointFrame.h"
20 #include "chrono/fea/ChLinkDirFrame.h"
21 #include "chrono/fea/ChLoadsBeam.h"
22 #include "chrono/fea/ChContactSurfaceNodeCloud.h"
23 #include "chrono/timestepper/ChTimestepper.h"
24 #include "chrono/solver/ChSolverPMINRES.h"
25 #include "chrono/core/ChTransform.h"
30 using namespace chrono::fea;
31 using namespace chrono::collision;
32 using namespace chrono::geometry;
39 ChVectorN<double, 12> m_GenForceVec0;
40 virtual void SetupInitial(ChSystem* system)
override {
46 this->mass = this->length * GetDensity();
50 ChVectorDynamic<> FVector0(12);
52 m_GenForceVec0.setZero();
53 ComputeInternalForces(FVector0);
54 m_GenForceVec0 = FVector0;
63 ChQuaternion<> q_element_ref_rot;
64 virtual void SetupInitial(ChSystem* system)
override {
70 this->mass = this->length * GetDensity();
74 auto node0 = GetNodeA();
75 auto node1 = GetNodeB();
76 ChVector<> mXele = node1->GetX0().GetPos() - node0->GetX0().GetPos();
77 ChVector<> myele = node0->GetX0().GetA().Get_A_Yaxis();
78 A0.Set_A_Xdir(mXele, myele);
79 q_element_ref_rot = A0.Get_A_quaternion();
82 ComputeStiffnessMatrix();
93 ChLoaderUdistributed(mloadable) {
94 Fa = ChVector<>(0.,0.,0.);
95 Fb = ChVector<>(0.,0.,0.);
102 ChVectorDynamic<>& F,
103 ChVectorDynamic<>* state_x,
104 ChVectorDynamic<>* state_w
106 double Fy_max = 0.005;
107 ChVector<> force = Fa*abs(-1+
U)/2.+Fb*(1+
U)/2.;
112 void SetF(ChVector<> Fa_in, ChVector<> Fb_in) {
149 std::vector<std::shared_ptr<ChNodeFEAxyzD>>
nodes;
150 std::vector<std::shared_ptr<ChNodeFEAxyzDD>>
nodesDD;
153 std::vector<std::shared_ptr<ChNodeFEAxyzrot>>
nodesRot;
162 cppCable(std::shared_ptr<ChSystem> system, std::shared_ptr<ChMesh> mesh,
double length,
163 int nb_elems,
double d,
double rho,
double E,
double L0, std::string beam_type);
165 void setFluidAccelerationAtNodes(
std::vector<ChVector<>> acc);
166 void setFluidDensityAtNodes(std::vector<double> vof);
175 void buildNodes(
bool last_node);
176 void buildNodesBeamEuler(
bool last_node);
177 void buildNodesCableANCF(
bool last_node);
178 void buildElements(
bool set_lastnodes);
179 void buildElementsBeamEuler(
bool set_lastnodes);
180 void buildElementsCableANCF(
bool set_lastnodes);
181 void buildMesh(
bool add_lastnode);
182 void buildMeshBeamEuler(
bool add_lastnode);
183 void buildMeshCableANCF(
bool add_lastnode);
185 void setAddedMassForce();
187 void addNodestoContactCloud(std::shared_ptr<ChContactSurfaceNodeCloud> cloud);
188 void setDragCoefficients(
double axial,
double normal);
189 void setAddedMassCoefficients(
double axial,
double normal);
190 void setRestLengthPerElement(std::vector<double> length_array);
191 void setIyy(
double Iyy_in);
205 std::vector<std::shared_ptr<cppCable>>
cables;
207 std::vector<double>
d;
209 std::vector<double>
E;
211 std::vector<std::shared_ptr<ChNodeFEAxyzD>>
nodes;
212 std::vector<std::shared_ptr<ChNodeFEAxyzDD>>
nodesDD;
213 std::vector<std::shared_ptr<ChNodeFEAxyzrot>>
nodesRot;
231 std::shared_ptr<ChMesh> mesh,
232 std::vector<double> length,
233 std::vector<int> nb_nodes,
234 std::vector<double> d,
235 std::vector<double> rho,
236 std::vector<double> E,
237 std::string beam_type);
240 void setFluidDensityAtNodes(std::vector<double> dens);
241 void updateDragForces();
242 void updateAddedMassForces();
244 std::vector<std::shared_ptr<ChVector<double>>> getNodalPositions();
246 void buildElements();
250 void attachBackNodeToBody(std::shared_ptr<ChBody> body);
251 void attachFrontNodeToBody(std::shared_ptr<ChBody> body);
252 void setContactMaterial(std::shared_ptr<ChMaterialSurfaceSMC> material);
253 void buildNodesCloud();
254 ChVector<> getTensionElement(
int i,
double eta);
259 std::shared_ptr<ChMesh> mesh,
260 std::vector<double> length,
261 std::vector<int> nb_elems,
262 std::vector<double> d,
263 std::vector<double> rho,
264 std::vector<double> E,
265 std::string beam_type=
"CableANCF"):
279 std::shared_ptr<cppCable> segment;
281 for (
int i = 0; i <
length.size(); ++i) {
282 segment = std::make_shared<cppCable>(
system,
291 cables.push_back(segment);
299 for (
int i = 0; i <
cables.size(); ++i) {
301 cables[i]->buildNodes(
true);
303 cables[i]->nodesRot.begin(),
304 cables[i]->nodesRot.end());
309 cables[i]->buildNodes(
false);
312 cables[i]->buildNodes(
true);
326 for (
int i = 0; i <
cables.size(); ++i) {
328 cables[i]->buildElements(
false);
337 cables[i]->buildElements(
true);
360 for (
int i = 0; i <
cables.size(); ++i) {
362 cables[i]->buildMesh(
false);
365 cables[i]->buildMesh(
true);
370 auto con1 = chrono_types::make_shared<ChLinkMateSpherical>();
371 auto nodeA =
cables[i]->nodesRot.front();
372 auto nodeB =
cables[i-1]->nodesRot.back();
373 con1->Initialize(nodeA, nodeB,
false, nodeA->GetPos(), nodeA->GetPos());
377 auto con1 = chrono_types::make_shared<ChLinkPointPoint>();
378 auto nodeA =
cables[i]->nodes.front();
379 auto nodeB =
cables[i-1]->nodes.back();
380 con1->Initialize(nodeA, nodeB);
411 int node_nb_prev = node_nb;
412 for (
int i = 0; i <
cables.size(); ++i) {
414 node_nb +=
cables[i]->nodesRot.size();
417 node_nb +=
cables[i]->nodes.size();
421 cables[i]->setFluidAccelerationAtNodes(fluid_acc);
422 node_nb_prev = node_nb;
429 int node_nb_prev = node_nb;
430 for (
int i = 0; i <
cables.size(); ++i) {
432 node_nb +=
cables[i]->nodesRot.size();
435 node_nb +=
cables[i]->nodes.size();
437 std::vector<ChVector<>> fluid_vel(
fluid_velocity.begin()+node_nb_prev,
439 cables[i]->setFluidVelocityAtNodes(fluid_vel);
440 node_nb_prev = node_nb;
447 int node_nb_prev = 0;
448 for (
int i = 0; i <
cables.size(); ++i) {
450 node_nb +=
cables[i]->nodesRot.size();
453 node_nb +=
cables[i]->nodes.size();
455 std::vector<double> fluid_dens(
fluid_density.begin()+node_nb_prev,
457 cables[i]->setFluidDensityAtNodes(fluid_dens);
458 node_nb_prev = node_nb;
464 for (
int i = 0; i <
cables.size(); ++i) {
465 cables[i]->setDragForce();
470 for (
int i = 0; i <
cables.size(); ++i) {
471 cables[i]->setAddedMassForce();
476 for (
int i = 0; i <
cables.size(); ++i) {
483 auto force = ChVector<>();
484 auto torque = ChVector<>();
493 auto mat2 = ChMatrixDynamic<>();
502 std::vector<std::shared_ptr<ChVector<double>>> nodal_positions;
503 for (
int i = 0; i <
nodes.size(); ++i) {
508 auto nodal_position = chrono_types::make_shared<ChVector<double>>(x, y,
z);
509 nodal_positions.push_back(nodal_position);
511 return nodal_positions;
516 auto constraint = chrono_types::make_shared<ChLinkMateSpherical>();
523 auto constraint = chrono_types::make_shared<ChLinkPointFrame>();
524 constraint->Initialize(
nodes.back(), body);
533 auto constraint = chrono_types::make_shared<ChLinkMateSpherical>();
540 auto constraint = chrono_types::make_shared<ChLinkPointFrame>();
541 constraint->Initialize(
nodes.front(), body);
555 auto contact_cloud = chrono_types::make_shared<ChContactSurfaceNodeCloud>(
contact_material);
557 mesh->AddContactSurface(contact_cloud);
560 for (
int i = 0; i <
cables.size(); ++i) {
561 cables[i]->addNodestoContactCloud(contact_cloud);
568 std::shared_ptr<ChMesh> mesh,
575 std::string beam_type =
"CableANCF"
596 for (
int i = 0; i <
nb_elems; i++) {
639 std::shared_ptr<ChNodeFEAxyzrot> node;
641 ChVector<> ref = ChVector<>(1.,0.,0.);
642 ChQuaternion<> frame_quat;
643 for (
int i = 0; i <
mvecs.size() - 1; ++i) {
646 double ang = acos(dir^ref);
648 frame_quat.Q_from_AngAxis(ang, axis);
649 node = chrono_types::make_shared<ChNodeFEAxyzrot>(ChFrame<>(
mvecs[i],
652 std::shared_ptr<ChVector<>> drag0 = chrono_types::make_shared<ChVector<>>(0.,0.,0.);
653 std::shared_ptr<ChVector<>> am0 = chrono_types::make_shared<ChVector<>>(0.,0.,0.);
657 if (last_node ==
true) {
660 double ang = -acos(dir^ref);
662 frame_quat.Q_from_AngAxis(ang, axis);
663 node = chrono_types::make_shared<ChNodeFEAxyzrot>(ChFrame<>(
mvecs[
mvecs.size()-1],
668 std::shared_ptr<ChVector<>> drag0 = chrono_types::make_shared<ChVector<>>(0.,0.,0.);
669 std::shared_ptr<ChVector<>> am0 = chrono_types::make_shared<ChVector<>>(0.,0.,0.);
683 std::shared_ptr<ChNodeFEAxyzD> node;
685 ChCoordsys<> coordsys;
686 for (
int i = 0; i <
mvecs.size() - 1; ++i) {
689 node = chrono_types::make_shared<ChNodeFEAxyzD>(
mvecs[i], dir);
690 nodes.push_back(node);
691 std::shared_ptr<ChVector<>> drag0 = chrono_types::make_shared<ChVector<>>(0.,0.,0.);
692 std::shared_ptr<ChVector<>> am0 = chrono_types::make_shared<ChVector<>>(0.,0.,0.);
696 if (last_node ==
true) {
699 node = chrono_types::make_shared<ChNodeFEAxyzD>(
mvecs[
mvecs.size()-1], dir);
700 nodes.push_back(node);
703 std::shared_ptr<ChVector<>> drag0 = chrono_types::make_shared<ChVector<>>(0.,0.,0.);
704 std::shared_ptr<ChVector<>> am0 = chrono_types::make_shared<ChVector<>>(0.,0.,0.);
724 auto loadcontainer = chrono_types::make_shared<ChLoadContainer>();
725 system->Add(loadcontainer);
732 for (
int i = 0; i <
nb_elems; ++i) {
733 auto element = chrono_types::make_shared<ChElementCableANCFmod>();
734 auto load_distributed = chrono_types::make_shared<ChLoadBeamWrenchDistributed>(element);
735 auto load = chrono_types::make_shared<ChLoadBeamWrench>(element);
736 std::shared_ptr<ChLoad<MyLoaderTriangular>> loadtri(
new ChLoad<MyLoaderTriangular>(element));
737 auto load_volumetric = chrono_types::make_shared<ChLoad<ChLoaderGravity>>(element);
738 load_volumetric->loader.Set_G_acc(
system->Get_G_acc());
741 loadcontainer->Add(loadtri);
742 loadcontainer->Add(load_volumetric);
754 if (set_lastnodes ==
true) {
762 auto loadcontainer = chrono_types::make_shared<ChLoadContainer>();
763 system->Add(loadcontainer);
769 for (
int i = 0; i <
nodesRot.size() - 1; ++i) {
770 auto element = chrono_types::make_shared<ChElementBeamEulermod>();
771 auto load_distributed = chrono_types::make_shared<ChLoadBeamWrenchDistributed>(element);
772 auto load = chrono_types::make_shared<ChLoadBeamWrench>(element);
773 std::shared_ptr<ChLoad<MyLoaderTriangular>> loadtri(
new ChLoad<MyLoaderTriangular>(element));
774 auto load_volumetric = chrono_types::make_shared<ChLoad<ChLoaderGravity>>(element);
775 load_volumetric->loader.Set_G_acc(
system->Get_G_acc());
778 loadcontainer->Add(loadtri);
779 loadcontainer->Add(load_volumetric);
791 if (set_lastnodes ==
true) {
816 if (add_lastnode ==
true) {
832 if (add_lastnode ==
true) {
882 for (
int i = 0; i <
nb_nodes; ++i) {
884 t_dir =
nodes[i]->GetD();
885 u_ch =
nodes[i]->GetPos_dt();
888 t_dir =
nodesRot[i]->GetRot().GetVector();
895 u_prot = ChVector<>(ux_prot, uy_prot, uz_prot);
896 u_rel = u_prot - u_ch;
899 double dot = u_rel^t_dir;
902 Fd_a = 0.5*rho_f*
Cd_axial*M_PI*
d*Va.Length()*Va;
928 for (
int i = 0; i <
nb_nodes; ++i) {
930 t_dir =
nodes[i]->GetD();
931 a_ch =
nodes[i]->GetPos_dtdt();
934 t_dir =
nodesRot[i]->GetRot().GetVector();
941 a_prot = ChVector<>(ax_prot, ay_prot, az_prot);
942 a_rel = a_prot - a_ch;
944 double dot = a_rel^t_dir;
949 Fm_f = rho_f*M_PI*
d*
d/4.*a_prot;
950 Fm = Fm_a + Fm_n + Fm_f;
956 for (
int i = 0; i <
nb_nodes-1; ++i) {
957 ChVector<> Fa = ChVector<>(0.,0.,0.);
958 ChVector<> Fb = ChVector<>(0.,0.,0.);
970 if (
mesh->GetAutomaticGravity() ==
true) {
981 for (
int i = 0; i <
nb_nodes-1; ++i) {
986 cloud->AddNode(
nodes[i],
d);
992 std::shared_ptr<ChMesh> mesh,
993 std::vector<double> length,
994 std::vector<int> nb_elems,
995 std::vector<double> d,
996 std::vector<double> rho,
997 std::vector<double> E,
998 std::string beam_type)
1015 auto con1 = chrono_types::make_shared<ChLinkPointPoint>();
1016 auto nodeA = cable1->
nodes[node1];
1017 auto nodeB = cable2->
nodes[node2];
1018 con1->Initialize(nodeA, nodeB);
1019 cable1->
system->Add(con1);
1026 auto con1 = chrono_types::make_shared<ChLinkMateSpherical>();
1027 auto nodeA = cable1->
nodesRot[node1];
1028 auto nodeB = cable2->
nodesRot[node2];
1029 con1->Initialize(nodeA, nodeB,
false, nodeA->GetPos(), nodeA->GetPos());
1030 cable1->
system->Add(con1);