aboutsummaryrefslogtreecommitdiff
path: root/Source/QED/QuantumSyncEngineWrapper.H
diff options
context:
space:
mode:
Diffstat (limited to 'Source/QED/QuantumSyncEngineWrapper.H')
-rw-r--r--Source/QED/QuantumSyncEngineWrapper.H266
1 files changed, 256 insertions, 10 deletions
diff --git a/Source/QED/QuantumSyncEngineWrapper.H b/Source/QED/QuantumSyncEngineWrapper.H
index a285dc8b6..1a6ffe4f3 100644
--- a/Source/QED/QuantumSyncEngineWrapper.H
+++ b/Source/QED/QuantumSyncEngineWrapper.H
@@ -2,18 +2,45 @@
#define WARPX_quantum_sync_engine_wrapper_h_
#include "QedWrapperCommons.H"
+#include "QuantumSyncEngineInnards.H"
-//QS ENGINE from PICSAR
+#include <AMReX_Array.H>
+#include <AMReX_Vector.H>
+#include <AMReX_Gpu.H>
+
+//#define PXRMP_CORE_ONLY allows importing only the 'core functions' of the
+//Quantum Synchrotron engine of the QED PICSAR library.
#define PXRMP_CORE_ONLY
-#include "quantum_sync_engine.hpp"
+#include <quantum_sync_engine.hpp>
+
+//Lookup table building function is in a dedicated (optional) class to
+//avoid including heavy dependencies if they are not needed.
+#ifdef WARPX_QED_TABLE_GEN
+ #include "QuantumSyncEngineTableBuilder.H"
+#endif
+
+#include <string>
+
+//Some handy aliases
+
+// The engine has two templated arguments: the numerical type
+// and a random number generator. However, random numbers are not
+// used to generate the lookup tables and the static member
+// functions which are called in the functors do not use
+// random numbers as well. Therefore, an empty "DummyStruct"
+// can be passed as a template parameter.
+using PicsarQuantumSynchrotronEngine = picsar::multi_physics::
+ quantum_synchrotron_engine<amrex::Real, QedUtils::DummyStruct>;
-using WarpXQuantumSynchrotronWrapper =
- picsar::multi_physics::quantum_synchrotron_engine<amrex::Real, DummyStruct>;
+using PicsarQuantumSynchrotronCtrl =
+ picsar::multi_physics::quantum_synchrotron_engine_ctrl<amrex::Real>;
+//__________
// Functors ==================================
-// These functors provide the core elementary functions of the library
-// Can be included in GPU kernels
+// These functors allow using the core elementary functions of the library.
+// They are generated by a factory class (QuantumSynchrotronEngine, see below).
+// They can be included in GPU kernels.
/**
* Functor to initialize the optical depth of leptons for the
@@ -22,33 +49,252 @@ using WarpXQuantumSynchrotronWrapper =
class QuantumSynchrotronGetOpticalDepth
{
public:
+ /**
+ * Constructor does nothing because optical depth initialization
+ * does not require control parameters or lookup tables.
+ */
QuantumSynchrotronGetOpticalDepth ()
{};
+ /**
+ * () operator is just a thin wrapper around a very simple function to
+ * generate the optical depth. It can be used on GPU.
+ */
AMREX_GPU_DEVICE
AMREX_FORCE_INLINE
- amrex::Real operator() () const
+ amrex::Real operator() () const noexcept
{
- return WarpXQuantumSynchrotronWrapper::
+ //A random number in [0,1) should be provided as an argument.
+ return PicsarQuantumSynchrotronEngine::
internal_get_optical_depth(amrex::Random());
}
};
//____________________________________________
+/**
+ * Functor to evolve the optical depth of leptons due to the
+ * Quantum Synchrotron process
+ */
+class QuantumSynchrotronEvolveOpticalDepth
+{
+public:
+ /**
+ * Constructor acquires a reference to control parameters and
+ * lookup tables data.
+ * lookup_table uses non-owning vectors under the hood. So no new data
+ * allocations should be triggered on GPU
+ */
+ QuantumSynchrotronEvolveOpticalDepth(
+ QuantumSynchrotronEngineInnards& r_innards):
+ m_ctrl{r_innards.ctrl},
+ m_KKfunc_size{r_innards.KKfunc_coords.size()},
+ m_p_KKfunc_coords{r_innards.KKfunc_coords.dataPtr()},
+ m_p_KKfunc_data{r_innards.KKfunc_data.dataPtr()}
+ {};
+
+ /**
+ * Evolves the optical depth. It can be used on GPU.
+ * @param[in] px,py,pz momentum components of the lepton (SI units)
+ * @param[in] ex,ey,ez electric field components (SI units)
+ * @param[in] bx,by,bz magnetic field components (SI units)
+ * @param[in] dt timestep (SI units)
+ * @param[in,out] opt_depth optical depth of the lepton. It is modified by the method.
+ * @return a flag which is 1 if optical depth becomes negative (i.e. a photon has to be generated).
+ */
+ AMREX_GPU_DEVICE
+ AMREX_FORCE_INLINE
+ int operator()(
+ amrex::Real px, amrex::Real py, amrex::Real pz,
+ amrex::Real ex, amrex::Real ey, amrex::Real ez,
+ amrex::Real bx, amrex::Real by, amrex::Real bz,
+ amrex::Real dt, amrex::Real& opt_depth) const noexcept
+ {
+ bool has_event_happened{false};
+
+ //the library provides the time (< dt) at which the event occurs, but this
+ //feature won't be used in WarpX for now.
+ amrex::Real unused_event_time{0.0};
+
+ PicsarQuantumSynchrotronEngine::
+ internal_evolve_opt_depth_and_determine_event(
+ px, py, pz,
+ ex, ey, ez,
+ bx, by, bz,
+ dt, opt_depth,
+ has_event_happened, unused_event_time,
+ m_dummy_lambda,
+ picsar::multi_physics::lookup_1d<amrex::Real>{
+ m_KKfunc_size,
+ m_p_KKfunc_coords,
+ m_p_KKfunc_data},
+ m_ctrl);
+
+ return has_event_happened;
+ }
+
+private:
+ //laser wavelenght is not used with SI units
+ const amrex::Real m_dummy_lambda{1.0};
+
+ const PicsarQuantumSynchrotronCtrl m_ctrl;
+
+ //lookup table data
+ size_t m_KKfunc_size;
+ amrex::Real* m_p_KKfunc_coords;
+ amrex::Real* m_p_KKfunc_data;
+};
+
+/**
+ * Functor to generate a photon via the Quantum Synchrotron process
+ * and to update momentum accordingly
+ */
+class QuantumSynchrotronGeneratePhotonAndUpdateMomentum
+{
+public:
+ /**
+ * Constructor acquires a reference to control parameters and
+ * lookup tables data.
+ * lookup_table uses non-owning vectors under the hood. So no new data
+ * allocations should be triggered on GPU
+ */
+ QuantumSynchrotronGeneratePhotonAndUpdateMomentum(
+ QuantumSynchrotronEngineInnards& r_innards):
+ m_ctrl{r_innards.ctrl},
+ m_cum_distrib_coords_1_size{r_innards.cum_distrib_coords_1.size()},
+ m_cum_distrib_coords_2_size{r_innards.cum_distrib_coords_2.size()},
+ m_p_distrib_coords_1{r_innards.cum_distrib_coords_1.data()},
+ m_p_distrib_coords_2{r_innards.cum_distrib_coords_2.data()},
+ m_p_cum_distrib_data{r_innards.cum_distrib_data.data()}
+ {};
+
+ /**
+ * Generates sampling (template parameter) photons according to Quantum Synchrotron process.
+ * It can be used on GPU.
+ * @param[in,out] px,py,pz momentum components of the lepton. They are modified (SI units)
+ * @param[in] ex,ey,ez electric field components (SI units)
+ * @param[in] bx,by,bz magnetic field components (SI units)
+ * @param[in] weight of the lepton (code units)
+ * @param[out] g_px,g_py,g_pz momenta of generated photons. Each array should have size=sampling (SI units)
+ * @param[out] g_weight weight of the generated photons. Array should have size=sampling (code units)
+ */
+ template <size_t sampling>
+ AMREX_GPU_DEVICE
+ AMREX_FORCE_INLINE
+ void operator()(
+ amrex::Real* px, amrex::Real* py, amrex::Real* pz,
+ amrex::Real ex, amrex::Real ey, amrex::Real ez,
+ amrex::Real bx, amrex::Real by, amrex::Real bz,
+ amrex::Real weight,
+ amrex::Real* g_px, amrex::Real* g_py, amrex::Real* g_pz,
+ amrex::Real* g_weight) const noexcept
+ {
+ //[sampling] random numbers are needed
+ amrex::GpuArray<amrex::Real, sampling>
+ rand_zero_one_minus_epsi;
+ for(auto& el : rand_zero_one_minus_epsi) el = amrex::Random();
+
+ PicsarQuantumSynchrotronEngine::
+ internal_generate_photons_and_update_momentum(
+ *px, *py, *pz,
+ ex, ey, ez,
+ bx, by, bz,
+ weight, sampling,
+ g_px, g_py, g_pz,
+ g_weight,
+ m_dummy_lambda,
+ picsar::multi_physics::lookup_2d<amrex::Real>{
+ m_cum_distrib_coords_1_size,
+ m_p_distrib_coords_1,
+ m_cum_distrib_coords_2_size,
+ m_p_distrib_coords_2,
+ m_p_cum_distrib_data},
+ m_ctrl,
+ rand_zero_one_minus_epsi.data());
+ }
+
+private:
+ //laser wavelenght is not used with SI units
+ const amrex::Real m_dummy_lambda{1.0};
+
+ const PicsarQuantumSynchrotronCtrl m_ctrl;
+
+ //lookup table data
+ size_t m_cum_distrib_coords_1_size;
+ size_t m_cum_distrib_coords_2_size;
+ amrex::Real* m_p_distrib_coords_1;
+ amrex::Real* m_p_distrib_coords_2;
+ amrex::Real* m_p_cum_distrib_data;
+};
+
// Factory class =============================
/**
- * \brief Wrapper for the Quantum Synchrotron engine of the PICSAR library
+ * Wrapper for the Quantum Synchrotron engine of the PICSAR library
*/
class QuantumSynchrotronEngine
{
public:
+ /**
+ * Constructor requires no arguments.
+ */
QuantumSynchrotronEngine ();
/**
- * \brief Builds the functor to initialize the optical depth
+ * Builds the functor to initialize the optical depth
*/
QuantumSynchrotronGetOpticalDepth build_optical_depth_functor ();
+
+ /**
+ * Builds the functor to evolve the optical depth
+ */
+ QuantumSynchrotronEvolveOpticalDepth build_evolve_functor ();
+
+ /**
+ * Builds the functor to generate photons
+ */
+ QuantumSynchrotronGeneratePhotonAndUpdateMomentum build_phot_em_functor ();
+
+ /**
+ * Checks if the optical tables are properly initialized
+ */
+ bool are_lookup_tables_initialized () const;
+
+ /**
+ * Init lookup tables from raw binary data.
+ * @param[in] raw_data a Vector of char
+ * @return true if it succeeds, false if it cannot parse raw_data
+ */
+ bool init_lookup_tables_from_raw_data (const amrex::Vector<char>& raw_data);
+
+ /**
+ * Export lookup tables data into a raw binary Vector
+ * @return the data in binary format. The Vector is empty if tables were
+ * not previously initialized.
+ */
+ amrex::Vector<char> export_lookup_tables_data () const;
+
+ /**
+ * Computes the lookup tables. It does nothing unless WarpX is compiled with QED_TABLE_GEN=TRUE
+ * @param[in] ctrl control params to generate the tables
+ */
+ void compute_lookup_tables (PicsarQuantumSynchrotronCtrl ctrl);
+
+ /**
+ * gets default (reasonable) values for the control parameters
+ * @return default control params to generate the tables
+ */
+ PicsarQuantumSynchrotronCtrl get_default_ctrl() const;
+
+private:
+ bool m_lookup_tables_initialized = false;
+
+ QuantumSynchrotronEngineInnards m_innards;
+
+//Table builing is available only if the libray is compiled with QED_TABLE_GEN=TRUE
+#ifdef WARPX_QED_TABLE_GEN
+ QuantumSynchrotronEngineTableBuilder m_table_builder;
+#endif
+
};
//============================================