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)30ChReissnerTire::ChReissnerTire(const std::string& name) : ChDeformableTire(name) {} 31 32 // ----------------------------------------------------------------------------- 33 // ----------------------------------------------------------------------------- CreatePressureLoad()34void 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()50void 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)69void 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