18template <
class Particle_T>
28 virtual std::string
getName()
override {
return "SPHHydroForceFunctor"; }
45 void AoSFunctor(Particle_T &i, Particle_T &j,
bool newton3 =
true)
override {
46 using namespace autopas::utils::ArrayMath::literals;
48 if (i.isDummy() or j.isDummy()) {
51 const std::array<double, 3> dr = i.getR() - j.getR();
60 const std::array<double, 3> dv = i.getV() - j.getV();
67 const double v_sig = i.getSoundSpeed() + j.getSoundSpeed() - 3.0 * w_ij;
70 i.checkAndSetVSigMax(v_sig);
72 j.checkAndSetVSigMax(v_sig);
75 const double AV = -0.5 * v_sig * w_ij / (0.5 * (i.getDensity() + j.getDensity()));
79 const std::array<double, 3> gradW_ij =
85 i.getPressure() / (i.getDensity() * i.getDensity()) + j.getPressure() / (j.getDensity() * j.getDensity()) + AV;
86 i.subAcceleration(gradW_ij * (scale * j.getMass()));
91 j.addAcceleration(gradW_ij * (scale * i.getMass()));
94 double scale2i = j.getMass() * (i.getPressure() / (i.getDensity() * i.getDensity()) + 0.5 * AV);
100 double scale2j = i.getMass() * (j.getPressure() / (j.getDensity() * j.getDensity()) + 0.5 * AV);
111 using namespace autopas::utils::ArrayMath::literals;
112 if (soa.
size() == 0)
return;
114 double *
const __restrict massptr = soa.template begin<Particle_T::AttributeNames::mass>();
115 double *
const __restrict densityptr = soa.template begin<Particle_T::AttributeNames::density>();
116 double *
const __restrict smthptr = soa.template begin<Particle_T::AttributeNames::smth>();
117 double *
const __restrict soundSpeedptr = soa.template begin<Particle_T::AttributeNames::soundSpeed>();
118 double *
const __restrict pressureptr = soa.template begin<Particle_T::AttributeNames::pressure>();
119 double *
const __restrict vsigmaxptr = soa.template begin<Particle_T::AttributeNames::vsigmax>();
120 double *
const __restrict engDotptr = soa.template begin<Particle_T::AttributeNames::engDot>();
122 double *
const __restrict xptr = soa.template begin<Particle_T::AttributeNames::posX>();
123 double *
const __restrict yptr = soa.template begin<Particle_T::AttributeNames::posY>();
124 double *
const __restrict zptr = soa.template begin<Particle_T::AttributeNames::posZ>();
125 double *
const __restrict velXptr = soa.template begin<Particle_T::AttributeNames::velX>();
126 double *
const __restrict velYptr = soa.template begin<Particle_T::AttributeNames::velY>();
127 double *
const __restrict velZptr = soa.template begin<Particle_T::AttributeNames::velZ>();
128 double *
const __restrict accXptr = soa.template begin<Particle_T::AttributeNames::accX>();
129 double *
const __restrict accYptr = soa.template begin<Particle_T::AttributeNames::accY>();
130 double *
const __restrict accZptr = soa.template begin<Particle_T::AttributeNames::accZ>();
132 const auto *
const __restrict ownedStatePtr = soa.template begin<Particle_T::AttributeNames::ownershipState>();
134 for (
unsigned int indexFirst = 0; indexFirst < soa.
size(); ++indexFirst) {
140 double localvsigmax = 0.;
141 double localengdotsum = 0.;
142 double localAccX = 0.;
143 double localAccY = 0.;
144 double localAccZ = 0.;
149 for (
unsigned int j = indexFirst + 1; j < soa.
size(); ++j) {
150 using namespace autopas::utils::ArrayMath::literals;
152 const double drx = xptr[indexFirst] - xptr[j];
153 const double dry = yptr[indexFirst] - yptr[j];
154 const double drz = zptr[indexFirst] - zptr[j];
156 const double drx2 = drx * drx;
157 const double dry2 = dry * dry;
158 const double drz2 = drz * drz;
160 const double dr2 = drx2 + dry2 + drz2;
164 const double dvX = velXptr[indexFirst] - velXptr[j];
165 const double dvY = velYptr[indexFirst] - velYptr[j];
166 const double dvZ = velZptr[indexFirst] - velZptr[j];
169 double dvdr = dvX * drx + dvY * dry + dvZ * drz;
170 const double w_ij = (dvdr < 0) ? dvdr / sqrt(dr2) : 0;
173 const double v_sig = soundSpeedptr[indexFirst] + soundSpeedptr[j] - 3.0 * w_ij;
176 localvsigmax = std::max(localvsigmax, v_sig);
178 vsigmaxptr[j] = vsigmaxptr[j] > v_sig ? vsigmaxptr[j] : v_sig;
181 const double AV = -0.5 * v_sig * w_ij / (0.5 * (densityptr[indexFirst] + densityptr[j]));
185 const std::array<double, 3> gradW_ij =
191 double scale = pressureptr[indexFirst] / (densityptr[indexFirst] * densityptr[indexFirst]) +
192 pressureptr[j] / (densityptr[j] * densityptr[j]) + AV;
193 const double massscale = scale * massptr[j];
194 localAccX -= gradW_ij[0] * massscale;
195 localAccY -= gradW_ij[1] * massscale;
196 localAccZ -= gradW_ij[2] * massscale;
201 const double massscale2 = scale * massptr[indexFirst];
202 accXptr[j] += gradW_ij[0] * massscale2;
203 accYptr[j] += gradW_ij[1] * massscale2;
204 accZptr[j] += gradW_ij[2] * massscale2;
208 massptr[j] * (pressureptr[indexFirst] / (densityptr[indexFirst] * densityptr[indexFirst]) + 0.5 * AV);
209 localengdotsum += (gradW_ij[0] * dvX + gradW_ij[1] * dvY + gradW_ij[2] * dvZ) * scale2i;
213 double scale2j = massptr[indexFirst] * (pressureptr[j] / (densityptr[j] * densityptr[j]) + 0.5 * AV);
214 engDotptr[j] += (gradW_ij[0] * dvX + gradW_ij[1] * dvY + gradW_ij[2] * dvZ) * scale2j;
218 engDotptr[indexFirst] += localengdotsum;
219 accXptr[indexFirst] += localAccX;
220 accYptr[indexFirst] += localAccY;
221 accZptr[indexFirst] += localAccZ;
222 vsigmaxptr[indexFirst] = std::max(localvsigmax, vsigmaxptr[indexFirst]);
230 bool newton3)
override {
231 using namespace autopas::utils::ArrayMath::literals;
232 if (soa1.
size() == 0 || soa2.
size() == 0)
return;
234 double *
const __restrict massptr1 = soa1.template begin<Particle_T::AttributeNames::mass>();
235 double *
const __restrict densityptr1 = soa1.template begin<Particle_T::AttributeNames::density>();
236 double *
const __restrict smthptr1 = soa1.template begin<Particle_T::AttributeNames::smth>();
237 double *
const __restrict soundSpeedptr1 = soa1.template begin<Particle_T::AttributeNames::soundSpeed>();
238 double *
const __restrict pressureptr1 = soa1.template begin<Particle_T::AttributeNames::pressure>();
239 double *
const __restrict vsigmaxptr1 = soa1.template begin<Particle_T::AttributeNames::vsigmax>();
240 double *
const __restrict engDotptr1 = soa1.template begin<Particle_T::AttributeNames::engDot>();
242 double *
const __restrict xptr1 = soa1.template begin<Particle_T::AttributeNames::posX>();
243 double *
const __restrict yptr1 = soa1.template begin<Particle_T::AttributeNames::posY>();
244 double *
const __restrict zptr1 = soa1.template begin<Particle_T::AttributeNames::posZ>();
245 double *
const __restrict velXptr1 = soa1.template begin<Particle_T::AttributeNames::velX>();
246 double *
const __restrict velYptr1 = soa1.template begin<Particle_T::AttributeNames::velY>();
247 double *
const __restrict velZptr1 = soa1.template begin<Particle_T::AttributeNames::velZ>();
248 double *
const __restrict accXptr1 = soa1.template begin<Particle_T::AttributeNames::accX>();
249 double *
const __restrict accYptr1 = soa1.template begin<Particle_T::AttributeNames::accY>();
250 double *
const __restrict accZptr1 = soa1.template begin<Particle_T::AttributeNames::accZ>();
252 double *
const __restrict massptr2 = soa2.template begin<Particle_T::AttributeNames::mass>();
253 double *
const __restrict densityptr2 = soa2.template begin<Particle_T::AttributeNames::density>();
254 double *
const __restrict smthptr2 = soa2.template begin<Particle_T::AttributeNames::smth>();
255 double *
const __restrict soundSpeedptr2 = soa2.template begin<Particle_T::AttributeNames::soundSpeed>();
256 double *
const __restrict pressureptr2 = soa2.template begin<Particle_T::AttributeNames::pressure>();
257 double *
const __restrict vsigmaxptr2 = soa2.template begin<Particle_T::AttributeNames::vsigmax>();
258 double *
const __restrict engDotptr2 = soa2.template begin<Particle_T::AttributeNames::engDot>();
260 double *
const __restrict xptr2 = soa2.template begin<Particle_T::AttributeNames::posX>();
261 double *
const __restrict yptr2 = soa2.template begin<Particle_T::AttributeNames::posY>();
262 double *
const __restrict zptr2 = soa2.template begin<Particle_T::AttributeNames::posZ>();
263 double *
const __restrict velXptr2 = soa2.template begin<Particle_T::AttributeNames::velX>();
264 double *
const __restrict velYptr2 = soa2.template begin<Particle_T::AttributeNames::velY>();
265 double *
const __restrict velZptr2 = soa2.template begin<Particle_T::AttributeNames::velZ>();
266 double *
const __restrict accXptr2 = soa2.template begin<Particle_T::AttributeNames::accX>();
267 double *
const __restrict accYptr2 = soa2.template begin<Particle_T::AttributeNames::accY>();
268 double *
const __restrict accZptr2 = soa2.template begin<Particle_T::AttributeNames::accZ>();
270 const auto *
const __restrict ownedStatePtr1 = soa1.template begin<Particle_T::AttributeNames::ownershipState>();
271 const auto *
const __restrict ownedStatePtr2 = soa2.template begin<Particle_T::AttributeNames::ownershipState>();
273 for (
unsigned int indexFirst = 0; indexFirst < soa1.
size(); ++indexFirst) {
279 double localvsigmax = 0.;
280 double localengdotsum = 0.;
281 double localAccX = 0.;
282 double localAccY = 0.;
283 double localAccZ = 0.;
288 for (
unsigned int j = 0; j < soa2.
size(); ++j) {
289 using namespace autopas::utils::ArrayMath::literals;
291 const double drx = xptr1[indexFirst] - xptr2[j];
292 const double dry = yptr1[indexFirst] - yptr2[j];
293 const double drz = zptr1[indexFirst] - zptr2[j];
295 const double drx2 = drx * drx;
296 const double dry2 = dry * dry;
297 const double drz2 = drz * drz;
299 const double dr2 = drx2 + dry2 + drz2;
303 const double dvX = velXptr1[indexFirst] - velXptr2[j];
304 const double dvY = velYptr1[indexFirst] - velYptr2[j];
305 const double dvZ = velZptr1[indexFirst] - velZptr2[j];
308 double dvdr = dvX * drx + dvY * dry + dvZ * drz;
309 const double w_ij = (dvdr < 0) ? dvdr / sqrt(dr2) : 0;
312 const double v_sig = soundSpeedptr1[indexFirst] + soundSpeedptr2[j] - 3.0 * w_ij;
315 localvsigmax = std::max(localvsigmax, v_sig);
318 vsigmaxptr2[j] = vsigmaxptr2[j] > v_sig ? vsigmaxptr2[j] : v_sig;
321 const double AV = -0.5 * v_sig * w_ij / (0.5 * (densityptr1[indexFirst] + densityptr2[j]));
325 const std::array<double, 3> gradW_ij = (
SPHKernels::gradW({drx, dry, drz}, smthptr1[indexFirst]) +
331 double scale = pressureptr1[indexFirst] / (densityptr1[indexFirst] * densityptr1[indexFirst]) +
332 pressureptr2[j] / (densityptr2[j] * densityptr2[j]) + AV;
333 const double massscale = scale * massptr2[j];
334 localAccX -= gradW_ij[0] * massscale;
335 localAccY -= gradW_ij[1] * massscale;
336 localAccZ -= gradW_ij[2] * massscale;
341 const double massscale = scale * massptr1[indexFirst];
342 accXptr2[j] += gradW_ij[0] * massscale;
343 accYptr2[j] += gradW_ij[1] * massscale;
344 accZptr2[j] += gradW_ij[2] * massscale;
348 massptr2[j] * (pressureptr1[indexFirst] / (densityptr1[indexFirst] * densityptr1[indexFirst]) + 0.5 * AV);
349 localengdotsum += (gradW_ij[0] * dvX + gradW_ij[1] * dvY + gradW_ij[2] * dvZ) * scale2i;
354 double scale2j = massptr1[indexFirst] * (pressureptr2[j] / (densityptr2[j] * densityptr2[j]) + 0.5 * AV);
355 engDotptr2[j] += (gradW_ij[0] * dvX + gradW_ij[1] * dvY + gradW_ij[2] * dvZ) * scale2j;
360 engDotptr1[indexFirst] += localengdotsum;
361 accXptr1[indexFirst] += localAccX;
362 accYptr1[indexFirst] += localAccY;
363 accZptr1[indexFirst] += localAccZ;
364 vsigmaxptr1[indexFirst] = std::max(localvsigmax, vsigmaxptr1[indexFirst]);
374 bool newton3)
override {
375 using namespace autopas::utils::ArrayMath::literals;
376 if (soa.
size() == 0)
return;
378 const auto *
const __restrict ownedStatePtr = soa.template begin<Particle_T::AttributeNames::ownershipState>();
385 double *
const __restrict massptr = soa.template begin<Particle_T::AttributeNames::mass>();
386 double *
const __restrict densityptr = soa.template begin<Particle_T::AttributeNames::density>();
387 double *
const __restrict smthptr = soa.template begin<Particle_T::AttributeNames::smth>();
388 double *
const __restrict soundSpeedptr = soa.template begin<Particle_T::AttributeNames::soundSpeed>();
389 double *
const __restrict pressureptr = soa.template begin<Particle_T::AttributeNames::pressure>();
390 double *
const __restrict vsigmaxptr = soa.template begin<Particle_T::AttributeNames::vsigmax>();
391 double *
const __restrict engDotptr = soa.template begin<Particle_T::AttributeNames::engDot>();
393 double *
const __restrict xptr = soa.template begin<Particle_T::AttributeNames::posX>();
394 double *
const __restrict yptr = soa.template begin<Particle_T::AttributeNames::posY>();
395 double *
const __restrict zptr = soa.template begin<Particle_T::AttributeNames::posZ>();
396 double *
const __restrict velXptr = soa.template begin<Particle_T::AttributeNames::velX>();
397 double *
const __restrict velYptr = soa.template begin<Particle_T::AttributeNames::velY>();
398 double *
const __restrict velZptr = soa.template begin<Particle_T::AttributeNames::velZ>();
399 double *
const __restrict accXptr = soa.template begin<Particle_T::AttributeNames::accX>();
400 double *
const __restrict accYptr = soa.template begin<Particle_T::AttributeNames::accY>();
401 double *
const __restrict accZptr = soa.template begin<Particle_T::AttributeNames::accZ>();
403 double localvsigmax = 0.;
404 double localengdotsum = 0.;
405 double localAccX = 0.;
406 double localAccY = 0.;
407 double localAccZ = 0.;
409 const auto ¤tList = neighborList;
410 size_t listSize = currentList.size();
415 for (
unsigned int j = 0; j < listSize; ++j) {
416 using namespace autopas::utils::ArrayMath::literals;
418 const double drx = xptr[indexFirst] - xptr[currentList[j]];
419 const double dry = yptr[indexFirst] - yptr[currentList[j]];
420 const double drz = zptr[indexFirst] - zptr[currentList[j]];
422 const double drx2 = drx * drx;
423 const double dry2 = dry * dry;
424 const double drz2 = drz * drz;
426 const double dr2 = drx2 + dry2 + drz2;
430 const double dvX = velXptr[indexFirst] - velXptr[currentList[j]];
431 const double dvY = velYptr[indexFirst] - velYptr[currentList[j]];
432 const double dvZ = velZptr[indexFirst] - velZptr[currentList[j]];
435 double dvdr = dvX * drx + dvY * dry + dvZ * drz;
436 const double w_ij = (dvdr < 0) ? dvdr / sqrt(dr2) : 0;
439 const double v_sig = soundSpeedptr[indexFirst] + soundSpeedptr[currentList[j]] - 3.0 * w_ij;
442 localvsigmax = std::max(localvsigmax, v_sig);
445 vsigmaxptr[currentList[j]] =
446 vsigmaxptr[currentList[j]] > v_sig ? vsigmaxptr[currentList[j]] : v_sig;
449 const double AV = -0.5 * v_sig * w_ij / (0.5 * (densityptr[indexFirst] + densityptr[currentList[j]]));
453 const std::array<double, 3> gradW_ij = (
SPHKernels::gradW({drx, dry, drz}, smthptr[indexFirst]) +
459 double scale = pressureptr[indexFirst] / (densityptr[indexFirst] * densityptr[indexFirst]) +
460 pressureptr[currentList[j]] / (densityptr[currentList[j]] * densityptr[currentList[j]]) + AV;
461 const double massscale = scale * massptr[currentList[j]];
462 localAccX -= gradW_ij[0] * massscale;
463 localAccY -= gradW_ij[1] * massscale;
464 localAccZ -= gradW_ij[2] * massscale;
469 const double massscale = scale * massptr[indexFirst];
470 accXptr[currentList[j]] += gradW_ij[0] * massscale;
471 accYptr[currentList[j]] += gradW_ij[1] * massscale;
472 accZptr[currentList[j]] += gradW_ij[2] * massscale;
475 double scale2i = massptr[currentList[j]] *
476 (pressureptr[indexFirst] / (densityptr[indexFirst] * densityptr[indexFirst]) + 0.5 * AV);
477 localengdotsum += (gradW_ij[0] * dvX + gradW_ij[1] * dvY + gradW_ij[2] * dvZ) * scale2i;
483 massptr[indexFirst] *
484 (pressureptr[currentList[j]] / (densityptr[currentList[j]] * densityptr[currentList[j]]) + 0.5 * AV);
485 engDotptr[currentList[j]] += (gradW_ij[0] * dvX + gradW_ij[1] * dvY + gradW_ij[2] * dvZ) * scale2j;
490 engDotptr[indexFirst] += localengdotsum;
491 accXptr[indexFirst] += localAccX;
492 accYptr[indexFirst] += localAccY;
493 accZptr[indexFirst] += localAccZ;
494 vsigmaxptr[indexFirst] = std::max(localvsigmax, vsigmaxptr[indexFirst]);
501 return std::array<typename Particle_T::AttributeNames, 17>{
502 Particle_T::AttributeNames::mass, Particle_T::AttributeNames::density,
503 Particle_T::AttributeNames::smth, Particle_T::AttributeNames::soundSpeed,
504 Particle_T::AttributeNames::pressure, Particle_T::AttributeNames::vsigmax,
505 Particle_T::AttributeNames::engDot, Particle_T::AttributeNames::posX,
506 Particle_T::AttributeNames::posY, Particle_T::AttributeNames::posZ,
507 Particle_T::AttributeNames::velX, Particle_T::AttributeNames::velY,
508 Particle_T::AttributeNames::velZ, Particle_T::AttributeNames::accX,
509 Particle_T::AttributeNames::accY, Particle_T::AttributeNames::accZ,
510 Particle_T::AttributeNames::ownershipState};
517 return std::array<typename Particle_T::AttributeNames, 12>{
518 Particle_T::AttributeNames::mass, Particle_T::AttributeNames::density,
519 Particle_T::AttributeNames::smth, Particle_T::AttributeNames::soundSpeed,
520 Particle_T::AttributeNames::pressure, Particle_T::AttributeNames::posX,
521 Particle_T::AttributeNames::posY, Particle_T::AttributeNames::posZ,
522 Particle_T::AttributeNames::velX, Particle_T::AttributeNames::velY,
523 Particle_T::AttributeNames::velZ, Particle_T::AttributeNames::ownershipState};
530 return std::array<typename Particle_T::AttributeNames, 6>{
531 Particle_T::AttributeNames::vsigmax, Particle_T::AttributeNames::engDot,
532 Particle_T::AttributeNames::accX, Particle_T::AttributeNames::accY,
533 Particle_T::AttributeNames::accZ, Particle_T::AttributeNames::ownershipState};
AlignedAllocator class.
Definition: AlignedAllocator.h:29
PairwiseFunctor class.
Definition: PairwiseFunctor.h:31
PairwiseFunctor(double cutoff)
Constructor.
Definition: PairwiseFunctor.h:42
View on a fixed part of a SoA between a start index and an end index.
Definition: SoAView.h:23
size_t size() const
Returns the number of particles in the view.
Definition: SoAView.h:83
Class that defines the hydrodynamic force functor.
Definition: SPHCalcHydroForceFunctor.h:19
typename Particle_T::SoAArraysType SoAArraysType
soa arrays type
Definition: SPHCalcHydroForceFunctor.h:22
bool allowsNewton3() override
Specifies whether the functor is capable of Newton3-like functors.
Definition: SPHCalcHydroForceFunctor.h:32
void SoAFunctorSingle(autopas::SoAView< SoAArraysType > soa, bool newton3) override
PairwiseFunctor for structure of arrays (SoA)
Definition: SPHCalcHydroForceFunctor.h:110
static constexpr auto getNeededAttr(std::false_type)
Get attributes needed for computation without N3 optimization.
Definition: SPHCalcHydroForceFunctor.h:516
void AoSFunctor(Particle_T &i, Particle_T &j, bool newton3=true) override
Calculates the contribution of the interaction of particle i and j to the hydrodynamic force.
Definition: SPHCalcHydroForceFunctor.h:45
virtual std::string getName() override
Returns name of functor.
Definition: SPHCalcHydroForceFunctor.h:28
static constexpr auto getNeededAttr()
Get attributes needed for computation.
Definition: SPHCalcHydroForceFunctor.h:500
void SoAFunctorPair(autopas::SoAView< SoAArraysType > soa1, autopas::SoAView< SoAArraysType > soa2, bool newton3) override
PairwiseFunctor for structure of arrays (SoA)
Definition: SPHCalcHydroForceFunctor.h:229
static constexpr auto getComputedAttr()
Get attributes computed by this functor.
Definition: SPHCalcHydroForceFunctor.h:529
bool isRelevantForTuning() override
Specifies whether the functor should be considered for the auto-tuning process.
Definition: SPHCalcHydroForceFunctor.h:30
bool allowsNonNewton3() override
Specifies whether the functor is capable of non-Newton3-like functors.
Definition: SPHCalcHydroForceFunctor.h:34
void SoAFunctorVerlet(autopas::SoAView< SoAArraysType > soa, const size_t indexFirst, const std::vector< size_t, autopas::AlignedAllocator< size_t > > &neighborList, bool newton3) override
PairwiseFunctor for structure of arrays (SoA) for neighbor lists.
Definition: SPHCalcHydroForceFunctor.h:372
static std::array< double, 3 > gradW(const std::array< double, 3 > &dr, const double h)
gradient of the kernel function W
Definition: SPHKernels.h:75
static double getKernelSupportRadius()
Get the kernelSupportRadius.
Definition: SPHKernels.h:28
constexpr T dot(const std::array< T, SIZE > &a, const std::array< T, SIZE > &b)
Generates the dot product of two arrays.
Definition: ArrayMath.h:233
constexpr T L2Norm(const std::array< T, SIZE > &a)
Computes the L2Norm / Euclidean norm.
Definition: ArrayMath.h:265
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32
@ dummy
Dummy or deleted state, a particle with this state is not an actual particle!