11 constexpr
Size N =
sizeof...(Is);
14 for (
Size i = 0; i <
N - 1; i++) {
15 for (
Size j = 0; j <
N - i - 1; j++) {
16 if (array[j] > array[j + 1]) {
18 array[j] = array[j + 1];
28 return (order + 1) * (order + 2) / 2;
36 return First +
sum<Second, Idxs...>();
39 template <
Size... Idxs>
48 static constexpr
Size value = I;
52 static constexpr
Size value =
60 template <std::size_t... Idxs, std::size_t... Is>
66 template <
Size... Idxs>
68 using Sequence = std::make_index_sequence<
sizeof...(Idxs)>;
88 Float data[COMPONENT_CNT];
96 for (
Float& v : data) {
101 template <
Size... Idxs>
103 static_assert(
sizeof...(Idxs) ==
Order,
"Number of indices must match the order");
106 return *(&data[0] + idx);
109 template <
Size... Idxs>
111 static_assert(
sizeof...(Idxs) ==
Order,
"Number of indices must match the order");
114 return *(&data[0] + idx);
123 for (
Size i = 0; i < COMPONENT_CNT; ++i) {
131 for (
Size i = 0; i < COMPONENT_CNT; ++i) {
132 m.data[i] = data[i] * f;
138 for (
Size i = 0; i < COMPONENT_CNT; ++i) {
139 if (data[i] != other[i]) {
147 for (
Size i = 0; i < COMPONENT_CNT; ++i) {
148 stream << m.data[i] <<
" ";
171 template <
typename TValue>
174 m.
value() = v.value();
181 template <
typename TValue>
184 m.
value<
X>() = v.template value<X>();
185 m.
value<
Y>() = v.template value<Y>();
186 m.
value<
Z>() = v.template value<Z>();
193 template <
typename TValue>
196 m.
value<
X,
X>() = v.template value<X, X>();
197 m.
value<
X,
Y>() = v.template value<X, Y>();
198 m.
value<
X,
Z>() = v.template value<X, Z>();
200 m.
value<
Y,
Y>() = v.template value<Y, Y>();
201 m.
value<
Y,
Z>() = v.template value<Y, Z>();
203 m.
value<
Z,
Z>() = v.template value<Z, Z>();
210 template <
typename TValue>
213 m.
value<
X,
X,
X>() = v.template value<X, X, X>();
214 m.
value<
X,
X,
Y>() = v.template value<X, X, Y>();
215 m.
value<
X,
X,
Z>() = v.template value<X, X, Z>();
216 m.
value<
X,
Y,
Y>() = v.template value<X, Y, Y>();
217 m.
value<
X,
Y,
Z>() = v.template value<X, Y, Z>();
218 m.
value<
X,
Z,
Z>() = v.template value<X, Z, Z>();
220 m.
value<
Y,
Y,
Y>() = v.template value<Y, Y, Y>();
221 m.
value<
Y,
Y,
Z>() = v.template value<Y, Y, Z>();
222 m.
value<
Y,
Z,
Z>() = v.template value<Y, Z, Z>();
224 m.
value<
Z,
Z,
Z>() = v.template value<Z, Z, Z>();
231 template <
typename TValue>
234 m.
value<
X,
X,
X,
X>() = v.template value<X, X, X, X>();
235 m.
value<
X,
X,
X,
Y>() = v.template value<X, X, X, Y>();
236 m.
value<
X,
X,
X,
Z>() = v.template value<X, X, X, Z>();
237 m.
value<
X,
X,
Y,
Y>() = v.template value<X, X, Y, Y>();
238 m.
value<
X,
X,
Y,
Z>() = v.template value<X, X, Y, Z>();
239 m.
value<
X,
X,
Z,
Z>() = v.template value<X, X, Z, Z>();
240 m.
value<
X,
Y,
Y,
Y>() = v.template value<X, Y, Y, Y>();
241 m.
value<
X,
Y,
Y,
Z>() = v.template value<X, Y, Y, Z>();
242 m.
value<
X,
Y,
Z,
Z>() = v.template value<X, Y, Z, Z>();
243 m.
value<
X,
Z,
Z,
Z>() = v.template value<X, Z, Z, Z>();
245 m.
value<
Y,
Y,
Y,
Y>() = v.template value<Y, Y, Y, Y>();
246 m.
value<
Y,
Y,
Y,
Z>() = v.template value<Y, Y, Y, Z>();
247 m.
value<
Y,
Y,
Z,
Z>() = v.template value<Y, Y, Z, Z>();
248 m.
value<
Y,
Z,
Z,
Z>() = v.template value<Y, Z, Z, Z>();
250 m.
value<
Z,
Z,
Z,
Z>() = v.template value<Z, Z, Z, Z>();
255 template <Size N,
typename TValue>
263 return 2 * order + 1;
266 template <
Size... Idxs>
269 template <
Size Second,
Size... Idxs>
273 template <
Size Second,
Size... Idxs>
280 static constexpr
Size value = I;
283 template <std::size_t... Idxs, std::size_t... Is>
289 template <
Size... Idxs>
291 using Sequence = std::make_index_sequence<
sizeof...(Idxs)>;
301 template <
Size... Idxs>
304 template <Size Order>
309 Float data[COMPONENT_CNT];
317 for (
Float& v : data) {
322 template <
Size... Idxs>
327 template <
Size... Idxs>
329 static_assert(
sizeof...(Idxs) ==
Order,
"Number of indices must match the order");
332 return *(&data[0] + idx);
335 template <
Size... Idxs>
337 static_assert(
sizeof...(Idxs) ==
Order,
"Number of indices must match the order");
339 SPH_ASSERT(idx < COMPONENT_CNT, idx, Idxs...);
340 return *(&data[0] + idx);
354 return COMPONENT_CNT;
358 for (
Size i = 0; i < COMPONENT_CNT; ++i) {
359 data[i] += other.data[i];
365 for (
Size i = 0; i < COMPONENT_CNT; ++i) {
366 if (data[i] != other.data[i]) {
374 for (
Size i = 0; i < COMPONENT_CNT; ++i) {
375 stream << m.data[i] <<
" ";
428 return data == other.data;
478 return data == other.data;
502 template <
typename TValue>
505 m.
value() = v.value();
512 template <
typename TValue>
515 m.
value<
X>() = v.template value<X>();
516 m.
value<
Y>() = v.template value<Y>();
517 m.
value<
Z>() = v.template value<Z>();
524 template <
typename TValue>
527 m.
value<
X,
X>() = v.template value<X, X>();
528 m.
value<
X,
Y>() = v.template value<X, Y>();
529 m.
value<
X,
Z>() = v.template value<X, Z>();
531 m.
value<
Y,
Y>() = v.template value<Y, Y>();
532 m.
value<
Y,
Z>() = v.template value<Y, Z>();
539 template <
typename TValue>
542 m.
value<
X,
X,
X>() = v.template value<X, X, X>();
543 m.
value<
X,
X,
Y>() = v.template value<X, X, Y>();
544 m.
value<
X,
X,
Z>() = v.template value<X, X, Z>();
545 m.
value<
X,
Y,
Y>() = v.template value<X, Y, Y>();
546 m.
value<
X,
Y,
Z>() = v.template value<X, Y, Z>();
548 m.
value<
Y,
Y,
Y>() = v.template value<Y, Y, Y>();
549 m.
value<
Y,
Y,
Z>() = v.template value<Y, Y, Z>();
556 template <
typename TValue>
559 m.
value<
X,
X,
X,
X>() = v.template value<X, X, X, X>();
560 m.
value<
X,
X,
X,
Y>() = v.template value<X, X, X, Y>();
561 m.
value<
X,
X,
X,
Z>() = v.template value<X, X, X, Z>();
562 m.
value<
X,
X,
Y,
Y>() = v.template value<X, X, Y, Y>();
563 m.
value<
X,
X,
Y,
Z>() = v.template value<X, X, Y, Z>();
564 m.
value<
X,
Y,
Y,
Y>() = v.template value<X, Y, Y, Y>();
565 m.
value<
X,
Y,
Y,
Z>() = v.template value<X, Y, Y, Z>();
567 m.
value<
Y,
Y,
Y,
Y>() = v.template value<Y, Y, Y, Y>();
568 m.
value<
Y,
Y,
Y,
Z>() = v.template value<Y, Y, Y, Z>();
573 template <Size N,
typename TValue>
577 template <
Size... Idxs>
580 return m.template valueImpl<Idxs...>();
583 template <std::size_t... Idxs, std::size_t... Is>
585 std::index_sequence<Is...>) {
591 template <
Size... Idxs>
593 using Sequence = std::make_index_sequence<
sizeof...(Idxs)>;
612 template <Size I, Size J>
621 return n <= 1 ? 1 : n *
factorial(n - 1);
623 static_assert(
factorial(1) == 1,
"static test failed");
624 static_assert(
factorial(2) == 2,
"static test failed");
625 static_assert(
factorial(3) == 6,
"static test failed");
626 static_assert(
factorial(4) == 24,
"static test failed");
640 template <Size Order>
646 static_assert(
sizeof...(Rest) + 4 ==
Order,
"Invalid number of indices");
647 return ((I == J) ? 1 : 0) *
Delta<
Order - 2>::template
value<K, L, Rest...>();
649 template <Size I, Size J>
651 static_assert(
Order == 2,
"Invalid number of indices");
652 return ((I == J) ? 1 : 0);
657 template <Size N1, Size N2,
typename Value1,
typename Value2>
660 template <Size N,
typename Value1,
typename Value2>
666 template <
Size... Is>
668 static_assert(
sizeof...(Is) ==
N,
"Invalid number of indices");
669 return v1.template value<Is...>() * v2.value();
672 template <Size N,
typename Value1,
typename Value2>
678 template <
Size... Is>
680 static_assert(
sizeof...(Is) ==
N,
"Invalid number of indices");
681 return v1.value() * v2.template value<Is...>();
684 template <
typename Value1,
typename Value2>
688 static constexpr
Size ORDER = 4;
690 template <Size I, Size J, Size K, Size L>
692 return v1.template value<I, J>() * v2.template value<K, L>() +
693 v1.template value<I, K>() * v2.template value<J, L>() +
694 v1.template value<I, L>() * v2.template value<J, K>() +
695 v1.template value<J, K>() * v2.template value<I, L>() +
696 v1.template value<J, L>() * v2.template value<I, K>() +
697 v1.template value<K, L>() * v2.template value<I, J>();
700 template <
typename Value1,
typename Value2>
704 static constexpr
Size ORDER = 4;
706 template <Size I, Size J, Size K, Size L>
708 return v1.template value<I, J, K>() * v2.template value<L>() +
709 v1.template value<I, J, L>() * v2.template value<K>() +
710 v1.template value<I, K, L>() * v2.template value<J>() +
711 v1.template value<J, K, L>() * v2.template value<I>();
714 template <
typename Value1,
typename Value2>
718 static constexpr
Size ORDER = 3;
720 template <Size I, Size J, Size K>
722 return v1.template value<I, J>() * v2.template value<K>() +
723 v1.template value<J, K>() * v2.template value<I>() +
724 v1.template value<K, I>() * v2.template value<J>();
727 template <
typename Value1,
typename Value2>
731 static constexpr
Size ORDER = 3;
733 template <Size I, Size J, Size K>
735 return v1.template value<I>() * v2.template value<J, K>() +
736 v1.template value<J>() * v2.template value<K, I>() +
737 v1.template value<K>() * v2.template value<I, J>();
741 template <
typename Value1,
typename Value2>
747 template <
typename TValue>
751 template <
Size... Is>
753 return v.template
value<0, 0, Is...>() +
v.template value<1, 1, Is...>() +
754 v.template
value<2, 2, Is...>();
758 template <
typename TValue>
763 template <Size N, Size O1,
typename TValue1,
typename TValue2>
766 template <
typename TValue1,
typename TValue2>
773 static_assert(TValue1::ORDER == 2,
"Invalid number of indices");
774 static_assert(TValue2::ORDER ==
sizeof...(Is) + 1,
"Invalid number of indices");
775 return v1.template value<0, I>() * v2.template value<0, Is...>() +
776 v1.template value<1, I>() * v2.template value<1, Is...>() +
777 v1.template value<2, I>() * v2.template value<2, Is...>();
780 template <
typename TValue1,
typename TValue2>
785 template <
Size... Is>
787 static_assert(TValue1::ORDER == 1,
"Invalid number of indices");
788 static_assert(TValue2::ORDER ==
sizeof...(Is) + 1,
"Invalid number of indices");
789 return v1.template value<0>() * v2.template value<0, Is...>() +
790 v1.template value<1>() * v2.template value<1, Is...>() +
791 v1.template value<2>() * v2.template value<2, Is...>();
795 template <
typename TValue1,
typename TValue2>
800 template <
Size... Is>
802 static_assert(TValue1::ORDER == 2,
"Invalid number of indices");
803 static_assert(TValue2::ORDER ==
sizeof...(Is) + 2,
"Invalid number of indices");
804 return v1.template value<0, 0>() * v2.template value<0, 0, Is...>() +
805 v1.template value<0, 1>() * v2.template value<0, 1, Is...>() +
806 v1.template value<0, 2>() * v2.template value<0, 2, Is...>() +
807 v1.template value<1, 0>() * v2.template value<1, 0, Is...>() +
808 v1.template value<1, 1>() * v2.template value<1, 1, Is...>() +
809 v1.template value<1, 2>() * v2.template value<1, 2, Is...>() +
810 v1.template value<2, 0>() * v2.template value<2, 0, Is...>() +
811 v1.template value<2, 1>() * v2.template value<2, 1, Is...>() +
812 v1.template value<2, 2>() * v2.template value<2, 2, Is...>();
816 template <
typename TValue1,
typename TValue2>
821 template <
Size... Is>
823 static_assert(TValue1::ORDER == 3,
"Invalid number of indices");
824 static_assert(TValue2::ORDER ==
sizeof...(Is) + 3,
"Invalid number of indices");
825 return v1.template value<0, 0, 0>() * v2.template value<0, 0, 0, Is...>() +
826 v1.template value<0, 0, 1>() * v2.template value<0, 0, 1, Is...>() +
827 v1.template value<0, 0, 2>() * v2.template value<0, 0, 2, Is...>() +
828 v1.template value<0, 1, 0>() * v2.template value<0, 1, 0, Is...>() +
829 v1.template value<0, 1, 1>() * v2.template value<0, 1, 1, Is...>() +
830 v1.template value<0, 1, 2>() * v2.template value<0, 1, 2, Is...>() +
831 v1.template value<0, 2, 0>() * v2.template value<0, 2, 0, Is...>() +
832 v1.template value<0, 2, 1>() * v2.template value<0, 2, 1, Is...>() +
833 v1.template value<0, 2, 2>() * v2.template value<0, 2, 2, Is...>() +
834 v1.template value<1, 0, 0>() * v2.template value<1, 0, 0, Is...>() +
835 v1.template value<1, 0, 1>() * v2.template value<1, 0, 1, Is...>() +
836 v1.template value<1, 0, 2>() * v2.template value<1, 0, 2, Is...>() +
837 v1.template value<1, 1, 0>() * v2.template value<1, 1, 0, Is...>() +
838 v1.template value<1, 1, 1>() * v2.template value<1, 1, 1, Is...>() +
839 v1.template value<1, 1, 2>() * v2.template value<1, 1, 2, Is...>() +
840 v1.template value<1, 2, 0>() * v2.template value<1, 2, 0, Is...>() +
841 v1.template value<1, 2, 1>() * v2.template value<1, 2, 1, Is...>() +
842 v1.template value<1, 2, 2>() * v2.template value<1, 2, 2, Is...>() +
843 v1.template value<2, 0, 0>() * v2.template value<2, 0, 0, Is...>() +
844 v1.template value<2, 0, 1>() * v2.template value<2, 0, 1, Is...>() +
845 v1.template value<2, 0, 2>() * v2.template value<2, 0, 2, Is...>() +
846 v1.template value<2, 1, 0>() * v2.template value<2, 1, 0, Is...>() +
847 v1.template value<2, 1, 1>() * v2.template value<2, 1, 1, Is...>() +
848 v1.template value<2, 1, 2>() * v2.template value<2, 1, 2, Is...>() +
849 v1.template value<2, 2, 0>() * v2.template value<2, 2, 0, Is...>() +
850 v1.template value<2, 2, 1>() * v2.template value<2, 2, 1, Is...>() +
851 v1.template value<2, 2, 2>() * v2.template value<2, 2, 2, Is...>();
855 template <Size N,
typename TValue1,
typename TValue2>
861 template <
typename TValue>
866 template <
Size... Is>
868 return f *
v.template
value<Is...>();
872 template <Size O1,
typename TValue1,
typename TValue2>
875 template <
typename TValue1,
typename TValue2>
882 static_assert(TValue1::ORDER == 1 && TValue2::ORDER ==
sizeof...(Is),
"Invalid number of indices");
883 return v1.template value<I>() * v2.template value<Is...>();
887 template <
typename TValue1,
typename TValue2>
894 static_assert(TValue1::ORDER == 2 && TValue2::ORDER ==
sizeof...(Is),
"Invalid number of indices");
895 return v1.template value<I, J>() * v2.template value<Is...>();
899 template <
typename TValue1,
typename TValue2>
906 static_assert(TValue1::ORDER == 4 && TValue2::ORDER ==
sizeof...(Is),
"Invalid number of indices");
907 return v1.template value<I, J, K, L>() * v2.template value<Is...>();
911 template <
typename TValue>
916 template <
typename TValue1,
typename TValue2>
921 template <
typename TValue1,
typename TValue2>
926 template <
Size... Is>
928 return v1.template
value<Is...>() +
v2.template value<Is...>();
932 template <
typename TValue1,
typename TValue2>
937 template <
typename TValue1,
typename TValue2>
942 template <
Size... Is>
944 return v1.template
value<Is...>() -
v2.template value<Is...>();
948 template <
typename TValue1,
typename TValue2>
953 template <Size Order>
961 static_assert(
sizeof...(Is) + 2 ==
Order,
"Invalid number of indices");
967 static_assert(
Order == 1,
"Invalid number of indices");
980 return lower.template order<M>();
983 INLINE std::enable_if_t<M != N, const TracelessMultipole<M>&>
order()
const {
984 return lower.template order<M>();
991 INLINE std::enable_if_t<M == N, const TracelessMultipole<M>&>
order()
const {
1010 static_assert(M == 0,
"Invalid index");
1016 static_assert(M == 0,
"Invalid index");
#define SPH_ASSERT(x,...)
uint32_t Size
Integral type used to index arrays (by default).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
constexpr NAMESPACE_SPH_BEGIN auto sortIndices()
c++14 sort of template parameters
INLINE auto almostEqual(const Multipole< N > &f1, const Multipole< N > &f2, const Float &eps=EPS)
Multipole< N > makeMultipole(const TValue &v)
TracelessMultipole< N > makeTracelessMultipole(const TValue &v)
constexpr Size doubleFactorial(const Size n)
constexpr Size factorial(const Size n)
constexpr Float expandTracelessMultipoleComponent(const TracelessMultipole< sizeof...(Idxs)> &m, std::index_sequence< Is... >)
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
Basic vector algebra. Computations are accelerated using SIMD.
Container similar to StaticArray, but with constexpr constructors and getters.
Float data[COMPONENT_CNT]
static constexpr Size COMPONENT_CNT
INLINE Float value() const
INLINE Float operator[](const Size idx) const
static constexpr Size ORDER
bool operator==(const Multipole &other) const
friend std::ostream & operator<<(std::ostream &stream, const Multipole &m)
Multipole & operator+=(const Multipole &other)
Multipole operator*(const Float f) const
Permutation, i.e. (discrete) invertible function int->int.
TracelessMultipole()=default
constexpr bool operator==(const TracelessMultipole &other) const
constexpr INLINE Float & value()
constexpr INLINE Size size() const
constexpr INLINE TracelessMultipole(const Float v)
TracelessMultipole & operator+=(const TracelessMultipole &other)
constexpr INLINE Float value() const
INLINE Float operator[](const Size idx) const
INLINE Float value() const
INLINE Float & operator[](const Size idx)
TracelessMultipole & operator+=(const TracelessMultipole &other)
INLINE TracelessMultipole(const Float v)
bool operator==(const TracelessMultipole &other) const
INLINE Float operator[](const Size idx) const
constexpr INLINE Size size() const
INLINE TracelessMultipole()=default
friend std::ostream & operator<<(std::ostream &stream, const TracelessMultipole &m)
TracelessMultipole & operator+=(const TracelessMultipole &other)
constexpr INLINE Size size() const
constexpr TracelessMultipole()=default
bool operator==(const TracelessMultipole &other) const
constexpr INLINE Float operator[](const Size idx) const
constexpr INLINE Float value() const
static constexpr Size ORDER
INLINE Float & operator[](const Size idx)
constexpr INLINE Float valueImpl() const
constexpr TracelessMultipole(const Float f)
friend std::ostream & operator<<(std::ostream &stream, const TracelessMultipole &m)
constexpr Size multipoleComponentCnt(Size order)
constexpr Size expandMultipoleArray(std::index_sequence< Is... >)
constexpr Size tracelessMultipoleComponentCnt(Size order)
constexpr Size expandTracelessMultipoleArray(std::index_sequence< Is... >)
InnerProduct< N, TValue1::ORDER, TValue1, TValue2 > makeInner(const TValue1 &v1, const TValue2 &v2)
Permutations< Value1::ORDER, Value2::ORDER, Value1, Value2 > makePermutations(const Value1 &v1, const Value2 &v2)
Difference< TValue1, TValue2 > operator-(const TValue1 &v1, const TValue2 &v2)
MultiplyByScalar< TValue > operator*(const TValue &v, const Float f)
Sum< TValue1, TValue2 > operator+(const TValue1 &v1, const TValue2 &v2)
MultiplyTwo< TValue1::ORDER, TValue1, TValue2 > makeMultiply(const TValue1 &v1, const TValue2 &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 constexpr Size value
std::make_index_sequence< sizeof...(Idxs)> Sequence
std::make_index_sequence< sizeof...(Idxs)> Sequence
static constexpr Size value
static Multipole< 0 > make(const TValue &v)
static Multipole< 1 > make(const TValue &v)
static Multipole< 2 > make(const TValue &v)
static Multipole< 3 > make(const TValue &v)
static Multipole< 4 > make(const TValue &v)
Creates multipole by evaluating given object for each independent component.
static TracelessMultipole< 0 > make(const TValue &v)
static TracelessMultipole< 1 > make(const TValue &v)
static TracelessMultipole< 2 > make(const TValue &v)
static TracelessMultipole< 3 > make(const TValue &v)
static TracelessMultipole< 4 > make(const TValue &v)
Creates multipole by evaluating given object for each independent component.
constexpr INLINE Float value() const
static constexpr INLINE int value()
static constexpr INLINE int value()
static constexpr Size ORDER
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
static constexpr Size ORDER
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
constexpr INLINE Float value() const
INLINE const TracelessMultipole< 0 > & order() const
MultipoleExpansion multiply(const Float factor) const
TracelessMultipole< 0 > Qn
INLINE TracelessMultipole< 0 > & order()
INLINE std::enable_if_t< M !=N, TracelessMultipole< M > & > order()
INLINE std::enable_if_t< M==N, const TracelessMultipole< M > & > order() const
TracelessMultipole< N > Qn
INLINE std::enable_if_t< M !=N, const TracelessMultipole< M > & > order() const
INLINE std::enable_if_t< M==N, TracelessMultipole< M > & > order()
MultipoleExpansion multiply(const Float factor) const
MultipoleExpansion< N - 1 > lower
static constexpr INLINE Float get(const TracelessMultipole< 4 > &m)
static constexpr INLINE Float get(const TracelessMultipole< 3 > &m)
static constexpr INLINE Float get(const TracelessMultipole< 2 > &m)
static INLINE Float get(const TracelessMultipole< sizeof...(Idxs)> &m)
std::make_index_sequence< sizeof...(Idxs)> Sequence
static constexpr INLINE Float get(const TracelessMultipole< sizeof...(Idxs)> &m)