1 // ============================================================================= 2 // PROJECT CHRONO - http://projectchrono.org 3 // 4 // Copyright (c) 2019 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: Conlain Kelly, Nic Olsen, Ruochun Zhang, Dan Negrut, Radu Serban 13 // ============================================================================= 14 15 #pragma once 16 17 #include "chrono_gpu/physics/ChSystemGpu_impl.h" 18 19 namespace chrono { 20 namespace gpu { 21 22 // Underlying implementation of the Chrono::Gpu mesh system. 23 // Implements functionality required to handle the interaction between a mesh soup and granular material. 24 // 25 // Mesh soup: a collection of meshes that each has a certain number of triangle elements. For instance, the meshes 26 // associated with the four wheels of a rover operating on granular material would be smashed into one soup having four 27 // mesh families. 28 class ChSystemGpuMesh_impl : public ChSystemGpu_impl { 29 public: 30 virtual ~ChSystemGpuMesh_impl(); 31 32 protected: 33 /// Position and rotation matrix defining the frame of a triangle mesh. 34 template <class T> 35 struct MeshFrame { 36 // TODO optimize rotations 37 T pos[3]; 38 T rot_mat[9]; 39 }; 40 41 /// Extra parameters needed for triangle-sphere contact. 42 struct MeshParams { 43 /// Sphere-to-mesh normal stiffness, expressed in SU (Hertzian spring) 44 float K_n_s2m_SU; 45 /// Sphere-to-mesh tangent stiffness, expressed in SU (Hertzian spring) 46 float K_t_s2m_SU; 47 48 /// Sphere-to-mesh normal contact damping coefficient, expressed in SU 49 float Gamma_n_s2m_SU; 50 /// Sphere-to-mesh tangent contact damping coefficient, expressed in SU 51 float Gamma_t_s2m_SU; 52 53 /// material based property 54 bool use_mat_based; 55 56 /// effective sphere-to-mesh youngs modulus, expressed in SU 57 float E_eff_s2m_SU; 58 59 /// effective sphere-to-mesh shear modulus, expressed in SU 60 float G_eff_s2m_SU; 61 62 /// effective sphere-to-mesh coefficient of restitution, expressed in SU 63 float COR_s2m_SU; 64 65 /// Acceleration caused by adhesion force (constant adhesion model) 66 float adhesionAcc_s2m; 67 68 /// Ratio of normal force to peak tangent force, also arctan(theta) where theta is the friction angle 69 float static_friction_coeff_s2m; 70 71 /// Coefficient of rolling resistance. Units and effect depend on the system rolling resistance model 72 float rolling_coeff_s2m_SU; 73 74 /// Coefficient of spinning resistance. Units and effect depend on the system spinning resistance model 75 float spinning_coeff_s2m_SU; 76 77 /// Number of triangle families 78 unsigned int num_triangle_families; 79 80 /// Reference frames of the triangle families in single precision 81 MeshFrame<float>* fam_frame_broad; 82 83 /// Reference frames of the triangle families in double precision 84 MeshFrame<double>* fam_frame_narrow; 85 }; 86 87 /// Structure used to hold pointers for mesh arrays. 88 /// Note: The order of the nodes in a triangle defines the positive face of the triangle; right-hand rule used. 89 struct TriangleSoup { 90 /// Total number of triangles in the soup 91 unsigned int nTrianglesInSoup; 92 /// Indicates how many meshes are squashed together in this soup 93 unsigned int numTriangleFamilies; 94 /// Each entry says what family that triagnle belongs to; size: nTrianglesInSoup 95 unsigned int* triangleFamily_ID; 96 97 /// Entry i is the SU mass of family i 98 float* familyMass_SU; 99 100 /// Position in local reference frame of triangle vertex 1 101 float3* node1; 102 /// Position in local reference frame of triangle vertex 2 103 float3* node2; 104 /// Position in local reference frame of triangle vertex 3 105 float3* node3; 106 107 /// Entry i is the linear velocity of family i (rigid body motion) 108 float3* vel; 109 /// Entry i is the angular velocity of family i (rigid body motion) 110 float3* omega; 111 112 /// Generalized forces acting on each family. Expressed 113 /// in the global reference frame. Size: 6 * numTriangleFamilies. 114 float* generalizedForcesPerFamily; 115 }; 116 getMeshSoup()117 TriangleSoup* getMeshSoup() { return meshSoup; } getTriParams()118 MeshParams* getTriParams() { return tri_params; } 119 120 // The system is not default-constructible 121 ChSystemGpuMesh_impl() = delete; 122 123 /// Construct Chrono::Gpu system with given sphere radius, density, big domain dimensions and frame origin. 124 ChSystemGpuMesh_impl(float sphere_rad, float density, float3 boxDims, float3 O); 125 126 /// combine material properties of two types to get effective ones 127 void combineMaterialSurface(); 128 129 130 /// Apply rigid body motion to specified mesh. 131 void ApplyMeshMotion(unsigned int mesh_id, 132 const double* pos, 133 const double* rot, 134 const double* lin_vel, 135 const double* ang_vel); 136 137 /// Initialize trimeshes before starting simulation (typically called by initialize). 138 void initializeTriangles(); 139 140 /// Clean up data structures associated with triangle mesh 141 void cleanupTriMesh(); 142 143 /// Broadphase CD for triangles 144 void runTriangleBroadphase(); 145 146 virtual double get_max_K() const override; 147 148 template <typename T> 149 void generate_rot_matrix(const double* ep, T* rot_mat); 150 151 static void ApplyFrameTransform(float3& p, float* pos, float* rot_mat); 152 153 /// Advance simulation by duration in user units, return actual duration elapsed. 154 /// Requires initialize() to have been called. 155 virtual double AdvanceSimulation(float duration) override; 156 157 /// Set of simulation parameters related to triangle data 158 MeshParams* tri_params; 159 160 /// Clean copy of mesh soup interacting with granular material in unified memory. Stored in UU 161 TriangleSoup* meshSoup; 162 163 /// Sphere-to-mesh normal contact stiffness, in user units (Hertzian spring) 164 double K_n_s2m_UU; 165 /// Sphere-to-mesh normal damping coefficient, in user units 166 double Gamma_n_s2m_UU; 167 168 /// Sphere-to-mesh tangent contact stiffness, in user units (Hertzian spring) 169 double K_t_s2m_UU; 170 /// Sphere-to-mesh tangent damping coefficient, in user units 171 double Gamma_t_s2m_UU; 172 173 /// flag for using material based property 174 bool use_mat_based = false; 175 176 /// youngs modulus of mesh 177 double YoungsModulus_mesh_UU; 178 179 /// Poisson ratio of mesh 180 double PoissonRatio_mesh_UU; 181 182 /// coefficient of restitution of mesh 183 double COR_mesh_UU; 184 185 /// Rolling friction coefficient for sphere-to-mesh -- units and effect depend on rolling resistance model 186 float rolling_coeff_s2m_UU; 187 188 /// Spinning friction coefficient for sphere-to-mesh -- units and effect depend on spinning resistance model 189 float spinning_coeff_s2m_UU; 190 191 /// Ratio of sphere-to-mesh adhesion to gravity (constant adhesion model) 192 float adhesion_s2m_over_gravity; 193 194 /// Enable or disable collision between spheres and meshes 195 bool mesh_collision_enabled = true; 196 197 /// stores list of triangles touching each SD; goes SD by SD; size can change during simulation 198 std::vector<unsigned int, cudallocator<unsigned int>> SD_trianglesInEachSD_composite; 199 200 /// the count of triangles touching each SD; size of vector should be # of SDs 201 std::vector<unsigned int, cudallocator<unsigned int>> SD_numTrianglesTouching; 202 203 /// offsets in the composite array for each SD; i.e., offset where each SD starts storing its triangles. 204 /// Size of vector should be # of SDs. 205 std::vector<unsigned int, cudallocator<unsigned int>> SD_TrianglesCompositeOffsets; 206 207 /// Number of SDs that each triangle touches; stored triangle by triangle. 208 /// Nonessential array, only needed to carry out broadphase for mesh 209 std::vector<unsigned int, cudallocator<unsigned int>> Triangle_NumSDsTouching; 210 211 /// Helper array that stores the prefix scan output done on Triangle_NumSDsTouching. 212 /// Nonessential array, only needed to carry out broadphase for mesh 213 std::vector<unsigned int, cudallocator<unsigned int>> Triangle_SDsCompositeOffsets; 214 215 /// for each triangle, lists the collection of SDs that triangle touches; e.g., triangle 0 touches SDs 23, 32, 9, 216 /// 199; triangle 0 touchs SDs 23, 33, 109; triangle 2 touches SDs 991; triangle 3 touches 43, 23, etc. 217 /// Nonessential array, only needed to carry out broadphase for mesh 218 std::vector<unsigned int, cudallocator<unsigned int>> SDsTouchedByEachTriangle_composite_out; 219 220 /// TriangleIDS_ByMultiplicity_out is mirroring the SDsTouchedByEachTriangle_composite_out vector. Its entries is 221 /// the list of triangle IDs, with the right multiplicity. It's used for a sort by key operation needed to figure 222 /// out what triangles are stored in each SD. Thus, for the example above, the entries would be 223 /// 0,0,0,0,1,1,1,2,3,3,etc. Nonessential array, only needed to carry out broadphase for mesh 224 std::vector<unsigned int, cudallocator<unsigned int>> TriangleIDS_ByMultiplicity_out; 225 226 /// dummy vector used in the broadphase done for the mesh, to understand what SD contains what triangles 227 std::vector<unsigned int, cudallocator<unsigned int>> SDsTouchedByEachTriangle_composite; 228 229 /// dummy vector used in the broadphase done for the mesh, to understand what SD contains what triangles 230 std::vector<unsigned int, cudallocator<unsigned int>> TriangleIDS_ByMultiplicity; 231 232 public: 233 /// Get nicer handles to pointer names, enforce const-ness on the mesh params 234 typedef const chrono::gpu::ChSystemGpuMesh_impl::MeshParams* MeshParamsPtr; 235 236 /// Get nicer handles to pointer names, enforce const-ness on the mesh params 237 typedef chrono::gpu::ChSystemGpuMesh_impl::TriangleSoup* TriangleSoupPtr; 238 239 friend class ChSystemGpuMesh; 240 }; 241 242 } // namespace gpu 243 } // namespace chrono 244