<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: <NAME>, <NAME>, <NAME>
// =============================================================================
//
// Sample toroidal tire based on Reissner shell elements
// This is a customizable Reissner tire class which uses a toroidal tire mesh
// composed of single-layer Reissner shell elements.
//
// =============================================================================

#include "chrono_fea/ChElementShellReissner4.h"

#include "ReissnerToroidalTire.h"

using namespace chrono;
using namespace chrono::vehicle;
using namespace chrono::fea;

ReissnerToroidalTire::ReissnerToroidalTire(const std::string& name)
    : ChReissnerTire(name),
      m_rim_radius(0.35),
      m_height(0.195),
      m_thickness(0.014),
      m_div_circumference(60),
      m_div_width(12),
      m_default_pressure(320.0e3),
      m_alpha(0.15) {}

void ReissnerToroidalTire::CreateMesh(const ChFrameMoving<>& wheel_frame, VehicleSide side) {
    // Create an isotropic material (shared by all elements)
    auto mat = std::make_shared<ChMaterialShellReissnerIsothropic>(500, 9.0e7, 0.3);

    // Create the mesh nodes.
    // The nodes are first created in the wheel local frame, assuming Y as the tire axis,
    // and are then transformed to the global frame.
    for (int i = 0; i < m_div_circumference; i++) {
        double phi = (CH_C_2PI * i) / m_div_circumference;

        for (int j = 0; j <= m_div_width; j++) {
            double theta = -CH_C_PI_2 + (CH_C_PI * j) / m_div_width;

            double x = (m_rim_radius + m_height * cos(theta)) * cos(phi);
            double y = m_height * sin(theta);
            double z = (m_rim_radius + m_height * cos(theta)) * sin(phi);
            ChVector<> loc = wheel_frame.TransformPointLocalToParent(ChVector<>(x, y, z));

            double nx = cos(theta) * cos(phi);
            double ny = sin(theta);
            double nz = cos(theta) * sin(phi);
            ChVector<> dir = wheel_frame.TransformDirectionLocalToParent(ChVector<>(nx, ny, nz));
            ChMatrix33<> mrot; mrot.Set_A_Xdir(dir,VECT_Y);

            auto node = std::make_shared<ChNodeFEAxyzrot>(ChFrame<>(loc, mrot));
            node->SetMass(0);
            m_mesh->AddNode(node);
        }
    }

    // Element dimensions
    double dz = m_thickness;
    double dx = CH_C_2PI * (m_rim_radius + m_height) / (2 * m_div_circumference);
    double dy = CH_C_PI * m_height / m_div_width;

    // Create the Reissner shell elements
    for (int i = 0; i < m_div_circumference; i++) {
        for (int j = 0; j < m_div_width; j++) {
            // Adjacent nodes
            int inode0, inode1, inode2, inode3;
            inode1 = j + i * (m_div_width + 1);
            inode2 = j + 1 + i * (m_div_width + 1);
            if (i == m_div_circumference - 1) {
                inode0 = j;
                inode3 = j + 1;
            }
            else {
                inode0 = j + (i + 1) * (m_div_width + 1);
                inode3 = j + 1 + (i + 1) * (m_div_width + 1);
            }

            auto node0 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode0));
            auto node1 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode1));
            auto node2 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode2));
            auto node3 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode3));

            // Create the element and set its nodes.
            auto element = std::make_shared<ChElementShellReissner4>();
            element->SetNodes(node0, node1, node2, node3);

            // Add a single layers with a fiber angle of 0 degrees.
            element->AddLayer(dz, 0 * CH_C_DEG_TO_RAD, mat);

            // Set other element properties
            //element->SetAlphaDamp(m_alpha);
            //***TODO*** add gravity load
            //element->SetGravityOn(true);

            // Add element to mesh
            m_mesh->AddElement(element);
        }
    }

    // Switch off automatic gravity
    m_mesh->SetAutomaticGravity(true);
}

