1#include "VirtualParticleShiftingStrategy.h"
4#include "ParticleSystem/Module/SummationDensity.h"
5#include "Collision/NeighborPointQuery.h"
8 IMPLEMENT_TCLASS(VirtualParticleShiftingStrategy, TDataType)
10 template <typename Real, typename Coord>
11 __global__ void T_ComputeLambdas(
12 DArray<Real> lambdaArr,
14 DArray<Coord> v_posArr,
15 DArrayList<int> vv_neighbors,
16 SpikyKernel<Real> kern,
20 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
21 if (pId >= v_posArr.size()) return;
23 Coord pos_i = v_posArr[pId];
25 Real lamda_i = Real(0);
28 List<int>& list_i = vv_neighbors[pId];
29 int nbSize = list_i.size();
30 for (int ne = 0; ne < nbSize; ne++)
34 if (j == pId) continue;
35 Real r = (pos_i - v_posArr[j]).norm();
39 Coord g = kern.Gradient(r, smoothingLength) * (pos_i - v_posArr[j]) * (1.0f / r);
46 lamda_i += grad_ci.dot(grad_ci);
48 Real rho_i = rhoArr[pId];
50 lamda_i = -(rho_i - maxDensity) / (lamda_i + 0.1f);
51 lambdaArr[pId] = lamda_i > 0.0f ? 0.0f : lamda_i;
54 template <typename Real, typename Coord>
55 __global__ void T_ComputeDisplacement(
58 DArray<Coord> v_posArr,
59 DArrayList<int> vv_neighbors,
60 SpikyKernel<Real> kern,
64 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
65 if (pId >= v_posArr.size()) return;
68 Coord pos_i = v_posArr[pId];
69 Real lamda_i = lambdas[pId];
72 List<int>& list_i = vv_neighbors[pId];
73 int nbSize = list_i.size();
74 for (int ne = 0; ne < nbSize; ne++)
78 if (j == pId) continue;
79 Real r = (pos_i - v_posArr[j]).norm();
82 Coord dp_ij = 20.0f * (pos_i - v_posArr[j]) * (lamda_i + lambdas[j]) * kern.Gradient(r, smoothingLength) * (1.0 / r);
85 atomicAdd(&dPos[pId][0], dp_ij[0]);
87 if (Coord::dims() >= 2)
89 atomicAdd(&dPos[pId][1], dp_ij[1]);
92 if (Coord::dims() >= 3)
94 atomicAdd(&dPos[pId][2], dp_ij[2]);
102 template <typename Real, typename Coord>
103 __global__ void T_UpdatePosition(
104 DArray<Coord> v_posArr,
108 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
109 if (pId >= v_posArr.size()) return;
110 v_posArr[pId] += dPos[pId];
117 template <typename Real, typename Coord>
118 __global__ void T_RealCopytoVirtual(
119 DArray<Coord> r_posArr,
120 DArray<Coord> v_posArr,
124 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
125 if (pId >= r_posArr.size()) return;
127 v_posArr[pId] = r_posArr[pId];
132 template<typename TDataType>
133 VirtualParticleShiftingStrategy<TDataType>::VirtualParticleShiftingStrategy()
134 : VirtualParticleGenerator<TDataType>()
136 this->varIterationNumber()->setValue(5);
137 maxDensity = this->varRestDensity()->getValue();
139 this->outVirtualParticles()->allocate();
141 this->varSamplingDistance()->setValue(Real(0.005));
142 this->varSmoothingLength()->setValue(Real(0.011));
143 this->varRestDensity()->setValue(Real(1000));
144 this->outVVNeighborIds()->allocate();
146 ///*Virtual particles' virtual neighbors*/
147 m_vv_nbrQuery = std::make_shared<NeighborPointQuery<TDataType>>();
148 this->varSmoothingLength()->connect(m_vv_nbrQuery->inRadius());
149 this->outVirtualParticles()->connect(m_vv_nbrQuery->inPosition());
150 m_vv_nbrQuery->outNeighborIds()->connect(this->outVVNeighborIds());
152 m_vv_density = std::make_shared<SummationDensity<TDataType>>();
153 this->varRestDensity()->connect(m_vv_density->varRestDensity());
154 this->varSmoothingLength()->connect(m_vv_density->inSmoothingLength());
155 this->varSamplingDistance()->connect(m_vv_density->inSamplingDistance());
156 this->outVirtualParticles()->connect(m_vv_density->inPosition());
157 this->outVVNeighborIds()->connect(m_vv_density->inNeighborIds());
158 m_vv_density->outDensity()->connect(this->outVDensity());
162 template<typename TDataType>
163 VirtualParticleShiftingStrategy<TDataType>::~VirtualParticleShiftingStrategy()
167 // m_position_old.clear();
170 template<typename TDataType>
171 bool VirtualParticleShiftingStrategy<TDataType>::VectorResize()
174 if (this->outVDensity()->size() != this->outVirtualParticles()->size())
175 this->outVDensity()->resize(this->outVirtualParticles()->size());
177 if (m_deltaPos.size() != this->inRPosition()->size())
178 m_deltaPos.resize(this->inRPosition()->size());
180 if (m_lamda.size() != this->inRPosition()->size())
181 m_lamda.resize(this->inRPosition()->size());
187 template<typename TDataType>
188 void VirtualParticleShiftingStrategy<TDataType>::constrain()
195 int itNum = this->varIterationNumber()->getData();
197 int num = this->inRPosition()->size();
199 if (num != this->outVirtualParticles()->size())
201 this->outVirtualParticles()->resize(num);
204 cuExecute(num, T_RealCopytoVirtual,
205 this->inRPosition()->getData(),
206 this->outVirtualParticles()->getData(),
207 this->inTimeStep()->getData()
210 m_vv_nbrQuery->update();
212 if (this->inFrameNumber()->getValue() == 0)
214 m_vv_density->update();
215 Reduction<Real> reduce;
216 maxDensity = reduce.maximum(m_vv_density->outDensity()->getData().begin(), m_vv_density->outDensity()->getData().size());
224 std::cout << "*DUAL-ISPH::ParticleShiftingStrategy(S.B.)::Iteration:" << it << std::endl;
228 template<typename TDataType>
229 void VirtualParticleShiftingStrategy<TDataType>::takeOneIteration()
232 Real dt = this->inTimeStep()->getData();
233 int num = this->inRPosition()->size();
234 uint pDims = cudaGridSize(num, BLOCK_SIZE);
238 m_vv_density->update();
241 cuExecute(num, T_ComputeLambdas,
243 m_vv_density->outDensity()->getData(),
244 this->outVirtualParticles()->getData(),
245 this->outVVNeighborIds()->getData(),
248 this->varSmoothingLength()->getData());
250 cuExecute(num, T_ComputeDisplacement,
253 this->outVirtualParticles()->getData(),
254 this->outVVNeighborIds()->getData(),
256 this->varSmoothingLength()->getData(),
259 cuExecute(num, T_UpdatePosition,
260 this->outVirtualParticles()->getData(),
266 DEFINE_CLASS(VirtualParticleShiftingStrategy);