aboutsummaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/FieldSolver/Make.package5
-rw-r--r--Source/FieldSolver/PicsarHybridSpectralSolver/Make.package6
-rw-r--r--Source/FieldSolver/PicsarHybridSpectralSolver/PicsarHybridFFTData.H32
-rw-r--r--Source/FieldSolver/PicsarHybridSpectralSolver/PicsarHybridSpectralSolver.cpp (renamed from Source/FieldSolver/WarpXFFT.cpp)54
-rw-r--r--Source/FieldSolver/PicsarHybridSpectralSolver/picsar_hybrid_spectral.F90 (renamed from Source/FieldSolver/WarpX_fft.F90)0
-rw-r--r--Source/FieldSolver/WarpXPushFieldsEM.cpp48
-rw-r--r--Source/Initialization/WarpXInitData.cpp2
-rw-r--r--Source/Make.WarpX25
-rw-r--r--Source/WarpX.H64
-rw-r--r--Source/WarpX.cpp15
10 files changed, 137 insertions, 114 deletions
diff --git a/Source/FieldSolver/Make.package b/Source/FieldSolver/Make.package
index 7eea52ee7..25e21c146 100644
--- a/Source/FieldSolver/Make.package
+++ b/Source/FieldSolver/Make.package
@@ -2,9 +2,10 @@ CEXE_headers += WarpX_K.H
CEXE_headers += WarpX_FDTD.H
CEXE_sources += WarpXPushFieldsEM.cpp
ifeq ($(USE_PSATD),TRUE)
- CEXE_sources += WarpXFFT.cpp
- F90EXE_sources += WarpX_fft.F90
include $(WARPX_HOME)/Source/FieldSolver/SpectralSolver/Make.package
+ ifeq ($(USE_CUDA),FALSE)
+ include $(WARPX_HOME)/Source/FieldSolver/PicsarHybridSpectralSolver/Make.package
+ endif
endif
ifeq ($(USE_OPENBC_POISSON),TRUE)
F90EXE_sources += openbc_poisson_solver.F90
diff --git a/Source/FieldSolver/PicsarHybridSpectralSolver/Make.package b/Source/FieldSolver/PicsarHybridSpectralSolver/Make.package
new file mode 100644
index 000000000..e185525e6
--- /dev/null
+++ b/Source/FieldSolver/PicsarHybridSpectralSolver/Make.package
@@ -0,0 +1,6 @@
+CEXE_headers += PicsarHybridFFTData.H
+CEXE_sources += PicsarHybridSpectralSolver.cpp
+F90EXE_sources += picsar_hybrid_spectral.F90
+
+INCLUDE_LOCATIONS += $(WARPX_HOME)/Source/FieldSolver/PicsarHybridSpectralSolver
+VPATH_LOCATIONS += $(WARPX_HOME)/Source/FieldSolver/PicsarHybridSpectralSolver \ No newline at end of file
diff --git a/Source/FieldSolver/PicsarHybridSpectralSolver/PicsarHybridFFTData.H b/Source/FieldSolver/PicsarHybridSpectralSolver/PicsarHybridFFTData.H
new file mode 100644
index 000000000..4e97ab675
--- /dev/null
+++ b/Source/FieldSolver/PicsarHybridSpectralSolver/PicsarHybridFFTData.H
@@ -0,0 +1,32 @@
+#ifndef WARPX_PICSAR_HYBRID_FFTDATA_H_
+#define WARPX_PICSAR_HYBRID_FFTDATA_H_
+
+// FFTData is a stuct containing a 22 pointers to auxiliary arrays
+// 1-11: padded arrays in real space (required by FFTW); 12-22: arrays in spectral space
+struct FFTData
+{
+ static constexpr int N = 22;
+ void* data[N] = { nullptr };
+
+ ~FFTData () {
+ for (int i = 0; i < N; ++i) { // The memory is allocated with fftw_alloc.
+ fftw_free(data[i]);
+ data[i] = nullptr;
+ }
+ }
+
+ FFTData () = default;
+
+ FFTData (FFTData && rhs) noexcept {
+ for (int i = 0; i < N; ++i) {
+ data[i] = rhs.data[i];
+ rhs.data[i] = nullptr;
+ }
+ }
+
+ FFTData (FFTData const&) = delete;
+ void operator= (FFTData const&) = delete;
+ void operator= (FFTData&&) = delete;
+};
+
+#endif // WARPX_PICSAR_HYBRID_FFTDATA_H_ \ No newline at end of file
diff --git a/Source/FieldSolver/WarpXFFT.cpp b/Source/FieldSolver/PicsarHybridSpectralSolver/PicsarHybridSpectralSolver.cpp
index f9cd7570a..26c93086a 100644
--- a/Source/FieldSolver/WarpXFFT.cpp
+++ b/Source/FieldSolver/PicsarHybridSpectralSolver/PicsarHybridSpectralSolver.cpp
@@ -5,10 +5,10 @@
using namespace amrex;
-constexpr int WarpX::FFTData::N;
+constexpr int FFTData::N;
namespace {
-static std::unique_ptr<WarpX::FFTData> nullfftdata; // This for process with nz_fft=0
+static std::unique_ptr<FFTData> nullfftdata; // This for process with nz_fft=0
/** \brief Returns an "owner mask" which 1 for all cells, except
* for the duplicated (physical) cells of a nodal grid.
@@ -122,6 +122,8 @@ WarpX::AllocLevelDataFFT (int lev)
static_assert(std::is_standard_layout<FFTData>::value, "FFTData must have standard layout");
static_assert(sizeof(FFTData) == sizeof(void*)*FFTData::N, "sizeof FFTData is wrong");
+
+
InitFFTComm(lev);
BoxArray ba_fp_fft;
@@ -366,52 +368,8 @@ WarpX::FreeFFT (int lev)
}
void
-WarpX::PushPSATD (amrex::Real a_dt)
-{
- for (int lev = 0; lev <= finest_level; ++lev) {
- AMREX_ALWAYS_ASSERT_WITH_MESSAGE(dt[lev] == a_dt, "dt must be consistent");
- if (fft_hybrid_mpi_decomposition){
- PushPSATD_hybridFFT(lev, a_dt);
- } else {
- PushPSATD_localFFT(lev, a_dt);
- }
- }
-}
-
-void WarpX::PushPSATD_localFFT (int lev, amrex::Real /* dt */)
-{
- auto& solver = *spectral_solver_fp[lev];
-
- // Perform forward Fourier transform
- solver.ForwardTransform(*Efield_fp[lev][0], SpectralFieldIndex::Ex);
- solver.ForwardTransform(*Efield_fp[lev][1], SpectralFieldIndex::Ey);
- solver.ForwardTransform(*Efield_fp[lev][2], SpectralFieldIndex::Ez);
- solver.ForwardTransform(*Bfield_fp[lev][0], SpectralFieldIndex::Bx);
- solver.ForwardTransform(*Bfield_fp[lev][1], SpectralFieldIndex::By);
- solver.ForwardTransform(*Bfield_fp[lev][2], SpectralFieldIndex::Bz);
- solver.ForwardTransform(*current_fp[lev][0], SpectralFieldIndex::Jx);
- solver.ForwardTransform(*current_fp[lev][1], SpectralFieldIndex::Jy);
- solver.ForwardTransform(*current_fp[lev][2], SpectralFieldIndex::Jz);
- solver.ForwardTransform(*rho_fp[lev], SpectralFieldIndex::rho_old, 0);
- solver.ForwardTransform(*rho_fp[lev], SpectralFieldIndex::rho_new, 1);
-
- // Advance fields in spectral space
- solver.pushSpectralFields();
-
- // Perform backward Fourier Transform
- solver.BackwardTransform(*Efield_fp[lev][0], SpectralFieldIndex::Ex);
- solver.BackwardTransform(*Efield_fp[lev][1], SpectralFieldIndex::Ey);
- solver.BackwardTransform(*Efield_fp[lev][2], SpectralFieldIndex::Ez);
- solver.BackwardTransform(*Bfield_fp[lev][0], SpectralFieldIndex::Bx);
- solver.BackwardTransform(*Bfield_fp[lev][1], SpectralFieldIndex::By);
- solver.BackwardTransform(*Bfield_fp[lev][2], SpectralFieldIndex::Bz);
-}
-
-void
WarpX::PushPSATD_hybridFFT (int lev, amrex::Real /* dt */)
{
-#ifndef AMREX_USE_CUDA // Running on CPU ; use PICSAR code for the hybrid FFT
-
BL_PROFILE_VAR_NS("WarpXFFT::CopyDualGrid", blp_copy);
BL_PROFILE_VAR_NS("PICSAR::FftPushEB", blp_push_eb);
@@ -486,8 +444,4 @@ WarpX::PushPSATD_hybridFFT (int lev, amrex::Real /* dt */)
{
amrex::Abort("WarpX::PushPSATD: TODO");
}
-#else // AMREX_USE_CUDA is defined ; running on GPU
- amrex::Abort("The option `psatd.fft_hybrid_mpi_decomposition` does not work on GPU.");
-#endif
-
}
diff --git a/Source/FieldSolver/WarpX_fft.F90 b/Source/FieldSolver/PicsarHybridSpectralSolver/picsar_hybrid_spectral.F90
index 35357a63f..35357a63f 100644
--- a/Source/FieldSolver/WarpX_fft.F90
+++ b/Source/FieldSolver/PicsarHybridSpectralSolver/picsar_hybrid_spectral.F90
diff --git a/Source/FieldSolver/WarpXPushFieldsEM.cpp b/Source/FieldSolver/WarpXPushFieldsEM.cpp
index 0887fa6a2..4fce4717b 100644
--- a/Source/FieldSolver/WarpXPushFieldsEM.cpp
+++ b/Source/FieldSolver/WarpXPushFieldsEM.cpp
@@ -17,6 +17,54 @@
using namespace amrex;
+#ifdef WARPX_USE_PSATD
+
+void
+WarpX::PushPSATD (amrex::Real a_dt)
+{
+ for (int lev = 0; lev <= finest_level; ++lev) {
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(dt[lev] == a_dt, "dt must be consistent");
+ if (fft_hybrid_mpi_decomposition){
+#ifndef AMREX_USE_CUDA // Only available on CPU
+ PushPSATD_hybridFFT(lev, a_dt);
+#endif
+ } else {
+ PushPSATD_localFFT(lev, a_dt);
+ }
+ }
+}
+
+void WarpX::PushPSATD_localFFT (int lev, amrex::Real /* dt */)
+{
+ auto& solver = *spectral_solver_fp[lev];
+
+ // Perform forward Fourier transform
+ solver.ForwardTransform(*Efield_fp[lev][0], SpectralFieldIndex::Ex);
+ solver.ForwardTransform(*Efield_fp[lev][1], SpectralFieldIndex::Ey);
+ solver.ForwardTransform(*Efield_fp[lev][2], SpectralFieldIndex::Ez);
+ solver.ForwardTransform(*Bfield_fp[lev][0], SpectralFieldIndex::Bx);
+ solver.ForwardTransform(*Bfield_fp[lev][1], SpectralFieldIndex::By);
+ solver.ForwardTransform(*Bfield_fp[lev][2], SpectralFieldIndex::Bz);
+ solver.ForwardTransform(*current_fp[lev][0], SpectralFieldIndex::Jx);
+ solver.ForwardTransform(*current_fp[lev][1], SpectralFieldIndex::Jy);
+ solver.ForwardTransform(*current_fp[lev][2], SpectralFieldIndex::Jz);
+ solver.ForwardTransform(*rho_fp[lev], SpectralFieldIndex::rho_old, 0);
+ solver.ForwardTransform(*rho_fp[lev], SpectralFieldIndex::rho_new, 1);
+
+ // Advance fields in spectral space
+ solver.pushSpectralFields();
+
+ // Perform backward Fourier Transform
+ solver.BackwardTransform(*Efield_fp[lev][0], SpectralFieldIndex::Ex);
+ solver.BackwardTransform(*Efield_fp[lev][1], SpectralFieldIndex::Ey);
+ solver.BackwardTransform(*Efield_fp[lev][2], SpectralFieldIndex::Ez);
+ solver.BackwardTransform(*Bfield_fp[lev][0], SpectralFieldIndex::Bx);
+ solver.BackwardTransform(*Bfield_fp[lev][1], SpectralFieldIndex::By);
+ solver.BackwardTransform(*Bfield_fp[lev][2], SpectralFieldIndex::Bz);
+}
+
+#endif
+
void
WarpX::EvolveB (Real a_dt)
{
diff --git a/Source/Initialization/WarpXInitData.cpp b/Source/Initialization/WarpXInitData.cpp
index d583b2b0f..2442e0205 100644
--- a/Source/Initialization/WarpXInitData.cpp
+++ b/Source/Initialization/WarpXInitData.cpp
@@ -317,7 +317,7 @@ WarpX::InitLevelData (int lev, Real time)
}
}
-#ifdef WARPX_USE_PSATD
+#ifdef WARPX_USE_PSATD_HYBRID
void
WarpX::InitLevelDataFFT (int lev, Real time)
diff --git a/Source/Make.WarpX b/Source/Make.WarpX
index bc837c797..3060ae8f0 100644
--- a/Source/Make.WarpX
+++ b/Source/Make.WarpX
@@ -111,20 +111,23 @@ endif
ifeq ($(USE_PSATD),TRUE)
- FFTW_HOME ?= NOT_SET
- ifneq ($(FFTW_HOME),NOT_SET)
- VPATH_LOCATIONS += $(FFTW_HOME)/include
- INCLUDE_LOCATIONS += $(FFTW_HOME)/include
- LIBRARY_LOCATIONS += $(FFTW_HOME)/lib
- endif
USERSuffix := $(USERSuffix).PSATD
DEFINES += -DWARPX_USE_PSATD
- ifeq ($(USE_CUDA),TRUE)
- DEFINES += -DFFTW -DCUDA_FFT=1 # PICSAR uses it
- LIBRARIES += -lfftw3_mpi -lfftw3 -lfftw3_threads -lcufft
+ ifeq ($(USE_CUDA),FALSE) # Running on CPU
+ # Use FFTW
+ LIBRARIES += -lfftw3_mpi -lfftw3 -lfftw3_threads
+ FFTW_HOME ?= NOT_SET
+ ifneq ($(FFTW_HOME),NOT_SET)
+ VPATH_LOCATIONS += $(FFTW_HOME)/include
+ INCLUDE_LOCATIONS += $(FFTW_HOME)/include
+ LIBRARY_LOCATIONS += $(FFTW_HOME)/lib
+ endif
+ # Compile with PICSAR's Hybrid-MPI PSATD
+ DEFINES += -DWARPX_USE_PSATD_HYBRID
+ DEFINES += -DFFTW # PICSAR uses it
else
- DEFINES += -DFFTW # PICSAR uses it
- LIBRARIES += -lfftw3_mpi -lfftw3 -lfftw3_threads
+ # Use cuFFT
+ LIBRARIES += -lcufft
endif
endif
diff --git a/Source/WarpX.H b/Source/WarpX.H
index ca7596589..35de5c88d 100644
--- a/Source/WarpX.H
+++ b/Source/WarpX.H
@@ -26,9 +26,11 @@
#include <NCIGodfreyFilter.H>
#ifdef WARPX_USE_PSATD
-#include <fftw3.h>
#include <SpectralSolver.H>
#endif
+#ifdef WARPX_USE_PSATD_HYBRID
+#include <PicsarHybridFFTData.H>
+#endif
#if defined(BL_USE_SENSEI_INSITU)
namespace amrex {
@@ -578,7 +580,7 @@ private:
amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > > Efield_slice;
amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > > Bfield_slice;
-#ifdef WARPX_USE_PSATD
+#ifdef WARPX_USE_PSATD_HYBRID
// Store fields in real space on the dual grid (i.e. the grid for the FFT push of the fields)
// This includes data for the FFT guard cells (between FFT groups)
amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > > Efield_fp_fft;
@@ -590,44 +592,30 @@ private:
amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > > Bfield_cp_fft;
amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > > current_cp_fft;
amrex::Vector< std::unique_ptr<amrex::MultiFab> > rho_cp_fft;
+#endif
-public:
- // FFTData is a stuct containing a 22 pointers to auxiliary arrays
- // 1-11: padded arrays in real space (required by FFTW); 12-22: arrays in spectral space
- struct FFTData
- {
- static constexpr int N = 22;
- void* data[N] = { nullptr };
-
- ~FFTData () {
- for (int i = 0; i < N; ++i) { // The memory is allocated with fftw_alloc.
- fftw_free(data[i]);
- data[i] = nullptr;
- }
- }
-
- FFTData () = default;
+#ifdef WARPX_USE_PSATD
+private:
+ void EvolvePSATD (int numsteps);
+ void PushPSATD (amrex::Real dt);
+ void PushPSATD_localFFT (int lev, amrex::Real dt);
- FFTData (FFTData && rhs) noexcept {
- for (int i = 0; i < N; ++i) {
- data[i] = rhs.data[i];
- rhs.data[i] = nullptr;
- }
- }
+ bool fft_hybrid_mpi_decomposition = false;
+ int ngroups_fft = 4;
+ int fftw_plan_measure = 1;
+ int nox_fft = 16;
+ int noy_fft = 16;
+ int noz_fft = 16;
- FFTData (FFTData const&) = delete;
- void operator= (FFTData const&) = delete;
- void operator= (FFTData&&) = delete;
- };
+ amrex::Vector<std::unique_ptr<SpectralSolver>> spectral_solver_fp;
+ amrex::Vector<std::unique_ptr<SpectralSolver>> spectral_solver_cp;
+#endif
+#ifdef WARPX_USE_PSATD_HYBRID
private:
-
amrex::Vector<std::unique_ptr<amrex::LayoutData<FFTData> > > dataptr_fp_fft;
amrex::Vector<std::unique_ptr<amrex::LayoutData<FFTData> > > dataptr_cp_fft;
- amrex::Vector<std::unique_ptr<SpectralSolver>> spectral_solver_fp;
- amrex::Vector<std::unique_ptr<SpectralSolver>> spectral_solver_cp;
-
// Domain decomposition containing the valid part of the dual grids (i.e. without FFT guard cells)
amrex::Vector<amrex::BoxArray> ba_valid_fp_fft;
amrex::Vector<amrex::BoxArray> ba_valid_cp_fft;
@@ -638,13 +626,6 @@ private:
amrex::Vector<MPI_Comm> comm_fft;
amrex::Vector<int> color_fft;
- bool fft_hybrid_mpi_decomposition = false;
- int ngroups_fft = 4;
- int fftw_plan_measure = 1;
- int nox_fft = 16;
- int noy_fft = 16;
- int noz_fft = 16;
-
void AllocLevelDataFFT (int lev);
void InitLevelDataFFT (int lev, amrex::Real time);
@@ -654,12 +635,7 @@ private:
const amrex::Box& domain);
void InitFFTDataPlan (int lev);
void FreeFFT (int lev);
-
- void EvolvePSATD (int numsteps);
- void PushPSATD (amrex::Real dt);
- void PushPSATD_localFFT (int lev, amrex::Real dt);
void PushPSATD_hybridFFT (int lev, amrex::Real dt);
-
#endif
#if defined(BL_USE_SENSEI_INSITU)
diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp
index 08948227c..f379d5f4c 100644
--- a/Source/WarpX.cpp
+++ b/Source/WarpX.cpp
@@ -202,6 +202,10 @@ WarpX::WarpX ()
costs.resize(nlevs_max);
#ifdef WARPX_USE_PSATD
+ spectral_solver_fp.resize(nlevs_max);
+ spectral_solver_cp.resize(nlevs_max);
+#endif
+#ifdef WARPX_USE_PSATD_HYBRID
Efield_fp_fft.resize(nlevs_max);
Bfield_fp_fft.resize(nlevs_max);
current_fp_fft.resize(nlevs_max);
@@ -215,9 +219,6 @@ WarpX::WarpX ()
dataptr_fp_fft.resize(nlevs_max);
dataptr_cp_fft.resize(nlevs_max);
- spectral_solver_fp.resize(nlevs_max);
- spectral_solver_cp.resize(nlevs_max);
-
ba_valid_fp_fft.resize(nlevs_max);
ba_valid_cp_fft.resize(nlevs_max);
@@ -511,8 +512,6 @@ WarpX::ReadParameters ()
pp.query("nox", nox_fft);
pp.query("noy", noy_fft);
pp.query("noz", noz_fft);
- // Override value
- if (fft_hybrid_mpi_decomposition==false) ngroups_fft=ParallelDescriptor::NProcs();
}
#endif
@@ -568,8 +567,12 @@ WarpX::MakeNewLevelFromScratch (int lev, Real time, const BoxArray& new_grids,
#ifdef WARPX_USE_PSATD
if (fft_hybrid_mpi_decomposition){
+#ifdef WARPX_USE_PSATD_HYBRID
AllocLevelDataFFT(lev);
InitLevelDataFFT(lev, time);
+#else
+ amrex::Abort("The option `psatd.fft_hybrid_mpi_decomposition` does not work on GPU.");
+#endif
}
#endif
}
@@ -614,7 +617,7 @@ WarpX::ClearLevel (int lev)
costs[lev].reset();
-#ifdef WARPX_USE_PSATD
+#ifdef WARPX_USE_PSATD_HYBRID
for (int i = 0; i < 3; ++i) {
Efield_fp_fft[lev][i].reset();
Bfield_fp_fft[lev][i].reset();