1#include "RigidSandCoupling.h"
5#include "Primitive/Primitive3D.h"
9 template<typename TDataType>
10 RigidSandCoupling<TDataType>::RigidSandCoupling()
15 template<typename TDataType>
16 RigidSandCoupling<TDataType>::~RigidSandCoupling()
20 template<typename TDataType>
21 void RigidSandCoupling<TDataType>::resetStates()
25 template<typename Real, typename Coord3D, typename Coord4D, typename Box3D>
26 __global__ void CQWS_CoupleSandWithBoxes(
27 DArray2D<Coord4D> grid,
28 DArray2D<Coord3D> displacements,
30 DArray<Coord3D> boxVel,
31 DArray<Coord3D> boxAngularVel,
36 int i = threadIdx.x + blockIdx.x * blockDim.x;
37 int j = threadIdx.y + blockIdx.y * blockDim.y;
39 uint nx = displacements.nx();
40 uint ny = displacements.ny();
44 Coord3D v = origin + spacing * Coord3D(i, 0, j) + displacements(i, j);
45 Point3D p = Point3D(v);
47 uint nb = boxes.size();
49 Real Dmin = 100000.0f;
50 for (uint k = 0; k < nb; k++)
52 Real d = p.distance(boxes[k]);
60 if (Dmin < 0 && boxId != -1)
62 Coord4D gij = grid(i + 1, j + 1);
64 Coord3D c = boxes[boxId].center;
66 Coord3D v_box = boxVel[offset + boxId];
67 Coord3D omega_box = boxAngularVel[offset + boxId];
69 Coord3D vv = v_box + omega_box.cross(v - c);
71 Real duh = gij.x * vv.x;
72 Real dvh = gij.x * vv.z;
73 Real dw = abs(Dmin) * 5;
74 atomicAdd(&grid(i + 1, j + 1).y, duh);
75 atomicAdd(&grid(i + 1, j + 1).z, dvh);
77 atomicAdd(&grid(i + 2, j + 1).y, 0.25 * dw);
78 atomicAdd(&grid(i + 0, j + 1).y, -0.25 * dw);
80 atomicAdd(&grid(i + 1, j + 2).z, 0.25 * dw);
81 atomicAdd(&grid(i + 1, j + 0).z, -0.25 * dw);
87 template<typename Real, typename Coord3D, typename Coord4D, typename Sphere3D>
88 __global__ void CQWS_CoupleSandAndSpheres(
89 DArray2D<Coord4D> grid,
90 DArray2D<Coord3D> displacements,
91 DArray<Sphere3D> spheres,
92 DArray<Coord3D> ele_vel,
93 DArray<Coord3D> ele_vel_angular,
98 int i = threadIdx.x + blockIdx.x * blockDim.x;
99 int j = threadIdx.y + blockIdx.y * blockDim.y;
101 uint nx = displacements.nx();
102 uint ny = displacements.ny();
104 if (i < nx && j < ny)
106 Coord3D v = origin + spacing * Coord3D(i, 0, j) + displacements(i, j);
107 Point3D p = Point3D(v);
109 uint nb = spheres.size();
111 Real Dmin = 100000.0f;
112 for (uint k = 0; k < nb; k++)
114 Real d = p.distance(spheres[k]);
122 if (Dmin < 0 && sphereId != -1)
124 Coord4D gij = grid(i + 1, j + 1);
126 Coord3D c = spheres[sphereId].center;
128 Coord3D v_i = ele_vel[offset + sphereId];
129 Coord3D omega_i = ele_vel_angular[offset + sphereId];
131 Coord3D vv = v_i + omega_i.cross(v - c);
133 Real duh = gij.x * vv.x;
134 Real dvh = gij.x * vv.z;
135 Real dw = abs(Dmin) * 5;
136 atomicAdd(&grid(i + 1, j + 1).y, duh);
137 atomicAdd(&grid(i + 1, j + 1).z, dvh);
139 atomicAdd(&grid(i + 2, j + 1).y, 0.25 * dw);
140 atomicAdd(&grid(i + 0, j + 1).y, -0.25 * dw);
142 atomicAdd(&grid(i + 1, j + 2).z, 0.25 * dw);
143 atomicAdd(&grid(i + 1, j + 0).z, -0.25 * dw);
148 template<typename Real, typename Coord3D, typename Coord4D, typename Capsule3D>
149 __global__ void CQWS_CoupleSandAndCapsules(
150 DArray2D<Coord4D> grid,
151 DArray2D<Coord3D> displacements,
152 DArray<Capsule3D> capsules,
153 DArray<Coord3D> ele_vel,
154 DArray<Coord3D> ele_vel_angular,
159 int i = threadIdx.x + blockIdx.x * blockDim.x;
160 int j = threadIdx.y + blockIdx.y * blockDim.y;
162 uint nx = displacements.nx();
163 uint ny = displacements.ny();
165 if (i < nx && j < ny)
167 Coord3D v = origin + spacing * Coord3D(i, 0, j) + displacements(i, j);
168 Point3D p = Point3D(v);
170 uint nb = capsules.size();
172 Real Dmin = 100000.0f;
173 for (uint k = 0; k < nb; k++)
175 Real d = p.distance(capsules[k]);
183 if (Dmin < 0 && sphereId != -1)
185 Coord4D gij = grid(i + 1, j + 1);
187 Coord3D c = capsules[sphereId].center;
189 Coord3D v_i = ele_vel[offset + sphereId];
190 Coord3D omega_i = ele_vel_angular[offset + sphereId];
192 Coord3D vv = v_i + omega_i.cross(v - c);
194 Real duh = gij.x * vv.x;
195 Real dvh = gij.x * vv.z;
196 Real dw = abs(Dmin) * 5;
197 atomicAdd(&grid(i + 1, j + 1).y, duh);
198 atomicAdd(&grid(i + 1, j + 1).z, dvh);
200 atomicAdd(&grid(i + 2, j + 1).y, 0.25 * dw);
201 atomicAdd(&grid(i + 0, j + 1).y, -0.25 * dw);
203 atomicAdd(&grid(i + 1, j + 2).z, 0.25 * dw);
204 atomicAdd(&grid(i + 1, j + 0).z, -0.25 * dw);
209 template<typename TDataType>
210 void RigidSandCoupling<TDataType>::updateStates()
212 Real dt = this->stateTimeStep()->getData();
214 auto sand = this->getGranularMedia();
215 auto rigidbody = this->getRigidBodySystem();
217 auto heights = sand->stateHeightField()->constDataPtr();
218 auto elements = rigidbody->stateTopology()->constDataPtr();
220 auto& grid2d = sand->stateGrid()->getData();
222 auto& ele_vel = rigidbody->stateVelocity()->getData();
223 auto& ele_angular_vel = rigidbody->stateAngularVelocity()->getData();
225 auto& boxes = elements->boxesInGlobal();
226 auto& spheres = elements->spheresInGlobal();
227 auto& capsules = elements->capsulesInGlobal();
229 auto offset = elements->calculateElementOffset();
231 auto& disp = heights->getDisplacement();
232 auto origin = heights->getOrigin();
233 auto spacing = heights->getGridSpacing();
235 uint boxOffset = offset.boxIndex();
236 uint sphereOffset = offset.sphereIndex();
237 uint capsuleOffset = offset.capsuleIndex();
239 cuExecute2D(make_uint2(disp.nx(), disp.ny()),
240 CQWS_CoupleSandWithBoxes,
250 cuExecute2D(make_uint2(disp.nx(), disp.ny()),
251 CQWS_CoupleSandAndSpheres,
261 cuExecute2D(make_uint2(disp.nx(), disp.ny()),
262 CQWS_CoupleSandAndCapsules,
273 DEFINE_CLASS(RigidSandCoupling);