10 gamma[0] = -
sqrt(invDistSqr);
11 for (
Size i = 1; i <
N + 2; ++i) {
12 gamma[i] = -(2._f * i - 1._f) * invDistSqr * gamma[i - 1];
24 static_assert(
N >= 2,
"invalid parameter");
33 static_assert(
N >= 4,
"invalid parameter");
39 template <Size M, Size N>
41 static_assert(
N >= 2 * M,
"invalid parameter");
45 template <Size N, Size M>
47 static_assert(
N > 0,
"Cannot be used for N == 0");
48 static_assert(2 *
N - 2 * M > 0,
"invalid parameter");
52 const Float factor = sign * num / denom;
64 Float T2 = computeTrace<2>(m).value();
67 const Float f0 = reducedFactor<4, 0>();
68 const Float f1 = reducedFactor<4, 1>();
69 const Float f2 = reducedFactor<4, 2>();
82 const Float f0 = reducedFactor<3, 0>();
83 const Float f1 = reducedFactor<3, 1>();
94 const Float f0 = reducedFactor<2, 0>();
95 const Float f1 = reducedFactor<2, 1>();
105 const Float f0 = reducedFactor<1, 0>();
108 return makeTracelessMultipole<1>(T0 * f0);
113 return makeTracelessMultipole<0>(m);
116 template <Size M, Size N>
119 static_assert(M <=
N,
"Incorrect parameters");
122 return makeTracelessMultipole<M>(makeInner<N - M>(dr, q) * (1._f /
factorial(
N - M)));
125 template <Size M, Size N>
131 template <Size M, Size N>
151 template <Size N,
typename TSequence>
155 const TSequence& sequence) {
157 for (
Size i : sequence) {
158 const Vector dr = r[i] - r0;
159 moments += Detail::computeMultipoleImpl<N>(dr, m[i]);
177 return makeTracelessMultipole<2>(Qij + f2 * Q);
185 template <Size I, Size J, Size K, Size L>
192 template <Size I, Size J, Size K>
194 return -2._f / 5._f *
195 (perm<I, J, K, 0>() *
d[0] + perm<I, J, K, 1>() *
d[1] + perm<I, J, K, 2>() *
d[2]);
203 template <Size I, Size J, Size K, Size L, Size M>
211 template <Size I, Size J, Size K, Size L>
213 return perm<I, J, K, L, 0>() *
d[0] + perm<I, J, K, L, 1>() *
d[1] + perm<I, J, K, L, 2>() *
d[2];
223 template <Size I, Size J, Size K, Size L, Size M, Size N>
225 return delta1.template value<I, J>() *
delta2.template value<K, M>() *
Q.template value<L, N>();
228 template <Size I, Size J, Size K, Size L, Size M, Size N>
231 return ddq<I, J, K, L, M, N>() + ddq<I, J, L, K, M, N>() + ddq<I, L, J, K, M, N>() +
232 ddq<I, L, K, J, M, N>() + ddq<I, K, J, L, M, N>() + ddq<I, K, L, J, M, N>() +
233 ddq<J, K, L, I, M, N>() + ddq<J, K, I, L, M, N>() + ddq<J, L, I, K, M, N>() +
234 ddq<J, L, K, I, M, N>() + ddq<K, L, I, J, M, N>() + ddq<K, L, J, I, M, N>();
236 return ddq<I, J, K, L, M, N>() + ddq<I, L, J, K, M, N>() + ddq<I, K, J, L, M, N>() +
237 ddq<J, K, L, I, M, N>() + ddq<J, L, I, K, M, N>() + ddq<K, L, I, J, M, N>();
241 template <Size I, Size J, Size K, Size L>
243 return perm<I, J, K, L, 0, 0>() *
f2.template value<0, 0>() +
244 perm<I, J, K, L, 0, 1>() *
f2.template value<0, 1>() +
245 perm<I, J, K, L, 0, 2>() *
f2.template value<0, 2>() +
246 perm<I, J, K, L, 1, 0>() *
f2.template value<1, 0>() +
247 perm<I, J, K, L, 1, 1>() *
f2.template value<1, 1>() +
248 perm<I, J, K, L, 1, 2>() *
f2.template value<1, 2>() +
249 perm<I, J, K, L, 2, 0>() *
f2.template value<2, 0>() +
250 perm<I, J, K, L, 2, 1>() *
f2.template value<2, 1>() +
251 perm<I, J, K, L, 2, 2>() *
f2.template value<2, 2>();
259 template <Size I, Size J, Size K, Size L>
262 makeInner<2>(
Q,
f2).value() * (-1._f / 5._f);
291 return makeTracelessMultipole<4>(
296 template <Size M, Size N>
301 const Float Q0 = computeMultipolePotential<0>(q, dr).value();
302 const Vector Q1 = (
N > 0) ? computeMultipolePotential<1>(q, dr).vector() :
Vector(0._f);
303 const Vector a = gamma[M + 1] * dr * Q0 + gamma[M] * Q1;
322 computeGreenGamma<N>(gamma, dr);
327 a += computeMultipoleAcceleration<3>(ms, gamma, -dr);
330 a += computeMultipoleAcceleration<2>(ms, gamma, -dr);
333 a += computeMultipoleAcceleration<0>(ms, gamma, -dr);
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
uint32_t Size
Integral type used to index arrays (by default).
int32_t SignedSize
Signed integral type, used where negative numbers are necessary. Should match Size.
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
constexpr INLINE bool isOdd(const T &f)
INLINE T sqrt(const T f)
Return a squared root of a value.
std::enable_if_t<(M< N), TracelessMultipole< M > > computeMultipolePotential(const TracelessMultipole< N > &q, const Vector &r)
Multipole< N > computeMultipole(ArrayView< const Vector > r, ArrayView< const Float > m, const Vector &r0, const TSequence &sequence)
INLINE TracelessMultipole< 1 > parallelAxisTheorem(const TracelessMultipole< 1 > &Qi, const Float Q, const Vector &d)
Multipole< N - 2 *M > computeTrace(const Multipole< N > &m)
Computes M-fold trace of given multipole moment.
INLINE Vector computeMultipoleAcceleration(const MultipoleExpansion< N > &ms, ArrayView< const Float > gamma, const Vector &dr)
TracelessMultipole< N > computeReducedMultipole(const Multipole< N > &m)
INLINE Float reducedFactor()
Vector evaluateGravity(const Vector &dr, const MultipoleExpansion< N > &ms, const MultipoleOrder maxOrder)
NAMESPACE_SPH_BEGIN INLINE void computeGreenGamma(ArrayView< Float > gamma, const Vector dr)
Multipole< N > makeMultipole(const TValue &v)
constexpr Size doubleFactorial(const Size n)
constexpr Size factorial(const Size n)
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
INLINE Float getSqrLength(const Vector &v)
BasicVector< Float > Vector
Array with fixed number of allocated elements.
void fill(const T &value)
Assigns a value to all constructed elements of the array.
constexpr INLINE Float value() const
INLINE Multipole< N > computeMultipoleImpl(const Vector &dr, const Float m)
Permutations< Value1::ORDER, Value2::ORDER, Value1, Value2 > makePermutations(const Value1 &v1, const Value2 &v2)
Contraction< TValue > makeContraction(const TValue &v)
SharedPtr< JobNode > make(const Id id, UniqueNameManager &nameMgr, const Size particleCnt=10000)
Creates a node tree for the preset with given ID.
static INLINE Multipole< N - 2 > make(const Multipole< N > &m)
static INLINE Multipole< N - 4 > make(const Multipole< N > &m)
static constexpr INLINE int value()
INLINE Float value() const
const TracelessMultipole< 2 > & Q
INLINE Float perm() const
INLINE Float value() const
const TracelessMultipole< 3 > & Q
INLINE Float perm() const
INLINE Float perm() const
INLINE Float value() const
static const Delta< 2 > delta1
const TracelessMultipole< 2 > & Q
static const Delta< 2 > delta2
const TracelessMultipole< 2 > & f2
INLINE Float value() const
const TracelessMultipole< 2 > & f2
const TracelessMultipole< 2 > & Q