IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
FFTOpenPoissonSolver.h
Go to the documentation of this file.
1//
2// Class FFTOpenPoissonSolver
3// FFT-based Poisson Solver for open boundaries.
4// Solves laplace(phi) = -rho, and E = -grad(phi).
5//
6//
7
8#ifndef IPPL_FFT_OPEN_POISSON_SOLVER_H_
9#define IPPL_FFT_OPEN_POISSON_SOLVER_H_
10
11#include <Kokkos_MathematicalConstants.hpp>
12#include <Kokkos_MathematicalFunctions.hpp>
13
14#include "Types/Vector.h"
15
17#include "Utility/IpplTimings.h"
18
19#include "Field/Field.h"
20
21#include "Communicate/Archive.h"
22#include "FFT/FFT.h"
23#include "Field/HaloCells.h"
26#include "Poisson.h"
27
28namespace ippl {
29 namespace detail {
30
39 template <int tensorRank, typename>
40 struct ViewAccess;
41
42 template <typename View>
43 struct ViewAccess<2, View> {
44 KOKKOS_INLINE_FUNCTION constexpr static auto& get(View&& view, unsigned dim1,
45 unsigned dim2, size_t i, size_t j,
46 size_t k) {
47 return view(i, j, k)[dim1][dim2];
48 }
49 };
50
51 template <typename View>
52 struct ViewAccess<1, View> {
53 KOKKOS_INLINE_FUNCTION constexpr static auto& get(View&& view, unsigned dim1,
54 [[maybe_unused]] unsigned dim2,
55 size_t i, size_t j, size_t k) {
56 return view(i, j, k)[dim1];
57 }
58 };
59
60 template <typename View>
61 struct ViewAccess<0, View> {
62 KOKKOS_INLINE_FUNCTION constexpr static auto& get(View&& view,
63 [[maybe_unused]] unsigned dim1,
64 [[maybe_unused]] unsigned dim2,
65 size_t i, size_t j, size_t k) {
66 return view(i, j, k);
67 }
68 };
69 } // namespace detail
70
71 template <typename FieldLHS, typename FieldRHS>
72 class FFTOpenPoissonSolver : public Poisson<FieldLHS, FieldRHS> {
73 constexpr static unsigned Dim = FieldLHS::dim;
74 using Trhs = typename FieldRHS::value_type;
75 using mesh_type = typename FieldLHS::Mesh_t;
76 using Tg = typename FieldLHS::value_type::value_type;
77
78 public:
79 // type of output
81
82 // types for LHS and RHS
83 using typename Base::lhs_type, typename Base::rhs_type;
84
85 // define a type for the 3 dimensional real to complex Fourier transform
87
88 // enum type for the algorithm
89 enum Algorithm {
90 HOCKNEY = 0b01,
91 VICO = 0b10,
92 BIHARMONIC = 0b11,
93 DCT_VICO = 0b100
94 };
95
96 // define a type for a 3 dimensional field (e.g. charge density field)
97 // define a type of Field with integers to be used for the helper Green's function
98 // also define a type for the Fourier transformed complex valued fields
99 // define matrix and matrix field types for the Hessian
100 typedef FieldRHS Field_t;
101 typedef typename FieldLHS::Centering_t Centering;
105 typedef typename FFT_t::ComplexField CxField_t;
107 typedef typename mesh_type::matrix_type Matrix_t;
109
110 // define type for field layout
112
113 // type for communication buffers
114 using memory_space = typename FieldLHS::memory_space;
116
117 // types of mesh and mesh spacing
118 using vector_type = typename mesh_type::vector_type;
119 using scalar_type = typename mesh_type::value_type;
120
121 // constructor and destructor
126
127 // override the setRhs function of the Solver class
128 // since we need to call initializeFields()
129 void setRhs(rhs_type& rhs) override;
130
131 // allows user to set gradient of phi = Efield instead of spectral
132 // calculation of Efield (which uses FFTs)
133 void setGradFD();
134
135 // solve the Poisson equation using FFT;
136 // more specifically, compute the scalar potential given a density field rho using
137 void solve() override;
138
139 // override getHessian to return Hessian field if flag is on
140 MField_t* getHessian() override {
141 bool hessian = this->params_m.template get<bool>("hessian");
142 if (!hessian) {
143 throw IpplException(
144 "FFTOpenPoissonSolver::getHessian()",
145 "Cannot call getHessian() if 'hessian' flag in ParameterList is false");
146 }
147 return &hess_m;
148 }
149
150 // compute standard Green's function
151 void greensFunction();
152
153 // function called in the constructor to initialize the fields
154 void initializeFields();
155
156 // communication used for multi-rank Vico-Greengard's Green's function
157 void communicateVico(Vector<int, Dim> size, typename CxField_gt::view_type view_g,
158 const ippl::NDIndex<Dim> ldom_g, const int nghost_g,
159 typename Field_t::view_type view, const ippl::NDIndex<Dim> ldom,
160 const int nghost);
161
162 // needed for improved Vico-Greengard (DCT VICO)
163 void communicateVico(Vector<int, Dim> size, typename Field_t::view_type view_g,
164 const ippl::NDIndex<Dim> ldom_g, const int nghost_g,
165 typename Field_t::view_type view, const ippl::NDIndex<Dim> ldom,
166 const int nghost);
167
168 private:
169 // create a field to use as temporary storage
170 // references to it can be created to make the code where it is used readable
172
174 storage_field; // the charge-density field with mesh doubled in each dimension
175 Field_t& grn_mr = storage_field; // the Green's function
176
177 // rho2tr_m is the Fourier transformed charge-density field
178 // domain3_m and mesh3_m are used
180
181 // grntr_m is the Fourier transformed Green's function
182 // domain3_m and mesh3_m are used
184
185 // temp_m field for the E-field computation
187
188 // fields that facilitate the calculation in greensFunction()
190
191 // hessian matrix field (only if hessian parameter is set)
193
194 // the FFT object
195 std::unique_ptr<FFT_t> fft_m;
196
197 // mesh and layout objects for rho_m (RHS)
200
201 // mesh and layout objects for rho2_m
202 std::unique_ptr<mesh_type> mesh2_m;
203 std::unique_ptr<FieldLayout_t> layout2_m;
204
205 // mesh and layout objects for the Fourier transformed Complex fields
206 std::unique_ptr<mesh_type> meshComplex_m;
207 std::unique_ptr<FieldLayout_t> layoutComplex_m;
208
209 // domains for the various fields
210 NDIndex<Dim> domain_m; // original domain, gridsize
211 NDIndex<Dim> domain2_m; // doubled gridsize (2*Nx,2*Ny,2*Nz)
212 NDIndex<Dim> domainComplex_m; // field for the complex values of the RC transformation
213
214 // mesh spacing and mesh size
217
218 // string specifying algorithm: Hockney or Vico-Greengard
219 std::string alg_m;
220
221 // members for Vico-Greengard
223
224 std::unique_ptr<FFT<CCTransform, CxField_gt>> fft4n_m;
225
226 std::unique_ptr<mesh_type> mesh4_m;
227 std::unique_ptr<FieldLayout_t> layout4_m;
228
230
231 // members for improved Vico-Greengard (DCT VICO)
233
234 std::unique_ptr<FFT<Cos1Transform, Field_t>> fft2n1_m;
235
236 std::unique_ptr<mesh_type> mesh2n1_m;
237 std::unique_ptr<FieldLayout_t> layout2n1_m;
238
240
241 // bool indicating whether we want gradient of solution to calculate E field
243
244 // buffer for communication
246
247 protected:
248 virtual void setDefaultParameters() override {
249 using heffteBackend = typename FFT_t::heffteBackend;
250 heffte::plan_options opts = heffte::default_options<heffteBackend>();
251 this->params_m.add("use_pencils", opts.use_pencils);
252 this->params_m.add("use_reorder", opts.use_reorder);
253 this->params_m.add("use_gpu_aware", opts.use_gpu_aware);
254 this->params_m.add("r2c_direction", 0);
255
256 switch (opts.algorithm) {
257 case heffte::reshape_algorithm::alltoall:
258 this->params_m.add("comm", a2a);
259 break;
260 case heffte::reshape_algorithm::alltoallv:
261 this->params_m.add("comm", a2av);
262 break;
263 case heffte::reshape_algorithm::p2p:
264 this->params_m.add("comm", p2p);
265 break;
266 case heffte::reshape_algorithm::p2p_plined:
267 this->params_m.add("comm", p2p_pl);
268 break;
269 default:
270 throw IpplException("FFTOpenPoissonSolver::setDefaultParameters",
271 "Unrecognized heffte communication type");
272 }
273
274 this->params_m.add("algorithm", HOCKNEY);
275 this->params_m.add("hessian", false);
276 }
277 };
278} // namespace ippl
279
281#endif
Definition Archive.h:20
@ p2p_pl
Definition FFT.h:59
@ a2av
Definition FFT.h:56
@ p2p
Definition FFT.h:58
@ a2a
Definition FFT.h:57
KOKKOS_INLINE_FUNCTION auto & get(Tuple< Ts... > &t)
Accessor function to get an element mutable reference at a specific index from a Tuple.
Definition Tuple.h:314
std::shared_ptr< archive_type< MemorySpace > > buffer_type
KOKKOS_INLINE_FUNCTION static constexpr auto & get(View &&view, unsigned dim1, unsigned dim2, size_t i, size_t j, size_t k)
KOKKOS_INLINE_FUNCTION static constexpr auto & get(View &&view, unsigned dim1, unsigned dim2, size_t i, size_t j, size_t k)
KOKKOS_INLINE_FUNCTION static constexpr auto & get(View &&view, unsigned dim1, unsigned dim2, size_t i, size_t j, size_t k)
typename FieldLHS::value_type::value_type Tg
Field< Tg, Dim, mesh_type, Centering > Field_gt
std::unique_ptr< mesh_type > mesh2n1_m
typename mesh_type::vector_type vector_type
Field< Matrix_t, Dim, mesh_type, Centering > MField_t
typename FieldLHS::memory_space memory_space
std::unique_ptr< FieldLayout_t > layout2_m
typename FieldRHS::value_type Trhs
Field< int, Dim, mesh_type, Centering > IField_t
std::unique_ptr< FieldLayout_t > layout4_m
Field< Kokkos::complex< Tg >, Dim, mesh_type, Centering > CxField_gt
std::unique_ptr< mesh_type > mesh2_m
virtual void setDefaultParameters() override
std::unique_ptr< FFT< CCTransform, CxField_gt > > fft4n_m
FieldLHS::Centering_t Centering
std::unique_ptr< mesh_type > meshComplex_m
Poisson< FieldLHS, FieldRHS > Base
std::unique_ptr< FFT< Cos1Transform, Field_t > > fft2n1_m
std::unique_ptr< FieldLayout_t > layout2n1_m
std::unique_ptr< FFT_t > fft_m
FFT< RCTransform, FieldRHS > FFT_t
static constexpr unsigned Dim
MField_t * getHessian() override
typename FieldLHS::Mesh_t mesh_type
detail::FieldBufferData< Trhs > fd_m
void setRhs(rhs_type &rhs) override
std::unique_ptr< FieldLayout_t > layoutComplex_m
std::unique_ptr< mesh_type > mesh4_m
mesh_type::matrix_type Matrix_t
mpi::Communicator::buffer_type< memory_space > buffer_type
typename mesh_type::value_type scalar_type
void communicateVico(Vector< int, Dim > size, typename CxField_gt::view_type view_g, const ippl::NDIndex< Dim > ldom_g, const int nghost_g, typename Field_t::view_type view, const ippl::NDIndex< Dim > ldom, const int nghost)
ParameterList params_m
Definition Poisson.h:120
FieldRHS rhs_type
Definition Poisson.h:25
FieldLHS lhs_type
Definition Poisson.h:24