1#include "BoundaryConstraint.h"
4#include "Algorithm/CudaRand.h"
5#include "Topology/DistanceField3D.h"
9 //IMPLEMENT_TCLASS(BoundaryConstraint, TDataType)
11 template<typename TDataType>
12 BoundaryConstraint<TDataType>::BoundaryConstraint()
17 m_cSDF = std::make_shared<DistanceField3D<DataType3f>>();
18 m_cSDF->setSpace(lo - 0.025f, hi + 0.025f, Real(0.005));
19 m_cSDF->loadBox(lo, hi, true);
22 template<typename TDataType>
23 BoundaryConstraint<TDataType>::~BoundaryConstraint()
28 template<typename Real, typename Coord, typename TDataType>
29 __global__ void K_ConstrainSDF(
32 DistanceField3D<TDataType> df,
34 Real tangentialFriction,
37 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
38 if (pId >= posArr.size()) return;
40 Coord pos = posArr[pId];
41 Coord vec = velArr[pId];
45 df.getDistance(pos, dist, normal);
50 dist = 0.0001f*rGen.Generate();
52 pos -= (olddist + dist)*normal;
54 Real vlength = vec.norm();
55 Real vec_n = vec.dot(normal);
56 Coord vec_normal = vec_n*normal;
57 Coord vec_tan = vec - vec_normal;
58 if (vec_n > 0) vec_normal = -vec_normal;
59 vec_normal *= (1.0f - normalFriction);
60 vec = vec_normal + vec_tan * (1.0f - tangentialFriction);
61 //vec *= pow(Real(M_E), -dt*tangentialFriction);
62 //vec *= (1.0f - tangentialFriction);
69 template<typename TDataType>
70 void BoundaryConstraint<TDataType>::constrain()
72 uint pDim = cudaGridSize(m_position.size(), BLOCK_SIZE);
73 K_ConstrainSDF << <pDim, BLOCK_SIZE >> > (
77 this->varNormalFriction()->getData(),
78 this->varTangentialFriction()->getData(),
79 this->getParentNode()->getDt());
82 template<typename TDataType>
83 bool BoundaryConstraint<TDataType>::constrain(DArray<Coord>& position, DArray<Coord>& velocity, Real dt)
85 uint pDim = cudaGridSize(position.size(), BLOCK_SIZE);
86 K_ConstrainSDF << <pDim, BLOCK_SIZE >> > (
90 this->varNormalFriction()->getData(),
91 this->varTangentialFriction()->getData(),
97 template<typename TDataType>
98 void BoundaryConstraint<TDataType>::constrain(DArray<Coord>& position, DArray<Coord>& velocity, DistanceField3D<TDataType>& sdf, Real dt)
100 uint pDim = cudaGridSize(position.size(), BLOCK_SIZE);
101 K_ConstrainSDF << <pDim, BLOCK_SIZE >> > (
105 this->varNormalFriction()->getData(),
106 this->varTangentialFriction()->getData(),
110 template<typename TDataType>
111 void BoundaryConstraint<TDataType>::load(std::string filename, bool inverted)
113 m_cSDF->loadSDF(filename, inverted);
117 template<typename TDataType>
118 void BoundaryConstraint<TDataType>::setCube(Coord lo, Coord hi, Real distance, bool inverted)
120 int nx = floor((hi[0] - lo[0]) / distance);
121 int ny = floor((hi[1] - lo[1]) / distance);
122 int nz = floor((hi[2] - lo[2]) / distance);
126 m_cSDF->setSpace(lo - padding *distance, hi + padding * distance, distance);
127 m_cSDF->loadBox(lo, hi, inverted);
131 template<typename TDataType>
132 void BoundaryConstraint<TDataType>::setSphere(Coord center, Real r, Real distance, bool inverted)
134 int nx = floor(2 * r / distance);
138 m_cSDF->setSpace(center - r - padding * distance, center + r + padding * distance, distance);
139 m_cSDF->loadSphere(center, r, inverted);
142 template<typename TDataType>
143 void BoundaryConstraint<TDataType>::setCylinder(Coord center, Real r, Real height, Real distance, int axis, bool inverted)
145 int nx = floor(2 * r / distance);
146 int ny = floor(0.5 * height / distance);
150 m_cSDF->setSpace(center - height - r - padding * distance, center + height + r + padding * distance, distance);
151 m_cSDF->loadCylinder(center, r, height, axis, inverted);
155 DEFINE_CLASS(BoundaryConstraint);