IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
FFTOpenPoissonSolver.h
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
16#include "Utility/IpplException.h"
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/FieldBufferOps.hpp"
24#include "Field/HaloCells.h"
25#include "FieldLayout/FieldLayout.h"
26#include "Meshes/UniformCartesian.h"
27#include "Poisson.h"
28
29namespace ippl {
30
31 template <typename FieldLHS, typename FieldRHS>
32 class FFTOpenPoissonSolver : public Poisson<FieldLHS, FieldRHS> {
33 constexpr static unsigned Dim = FieldLHS::dim;
34 using Trhs = typename FieldRHS::value_type;
35 using mesh_type = typename FieldLHS::Mesh_t;
36 using Tg = typename FieldLHS::value_type::value_type;
37
38 public:
39 // type of output
40 using Base = Poisson<FieldLHS, FieldRHS>;
41
42 // types for LHS and RHS
43 using typename Base::lhs_type, typename Base::rhs_type;
44
45 // define a type for the 3 dimensional real to complex Fourier transform
46 typedef FFT<RCTransform, FieldRHS> FFT_t;
47
48 // enum type for the algorithm
49 enum Algorithm {
50 HOCKNEY = 0b01,
51 VICO = 0b10,
52 BIHARMONIC = 0b11,
53 DCT_VICO = 0b100
54 };
55
91 STANDARD = 0,
92 INTEGRATED = 1
93 };
94
95 // define a type for a 3 dimensional field (e.g. charge density field)
96 // define a type of Field with integers to be used for the helper Green's function
97 // also define a type for the Fourier transformed complex valued fields
98 // define matrix and matrix field types for the Hessian
99 typedef FieldRHS Field_t;
100 typedef typename FieldLHS::Centering_t Centering;
103 typedef Field<Kokkos::complex<Tg>, Dim, mesh_type, Centering> CxField_gt;
104 typedef typename FFT_t::ComplexField CxField_t;
106 typedef typename mesh_type::matrix_type Matrix_t;
108
109 // define type for field layout
111
112 // type for communication buffers
113 using memory_space = typename FieldLHS::memory_space;
114 using buffer_type = mpi::Communicator::buffer_type<memory_space>;
115
116 // types of mesh and mesh spacing
117 using vector_type = typename mesh_type::vector_type;
118 using scalar_type = typename mesh_type::value_type;
119
120 // constructor and destructor
122 FFTOpenPoissonSolver(rhs_type& rhs, ParameterList& params);
123 FFTOpenPoissonSolver(lhs_type& lhs, rhs_type& rhs, ParameterList& params);
124 ~FFTOpenPoissonSolver() = default;
125
126 // override the setRhs function of the Solver class
127 // since we need to call initializeFields()
128 void setRhs(rhs_type& rhs) override;
129
130 // allows user to set gradient of phi = Efield instead of spectral
131 // calculation of Efield (which uses FFTs)
132 void setGradFD();
133
134 // solve the Poisson equation using FFT;
135 // more specifically, compute the scalar potential given a density field rho using
136 void solve() override;
137
138 // override getHessian to return Hessian field if flag is on
139 MField_t* getHessian() override {
140 bool hessian = this->params_m.template get<bool>("hessian");
141 if (!hessian) {
142 throw IpplException(
143 "FFTOpenPoissonSolver::getHessian()",
144 "Cannot call getHessian() if 'hessian' flag in ParameterList is false");
145 }
146 return &hess_m;
147 }
148
158 void greensFunction();
159
192
193 // function called in the constructor to initialize the fields
194 void initializeFields();
195
196 // communication used for multi-rank Vico-Greengard's Green's function
197 void communicateVico(Vector<int, Dim> size, typename CxField_gt::view_type view_g,
198 const ippl::NDIndex<Dim> ldom_g, const int nghost_g,
199 typename Field_t::view_type view, const ippl::NDIndex<Dim> ldom,
200 const int nghost);
201
202 // needed for improved Vico-Greengard (DCT VICO)
203 void communicateVico(Vector<int, Dim> size, typename Field_t::view_type view_g,
204 const ippl::NDIndex<Dim> ldom_g, const int nghost_g,
205 typename Field_t::view_type view, const ippl::NDIndex<Dim> ldom,
206 const int nghost);
207
208 private:
209 // create a field to use as temporary storage
210 // references to it can be created to make the code where it is used readable
211 Field_t storage_field;
212
213 Field_t& rho2_mr =
214 storage_field; // the charge-density field with mesh doubled in each dimension
215 Field_t& grn_mr = storage_field; // the Green's function
216
217 // rho2tr_m is the Fourier transformed charge-density field
218 // domain3_m and mesh3_m are used
219 CxField_t rho2tr_m;
220
221 // grntr_m is the Fourier transformed Green's function
222 // domain3_m and mesh3_m are used
223 CxField_t grntr_m;
224
225 // temp_m field for the E-field computation
226 CxField_t temp_m;
227
228 // fields that facilitate the calculation in greensFunction()
229 IField_t grnIField_m[Dim];
230
231 // hessian matrix field (only if hessian parameter is set)
232 MField_t hess_m;
233
234 // the FFT object
235 std::unique_ptr<FFT_t> fft_m;
236
237 // mesh and layout objects for rho_m (RHS)
238 mesh_type* mesh_mp;
239 FieldLayout_t* layout_mp;
240
241 // mesh and layout objects for rho2_m
242 std::unique_ptr<mesh_type> mesh2_m;
243 std::unique_ptr<FieldLayout_t> layout2_m;
244
245 // mesh and layout objects for the Fourier transformed Complex fields
246 std::unique_ptr<mesh_type> meshComplex_m;
247 std::unique_ptr<FieldLayout_t> layoutComplex_m;
248
249 // domains for the various fields
250 NDIndex<Dim> domain_m; // original domain, gridsize
251 NDIndex<Dim> domain2_m; // doubled gridsize (2*Nx,2*Ny,2*Nz)
252 NDIndex<Dim> domainComplex_m; // field for the complex values of the RC transformation
253
254 // mesh spacing and mesh size
255 vector_type hr_m;
256 Vector<int, Dim> nr_m;
257
258 // string specifying algorithm: Hockney or Vico-Greengard
259 std::string alg_m;
260
261 // members for Vico-Greengard
262 CxField_gt grnL_m;
263
264 std::unique_ptr<FFT<CCTransform, CxField_gt>> fft4n_m;
265
266 std::unique_ptr<mesh_type> mesh4_m;
267 std::unique_ptr<FieldLayout_t> layout4_m;
268
269 NDIndex<Dim> domain4_m;
270
271 // members for improved Vico-Greengard (DCT VICO)
272 Field_t grn2n1_m;
273
274 std::unique_ptr<FFT<Cos1Transform, Field_t>> fft2n1_m;
275
276 std::unique_ptr<mesh_type> mesh2n1_m;
277 std::unique_ptr<FieldLayout_t> layout2n1_m;
278
279 NDIndex<Dim> domain2n1_m;
280
281 // bool indicating whether we want gradient of solution to calculate E field
282 bool isGradFD_m;
283
284 // buffer for communication
286
301 KOKKOS_INLINE_FUNCTION static scalar_type integratedGreenAntiderivative(
302 const scalar_type& x, const scalar_type& y, const scalar_type& z);
303
304 KOKKOS_INLINE_FUNCTION static scalar_type integratedGreenLogTerm(const scalar_type& a,
305 const scalar_type& b,
306 const scalar_type& c,
307 const scalar_type& r);
308
309 KOKKOS_INLINE_FUNCTION static scalar_type integratedGreenAtanTerm(
310 const scalar_type& numerator, const scalar_type& denominator);
311
319 KOKKOS_INLINE_FUNCTION static scalar_type integratedGreenAverage(const scalar_type& x,
320 const scalar_type& y,
321 const scalar_type& z,
322 const vector_type& h);
323
324 protected:
325 virtual void setDefaultParameters() override {
326 using heffteBackend = typename FFT_t::heffteBackend;
327 heffte::plan_options opts = heffte::default_options<heffteBackend>();
328 this->params_m.add("use_pencils", opts.use_pencils);
329 this->params_m.add("use_reorder", opts.use_reorder);
330 this->params_m.add("use_gpu_aware", opts.use_gpu_aware);
331 this->params_m.add("r2c_direction", 0);
332
333 switch (opts.algorithm) {
334 case heffte::reshape_algorithm::alltoall:
335 this->params_m.add("comm", a2a);
336 break;
337 case heffte::reshape_algorithm::alltoallv:
338 this->params_m.add("comm", a2av);
339 break;
340 case heffte::reshape_algorithm::p2p:
341 this->params_m.add("comm", p2p);
342 break;
343 case heffte::reshape_algorithm::p2p_plined:
344 this->params_m.add("comm", p2p_pl);
345 break;
346 default:
347 throw IpplException("FFTOpenPoissonSolver::setDefaultParameters",
348 "Unrecognized heffte communication type");
349 }
350
351 this->params_m.add("algorithm", HOCKNEY);
352 this->params_m.add("greens_function", STANDARD);
353 this->params_m.add("hessian", false);
354 }
355 };
356} // namespace ippl
357
358#include "PoissonSolvers/FFTOpenPoissonSolver.hpp"
359#endif
Definition Centering.h:25
Definition IpplException.h:6
Definition FFTOpenPoissonSolver.h:32
void greensFunction()
Compute and cache the FFT of the selected Green function.
Definition FFTOpenPoissonSolver.hpp:1021
virtual void setDefaultParameters() override
Definition FFTOpenPoissonSolver.h:325
void shiftedGreensFunction(const Vector< double, Dim > &shift)
Replace the cached kernel by a shifted Hockney Green function.
Definition FFTOpenPoissonSolver.hpp:2212
MField_t * getHessian() override
Definition FFTOpenPoissonSolver.h:139
void setRhs(rhs_type &rhs) override
Definition FFTOpenPoissonSolver.hpp:88
void solve() override
Definition FFTOpenPoissonSolver.hpp:358
GreenFunction
Real-space Green-function model used by the Hockney open-boundary solver.
Definition FFTOpenPoissonSolver.h:90
Definition FieldLayout.h:166
Definition NDIndex.h:21
Definition ParameterList.h:29
void add(const std::string &key, const T &value)
Definition ParameterList.h:44
Definition Poisson.h:16
Definition Vector.h:23
Definition Archive.h:20
Definition HaloCells.h:23