aboutsummaryrefslogtreecommitdiff
path: root/Source/FieldSolver/SpectralSolver/SpectralAlgorithms
diff options
context:
space:
mode:
authorGravatar Edoardo Zoni <59625522+EZoni@users.noreply.github.com> 2020-05-05 17:54:28 -0700
committerGravatar GitHub <noreply@github.com> 2020-05-05 17:54:28 -0700
commite50f166a7e1cf517fe9383db6c59dbcae0fcea89 (patch)
treebb6239ad98778020e8f31220cf93f6fe26e78409 /Source/FieldSolver/SpectralSolver/SpectralAlgorithms
parentf1fcac8a018c46fe0ae587469b2bf92862110f7a (diff)
downloadWarpX-e50f166a7e1cf517fe9383db6c59dbcae0fcea89.tar.gz
WarpX-e50f166a7e1cf517fe9383db6c59dbcae0fcea89.tar.zst
WarpX-e50f166a7e1cf517fe9383db6c59dbcae0fcea89.zip
Current correction in Fourier space (#675)
* Start implementing PSATD push without rho. TODO: 1) fix unit test pml_x_psatd; 2) try new PSATD push in PML; 3) avoid intro of new derived class? * Correct PSATD push to fix PML test. * Few improvements on new PSATD push: - new class name is 'PsatdAlgorithmMixed' (both rho and J are used); - new algorithm parameter to choose between available implementations: parameter name is 'psatd_push', possible values are 'standard' for old implementation using rho via Gauss law and continuity equation and 'mixed' for new implementation using rho via Gauss law and J for all remaining terms. * Fix style error (tabs vs four white spaces). * Improve comments for available PSATD algorithms. * Correct few typos in latest comments. * Implement first current correction: - new member function 'CurrentCorrection' in class SpectralSolver; - correction applied only without subcycling (in function 'OneStep_nosub'); - TODO: add correction when subcycling is used (in function 'OneStep_sub1'); - back to old implementation of PSATD push of E and B (class 'PsatdAlgorithmMixed' removed); - TODO: PML unit test 'pml_x_psatd' does not pass. * Small cleanup: - remove residual option for choice of PSATD push algorithm (only one choice now); - improve comments. * Implement div(E) diagnostics for spectral case. * split travis tests in bigger matrix * split more TravisCI tests, add electrostatic, use defaults values * typo * Move computation of div(E) to base class SpectralBaseAlgorithm. * need to split psatd too * consistent variable names and use function to avoid duplication * fix typo for qed tests * typo * also need to update run_tests.sg * Update copyright tags. * change matrix * Add test of div(E) vs rho/epsilon_0 in PML test. * Small clean-up. * Small clean-up * Remove option for current correction from input files of two new tests (not used) * Small clean-up: remove unnecessary references * More clean-up (minimize style changes to keep PR simple). * Add specific 2D/3D tests for current correction: - 'Langmuir_multi_2d_psatd_cc': same input file as 'Langmuir_multi_2d_psatd', except for current correction and output of divE; - 'Langmuir_multi_psatd_cc': same input file (3D) as 'Langmuir_multi_psatd', except for current correction and output of divE; - add corresponding Python scripts for analysis: same as previous ones, except for check on L-infinity spatial norm of rho/epsilon_0 vs div(E); - revert changes on old tests: do not use current correction in old tests (benchmarks on Battra do not need to be updated). * Improve comments. * Start implementation of new averaging with staggering: - face-to-cell-center and edge-to-cell-center replaced so far; - TODO: node-to-cell-center and 1D behavior (AMREX_SPACEDIM=1). * Remove unrelated style changes (cleaner PR). * Avoid duplication of input files and analysis scripts for new tests * Improve comments for Doxygen documentation. * Improve comments for Doxygen documentation. * Small clean-up * first implementation of Diags base classes * Small clean-up * Small clean-up * Fix erroneous non-ASCII character * Small clean-up * Auxiliary function for current correction in class WarpX to keep OneStep_nosub clean * Remove unrelated style changes (cleaner PR) * Improve comments * Instrument virtual function 'CurrentCorrection' * Trying to fix build error detected by LGTM analysis only * add example, temporarily * Continue implementation of new averaging with staggering: - new function takes reference to single MultiFab (no vector); - TODO: node-to-cell-center still in progress. * Fix small bug and clean up * Fix bug in loop over n=0,...,ncomp-1 and clean up * add more functions * Add Doxygen documentation and clean up * Small clean-up in Doxygen documentation * Compile in single precision: add _rt suffix to avoid unnecessary conversions * Avoid accessing staggering index directly from IntVect in innermost loops * Implement periodic-single box option for spectral * Fix out-of-bound in the periodic, single-box case * Replace do-while loop with for loop (default ncomp=1) * Remove temporary pointer and pass reference to MultiFab (instead of MultiFab*) * Replace AMREX_LAUNCH_HOST_DEVICE_LAMBDA with ParallelFor * cleaning and initialize output mf * use general average routine * move flush in new class, and implemented the Plotfile derived class * add comments * eol * free memory in destructor * typo * typo * no need to clear MF pointers there * though shalt not break existing tests * FlushRaw doesnt have to be virtual for now * The importance of being constant * Capability to select fields in output files * EOL * revert to old inputs * const in right place * avoid brace initializer there * oops, fix logic error in is_in * Use old name for output image of new 2D test * user can choose flush interval, same behavior as plot_int * Small clean-up in Doxygen documentation * Add option to plot raw fields * eol * replace ter flush with dump to avoid confusion * add options * Diagnostics stores a vector of functors to compute diags on the fly * eol * Field gather from diags to sync particle quantities * New diagnostics handle RZ with same behavior as old ones * cleaning and doc * const ref for string * smarter for loop from Axel and typo fix from Reva * Functors to compute some fields * simplify code following Dave's comments * Create subfolders and add more output options (divE etc.) * eol * Add documentation for periodic_single_box_fft * For periodic, single-box, apply current correction after guard cell exchange * rename mode_avg to convertRZmodes2cartesian * Update CellCenterFunctor.H * fill varnames and vector of functors at the same time * output rho_new, not rho_old * WarpX instance not needed here * add const * little bit more of reorganization * Travis CI: force 2 MPI processes only for numprocs > 2 * Use special FFT (PR #834) and new diagnostics (PR #844) in new tests * Improve Doxygen documentation * Move option do_current_correction from warpx to psatd * Fix path to output files for tests using new diagnostics * Fix additional paths to output files for new diagnostics * Add input paramter do_current_correction to documentation * Fix test Langmuir_multi_psatd_hybrid: do not plot divE * Remove input parameter amr.plot_int in tests using new diagnostics * Trigger failing source/style checks on Travis CI * Fix build error due to public include * Add missing const keywords * Change test names and corresponding analysis scripts * Improve Python script for analysis * Do not rename output files in old CI tests (without current correction) * Fix output file name prefix for some tests * Trigger Travis CI build after AMReX bug fix * Void commit: trigger Travis CI build * Fix some tests failing due to recent changes in master * Use new diagnostics for particle output correctly Co-authored-by: MaxThevenet <mthevenet@lbl.gov> * Print tolerance and error in Python analysis Co-authored-by: MaxThevenet <mthevenet@lbl.gov> * Print tolerance and error in Python analysis Co-authored-by: MaxThevenet <mthevenet@lbl.gov> * Improve documentation Co-authored-by: MaxThevenet <mthevenet@lbl.gov> * Fix EOL white spaces * Fix name of particle output variables Co-authored-by: MaxThevenet <mthevenet@lbl.gov> Co-authored-by: Remi Lehe <remi.lehe@normalesup.org>
Diffstat (limited to 'Source/FieldSolver/SpectralSolver/SpectralAlgorithms')
-rw-r--r--Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.H19
-rw-r--r--Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.cpp96
-rw-r--r--Source/FieldSolver/SpectralSolver/SpectralAlgorithms/SpectralBaseAlgorithm.H16
3 files changed, 126 insertions, 5 deletions
diff --git a/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.H b/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.H
index d71c0ab18..eb440d118 100644
--- a/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.H
+++ b/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.H
@@ -1,4 +1,4 @@
-/* Copyright 2019 Maxence Thevenet, Remi Lehe, Revathi Jambunathan
+/* Copyright 2019 Maxence Thevenet, Remi Lehe, Revathi Jambunathan, Edoardo Zoni
*
*
* This file is part of WarpX.
@@ -36,8 +36,25 @@ class PsatdAlgorithm : public SpectralBaseAlgorithm
const amrex::DistributionMapping& dm,
const amrex::Real dt);
+ /**
+ * \brief Virtual function for current correction in Fourier space
+ * (equation (19) of https://doi.org/10.1016/j.jcp.2013.03.010).
+ * This function overrides the virtual function \c CurrentCorrection in the
+ * base class \c SpectralBaseAlgorithm (qualifier \c override) and cannot be
+ * overridden by further derived classes (qualifier \c final).
+ *
+ * \param[in,out] field_data all fields in Fourier space
+ * \param[in,out] current three-dimensional array of unique pointers to MultiFab
+ * storing the three components of the current density
+ * \param[in] rho unique pointer to MultiFab storing the charge density
+ */
+ virtual void CurrentCorrection ( SpectralFieldData& field_data,
+ std::array<std::unique_ptr<amrex::MultiFab>,3>& current,
+ const std::unique_ptr<amrex::MultiFab>& rho ) override final;
+
private:
SpectralRealCoefficients C_coef, S_ck_coef, X1_coef, X2_coef, X3_coef;
+ amrex::Real m_dt;
};
#endif // WARPX_USE_PSATD
diff --git a/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.cpp b/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.cpp
index 8fee0967d..9684fde27 100644
--- a/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.cpp
+++ b/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/PsatdAlgorithm.cpp
@@ -1,11 +1,13 @@
-/* Copyright 2019 Remi Lehe, Revathi Jambunathan
+/* Copyright 2019 Remi Lehe, Revathi Jambunathan, Edoardo Zoni
*
* This file is part of WarpX.
*
* License: BSD-3-Clause-LBNL
*/
+#include "WarpX.H"
#include "PsatdAlgorithm.H"
#include "Utils/WarpXConst.H"
+#include "Utils/WarpXProfilerWrapper.H"
#include <cmath>
@@ -13,7 +15,9 @@
#if WARPX_USE_PSATD
using namespace amrex;
-/* \brief Initialize coefficients for the update equation */
+/**
+ * \brief Constructor
+ */
PsatdAlgorithm::PsatdAlgorithm(const SpectralKSpace& spectral_kspace,
const DistributionMapping& dm,
const int norder_x, const int norder_y,
@@ -31,11 +35,15 @@ PsatdAlgorithm::PsatdAlgorithm(const SpectralKSpace& spectral_kspace,
X2_coef = SpectralRealCoefficients(ba, dm, 1, 0);
X3_coef = SpectralRealCoefficients(ba, dm, 1, 0);
+ // Initialize coefficients for update equations
InitializeSpectralCoefficients(spectral_kspace, dm, dt);
+
+ m_dt = dt;
}
-/* Advance the E and B field in spectral space (stored in `f`)
- * over one time step */
+/**
+ * \brief Advance E and B fields in spectral space (stored in `f`) over one time step
+ */
void
PsatdAlgorithm::pushSpectralFields(SpectralFieldData& f) const{
@@ -120,6 +128,9 @@ PsatdAlgorithm::pushSpectralFields(SpectralFieldData& f) const{
}
};
+/**
+ * \brief Initialize coefficients for update equations
+ */
void PsatdAlgorithm::InitializeSpectralCoefficients(const SpectralKSpace& spectral_kspace,
const amrex::DistributionMapping& dm,
const amrex::Real dt)
@@ -179,4 +190,81 @@ void PsatdAlgorithm::InitializeSpectralCoefficients(const SpectralKSpace& spectr
});
}
}
+
+void
+PsatdAlgorithm::CurrentCorrection( SpectralFieldData& field_data,
+ std::array<std::unique_ptr<amrex::MultiFab>,3>& current,
+ const std::unique_ptr<amrex::MultiFab>& rho ) {
+ // Profiling
+ WARPX_PROFILE( "PsatdAlgorithm::CurrentCorrection" );
+
+ using Idx = SpectralFieldIndex;
+
+ // Forward Fourier transform of J and rho
+ field_data.ForwardTransform( *current[0], Idx::Jx, 0 );
+ field_data.ForwardTransform( *current[1], Idx::Jy, 0 );
+ field_data.ForwardTransform( *current[2], Idx::Jz, 0 );
+ field_data.ForwardTransform( *rho, Idx::rho_old, 0 );
+ field_data.ForwardTransform( *rho, Idx::rho_new, 1 );
+
+ // Loop over boxes
+ for (MFIter mfi(field_data.fields); mfi.isValid(); ++mfi){
+
+ const Box& bx = field_data.fields[mfi].box();
+
+ // Extract arrays for the fields to be updated
+ Array4<Complex> fields = field_data.fields[mfi].array();
+ // Extract pointers for the k vectors
+ const Real* const modified_kx_arr = modified_kx_vec[mfi].dataPtr();
+#if (AMREX_SPACEDIM==3)
+ const Real* const modified_ky_arr = modified_ky_vec[mfi].dataPtr();
+#endif
+ const Real* const modified_kz_arr = modified_kz_vec[mfi].dataPtr();
+
+ // Local copy of member variables before GPU loop
+ const Real dt = m_dt;
+
+ // Loop over indices within one box
+ ParallelFor(bx,
+ [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
+ {
+ // Record old values of the fields to be updated
+ using Idx = SpectralFieldIndex;
+ // Shortcuts for the values of J and rho
+ 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
+ constexpr Complex I = Complex{0,1};
+
+ const Real k_norm = std::sqrt( kx*kx + ky*ky + kz*kz );
+
+ // div(J) in Fourier space
+ const Complex k_dot_J = kx*Jx + ky*Jy + kz*Jz;
+
+ // Correct J
+ if ( k_norm != 0 )
+ {
+ fields(i,j,k,Idx::Jx) = Jx - (k_dot_J-I*(rho_new-rho_old)/dt)*kx/(k_norm*k_norm);
+ fields(i,j,k,Idx::Jy) = Jy - (k_dot_J-I*(rho_new-rho_old)/dt)*ky/(k_norm*k_norm);
+ fields(i,j,k,Idx::Jz) = Jz - (k_dot_J-I*(rho_new-rho_old)/dt)*kz/(k_norm*k_norm);
+ }
+ });
+ }
+
+ // Backward Fourier transform of J
+ field_data.BackwardTransform( *current[0], Idx::Jx, 0 );
+ field_data.BackwardTransform( *current[1], Idx::Jy, 0 );
+ field_data.BackwardTransform( *current[2], Idx::Jz, 0 );
+}
#endif // WARPX_USE_PSATD
diff --git a/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/SpectralBaseAlgorithm.H b/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/SpectralBaseAlgorithm.H
index 7ce774ab2..7143b7aa9 100644
--- a/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/SpectralBaseAlgorithm.H
+++ b/Source/FieldSolver/SpectralSolver/SpectralAlgorithms/SpectralBaseAlgorithm.H
@@ -32,6 +32,22 @@ class SpectralBaseAlgorithm
virtual ~SpectralBaseAlgorithm() {};
/**
+ * \brief Virtual function for current correction in Fourier space
+ * (equation (19) of https://doi.org/10.1016/j.jcp.2013.03.010).
+ * This virtual function is not pure: it can be overridden in derived
+ * classes (e.g. PsatdAlgorithm, PMLPsatdAlgorithm), but a base-class
+ * implementation is provided (empty implementation in this case).
+ *
+ * \param[in,out] field_data all fields in Fourier space
+ * \param[in,out] current three-dimensional array of unique pointers to MultiFab
+ * storing the three components of the current density
+ * \param[in] rho unique pointer to MultiFab storing the charge density
+ */
+ virtual void CurrentCorrection ( SpectralFieldData& field_data,
+ std::array<std::unique_ptr<amrex::MultiFab>,3>& current,
+ const std::unique_ptr<amrex::MultiFab>& rho ) {};
+
+ /**
* \brief Compute spectral divergence of E
*/
void ComputeSpectralDivE ( SpectralFieldData& field_data,