1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2014 projectchrono.org
5 // All rights reserved.
6 //
7 // Use of this source code is governed by a BSD-style license that can be found
8 // in the LICENSE file at the top level of the distribution and at
9 // http://projectchrono.org/license-chrono.txt.
10 //
11 // =============================================================================
12 // Authors: Alessandro Tasora
13 // =============================================================================
14 //
15 // Template for a deformable tire based on Reissner-Mindlin 4 nodes shells
16 //
17 // =============================================================================
18 
19 #include "chrono/fea/ChElementShellReissner4.h"
20 
21 #include "chrono_vehicle/wheeled_vehicle/tire/ChReissnerTire.h"
22 
23 namespace chrono {
24 namespace vehicle {
25 
26 using namespace chrono::fea;
27 
28 // -----------------------------------------------------------------------------
29 // -----------------------------------------------------------------------------
ChReissnerTire(const std::string & name)30 ChReissnerTire::ChReissnerTire(const std::string& name) : ChDeformableTire(name) {}
31 
32 // -----------------------------------------------------------------------------
33 // -----------------------------------------------------------------------------
CreatePressureLoad()34 void ChReissnerTire::CreatePressureLoad() {
35     // Create a pressure load for each element in the mesh.  Note that we set a
36     // negative pressure (i.e. internal pressure, acting opposite to the surface normal)
37     for (unsigned int ie = 0; ie < m_mesh->GetNelements(); ie++) {
38         if (auto mshell = std::dynamic_pointer_cast<ChElementShellReissner4>(m_mesh->GetElement(ie))) {
39             auto load = chrono_types::make_shared<ChLoad<ChLoaderPressure>>(mshell);
40             load->loader.SetPressure(-m_pressure);
41             load->loader.SetStiff(false);          //// TODO:  user control?
42             load->loader.SetIntegrationPoints(2);  //// TODO:  user control?
43             m_load_container->Add(load);
44         }
45     }
46 }
47 
48 // -----------------------------------------------------------------------------
49 // -----------------------------------------------------------------------------
CreateContactSurface()50 void ChReissnerTire::CreateContactSurface() {
51     switch (m_contact_type) {
52         case ContactSurfaceType::NODE_CLOUD: {
53             auto contact_surf = chrono_types::make_shared<ChContactSurfaceNodeCloud>(m_contact_mat);
54             m_mesh->AddContactSurface(contact_surf);
55             contact_surf->AddAllNodes(m_contact_node_radius);
56             break;
57         }
58         case ContactSurfaceType::TRIANGLE_MESH: {
59             auto contact_surf = chrono_types::make_shared<ChContactSurfaceMesh>(m_contact_mat);
60             m_mesh->AddContactSurface(contact_surf);
61             contact_surf->AddFacesFromBoundary(m_contact_face_thickness, false);
62             break;
63         }
64     }
65 }
66 
67 // -----------------------------------------------------------------------------
68 // -----------------------------------------------------------------------------
CreateRimConnections(std::shared_ptr<ChBody> wheel)69 void ChReissnerTire::CreateRimConnections(std::shared_ptr<ChBody> wheel) {
70     auto nodes = GetConnectedNodes();
71 
72     m_connectionsF.resize(nodes.size());
73 
74     for (size_t in = 0; in < nodes.size(); ++in) {
75         auto node = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(nodes[in]);
76         m_connectionsF[in] = chrono_types::make_shared<ChLinkMateFix>();
77         m_connectionsF[in]->Initialize(node, wheel);
78         wheel->GetSystem()->Add(m_connectionsF[in]);
79     }
80 
81 }
82 
83 }  // end namespace vehicle
84 }  // end namespace chrono
85