1616FFTPoissonSolverDirichletDirect::FFTPoissonSolverDirichletDirect (
1717 amrex::BoxArray const & realspace_ba,
1818 amrex::DistributionMapping const & dm,
19- amrex::Geometry const & gm )
19+ amrex::Geometry const & gm,
20+ bool is_even)
2021{
21- define (realspace_ba, dm, gm);
22+ define (realspace_ba, dm, gm, is_even );
2223}
2324
2425void
2526FFTPoissonSolverDirichletDirect::define (amrex::BoxArray const & a_realspace_ba,
2627 amrex::DistributionMapping const & dm,
27- amrex::Geometry const & gm )
28+ amrex::Geometry const & gm,
29+ bool is_even)
2830{
2931 HIPACE_PROFILE (" FFTPoissonSolverDirichletDirect::define()" );
3032 using namespace amrex ::literals;
3133
34+ m_is_even = is_even;
35+
3236 // If we are going to support parallel FFT, the constructor needs to take a communicator.
3337 AMREX_ALWAYS_ASSERT_WITH_MESSAGE (a_realspace_ba.size () == 1 , " Parallel FFT not supported yet" );
3438
@@ -52,15 +56,17 @@ FFTPoissonSolverDirichletDirect::define (amrex::BoxArray const& a_realspace_ba,
5256 const amrex::IntVect fft_size = fft_box.length ();
5357 const int nx = fft_size[0 ];
5458 const int ny = fft_size[1 ];
59+ const int logical_nx = is_even ? nx : nx + 1 ;
60+ const int logical_ny = is_even ? ny : ny + 1 ;
5561 const auto dx = gm.CellSizeArray ();
5662 const amrex::Real dxsquared = dx[0 ]*dx[0 ];
5763 const amrex::Real dysquared = dx[1 ]*dx[1 ];
58- const amrex::Real sine_x_factor = MathConst::pi / ( 2 . * ( nx + 1 ) );
59- const amrex::Real sine_y_factor = MathConst::pi / ( 2 . * ( ny + 1 ) );
64+ const amrex::Real sine_x_factor = MathConst::pi / ( 2 . * logical_nx );
65+ const amrex::Real sine_y_factor = MathConst::pi / ( 2 . * logical_ny );
6066
6167 // Normalization of FFTW's 'DST-I' discrete sine transform (FFTW_RODFT00)
6268 // This normalization is used regardless of the sine transform library
63- const amrex::Real norm_fac = 0.5 / ( 2 * (( nx + 1 ) * ( ny + 1 ) ));
69+ const amrex::Real norm_fac = 0.5 / ( 2 * (logical_nx * logical_ny ));
6470
6571 // Calculate the array of m_eigenvalue_matrix
6672 for (amrex::MFIter mfi (m_eigenvalue_matrix, DfltMfi); mfi.isValid (); ++mfi ){
@@ -84,8 +90,10 @@ FFTPoissonSolverDirichletDirect::define (amrex::BoxArray const& a_realspace_ba,
8490 }
8591
8692 // Allocate and initialize the FFT plans
87- std::size_t fwd_area = m_forward_fft.Initialize (FFTType::R2R_2D, fft_size[0 ], fft_size[1 ]);
88- std::size_t bkw_area = m_backward_fft.Initialize (FFTType::R2R_2D, fft_size[0 ], fft_size[1 ]);
93+ std::size_t fwd_area = m_forward_fft.Initialize (
94+ is_even ? FFTType::R2R_2D_DST2 : FFTType::R2R_2D_DST1, fft_size[0 ], fft_size[1 ]);
95+ std::size_t bkw_area = m_backward_fft.Initialize (
96+ is_even ? FFTType::R2R_2D_DST3 : FFTType::R2R_2D_DST1, fft_size[0 ], fft_size[1 ]);
8997
9098 // Allocate work area for both FFTs
9199 m_fft_work_area.resize (std::max (fwd_area, bkw_area));
0 commit comments