PeriDyno 1.0.0
Loading...
Searching...
No Matches
VirtualParticleShiftingStrategy.cu
Go to the documentation of this file.
1#include "VirtualParticleShiftingStrategy.h"
2
3#include "Node.h"
4#include "ParticleSystem/Module/SummationDensity.h"
5#include "Collision/NeighborPointQuery.h"
6namespace dyno
7{
8 IMPLEMENT_TCLASS(VirtualParticleShiftingStrategy, TDataType)
9
10 template <typename Real, typename Coord>
11 __global__ void T_ComputeLambdas(
12 DArray<Real> lambdaArr,
13 DArray<Real> rhoArr,
14 DArray<Coord> v_posArr,
15 DArrayList<int> vv_neighbors,
16 SpikyKernel<Real> kern,
17 Real maxDensity,
18 Real smoothingLength)
19 {
20 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
21 if (pId >= v_posArr.size()) return;
22
23 Coord pos_i = v_posArr[pId];
24
25 Real lamda_i = Real(0);
26 Coord grad_ci(0);
27
28 List<int>& list_i = vv_neighbors[pId];
29 int nbSize = list_i.size();
30 for (int ne = 0; ne < nbSize; ne++)
31 {
32
33 int j = list_i[ne];
34 if (j == pId) continue;
35 Real r = (pos_i - v_posArr[j]).norm();
36
37 if (r > EPSILON)
38 {
39 Coord g = kern.Gradient(r, smoothingLength) * (pos_i - v_posArr[j]) * (1.0f / r);
40 grad_ci += g;
41 lamda_i += g.dot(g);
42
43 }
44 }
45
46 lamda_i += grad_ci.dot(grad_ci);
47
48 Real rho_i = rhoArr[pId];
49
50 lamda_i = -(rho_i - maxDensity) / (lamda_i + 0.1f);
51 lambdaArr[pId] = lamda_i > 0.0f ? 0.0f : lamda_i;
52 }
53
54 template <typename Real, typename Coord>
55 __global__ void T_ComputeDisplacement(
56 DArray<Coord> dPos,
57 DArray<Real> lambdas,
58 DArray<Coord> v_posArr,
59 DArrayList<int> vv_neighbors,
60 SpikyKernel<Real> kern,
61 Real smoothingLength,
62 Real dt)
63 {
64 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
65 if (pId >= v_posArr.size()) return;
66
67
68 Coord pos_i = v_posArr[pId];
69 Real lamda_i = lambdas[pId];
70
71 Coord dP_i(0);
72 List<int>& list_i = vv_neighbors[pId];
73 int nbSize = list_i.size();
74 for (int ne = 0; ne < nbSize; ne++)
75 {
76
77 int j = list_i[ne];
78 if (j == pId) continue;
79 Real r = (pos_i - v_posArr[j]).norm();
80 if (r > EPSILON)
81 {
82 Coord dp_ij = 20.0f * (pos_i - v_posArr[j]) * (lamda_i + lambdas[j]) * kern.Gradient(r, smoothingLength) * (1.0 / r);
83 dP_i += dp_ij;
84
85 atomicAdd(&dPos[pId][0], dp_ij[0]);
86
87 if (Coord::dims() >= 2)
88 {
89 atomicAdd(&dPos[pId][1], dp_ij[1]);
90 }
91
92 if (Coord::dims() >= 3)
93 {
94 atomicAdd(&dPos[pId][2], dp_ij[2]);
95
96 }
97 }
98 }
99
100 }
101
102 template <typename Real, typename Coord>
103 __global__ void T_UpdatePosition(
104 DArray<Coord> v_posArr,
105 DArray<Coord> dPos,
106 Real dt)
107 {
108 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
109 if (pId >= v_posArr.size()) return;
110 v_posArr[pId] += dPos[pId];
111
112
113 }
114
115
116
117 template <typename Real, typename Coord>
118 __global__ void T_RealCopytoVirtual(
119 DArray<Coord> r_posArr,
120 DArray<Coord> v_posArr,
121 Real dt
122 )
123 {
124 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
125 if (pId >= r_posArr.size()) return;
126
127 v_posArr[pId] = r_posArr[pId];
128
129 }
130
131
132 template<typename TDataType>
133 VirtualParticleShiftingStrategy<TDataType>::VirtualParticleShiftingStrategy()
134 : VirtualParticleGenerator<TDataType>()
135 {
136 this->varIterationNumber()->setValue(5);
137 maxDensity = this->varRestDensity()->getValue();
138
139 this->outVirtualParticles()->allocate();
140
141 this->varSamplingDistance()->setValue(Real(0.005));
142 this->varSmoothingLength()->setValue(Real(0.011));
143 this->varRestDensity()->setValue(Real(1000));
144 this->outVVNeighborIds()->allocate();
145
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());
151
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());
159
160 }
161
162 template<typename TDataType>
163 VirtualParticleShiftingStrategy<TDataType>::~VirtualParticleShiftingStrategy()
164 {
165 m_lamda.clear();
166 m_deltaPos.clear();
167 // m_position_old.clear();
168 }
169
170 template<typename TDataType>
171 bool VirtualParticleShiftingStrategy<TDataType>::VectorResize()
172 {
173
174 if (this->outVDensity()->size() != this->outVirtualParticles()->size())
175 this->outVDensity()->resize(this->outVirtualParticles()->size());
176
177 if (m_deltaPos.size() != this->inRPosition()->size())
178 m_deltaPos.resize(this->inRPosition()->size());
179
180 if (m_lamda.size() != this->inRPosition()->size())
181 m_lamda.resize(this->inRPosition()->size());
182
183 return true;
184 }
185
186
187 template<typename TDataType>
188 void VirtualParticleShiftingStrategy<TDataType>::constrain()
189 {
190
191 VectorResize();
192
193 int it = 0;
194
195 int itNum = this->varIterationNumber()->getData();
196
197 int num = this->inRPosition()->size();
198
199 if (num != this->outVirtualParticles()->size())
200 {
201 this->outVirtualParticles()->resize(num);
202 }
203
204 cuExecute(num, T_RealCopytoVirtual,
205 this->inRPosition()->getData(),
206 this->outVirtualParticles()->getData(),
207 this->inTimeStep()->getData()
208 );
209
210 m_vv_nbrQuery->update();
211
212 if (this->inFrameNumber()->getValue() == 0)
213 {
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());
217 }
218
219 while (it < itNum)
220 {
221 takeOneIteration();
222 it++;
223 }
224 std::cout << "*DUAL-ISPH::ParticleShiftingStrategy(S.B.)::Iteration:" << it << std::endl;
225 }
226
227
228 template<typename TDataType>
229 void VirtualParticleShiftingStrategy<TDataType>::takeOneIteration()
230 {
231
232 Real dt = this->inTimeStep()->getData();
233 int num = this->inRPosition()->size();
234 uint pDims = cudaGridSize(num, BLOCK_SIZE);
235
236 m_deltaPos.reset();
237
238 m_vv_density->update();
239
240
241 cuExecute(num, T_ComputeLambdas,
242 m_lamda,
243 m_vv_density->outDensity()->getData(),
244 this->outVirtualParticles()->getData(),
245 this->outVVNeighborIds()->getData(),
246 m_kernel,
247 maxDensity,
248 this->varSmoothingLength()->getData());
249
250 cuExecute(num, T_ComputeDisplacement,
251 m_deltaPos,
252 m_lamda,
253 this->outVirtualParticles()->getData(),
254 this->outVVNeighborIds()->getData(),
255 m_kernel,
256 this->varSmoothingLength()->getData(),
257 dt);
258
259 cuExecute(num, T_UpdatePosition,
260 this->outVirtualParticles()->getData(),
261 m_deltaPos,
262 dt);
263 }
264
265
266 DEFINE_CLASS(VirtualParticleShiftingStrategy);
267
268}