LCOV - code coverage report
Current view: top level - src/PoissonSolvers - FFTOpenPoissonSolver.h (source / functions) Coverage Total Hit
Test: report.info Lines: 0.0 % 36 0
Test Date: 2025-05-21 11:16:25 Functions: 0.0 % 14 0
Branches: 0.0 % 69 0

             Branch data     Line data    Source code
       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/HaloCells.h"
      24                 :             : #include "FieldLayout/FieldLayout.h"
      25                 :             : #include "Meshes/UniformCartesian.h"
      26                 :             : #include "Poisson.h"
      27                 :             : 
      28                 :             : namespace ippl {
      29                 :             :     namespace detail {
      30                 :             : 
      31                 :             :         /*!
      32                 :             :          * Access a view that either contains a vector field or a scalar field
      33                 :             :          * in such a way that the correct element access is determined at compile
      34                 :             :          * time, reducing the number of functions needed to achieve the same
      35                 :             :          * behavior for both kinds of fields
      36                 :             :          * @tparam tensorRank indicates whether scalar, vector, or matrix field
      37                 :             :          * @tparam - the view type
      38                 :             :          */
      39                 :             :         template <int tensorRank, typename>
      40                 :             :         struct ViewAccess;
      41                 :             : 
      42                 :             :         template <typename View>
      43                 :             :         struct ViewAccess<2, View> {
      44                 :           0 :             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                 :           0 :                 return view(i, j, k)[dim1][dim2];
      48                 :             :             }
      49                 :             :         };
      50                 :             : 
      51                 :             :         template <typename View>
      52                 :             :         struct ViewAccess<1, View> {
      53                 :           0 :             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                 :           0 :                 return view(i, j, k)[dim1];
      57                 :             :             }
      58                 :             :         };
      59                 :             : 
      60                 :             :         template <typename View>
      61                 :             :         struct ViewAccess<0, View> {
      62                 :           0 :             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                 :           0 :                 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
      80                 :             :         using Base = Poisson<FieldLHS, FieldRHS>;
      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
      86                 :             :         typedef FFT<RCTransform, FieldRHS> FFT_t;
      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;
     102                 :             :         typedef Field<int, Dim, mesh_type, Centering> IField_t;
     103                 :             :         typedef Field<Tg, Dim, mesh_type, Centering> Field_gt;
     104                 :             :         typedef Field<Kokkos::complex<Tg>, Dim, mesh_type, Centering> CxField_gt;
     105                 :             :         typedef typename FFT_t::ComplexField CxField_t;
     106                 :             :         typedef Vector<Trhs, Dim> Vector_t;
     107                 :             :         typedef typename mesh_type::matrix_type Matrix_t;
     108                 :             :         typedef Field<Matrix_t, Dim, mesh_type, Centering> MField_t;
     109                 :             : 
     110                 :             :         // define type for field layout
     111                 :             :         typedef FieldLayout<Dim> FieldLayout_t;
     112                 :             : 
     113                 :             :         // type for communication buffers
     114                 :             :         using memory_space = typename FieldLHS::memory_space;
     115                 :             :         using buffer_type  = mpi::Communicator::buffer_type<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
     122                 :             :         FFTOpenPoissonSolver();
     123                 :             :         FFTOpenPoissonSolver(rhs_type& rhs, ParameterList& params);
     124                 :             :         FFTOpenPoissonSolver(lhs_type& lhs, rhs_type& rhs, ParameterList& params);
     125   [ #  #  #  # ]:           0 :         ~FFTOpenPoissonSolver() = default;
     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                 :           0 :         MField_t* getHessian() override {
     141   [ #  #  #  # ]:           0 :             bool hessian = this->params_m.template get<bool>("hessian");
     142         [ #  # ]:           0 :             if (!hessian) {
     143   [ #  #  #  #  :           0 :                 throw IpplException(
                   #  # ]
     144                 :             :                     "FFTOpenPoissonSolver::getHessian()",
     145                 :             :                     "Cannot call getHessian() if 'hessian' flag in ParameterList is false");
     146                 :             :             }
     147                 :           0 :             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
     171                 :             :         Field_t storage_field;
     172                 :             : 
     173                 :             :         Field_t& rho2_mr =
     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
     179                 :             :         CxField_t rho2tr_m;
     180                 :             : 
     181                 :             :         // grntr_m is the Fourier transformed Green's function
     182                 :             :         // domain3_m and mesh3_m are used
     183                 :             :         CxField_t grntr_m;
     184                 :             : 
     185                 :             :         // temp_m field for the E-field computation
     186                 :             :         CxField_t temp_m;
     187                 :             : 
     188                 :             :         // fields that facilitate the calculation in greensFunction()
     189                 :             :         IField_t grnIField_m[Dim];
     190                 :             : 
     191                 :             :         // hessian matrix field (only if hessian parameter is set)
     192                 :             :         MField_t hess_m;
     193                 :             : 
     194                 :             :         // the FFT object
     195                 :             :         std::unique_ptr<FFT_t> fft_m;
     196                 :             : 
     197                 :             :         // mesh and layout objects for rho_m (RHS)
     198                 :             :         mesh_type* mesh_mp;
     199                 :             :         FieldLayout_t* layout_mp;
     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
     215                 :             :         vector_type hr_m;
     216                 :             :         Vector<int, Dim> nr_m;
     217                 :             : 
     218                 :             :         // string specifying algorithm: Hockney or Vico-Greengard
     219                 :             :         std::string alg_m;
     220                 :             : 
     221                 :             :         // members for Vico-Greengard
     222                 :             :         CxField_gt grnL_m;
     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                 :             : 
     229                 :             :         NDIndex<Dim> domain4_m;
     230                 :             : 
     231                 :             :         // members for improved Vico-Greengard (DCT VICO)
     232                 :             :         Field_t grn2n1_m;
     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                 :             : 
     239                 :             :         NDIndex<Dim> domain2n1_m;
     240                 :             : 
     241                 :             :         // bool indicating whether we want gradient of solution to calculate E field
     242                 :             :         bool isGradFD_m;
     243                 :             : 
     244                 :             :         // buffer for communication
     245                 :             :         detail::FieldBufferData<Trhs> fd_m;
     246                 :             : 
     247                 :             :     protected:
     248                 :           0 :         virtual void setDefaultParameters() override {
     249                 :             :             using heffteBackend       = typename FFT_t::heffteBackend;
     250         [ #  # ]:           0 :             heffte::plan_options opts = heffte::default_options<heffteBackend>();
     251   [ #  #  #  # ]:           0 :             this->params_m.add("use_pencils", opts.use_pencils);
     252   [ #  #  #  # ]:           0 :             this->params_m.add("use_reorder", opts.use_reorder);
     253   [ #  #  #  # ]:           0 :             this->params_m.add("use_gpu_aware", opts.use_gpu_aware);
     254   [ #  #  #  # ]:           0 :             this->params_m.add("r2c_direction", 0);
     255                 :             : 
     256   [ #  #  #  #  :           0 :             switch (opts.algorithm) {
                      # ]
     257                 :           0 :                 case heffte::reshape_algorithm::alltoall:
     258   [ #  #  #  # ]:           0 :                     this->params_m.add("comm", a2a);
     259                 :           0 :                     break;
     260                 :           0 :                 case heffte::reshape_algorithm::alltoallv:
     261   [ #  #  #  # ]:           0 :                     this->params_m.add("comm", a2av);
     262                 :           0 :                     break;
     263                 :           0 :                 case heffte::reshape_algorithm::p2p:
     264   [ #  #  #  # ]:           0 :                     this->params_m.add("comm", p2p);
     265                 :           0 :                     break;
     266                 :           0 :                 case heffte::reshape_algorithm::p2p_plined:
     267   [ #  #  #  # ]:           0 :                     this->params_m.add("comm", p2p_pl);
     268                 :           0 :                     break;
     269                 :           0 :                 default:
     270   [ #  #  #  #  :           0 :                     throw IpplException("FFTOpenPoissonSolver::setDefaultParameters",
                   #  # ]
     271                 :             :                                         "Unrecognized heffte communication type");
     272                 :             :             }
     273                 :             : 
     274   [ #  #  #  # ]:           0 :             this->params_m.add("algorithm", HOCKNEY);
     275   [ #  #  #  # ]:           0 :             this->params_m.add("hessian", false);
     276                 :           0 :         }
     277                 :             :     };
     278                 :             : }  // namespace ippl
     279                 :             : 
     280                 :             : #include "PoissonSolvers/FFTOpenPoissonSolver.hpp"
     281                 :             : #endif
        

Generated by: LCOV version 2.0-1