milupHPC documentation
  • src
  • sph
internal_forces.cu
Go to the documentation of this file.
1#include "../../include/sph/internal_forces.cuh"
2#include "../../include/cuda_utils/cuda_launcher.cuh"
3
4__global__ void SPH::Kernel::internalForces(::SPH::SPH_kernel kernel, Material *materials, Tree *tree, Particles *particles,
5 int *interactions, int numRealParticles) {
6
7 int i, k, inc, j, numInteractions;
8 int f, kk;
9
10 real W;
11 real tmp;
12
13 real ax;
14#if DIM > 1
15 real ay;
16#if DIM == 3
17 real az;
18#endif
19#endif
20
21 real sml;
22
23 int matId, matIdj;
24 real sml1;
25
26 real vxj, vyj, vzj;
27
28 real vr;
29 real rr;
30 real rhobar;
31 real mu;
32 real muijmax;
33 real smooth;
34 real csbar;
35 real alpha, beta;
36
37#if BALSARA_SWITCH
38 real fi, fj;
39 real curli, curlj;
40 const real eps_balsara = 1e-4;
41#endif
42
43#if ARTIFICIAL_STRESS
44 real artf = 0;
45#endif
46
47 int d;
48 int dd;
49 int e;
50
51 real dr[DIM];
52 real dv[DIM];
53
54 real x, vx;
55#if DIM > 1
56 real y, vy;
57#if DIM == 3
58 real z, vz;
59#endif
60#endif
61
62 real drhodt;
63
64#if INTEGRATE_ENERGY
65 real dedt;
66#endif
67
68 real dvx;
69#if DIM > 1
70 real dvy;
71#if DIM == 3
72 real dvz;
73#endif
74#endif
75
76#if NAVIER_STOKES
77 real eta;
78 real zetaij;
79#endif
80
81 real vvnablaW;
82 real dWdr;
83 real dWdrj;
84 real dWdx[DIM];
85 real Wj;
86 real dWdxj[DIM];
87 real pij = 0;
88 real r;
89 real accels[DIM];
90 real accelsj[DIM];
91 real accelshearj[DIM];
92
93 inc = blockDim.x * gridDim.x;
94 for (i = threadIdx.x + blockIdx.x * blockDim.x; i < numRealParticles; i += inc) {
95
96 matId = particles->materialId[i];
97
98 numInteractions = particles->noi[i];
99
100 ax = 0;
101#if DIM > 1
102 ay = 0;
103#if DIM == 3
104 az = 0;
105#endif
106#endif
107
108 alpha = materials[matId].artificialViscosity.alpha; //matAlpha[matId];
109 beta = materials[matId].artificialViscosity.beta; //matBeta[matId];
110 muijmax = 0;
111
112 sml1 = particles->sml[i];
113
114 drhodt = 0;
115#if INTEGRATE_ENERGY
116 dedt = 0;
117#endif
118#if INTEGRATE_SML
119 particles->dsmldt[i] = 0.0;
120#endif
121
122 #pragma unroll
123 for (d = 0; d < DIM; d++) {
124 accels[d] = 0.0;
125 accelsj[d] = 0.0;
126 accelshearj[d] = 0.0;
127 }
128 sml = particles->sml[i];
129
130 x = particles->x[i];
131#if DIM > 1
132 y = particles->y[i];
133#if DIM == 3
134 z = particles->z[i];
135#endif
136#endif
137 vx = particles->vx[i];
138#if DIM > 1
139 vy = particles->vy[i];
140#if DIM == 3
141 vz = particles->vz[i];
142#endif
143#endif
144
145
146 //particles->dxdt[i] = 0;
147 particles->ax[i] = 0;
148#if DIM > 1
149 //p.dydt[i] = 0;
150 particles->ay[i] = 0;
151#if DIM == 3
152 //p.dzdt[i] = 0;
153 particles->az[i] = 0;
154#endif
155#endif
156
157 particles->drhodt[i] = 0.0;
158#if INTEGRATE_ENERGY
159 particles->dedt[i] = 0.0;
160#endif
161#if INTEGRATE_SML
162 particles->dsmldt[i] = 0.0;
163#endif
164
165 // if particle has no interactions continue and set all derivs to zero
166 // but not the accels (these are handled in the tree for gravity)
167 if (numInteractions < 1) {
168 // finally continue
169 continue;
170 }
171
172#if BALSARA_SWITCH
173 curli = 0;
174 for (d = 0; d < DIM; d++) {
175 curli += particles->curlv[i*DIM+d]*particles->curlv[i*DIM+d];
176 }
177 curli = cuda::math::sqrt(curli);
178 fi = cuda::math::abs(particles->divv[i]) / (cuda::math::abs(particles->divv[i])
179 + curli + eps_balsara*particles->cs[i]/particles->sml[i]);
180#endif
181
182 // THE MAIN SPH LOOP FOR ALL INTERNAL FORCES
183 // loop over interaction partners for SPH sums
184 for (k = 0; k < numInteractions; k++) {
185 //matIdj = EOS_TYPE_IGNORE;
186 // the interaction partner
187 j = interactions[i * MAX_NUM_INTERACTIONS + k];
188
189 if (i == j) {
190 cudaTerminate("i = %i == j = %i\n", i, j);
191 }
192
193 matIdj = particles->materialId[j];
194
195 #pragma unroll
196 for (d = 0; d < DIM; d++) {
197 accelsj[d] = 0.0;
198 }
199
200#if (VARIABLE_SML || INTEGRATE_SML) // || DEAL_WITH_TOO_MANY_INTERACTIONS)
201 sml = 0.5 * (particles->sml[i] + particles->sml[j]);
202#endif
203
204 vxj = particles->vx[j];
205#if DIM > 1
206 vyj = particles->vy[j];
207#if DIM == 3
208 vzj = particles->vz[j];
209#endif
210#endif
211 // relative vector
212 dr[0] = x - particles->x[j];
213#if DIM > 1
214 dr[1] = y - particles->y[j];
215#if DIM == 3
216 dr[2] = z - particles->z[j];
217#endif
218#endif
219 r = 0;
220 #pragma unroll
221 for (e = 0; e < DIM; e++) {
222 r += dr[e]*dr[e];
223 dWdx[e] = 0.0;
224#if AVERAGE_KERNELS
225 dWdxj[e] = 0.0;
226#endif
227 }
228 W = 0.0;
229 dWdr = 0.0;
230#if AVERAGE_KERNELS
231 Wj = 0.0;
232 dWdrj = 0.0;
233#endif
234 r = cuda::math::sqrt(r);
235
236 // get kernel values for this interaction
237#if AVERAGE_KERNELS
238 kernel(&W, dWdx, &dWdr, dr, particles->sml[i]);
239 kernel(&Wj, dWdxj, &dWdrj, dr, particles->sml[j]);
240# if SHEPARD_CORRECTION
241 W /= p_rhs.shepard_correction[i];
242 Wj /= p_rhs.shepard_correction[j];
243 for (e = 0; e < DIM; e++) {
244 dWdx[e] /= p_rhs.shepard_correction[i];
245 dWdxj[e] /= p_rhs.shepard_correction[j];
246 }
247 dWdr /= p_rhs.shepard_correction[i];
248 dWdrj /= p_rhs.shepard_correction[j];
249
250 W = 0.5 * (W + Wj);
251 dWdr = 0.5 * (dWdr + dWdrj);
252 for (e = 0; e < DIM; e++) {
253 dWdx[e] = 0.5 * (dWdx[e] + dWdxj[e]);
254 }
255# endif // SHEPARD_CORRECTION
256#else
257 kernel(&W, dWdx, &dWdr, dr, sml);
258#if SHEPARD_CORRECTION
259 W /= p_rhs.shepard_correction[i];
260 for (e = 0; e < DIM; e++) {
261 dWdx[e] /= p_rhs.shepard_correction[i];
262 }
263 dWdr /= p_rhs.shepard_correction[i];
264#endif
265#endif
266
267 dv[0] = dvx = vx - vxj;
268#if DIM > 1
269 dv[1] = dvy = vy - vyj;
270#if DIM == 3
271 dv[2] = dvz = vz - vzj;
272#endif
273#endif
274
275 vvnablaW = dvx * dWdx[0];
276#if DIM > 1
277 vvnablaW += dvy * dWdx[1];
278#if DIM == 3
279 vvnablaW += dvz * dWdx[2];
280#endif
281#endif
282
283 rr = 0.0;
284 vr = 0.0;
285 #pragma unroll
286 for (e = 0; e < DIM; e++) {
287 rr += dr[e]*dr[e];
288 vr += dv[e]*dr[e];
289 //printf("vr += %e * %e\n", dv[e], dr[e]);
290 }
291 //printf("pij: vr = %e\n", vr);
292
293 pij = 0.0;
294
295 // artificial viscosity force only if v_ij * r_ij < 0
296 if (vr < 0) {
297 csbar = 0.5*(particles->cs[i] + particles->cs[j]);
298 //if (std::isnan(csbar)) {
299 // printf("csbar = %e, cs[%i] = %e, cs[%i] = %e\n", csbar, i, particles->cs[i], j, particles->cs[j]);
300 //}
301 smooth = 0.5*(sml1 + particles->sml[j]);
302
303 const real eps_artvisc = 1e-2;
304 mu = smooth*vr/(rr + smooth*smooth*eps_artvisc);
305
306 if (mu > muijmax) {
307 muijmax = mu;
308 }
309 rhobar = 0.5 * (particles->rho[i] + particles->rho[j]);
310# if BALSARA_SWITCH
311 curlj = 0;
312 for (d = 0; d < DIM; d++) {
313 curlj += particles->curlv[j*DIM+d]*particles->curlv[j*DIM+d];
314 }
315 curlj = cuda::math::sqrt(curlj);
316 fj = cuda::math::abs(particles->divv[j]) / (cuda::math::abs(particles->divv[j])
317 + curlj + eps_balsara*particles->cs[j]/particles->sml[j]);
318 mu *= (fi+fj)/2.;
319# endif
320 pij = (beta*mu - alpha*csbar) * mu/rhobar;
321 //if (std::isnan(pij) || std::isinf(pij)) {
322 // cudaTerminate("pij = (%e * %e - %e * %e) * (%e/%e), cs[i] = %e, cs[j] = %e\n", beta, mu, alpha, csbar, mu, rhobar,
323 // particles->cs[i], particles->cs[j]);
324 //}
325 }
326
327#if NAVIER_STOKES
328 eta = (particles->eta[i] + particles->eta[j]) * 0.5 ;
329 for (d = 0; d < DIM; d++) {
330 accelshearj[d] = 0;
331 for (dd = 0; dd < DIM; dd++) {
332# if (SPH_EQU_VERSION == 1)
333# if SML_CORRECTION
334 accelshearj[d] += eta * particles->mass[j] * (particles->Tshear[CudaUtils::stressIndex(j,d,dd)]/(particles->sml_omega[j]*particles->rho[j]*particles->rho[j])+ particles->Tshear[stressIndex(i,d,dd)]/(particles->sml_omega[i]*particles->rho[i]*particles->rho[i])) *dWdx[dd];
335# else
336 accelshearj[d] += eta * particles->mass[j] * (particles->Tshear[CudaUtils::stressIndex(j,d,dd)]/(particles->rho[j]*particles->rho[j]) + particles->Tshear[CudaUtils::stressIndex(i,d,dd)]/(particles->rho[i]*particles->rho[i])) *dWdx[dd];
337# endif
338# elif (SPH_EQU_VERSION == 2)
339# if SML_CORRECTION
340 accelshearj[d] += eta * particles->mass[j] * (particles->Tshear[CudaUtils::stressIndex(j,d,dd)]+particles->Tshear[CudaUtils::stressIndex(i,d,dd)])/(particles->sml_omega[i]*particles->rho[i]*particles->sml_omega[j]*particles->rho[j]) *dWdx[dd];
341# else
342 accelshearj[d] += eta * particles->mass[j] * (particles->Tshear[CudaUtils::stressIndex(j,d,dd)]+particles->Tshear[CudaUtils::stressIndex(i,d,dd)])/(particles->rho[i]*particles->rho[j]) *dWdx[dd];
343# endif
344# endif // SPH_EQU_VERSION
345 }
346 }
347#if KLEY_VISCOSITY //artificial bulk viscosity with f=0.5
348 zetaij = 0.0;
349 if (vr < 0) { // only for approaching particles
350 zetaij = -0.5 * (0.25*(p.h[i] + p.h[j])*(p.h[i]+p.h[j])) * (p.rho[i]+p.rho[j])*0.5 * (p_rhs.divv[i] + p_rhs.divv[j])*0.5;
351 }
352 for (d = 0; d < DIM; d++) {
353# if (SPH_EQU_VERSION == 1)
354 accelshearj[d] += zetaij * p.m[j] * (p_rhs.divv[i] + p_rhs.divv[j]) /(p.rho[i]*p.rho[j]) * dWdx[d];
355# elif (SPH_EQU_VERSION == 2)
356 accelshearj[d] += zetaij * p.m[j] * (p_rhs.divv[i]/(p.rho[i]*p.rho[i]) + p_rhs.divv[j]/(p.rho[j]*p.rho[j])) * dWdx[d];
357# endif
358 }
359#endif // KLEY_VISCOSITY
360#endif // NAVIER_STOKES
361
362#if (SPH_EQU_VERSION == 1)
363 #pragma unroll
364 for (d = 0; d < DIM; d++) {
365 accelsj[d] = -particles->mass[j] * (particles->p[i]/(particles->rho[i]*particles->rho[i]) + particles->p[j]/(particles->rho[j]*particles->rho[j])) * dWdx[d];
366 accels[d] += accelsj[d];
367 }
368#elif (SPH_EQU_VERSION == 2)
369 #pragma unroll
370 for (d = 0; d < DIM; d++) {
371 accelsj[d] = -particles->mass[j] * ((particles->p[i]+particles->p[j])/(particles->rho[i]*particles->rho[j])) * dWdx[d];
372 accels[d] += accelsj[d];
373 }
374#endif // SPH_EQU_VERSION
375
376 //if (std::isnan(accelsj[0])) {
377 // cudaTerminate("accelsj[0] = %e\n", accelsj[0]);
378 //}
379
380#if NAVIER_STOKES
381 #pragma unroll
382 for (d = 0; d < DIM; d++) {
383 accels[d] += accelshearj[d];
384 }
385#endif
386
387 accels[0] += particles->mass[j]*(-pij)*dWdx[0];
388#if DIM > 1
389 accels[1] += particles->mass[j]*(-pij)*dWdx[1];
390#if DIM == 3
391 accels[2] += particles->mass[j]*(-pij)*dWdx[2];
392#endif
393#endif
394 //if (std::isnan(accels[0])) {
395 // cudaTerminate("accels[0] = %e, mass = %e, pij = %e, dWdx[0] = %e\n", accels[0],
396 // particles->mass[j], pij, dWdx[0]);
397 //}
398 drhodt += particles->rho[i]/particles->rho[j] * particles->mass[j] * vvnablaW;
399
400#if INTEGRATE_SML
401 // minus since vvnablaW is v_i - v_j \nabla W_ij
402#if TENSORIAL_CORRECTION
403 for (d = 0; d < DIM; d++) {
404 for (dd = 0; dd < DIM; dd++) {
405 particles->dsmldt[i] -= 1./DIM * particles->sml[i] * particles->mass[j]/particles->rho[j] * dv[d] * dWdx[dd] * particles->tensorialCorrectionMatrix[i*DIM*DIM+d*DIM+dd];
406 }
407 }
408# else
409# if !SML_CORRECTION
410 particles->dsmldt[i] -= 1./DIM * particles->sml[i] * particles->mass[j]/particles->rho[j] * vvnablaW;
411# endif // SML_CORRECTION
412#endif
413#endif // INTEGRATE_SML
414
415#if INTEGRATE_ENERGY
416 if (true) { // !isRelaxationRun) {
417 dedt += 0.5 * particles->mass[j] * pij * vvnablaW;
418 //if (dedt < 0.) {
419 // printf("dedt (= %e) += 0.5 * %e * %e * %e (= %e)\n", dedt, particles->mass[j], pij, vvnablaW, particles->mass[j] * pij * vvnablaW);
420 //}
421 }
422
423 // remember, accelsj are accelerations by particle j, and dv = v_i - v_j
424 dedt += 0.5 * accelsj[0] * -dvx;
425# if DIM > 1
426 dedt += 0.5 * accelsj[1] * -dvy;
427# endif
428# if DIM > 2
429 dedt += 0.5 * accelsj[2] * -dvz;
430# endif
431 //if (dedt < 0.) {
432 // printf("dedt (= %e) += (%e + %e + %e) = %e dv (%e, %e, %e)\n", dedt, 0.5 * accelsj[0] * -dvx, 0.5 * accelsj[1] * -dvy, 0.5 * accelsj[2] * -dvz,
433 // 0.5 * accelsj[0] * -dvx + 0.5 * accelsj[1] * -dvy + 0.5 * accelsj[2] * -dvz, dvx, dvy, dvz);
434 //}
435
436#endif // INTEGRATE ENERGY
437
438 } // neighbors loop end
439
440 ax = accels[0];
441#if DIM > 1
442 ay = accels[1];
443#if DIM == 3
444 az = accels[2];
445#endif
446#endif
447 particles->ax[i] = ax;
448#if DIM > 1
449 particles->ay[i] = ay;
450#if DIM == 3
451 particles->az[i] = az;
452#endif
453#endif
454
455 //if (std::isnan(ax)) {
456 // cudaTerminate("ax[%i] = %e, density = %e\n", i, ax, particles->rho[i]);
457 //}
458
459 particles->drhodt[i] = drhodt;
460
461
462#if INTEGRATE_ENERGY
463 particles->dedt[i] = dedt;
464#endif // INTEGRATE_ENERGY
465
466 } // particle loop end
467
468}
469
470
471real SPH::Kernel::Launch::internalForces(::SPH::SPH_kernel kernel, Material *materials, Tree *tree, Particles *particles,
472 int *interactions, int numRealParticles) {
473 ExecutionPolicy executionPolicy;
474 return cuda::launch(true, executionPolicy, ::SPH::Kernel::internalForces, kernel, materials, tree, particles, interactions,
475 numRealParticles);
476}
477
478
ExecutionPolicy
Execution policy/instruction for CUDA kernel execution.
Definition: cuda_launcher.cuh:33
Material
Material parameters.
Definition: material.cuh:88
Material::artificialViscosity
ArtificialViscosity artificialViscosity
Definition: material.cuh:114
Particles
Particle(s) class based on SoA (Structur of Arrays).
Definition: particles.cuh:50
Particles::noi
integer * noi
(pointer to) number of interactions (array)
Definition: particles.cuh:118
Particles::materialId
integer * materialId
(pointer to) material identifier (array)
Definition: particles.cuh:111
Particles::x
real * x
(pointer to) x position (array)
Definition: particles.cuh:62
Particles::rho
real * rho
(pointer to) density (array)
Definition: particles.cuh:133
Particles::drhodt
real * drhodt
(pointer to) time derivative of density (array)
Definition: particles.cuh:148
Particles::ay
real * ay
(pointer to) y acceleration (array)
Definition: particles.cuh:74
Particles::az
real * az
(pointer to) z acceleration (array)
Definition: particles.cuh:82
Particles::p
real * p
(pointer to) pressure (array)
Definition: particles.cuh:135
Particles::cs
real * cs
(pointer to) sound of speed (array)
Definition: particles.cuh:129
Particles::y
real * y
(pointer to) y position (array)
Definition: particles.cuh:70
Particles::ax
real * ax
(pointer to) x acceleration (array)
Definition: particles.cuh:66
Particles::sml
real * sml
(pointer to) smoothing length (array)
Definition: particles.cuh:113
Particles::dedt
real * dedt
(pointer to) time derivative of internal energy (array)
Definition: particles.cuh:123
Particles::mass
real * mass
(pointer to) mass (array)
Definition: particles.cuh:60
Particles::z
real * z
(pointer to) z position (array)
Definition: particles.cuh:78
Particles::vz
real * vz
(pointer to) z velocity (array)
Definition: particles.cuh:80
Particles::vx
real * vx
(pointer to) x velocity (array)
Definition: particles.cuh:64
Particles::vy
real * vy
(pointer to) y velocity (array)
Definition: particles.cuh:72
Tree
Tree class.
Definition: tree.cuh:140
cudaTerminate
#define cudaTerminate(...)
Definition: cuda_utilities.cuh:70
CudaUtils::stressIndex
__device__ int stressIndex(int particleIndex, int row, int col)
map [i][j] to [i*DIM*DIM+j] for the tensors
Definition: linalg.cu:11
ProfilerIds::Time::SPH::internalForces
const char *const internalForces
Definition: h5profiler.h:107
ProfilerIds::Time::tree
const char *const tree
Definition: h5profiler.h:57
SPH::Kernel::Launch::internalForces
real internalForces(::SPH::SPH_kernel kernel, Material *materials, Tree *tree, Particles *particles, int *interactions, int numRealParticles)
Wrapper for SPH::Kernel::internalForces().
Definition: internal_forces.cu:471
SPH::Kernel::internalForces
__global__ void internalForces(::SPH::SPH_kernel kernel, Material *materials, Tree *tree, Particles *particles, int *interactions, int numRealParticles)
Internal SPH forces.
Definition: internal_forces.cu:4
SPH::SPH_kernel
void(* SPH_kernel)(real *W, real dWdx[DIM], real *dWdr, real dx[DIM], real h)
Function pointer to generic SPH kernel function.
Definition: kernel.cuh:26
cuda::math::sqrt
__device__ real sqrt(real a)
Square root of a floating point value.
Definition: cuda_utilities.cu:456
cuda::math::abs
__device__ real abs(real a)
Absolute value of a floating point value.
Definition: cuda_utilities.cu:448
cuda::launch
real launch(bool timeKernel, const ExecutionPolicy &policy, void(*f)(Arguments...), Arguments... args)
CUDA execution wrapper function.
Definition: cuda_launcher.cuh:114
real
double real
Definition: parameter.h:15
MAX_NUM_INTERACTIONS
#define MAX_NUM_INTERACTIONS
Definition: parameter.h:106
DIM
#define DIM
Dimension of the problem.
Definition: parameter.h:38
ArtificialViscosity::alpha
real alpha
Artificial viscosity .
Definition: material.cuh:48
ArtificialViscosity::beta
real beta
Artificial viscosity .
Definition: material.cuh:50

milupHPC - src/sph/internal_forces.cu Source File
Generated on Wed Aug 31 2022 12:16:53 by Doxygen 1.9.3