aboutsummaryrefslogtreecommitdiff
path: root/Source/FieldSolver
diff options
context:
space:
mode:
Diffstat (limited to 'Source/FieldSolver')
-rw-r--r--Source/FieldSolver/SpectralSolver/PsatdAlgorithm.cpp59
-rw-r--r--Source/FieldSolver/SpectralSolver/SpectralFieldData.H13
-rw-r--r--Source/FieldSolver/SpectralSolver/SpectralFieldData.cpp60
-rw-r--r--Source/FieldSolver/SpectralSolver/SpectralKSpace.cpp5
-rw-r--r--Source/FieldSolver/WarpXFFT.cpp6
5 files changed, 58 insertions, 85 deletions
diff --git a/Source/FieldSolver/SpectralSolver/PsatdAlgorithm.cpp b/Source/FieldSolver/SpectralSolver/PsatdAlgorithm.cpp
index 56e58bcc4..ada7506c3 100644
--- a/Source/FieldSolver/SpectralSolver/PsatdAlgorithm.cpp
+++ b/Source/FieldSolver/SpectralSolver/PsatdAlgorithm.cpp
@@ -56,8 +56,10 @@ PsatdAlgorithm::PsatdAlgorithm(const SpectralKSpace& spectral_kspace,
std::pow(modified_kx[i], 2) +
#if (AMREX_SPACEDIM==3)
std::pow(modified_ky[j], 2) +
-#endif
std::pow(modified_kz[k], 2));
+#else
+ std::pow(modified_kz[j], 2));
+#endif
// Calculate coefficients
constexpr Real c = PhysConst::c;
@@ -85,23 +87,12 @@ void
PsatdAlgorithm::pushSpectralFields(SpectralFieldData& f) const{
// Loop over boxes
- for (MFIter mfi(f.Ex); mfi.isValid(); ++mfi){
+ for (MFIter mfi(f.fields); mfi.isValid(); ++mfi){
- const Box& bx = f.Ex[mfi].box();
+ const Box& bx = f.fields[mfi].box();
// Extract arrays for the fields to be updated
- Array4<Complex> Ex_arr = f.Ex[mfi].array();
- Array4<Complex> Ey_arr = f.Ey[mfi].array();
- Array4<Complex> Ez_arr = f.Ez[mfi].array();
- Array4<Complex> Bx_arr = f.Bx[mfi].array();
- Array4<Complex> By_arr = f.By[mfi].array();
- Array4<Complex> Bz_arr = f.Bz[mfi].array();
- // Extract arrays for J and rho
- Array4<const Complex> Jx_arr = f.Jx[mfi].array();
- Array4<const Complex> Jy_arr = f.Jy[mfi].array();
- Array4<const Complex> Jz_arr = f.Jz[mfi].array();
- Array4<const Complex> rho_old_arr = f.rho_old[mfi].array();
- Array4<const Complex> rho_new_arr = f.rho_new[mfi].array();
+ Array4<Complex> fields = f.fields[mfi].array();
// Extract arrays for the coefficients
Array4<const Real> C_arr = C_coef[mfi].array();
Array4<const Real> S_ck_arr = S_ck_coef[mfi].array();
@@ -120,26 +111,28 @@ PsatdAlgorithm::pushSpectralFields(SpectralFieldData& f) const{
[=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
{
// Record old values of the fields to be updated
- const Complex Ex_old = Ex_arr(i,j,k);
- const Complex Ey_old = Ey_arr(i,j,k);
- const Complex Ez_old = Ez_arr(i,j,k);
- const Complex Bx_old = Bx_arr(i,j,k);
- const Complex By_old = By_arr(i,j,k);
- const Complex Bz_old = Bz_arr(i,j,k);
+ using Idx = SpectralFieldIndex;
+ const Complex Ex_old = fields(i,j,k,Idx::Ex);
+ const Complex Ey_old = fields(i,j,k,Idx::Ey);
+ const Complex Ez_old = fields(i,j,k,Idx::Ez);
+ const Complex Bx_old = fields(i,j,k,Idx::Bx);
+ const Complex By_old = fields(i,j,k,Idx::By);
+ const Complex Bz_old = fields(i,j,k,Idx::Bz);
// Shortcut for the values of J and rho
- const Complex Jx = Jx_arr(i,j,k);
- const Complex Jy = Jy_arr(i,j,k);
- const Complex Jz = Jz_arr(i,j,k);
- const Complex rho_old = rho_old_arr(i,j,k);
- const Complex rho_new = rho_new_arr(i,j,k);
+ const Complex Jx = fields(i,j,k,Idx::Jx);
+ const Complex Jy = fields(i,j,k,Idx::Jy);
+ const Complex Jz = fields(i,j,k,Idx::Jz);
+ const Complex rho_old = fields(i,j,k,Idx::rho_old);
+ const Complex rho_new = fields(i,j,k,Idx::rho_new);
// k vector values, and coefficients
const Real kx = modified_kx_arr[i];
#if (AMREX_SPACEDIM==3)
const Real ky = modified_ky_arr[j];
+ const Real kz = modified_kz_arr[k];
#else
constexpr Real ky = 0;
+ const Real kz = modified_kz_arr[j];
#endif
- const Real kz = modified_kz_arr[k];
constexpr Real c2 = PhysConst::c*PhysConst::c;
constexpr Real inv_ep0 = 1./PhysConst::ep0;
constexpr Complex I = Complex{0,1};
@@ -150,23 +143,23 @@ PsatdAlgorithm::pushSpectralFields(SpectralFieldData& f) const{
const Real X3 = X3_arr(i,j,k);
// Update E (see WarpX online documentation: theory section)
- Ex_arr(i,j,k) = C*Ex_old
+ fields(i,j,k,Idx::Ex) = C*Ex_old
+ S_ck*(c2*I*(ky*Bz_old - kz*By_old) - inv_ep0*Jx)
- I*(X2*rho_new - X3*rho_old)*kx;
- Ey_arr(i,j,k) = C*Ey_old
+ fields(i,j,k,Idx::Ey) = C*Ey_old
+ S_ck*(c2*I*(kz*Bx_old - kx*Bz_old) - inv_ep0*Jy)
- I*(X2*rho_new - X3*rho_old)*ky;
- Ez_arr(i,j,k) = C*Ez_old
+ fields(i,j,k,Idx::Ez) = C*Ez_old
+ S_ck*(c2*I*(kx*By_old - ky*Bx_old) - inv_ep0*Jz)
- I*(X2*rho_new - X3*rho_old)*kz;
// Update B (see WarpX online documentation: theory section)
- Bx_arr(i,j,k) = C*Bx_old
+ fields(i,j,k,Idx::Bx) = C*Bx_old
- S_ck*I*(ky*Ez_old - kz*Ey_old)
+ X1*I*(ky*Jz - kz*Jy);
- By_arr(i,j,k) = C*By_old
+ fields(i,j,k,Idx::By) = C*By_old
- S_ck*I*(kz*Ex_old - kx*Ez_old)
+ X1*I*(kz*Jx - kx*Jz);
- Bz_arr(i,j,k) = C*Bz_old
+ fields(i,j,k,Idx::Bz) = C*Bz_old
- S_ck*I*(kx*Ey_old - ky*Ex_old)
+ X1*I*(kx*Jy - ky*Jx);
});
diff --git a/Source/FieldSolver/SpectralSolver/SpectralFieldData.H b/Source/FieldSolver/SpectralSolver/SpectralFieldData.H
index c62513de6..9e31ac5b8 100644
--- a/Source/FieldSolver/SpectralSolver/SpectralFieldData.H
+++ b/Source/FieldSolver/SpectralSolver/SpectralFieldData.H
@@ -9,8 +9,9 @@
using SpectralField = amrex::FabArray< amrex::BaseFab <Complex> >;
/* Index for the fields that will be stored in spectral space */
-struct SpectralFieldIndex{
- enum { Ex=0, Ey, Ez, Bx, By, Bz, Jx, Jy, Jz, rho_old, rho_new };
+struct SpectralFieldIndex {
+ enum { Ex=0, Ey, Ez, Bx, By, Bz, Jx, Jy, Jz, rho_old, rho_new, n_fields };
+ // n_fields is automatically the total number of fields
};
/* \brief Class that stores the fields in spectral space, and performs the
@@ -37,12 +38,13 @@ class SpectralFieldData
SpectralFieldData& operator=(SpectralFieldData&& field_data) = default;
~SpectralFieldData();
void ForwardTransform( const amrex::MultiFab& mf,
- const int field_index, const int i_comp );
+ const int field_index, const int i_comp);
void BackwardTransform( amrex::MultiFab& mf,
- const int field_index, const int i_comp );
+ const int field_index, const int i_comp);
private:
- SpectralField Ex, Ey, Ez, Bx, By, Bz, Jx, Jy, Jz, rho_old, rho_new;
+ // `fields` stores fields in spectral space, as multicomponent FabArray
+ SpectralField fields;
// tmpRealField and tmpSpectralField store fields
// right before/after the Fourier transform
SpectralField tmpRealField, tmpSpectralField;
@@ -54,7 +56,6 @@ class SpectralFieldData
#if (AMREX_SPACEDIM==3)
SpectralShiftFactor yshift_FFTfromCell, yshift_FFTtoCell;
#endif
- SpectralField& getSpectralField( const int field_index );
};
#endif // WARPX_SPECTRAL_FIELD_DATA_H_
diff --git a/Source/FieldSolver/SpectralSolver/SpectralFieldData.cpp b/Source/FieldSolver/SpectralSolver/SpectralFieldData.cpp
index 291fe945e..6e6cc124f 100644
--- a/Source/FieldSolver/SpectralSolver/SpectralFieldData.cpp
+++ b/Source/FieldSolver/SpectralSolver/SpectralFieldData.cpp
@@ -10,17 +10,9 @@ SpectralFieldData::SpectralFieldData( const BoxArray& realspace_ba,
const BoxArray& spectralspace_ba = k_space.spectralspace_ba;
// Allocate the arrays that contain the fields in spectral space
- Ex = SpectralField(spectralspace_ba, dm, 1, 0);
- Ey = SpectralField(spectralspace_ba, dm, 1, 0);
- Ez = SpectralField(spectralspace_ba, dm, 1, 0);
- Bx = SpectralField(spectralspace_ba, dm, 1, 0);
- By = SpectralField(spectralspace_ba, dm, 1, 0);
- Bz = SpectralField(spectralspace_ba, dm, 1, 0);
- Jx = SpectralField(spectralspace_ba, dm, 1, 0);
- Jy = SpectralField(spectralspace_ba, dm, 1, 0);
- Jz = SpectralField(spectralspace_ba, dm, 1, 0);
- rho_old = SpectralField(spectralspace_ba, dm, 1, 0);
- rho_new = SpectralField(spectralspace_ba, dm, 1, 0);
+ // (one component per field)
+ fields = SpectralField(spectralspace_ba, dm,
+ SpectralFieldIndex::n_fields, 0);
// Allocate temporary arrays - in real space and spectral space
// These arrays will store the data just before/after the FFT
@@ -147,12 +139,11 @@ SpectralFieldData::ForwardTransform( const MultiFab& mf,
#endif
// Copy the spectral-space field `tmpSpectralField` to the appropriate
- // field (specified by the input argument field_index )
+ // index of the FabArray `fields` (specified by `field_index`)
// and apply correcting shift factor if the real space data comes
// from a cell-centered grid in real space instead of a nodal grid.
{
- SpectralField& field = getSpectralField( field_index );
- Array4<Complex> field_arr = field[mfi].array();
+ Array4<Complex> fields_arr = SpectralFieldData::fields[mfi].array();
Array4<const Complex> tmp_arr = tmpSpectralField[mfi].array();
const Complex* xshift_arr = xshift_FFTfromCell[mfi].dataPtr();
#if (AMREX_SPACEDIM == 3)
@@ -168,10 +159,12 @@ SpectralFieldData::ForwardTransform( const MultiFab& mf,
if (is_nodal_x==false) spectral_field_value *= xshift_arr[i];
#if (AMREX_SPACEDIM == 3)
if (is_nodal_y==false) spectral_field_value *= yshift_arr[j];
-#endif
if (is_nodal_z==false) spectral_field_value *= zshift_arr[k];
- // Copy field into temporary array
- field_arr(i,j,k) = spectral_field_value;
+#elif (AMREX_SPACEDIM == 2)
+ if (is_nodal_z==false) spectral_field_value *= zshift_arr[j];
+#endif
+ // Copy field into the right index
+ fields_arr(i,j,k,field_index) = spectral_field_value;
});
}
}
@@ -182,7 +175,8 @@ SpectralFieldData::ForwardTransform( const MultiFab& mf,
* real space, and store it in the component `i_comp` of `mf` */
void
SpectralFieldData::BackwardTransform( MultiFab& mf,
- const int field_index, const int i_comp )
+ const int field_index,
+ const int i_comp )
{
// Check field index type, in order to apply proper shift in spectral space
const bool is_nodal_x = mf.is_nodal(0);
@@ -202,8 +196,7 @@ SpectralFieldData::BackwardTransform( MultiFab& mf,
// to a cell-centered grid in real space instead of a nodal grid.
// Normalize (divide by 1/N) since the FFT+IFFT results in a factor N
{
- SpectralField& field = getSpectralField( field_index );
- Array4<const Complex> field_arr = field[mfi].array();
+ Array4<const Complex> field_arr = SpectralFieldData::fields[mfi].array();
Array4<Complex> tmp_arr = tmpSpectralField[mfi].array();
const Complex* xshift_arr = xshift_FFTtoCell[mfi].dataPtr();
#if (AMREX_SPACEDIM == 3)
@@ -216,13 +209,15 @@ SpectralFieldData::BackwardTransform( MultiFab& mf,
const Real inv_N = 1./spectralspace_bx.numPts();
ParallelFor( spectralspace_bx,
[=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
- Complex spectral_field_value = field_arr(i,j,k);
+ Complex spectral_field_value = field_arr(i,j,k,field_index);
// Apply proper shift in each dimension
if (is_nodal_x==false) spectral_field_value *= xshift_arr[i];
#if (AMREX_SPACEDIM == 3)
if (is_nodal_y==false) spectral_field_value *= yshift_arr[j];
-#endif
if (is_nodal_z==false) spectral_field_value *= zshift_arr[k];
+#elif (AMREX_SPACEDIM == 2)
+ if (is_nodal_z==false) spectral_field_value *= zshift_arr[j];
+#endif
// Copy field into temporary array (after normalization)
tmp_arr(i,j,k) = inv_N*spectral_field_value;
});
@@ -248,24 +243,3 @@ SpectralFieldData::BackwardTransform( MultiFab& mf,
}
}
}
-
-
-SpectralField&
-SpectralFieldData::getSpectralField( const int field_index )
-{
- switch(field_index)
- {
- case SpectralFieldIndex::Ex : return Ex; break;
- case SpectralFieldIndex::Ey : return Ey; break;
- case SpectralFieldIndex::Ez : return Ez; break;
- case SpectralFieldIndex::Bx : return Bx; break;
- case SpectralFieldIndex::By : return By; break;
- case SpectralFieldIndex::Bz : return Bz; break;
- case SpectralFieldIndex::Jx : return Jx; break;
- case SpectralFieldIndex::Jy : return Jy; break;
- case SpectralFieldIndex::Jz : return Jz; break;
- case SpectralFieldIndex::rho_old : return rho_old; break;
- case SpectralFieldIndex::rho_new : return rho_new; break;
- default : return tmpSpectralField; // For synthax; should not occur in practice
- }
-}
diff --git a/Source/FieldSolver/SpectralSolver/SpectralKSpace.cpp b/Source/FieldSolver/SpectralSolver/SpectralKSpace.cpp
index d91891a30..ddb2020d8 100644
--- a/Source/FieldSolver/SpectralSolver/SpectralKSpace.cpp
+++ b/Source/FieldSolver/SpectralSolver/SpectralKSpace.cpp
@@ -161,12 +161,13 @@ SpectralKSpace::getModifiedKComponent( const DistributionMapping& dm,
// Fill the modified k vector
for (int i=0; i<k.size(); i++ ){
+ modified_k[i] = 0;
for (int n=1; n<stencil_coef.size(); n++){
if (nodal){
- modified_k[i] = stencil_coef[n]* \
+ modified_k[i] += stencil_coef[n]* \
std::sin( k[i]*n*delta_x )/( n*delta_x );
} else {
- modified_k[i] = stencil_coef[n]* \
+ modified_k[i] += stencil_coef[n]* \
std::sin( k[i]*(n-0.5)*delta_x )/( (n-0.5)*delta_x );
}
}
diff --git a/Source/FieldSolver/WarpXFFT.cpp b/Source/FieldSolver/WarpXFFT.cpp
index 4bccc956b..1cf5460f2 100644
--- a/Source/FieldSolver/WarpXFFT.cpp
+++ b/Source/FieldSolver/WarpXFFT.cpp
@@ -130,7 +130,11 @@ WarpX::AllocLevelDataFFT (int lev)
// Allocate and initialize objects for the spectral solver
// (all use the same distribution mapping)
std::array<Real,3> dx = CellSize(lev);
- RealVect dx_vect = RealVect( AMREX_D_DECL(dx[0], dx[1], dx[2]) );
+#if (AMREX_SPACEDIM == 3)
+ RealVect dx_vect(dx[0], dx[1], dx[2]);
+#elif (AMREX_SPACEDIM == 2)
+ RealVect dx_vect(dx[0], dx[2]);
+#endif
spectral_solver_fp[lev].reset( new SpectralSolver( ba_fp_fft, dm_fp_fft,
nox_fft, noy_fft, noz_fft, do_nodal, dx_vect, dt[lev] ) );
}