IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
BareFieldOperations.hpp
1//
2// File BareFieldOperations
3// Norms and a scalar product for fields
4//
5
6#include <Kokkos_MathematicalFunctions.hpp>
7
8namespace ippl {
15 template <typename BareField>
16 typename BareField::value_type innerProduct(const BareField& f1, const BareField& f2) {
17 using T = typename BareField::value_type;
18 constexpr unsigned Dim = BareField::dim;
19
20 static IpplTimings::TimerRef setup = IpplTimings::getTimer("inner_setup");
21 static IpplTimings::TimerRef ippl_red = IpplTimings::getTimer("ippl_reduce");
22 static IpplTimings::TimerRef mpi_red = IpplTimings::getTimer("mpi_reduce");
23
24 IpplTimings::startTimer(setup);
25
26 T sum = 0;
27 auto& layout = f1.getLayout();
28 auto& view1 = f1.getView();
29 auto& view2 = f2.getView();
30 using exec_space = typename BareField::execution_space;
31 using index_array_type = typename RangePolicy<Dim, exec_space>::index_array_type;
32
33 IpplTimings::stopTimer(setup);
34 IpplTimings::startTimer(ippl_red);
35
36 ippl::parallel_reduce(
37 "Field::innerProduct(Field&, Field&)", f1.getFieldRangePolicy(),
38 KOKKOS_LAMBDA(const index_array_type& args, T& val) {
39 val += apply(view1, args) * apply(view2, args);
40 },
41 Kokkos::Sum<T>(sum));
42
43 IpplTimings::stopTimer(ippl_red);
44 IpplTimings::startTimer(mpi_red);
45
46 T globalSum = 0;
47 layout.comm.allreduce(sum, globalSum, 1, std::plus<T>());
48
49 IpplTimings::stopTimer(mpi_red);
50
51 return globalSum;
52 }
53
60 template <typename BareField>
61 typename BareField::value_type norm(const BareField& field, int p = 2) {
62 using T = typename BareField::value_type;
63 constexpr unsigned Dim = BareField::dim;
64
65 T local = 0;
66 auto& layout = field.getLayout();
67 auto& view = field.getView();
68 using exec_space = typename BareField::execution_space;
69 using index_array_type = typename RangePolicy<Dim, exec_space>::index_array_type;
70 switch (p) {
71 case 0: {
72 ippl::parallel_reduce(
73 "Field::norm(0)", field.getFieldRangePolicy(),
74 KOKKOS_LAMBDA(const index_array_type& args, T& val) {
75 T myVal = Kokkos::abs(apply(view, args));
76 if (myVal > val)
77 val = myVal;
78 },
79 Kokkos::Max<T>(local));
80 T globalMax = 0;
81 layout.comm.allreduce(local, globalMax, 1, std::greater<T>());
82 return globalMax;
83 }
84 default: {
85 ippl::parallel_reduce(
86 "Field::norm(int) general", field.getFieldRangePolicy(),
87 KOKKOS_LAMBDA(const index_array_type& args, T& val) {
88 val += Kokkos::pow(Kokkos::abs(apply(view, args)), p);
89 },
90 Kokkos::Sum<T>(local));
91 T globalSum = 0;
92 layout.comm.allreduce(local, globalSum, 1, std::plus<T>());
93 return std::pow(globalSum, 1.0 / p);
94 }
95 }
96 }
97} // namespace ippl
Definition BareField.h:42
policy_type< execution_space, PolicyArgs... > getFieldRangePolicy(const int nghost=0) const
Definition BareField.h:183
Definition Vector.h:23
Definition Archive.h:20
KOKKOS_INLINE_FUNCTION constexpr decltype(auto) apply(const View &view, const Coords &coords)
Definition IpplOperations.h:64
T innerProduct(const FEMVector< T > &a, const FEMVector< T > &b)
Calculate the inner product between two ippl::FEMVector(s).
Definition FEMVector.h:407