IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
TruncatedGreenParticleInteraction.hpp
1//
2// Class TruncatedGreenParticleInteraction
3// This class implements the short range interaction part of the green function splitting obtained
4// by taking the gradient of [forceConstant * (1 - erf(alpha * r)) / r]. The long range part is
5// handled by FFTTruncatedGreenPeriodicSolver.
6//
7// It assumes that ParticleContainer implements a function forAllPairs() to iterate over all
8// relevant particle pairs.
9//
10
11namespace ippl {
12 template <typename ParticleContainer, typename ScalarAttribute, typename VectorAttribute>
13 KOKKOS_INLINE_FUNCTION constexpr
14 typename TruncatedGreenParticleInteraction<ParticleContainer, ScalarAttribute,
15 VectorAttribute>::Vector_t
16 TruncatedGreenParticleInteraction<ParticleContainer, ScalarAttribute,
17 VectorAttribute>::fieldFromPair(const Vector_t& dist,
18 Scalar_t r2,
19 Scalar_t alpha,
20 Scalar_t forceConstant,
21 Scalar_t qm) {
22 const Scalar_t r = Kokkos::sqrt(r2);
23
24 // F = - q * forceConstant grad [(1 - erf(alpha * r)) / r].
25 return forceConstant * qm * (dist / r)
26 * (2.0 * alpha * Kokkos::exp(-alpha * alpha * r2)
27 / (Kokkos::sqrt(Kokkos::numbers::pi) * r)
28 + (1.0 - Kokkos::erf(alpha * r)) / r2);
29 }
30
31 template <typename ParticleContainer, typename ScalarAttribute, typename VectorAttribute>
32 void TruncatedGreenParticleInteraction<ParticleContainer, ScalarAttribute,
33 VectorAttribute>::solve() {
34 static IpplTimings::TimerRef solveTimer =
35 IpplTimings::getTimer("TruncatedGreenParticleInteraction::solve()");
36 IpplTimings::startTimer(solveTimer);
37 // get particle data
38 auto& Field = Field_m;
39 const auto& R = R_m;
40 const auto& QM = QM_m;
41
42 // get simulation specific data
43 const auto rcut2 = std::pow<Scalar_t>(this->params_m.template get<Scalar_t>("rcut"), 2);
44 const auto alpha = this->params_m.template get<Scalar_t>("alpha");
45 const auto forceConstant = this->params_m.template get<Scalar_t>("force_constant");
46
47 const auto& particleLayout = this->pc_m.getLayout();
48
49 particleLayout.template forEachPair<execution_space>(
50 KOKKOS_LAMBDA(const size_t& i, const size_t& j) {
51 const Vector_t dist_ij = R(i) - R(j);
52 const Scalar_t rsq_ij = dist_ij.dot(dist_ij);
53
54 if (rsq_ij >= rcut2) {
55 return;
56 }
57
58 const auto F_ij = fieldFromPair(dist_ij, rsq_ij, alpha, forceConstant, QM(j));
59
60 // add force to particle i, don't do it for j as the ranges of i and j are
61 // asymmetric
62 Kokkos::atomic_sub(&Field(i), F_ij);
63 });
64 IpplTimings::stopTimer(solveTimer);
65 }
66} // namespace ippl
Definition Field.h:18
Definition Vector.h:23
Definition Archive.h:20