aboutsummaryrefslogtreecommitdiff
path: root/Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp')
-rw-r--r--Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp80
1 files changed, 72 insertions, 8 deletions
diff --git a/Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp b/Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp
index f62eaaa16..a87bfdb54 100644
--- a/Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp
+++ b/Source/FieldSolver/SpectralSolver/SpectralFieldDataRZ.cpp
@@ -545,7 +545,7 @@ SpectralFieldDataRZ::BackwardTransform (const int lev,
}
amrex::Real wt = amrex::second();
- amrex::Box const& realspace_bx = tempHTransformed[mfi].box();
+ amrex::Box realspace_bx = tempHTransformed[mfi].box();
FABZBackwardTransform(mfi, realspace_bx, field_index, tempHTransformedSplit, is_nodal_z);
@@ -553,7 +553,43 @@ SpectralFieldDataRZ::BackwardTransform (const int lev,
// tempHTransformedSplit includes the imaginary component of mode 0.
// field_mf does not.
multi_spectral_hankel_transformer[mfi].SpectralToPhysical_Scalar(tempHTransformedSplit[mfi], field_mf_copy[mfi]);
- field_mf[mfi].copy<amrex::RunOn::Device>(field_mf_copy[mfi], 0, i_comp*ncomp, ncomp);
+
+ amrex::Array4<amrex::Real> const & field_mf_array = field_mf[mfi].array();
+ amrex::Array4<amrex::Real> const & field_mf_copy_array = field_mf_copy[mfi].array();
+
+ // The box will be extended to include the guards cells below the axis
+ // so that they can be filled in. This will not be a simple copy of the
+ // fields since the signs will change when there is anti-symmetry.
+ amrex::Box const& realspace_bx_with_guards = field_mf[mfi].box();
+ const int* lo_with_guards = realspace_bx_with_guards.loVect();
+
+ // Grow the lower side of realspace_bx by the number of guard cells.
+ // This assumes that the box extends over the full extent radially, so
+ // lo_with_guards[0] will be equal to minus the number of guard cells radially.
+ const int nguard_r = -lo_with_guards[0];
+ realspace_bx.growLo(0, nguard_r);
+
+ // Get the intersection of the two boxes in case the field_mf has fewer z-guard cells
+ realspace_bx &= realspace_bx_with_guards;
+
+ ParallelFor(realspace_bx, ncomp,
+ [=] AMREX_GPU_DEVICE(int i, int j, int k, int icomp) noexcept {
+ int ii = i;
+ amrex::Real sign = +1._rt;
+ if (i < 0) {
+ ii = -i - 1;
+ if (icomp == 0) {
+ // Mode zero is symmetric
+ sign = +1._rt;
+ } else {
+ // Odd modes are anti-symmetric
+ int imode = (icomp + 1)/2;
+ sign = std::pow(-1._rt, imode);
+ }
+ }
+ int ic = icomp + i_comp;
+ field_mf_array(i,j,k,ic) = sign*field_mf_copy_array(ii,j,k,icomp);
+ });
if (cost && WarpX::load_balance_costs_update_algo == LoadBalanceCostsUpdateAlgo::Timers)
{
@@ -593,7 +629,7 @@ SpectralFieldDataRZ::BackwardTransform (const int lev,
}
amrex::Real wt = amrex::second();
- amrex::Box const& realspace_bx = tempHTransformed[mfi].box();
+ amrex::Box realspace_bx = tempHTransformed[mfi].box();
FABZBackwardTransform(mfi, realspace_bx, field_index_r, tempHTransformedSplit_p, is_nodal_z);
FABZBackwardTransform(mfi, realspace_bx, field_index_t, tempHTransformedSplit_m, is_nodal_z);
@@ -610,15 +646,43 @@ SpectralFieldDataRZ::BackwardTransform (const int lev,
amrex::Array4<amrex::Real> const & field_mf_r_copy_array = field_mf_r_copy[mfi].array();
amrex::Array4<amrex::Real> const & field_mf_t_copy_array = field_mf_t_copy[mfi].array();
+ // The box will be extended to include the guards cells below the axis
+ // so that they can be filled in. This will not be a simple copy of the
+ // fields since the signs will change when there is anti-symmetry.
+ amrex::Box const& realspace_bx_with_guards = field_mf_r[mfi].box();
+ const int* lo_with_guards = realspace_bx_with_guards.loVect();
+
+ // Grow the lower side of realspace_bx by the number of guard cells.
+ // This assumes that the box extends over the full extent radially, so
+ // lo_with_guards[0] will be equal to minus the number of guard cells radially.
+ const int nguard_r = -lo_with_guards[0];
+ realspace_bx.growLo(0, nguard_r);
+
+ // Get the intersection of the two boxes in case the field_mf has fewer z-guard cells
+ realspace_bx &= realspace_bx_with_guards;
+
ParallelFor(realspace_bx, 2*n_rz_azimuthal_modes-1,
[=] AMREX_GPU_DEVICE(int i, int j, int k, int icomp) noexcept {
+ int ii = i;
+ amrex::Real sign = +1._rt;
+ if (i < 0) {
+ ii = -i - 1;
+ if (icomp == 0) {
+ // Mode zero is anti-symmetric
+ sign = -1._rt;
+ } else {
+ // Even modes are anti-symmetric
+ int imode = (icomp + 1)/2;
+ sign = std::pow(-1._rt, imode+1);
+ }
+ }
if (icomp == 0) {
- // mode 0
- field_mf_r_array(i,j,k,icomp) = field_mf_r_copy_array(i,j,k,icomp);
- field_mf_t_array(i,j,k,icomp) = field_mf_t_copy_array(i,j,k,icomp);
+ // mode zero
+ field_mf_r_array(i,j,k,icomp) = sign*field_mf_r_copy_array(ii,j,k,icomp);
+ field_mf_t_array(i,j,k,icomp) = sign*field_mf_t_copy_array(ii,j,k,icomp);
} else {
- field_mf_r_array(i,j,k,icomp) = field_mf_r_copy_array(i,j,k,icomp+1);
- field_mf_t_array(i,j,k,icomp) = field_mf_t_copy_array(i,j,k,icomp+1);
+ field_mf_r_array(i,j,k,icomp) = sign*field_mf_r_copy_array(ii,j,k,icomp+1);
+ field_mf_t_array(i,j,k,icomp) = sign*field_mf_t_copy_array(ii,j,k,icomp+1);
}
});