1#include "IterativeDensitySolver.h"
3#include "SummationDensity.h"
7 template<typename TDataType>
8 IterativeDensitySolver<TDataType>::IterativeDensitySolver()
9 : ParticleApproximation<TDataType>()
11 this->varIterationNumber()->setValue(3);
12 this->varRestDensity()->setValue(Real(1000));
14 this->inAttribute()->tagOptional(true);
16 mSummation = std::make_shared<SummationDensity<TDataType>>();
18 this->inSmoothingLength()->connect(mSummation->inSmoothingLength());
19 this->inSamplingDistance()->connect(mSummation->inSamplingDistance());
20 this->inPosition()->connect(mSummation->inPosition());
21 this->inNeighborIds()->connect(mSummation->inNeighborIds());
23 mSummation->outDensity()->connect(this->outDensity());
26 template<typename TDataType>
27 IterativeDensitySolver<TDataType>::~IterativeDensitySolver()
35 template <typename Real, typename Coord, typename Kernel>
36 __global__ void IDS_ComputeLambdas(
37 DArray<Real> lambdaArr,
39 DArrayList<int> neighbors,
42 Real samplingDistance,
46 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
47 if (pId >= posArr.size()) return;
49 Coord pos_i = posArr[pId];
54 Real V_0 = samplingDistance * samplingDistance * samplingDistance;
56 List<int>& list_i = neighbors[pId];
57 int nbSize = list_i.size();
58 for (int ne = 0; ne < nbSize; ne++)
61 Real r = (pos_i - posArr[j]).norm();
65 Coord g = V_0 * gradient(r, smoothingLength, scale) * (pos_i - posArr[j]) * (1.0f / r);
70 atomicAdd(&lambdaArr[pId], gg_j);
71 atomicAdd(&lambdaArr[j], gg_j);
77 gg_i += grad_ci.dot(grad_ci);
79 atomicAdd(&lambdaArr[pId], gg_i);
82 template <typename Real>
83 __global__ void IDS_ClumpLambdas(
84 DArray<Real> lambdaArr,
88 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
89 if (pId >= rhoArr.size()) return;
91 Real rho_i = rhoArr[pId];
92 Real lambda_i = lambdaArr[pId];
94 lambda_i = -(rho_i - rho_0) / (lambda_i + EPSILON) / rho_0;
96 lambdaArr[pId] = lambda_i > 0.0f ? 0.0f : lambda_i;
99 template <typename Real, typename Coord, typename Kernel>
100 __global__ void IDS_ComputeDisplacement(
102 DArray<Real> lambdas,
103 DArray<Coord> posArr,
104 DArrayList<int> neighbors,
105 Real smoothingLength,
106 Real samplingDistance,
113 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
114 if (pId >= posArr.size()) return;
116 Coord pos_i = posArr[pId];
117 Real lamda_i = lambdas[pId];
119 Real V_0 = samplingDistance * samplingDistance * samplingDistance;
122 List<int>& list_i = neighbors[pId];
123 int nbSize = list_i.size();
124 for (int ne = 0; ne < nbSize; ne++)
127 Real r = (pos_i - posArr[j]).norm();
130 Coord dp_ij = V_0 * (pos_i - posArr[j]) * (lamda_i + lambdas[j]) * gradient(r, smoothingLength, scale) * (1.0 / r);
133 atomicAdd(&dPos[pId][0], dp_ij[0]);
134 atomicAdd(&dPos[j][0], -dp_ij[0]);
136 if (Coord::dims() >= 2)
138 atomicAdd(&dPos[pId][1], dp_ij[1]);
139 atomicAdd(&dPos[j][1], -dp_ij[1]);
142 if (Coord::dims() >= 3)
144 atomicAdd(&dPos[pId][2], dp_ij[2]);
145 atomicAdd(&dPos[j][2], -dp_ij[2]);
151 template <typename Real, typename Coord>
152 __global__ void IDS_UpdatePosition(
153 DArray<Coord> posArr,
154 DArray<Coord> velArr,
158 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
159 if (pId >= posArr.size()) return;
161 posArr[pId] += dPos[pId];
164 template <typename Real, typename Coord>
165 __global__ void IDS_UpdatePosition(
166 DArray<Coord> posArr,
167 DArray<Coord> velArr,
169 DArray<Attribute> attributes,
172 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
173 if (pId >= posArr.size()) return;
175 if (attributes[pId].isDynamic())
177 posArr[pId] += dPos[pId];
181 template<typename TDataType>
182 void IterativeDensitySolver<TDataType>::compute()
184 int num = this->inPosition()->size();
186 if (mPositionOld.size() != this->inPosition()->size())
187 mPositionOld.resize(this->inPosition()->size());
189 mPositionOld.assign(this->inPosition()->getData());
191 if (this->outDensity()->size() != this->inPosition()->size())
192 this->outDensity()->resize(this->inPosition()->size());
194 if (mDeltaPos.size() != this->inPosition()->size())
195 mDeltaPos.resize(this->inPosition()->size());
197 if (mLamda.size() != this->inPosition()->size())
198 mLamda.resize(this->inPosition()->size());
202 int itNum = this->varIterationNumber()->getValue();
205 mSummation->varRestDensity()->setValue(this->varRestDensity()->getValue());
206 mSummation->varKernelType()->setCurrentKey(this->varKernelType()->currentKey());
207 mSummation->update();
216 template<typename TDataType>
217 void IterativeDensitySolver<TDataType>::takeOneIteration()
219 Real dt = this->inTimeStep()->getData();
220 int num = this->inPosition()->size();
221 Real rho_0 = this->varRestDensity()->getValue();
224 mSummation->varRestDensity()->setValue(rho_0);
225 mSummation->varKernelType()->setCurrentKey(this->varKernelType()->currentKey());
226 mSummation->update();
230 cuFirstOrder(num, this->varKernelType()->getDataPtr()->currentKey(), this->mScalingFactor,
233 this->inPosition()->getData(),
234 this->inNeighborIds()->getData(),
236 this->inSmoothingLength()->getValue(),
237 this->inSamplingDistance()->getValue());
242 mSummation->outDensity()->constData(),
245 cuFirstOrder(num, this->varKernelType()->getDataPtr()->currentKey(), this->mScalingFactor,
246 IDS_ComputeDisplacement,
249 this->inPosition()->getData(),
250 this->inNeighborIds()->getData(),
251 this->inSmoothingLength()->getValue(),
252 this->inSamplingDistance()->getValue(),
253 this->varKappa()->getValue(),
257 if (this->inAttribute()->isEmpty())
261 this->inPosition()->getData(),
262 this->inVelocity()->getData(),
270 this->inPosition()->getData(),
271 this->inVelocity()->getData(),
273 this->inAttribute()->constData(),
278 template <typename Real, typename Coord>
279 __global__ void DP_UpdateVelocity(
280 DArray<Coord> velArr,
281 DArray<Coord> curPos,
282 DArray<Coord> prePos,
285 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
286 if (pId >= velArr.size()) return;
288 velArr[pId] += (curPos[pId] - prePos[pId]) / dt;
291 template<typename TDataType>
292 void IterativeDensitySolver<TDataType>::updateVelocity()
294 int num = this->inPosition()->size();
296 Real dt = this->inTimeStep()->getData();
298 cuExecute(num, DP_UpdateVelocity,
299 this->inVelocity()->getData(),
300 this->inPosition()->getData(),
305 DEFINE_CLASS(IterativeDensitySolver);