std::vector<std::shared_ptr<ChNodeFEAbase>> ReissnerToroidalTire::GetConnectedNodes() const {<commit_msg>Enable damping for toroidal corotational tire<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: <NAME>, <NAME>, <NAME>
// =============================================================================
//
// Sample toroidal tire based on Reissner shell elements
// This is a customizable Reissner tire class which uses a toroidal tire mesh
// composed of single-layer Reissner shell elements.
//
// =============================================================================

#include "chrono_fea/ChElementShellReissner4.h"

#include "ReissnerToroidalTire.h"

using namespace chrono;
using namespace chrono::vehicle;
using namespace chrono::fea;

ReissnerToroidalTire::ReissnerToroidalTire(const std::string& name)
    : ChReissnerTire(name),
      m_rim_radius(0.35),
      m_height(0.195),
      m_thickness(0.014),
      m_div_circumference(60),
      m_div_width(12),
      m_default_pressure(320.0e3),
      m_alpha(0.15) {}

void ReissnerToroidalTire::CreateMesh(const ChFrameMoving<>& wheel_frame, VehicleSide side) {
    // Create an isotropic material (shared by all elements)
    auto mat = std::make_shared<ChMaterialShellReissnerIsothropic>(500, 9.0e7, 0.3);

    // Create the mesh nodes.
    // The nodes are first created in the wheel local frame, assuming Y as the tire axis,
    // and are then transformed to the global frame.
    for (int i = 0; i < m_div_circumference; i++) {
        double phi = (CH_C_2PI * i) / m_div_circumference;

        for (int j = 0; j <= m_div_width; j++) {
            double theta = -CH_C_PI_2 + (CH_C_PI * j) / m_div_width;

            double x = (m_rim_radius + m_height * cos(theta)) * cos(phi);
            double y = m_height * sin(theta);
            double z = (m_rim_radius + m_height * cos(theta)) * sin(phi);
            ChVector<> loc = wheel_frame.TransformPointLocalToParent(ChVector<>(x, y, z));

            double nx = cos(theta) * cos(phi);
            double ny = sin(theta);
            double nz = cos(theta) * sin(phi);
            ChVector<> dir = wheel_frame.TransformDirectionLocalToParent(ChVector<>(nx, ny, nz));
            ChMatrix33<> mrot; mrot.Set_A_Xdir(dir,VECT_Y);

            auto node = std::make_shared<ChNodeFEAxyzrot>(ChFrame<>(loc, mrot));
            node->SetMass(0);
            m_mesh->AddNode(node);
        }
    }

    // Element dimensions
    double dz = m_thickness;
    double dx = CH_C_2PI * (m_rim_radius + m_height) / (2 * m_div_circumference);
    double dy = CH_C_PI * m_height / m_div_width;

    // Create the Reissner shell elements
    for (int i = 0; i < m_div_circumference; i++) {
        for (int j = 0; j < m_div_width; j++) {
            // Adjacent nodes
            int inode0, inode1, inode2, inode3;
            inode1 = j + i * (m_div_width + 1);
            inode2 = j + 1 + i * (m_div_width + 1);
            if (i == m_div_circumference - 1) {
                inode0 = j;
                inode3 = j + 1;
            }
            else {
                inode0 = j + (i + 1) * (m_div_width + 1);
                inode3 = j + 1 + (i + 1) * (m_div_width + 1);
            }

            auto node0 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode0));
            auto node1 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode1));
            auto node2 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode2));
            auto node3 = std::dynamic_pointer_cast<ChNodeFEAxyzrot>(m_mesh->GetNode(inode3));

            // Create the element and set its nodes.
            auto element = std::make_shared<ChElementShellReissner4>();
            element->SetNodes(node0, node1, node2, node3);

            // Add a single layers with a fiber angle of 0 degrees.
            element->AddLayer(dz, 0 * CH_C_DEG_TO_RAD, mat);

            // Set other element properties
            element->SetAlphaDamp(m_alpha);

            // Add element to mesh
            m_mesh->AddElement(element);
        }
    }

    // automatic gravity
    m_mesh->SetAutomaticGravity(true);
}

std::vector<std::shared_ptr<ChNodeFEAbase>> ReissnerToroidalTire::GetConnectedNodes() const {
{'fraction_non_alphanumeric': 0.17804508019072388, 'fraction_numerical': 0.017771998266146512, 'mean_word_length': 2.7004811547714516, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 64, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4042027', 'n_tokens_mistral': 2978, 'n_tokens_neox': 2787, 'n_words': 706}