WarpX
Loading...
Searching...
No Matches
SingleLinearComptonCollisionEvent.H
Go to the documentation of this file.
1/* Copyright 2023 Arianna Formenti
2 *
3 * This file is part of WarpX.
4 *
5 * License: BSD-3-Clause-LBNL
6 */
7
8#ifndef SINGLE_LINEAR_COMPTON_COLLISION_EVENT_H_
9#define SINGLE_LINEAR_COMPTON_COLLISION_EVENT_H_
10
12#include "Utils/WarpXConst.H"
13
14#include <AMReX_Algorithm.H>
15#include <AMReX_Random.H>
16#include <AMReX_REAL.H>
17
18#include <cmath>
19
20
47template <typename index_type>
49void SingleLinearComptonCollisionEvent (const amrex::ParticleReal& u1x, const amrex::ParticleReal& u1y,
50 const amrex::ParticleReal& u1z, const amrex::ParticleReal& u2x,
51 const amrex::ParticleReal& u2y, const amrex::ParticleReal& u2z,
52 amrex::ParticleReal w1, amrex::ParticleReal w2,
53 const amrex::Real& dt, const amrex::ParticleReal& dV, const int& pair_index,
54 index_type* AMREX_RESTRICT p_mask,
55 amrex::ParticleReal* AMREX_RESTRICT p_pair_reaction_weight,
56 const amrex::ParticleReal& event_multiplier,
57 const int& multiplier_ratio,
58 const amrex::ParticleReal& probability_threshold,
59 const amrex::ParticleReal& probability_target_value,
60 const amrex::RandomEngine& engine)
61{
62 using namespace amrex::literals;
63 constexpr amrex::ParticleReal inv_c = 1._prt / PhysConst::c;
64 constexpr amrex::ParticleReal inv_c_sq = inv_c * inv_c;
65
66 const amrex::ParticleReal w_min = amrex::min(w1, w2);
67 const amrex::ParticleReal w_max = amrex::max(w1, w2);
68
69 // When checking the user input, we ensure that the first particle is the photon
70 // and the second particle is the lepton (electron/positron).
71 // The cross-section is computed in the rest frame of the lepton.
72
73 // Lepton's Lorentz factor
74 const amrex::ParticleReal gamma_lepton = std::sqrt(1._prt + (u2x*u2x + u2y*u2y + u2z*u2z)*inv_c_sq);
75 // Photon's normalized momentum in the lab frame
76 amrex::ParticleReal const u1_norm = std::sqrt(u1x*u1x + u1y*u1y + u1z*u1z);
77 // Photon's normalized momentum in the rest frame of the lepton
78 // (obtained from the fact that the product of the photon and lepton's 4-momenta is invariant)
79 const amrex::ParticleReal u1_norm_rest = u1_norm * gamma_lepton - (u1x*u2x + u1y*u2y + u1z*u2z)*inv_c;
80 // Factor that converts collision rate from rest frame to lab frame: ration of energies in rest frame and lab frame
81 // (See L. D. Landau and E. M. Lifshitz. The classical theory of fields, Eq. 12.5, 12.6)
82 const amrex::ParticleReal lab_to_rest_frame_factor = u1_norm_rest * 1._prt / (u1_norm * gamma_lepton);
83 // sqrt( | v1 - v2 |^2 - | v1 x v2 |^2/c^2 ) evaluated in the rest frame
84 const amrex::ParticleReal v_rel = PhysConst::c;
85
86
87 // Calculate the Klein-Nishina cross-section (cross-section in the rest frame of the lepton)
88 const amrex::ParticleReal k = u1_norm_rest * inv_c;
89 // By convention, in WarpX, the photon momentum u is normalized by the electron mass m_e, so k corresponds to p/(m_e*c)
90 const amrex::ParticleReal f1 = 2._prt * ( 2._prt + k*(1._prt+k)*(8._prt+k) ) / ( k*k * (1._prt + 2._prt*k)*(1._prt + 2._prt*k) );
91 const amrex::ParticleReal f2 = ( 2._prt + k*(2._prt-k) ) * std::log( 1._prt + 2._prt*k ) / (k*k*k);
92 const amrex::ParticleReal klein_nishina_cross_section = MathConst::pi * PhysConst::r_e * PhysConst::r_e * ( f1 - f2 );
93
94 // First estimate of probability for scattering
95 // (Convert from rest frame to lab frame, using lab_to_rest_frame_factor)
96 amrex::ParticleReal probability_estimate = multiplier_ratio * event_multiplier *
97 lab_to_rest_frame_factor * w_max * klein_nishina_cross_section * v_rel * dt / dV;
98
99 // Effective event multiplier
100 amrex::ParticleReal event_multiplier_eff = event_multiplier;
101
102 // If the scattering probability is too high and the event multiplier greater than one,
103 // we risk to systematically underestimate the Compton scattering yield. In this case,
104 // we reduce the event multiplier to reduce the scattering probability
105 if (probability_estimate > probability_threshold)
106 {
107 // We aim for a scattering probability of probability_target_value but take into account
108 // the constraint that the event_multiplier cannot be smaller than one
109 event_multiplier_eff = amrex::max(event_multiplier *
110 probability_target_value / probability_estimate , 1._prt);
111 probability_estimate *= event_multiplier_eff/event_multiplier;
112 }
113
114 // Compute actual scattering probability that is always between zero and one
115 // In principle this is obtained by computing 1 - exp(-probability_estimate)
116 // However, the computation of this quantity can fail numerically when probability_estimate is
117 // too small (e.g. exp(-probability_estimate) returns 1 and the computation returns 0).
118 // In this case, we simply use "probability_estimate" instead of 1 - exp(-probability_estimate)
119 const amrex::ParticleReal probability = -std::expm1(-probability_estimate);
120
121 // Get a random number
122 const amrex::ParticleReal random_number = amrex::Random(engine);
123
124 // If we have a scattering event, set the mask to true and fill the product weight array
125 if (random_number < probability)
126 {
127 p_mask[pair_index] = true;
128 p_pair_reaction_weight[pair_index] = w_min/event_multiplier_eff;
129 }
130 else
131 {
132 p_mask[pair_index] = false;
133 }
134}
135
136#endif // SINGLE_LINEAR_COMPTON_COLLISION_EVENT_H_
#define AMREX_RESTRICT
#define AMREX_INLINE
#define AMREX_GPU_HOST_DEVICE
AMREX_GPU_HOST_DEVICE AMREX_INLINE void SingleLinearComptonCollisionEvent(const amrex::ParticleReal &u1x, const amrex::ParticleReal &u1y, const amrex::ParticleReal &u1z, const amrex::ParticleReal &u2x, const amrex::ParticleReal &u2y, const amrex::ParticleReal &u2z, amrex::ParticleReal w1, amrex::ParticleReal w2, const amrex::Real &dt, const amrex::ParticleReal &dV, const int &pair_index, index_type *AMREX_RESTRICT p_mask, amrex::ParticleReal *AMREX_RESTRICT p_pair_reaction_weight, const amrex::ParticleReal &event_multiplier, const int &multiplier_ratio, const amrex::ParticleReal &probability_threshold, const amrex::ParticleReal &probability_target_value, const amrex::RandomEngine &engine)
This function computes whether the collision between a photon and lepton results in a scattering even...
Definition SingleLinearComptonCollisionEvent.H:49
static constexpr auto r_e
classical electron radius = 1./(4*pi*ep0) * q_e*q_e/(m_e*c*c) [m]
Definition constant.H:67
static constexpr auto c
vacuum speed of light [m/s]
Definition constant.H:44
static constexpr amrex::Real pi
ratio of a circle's circumference to its diameter
Definition constant.H:23
Real Random()
__host__ __device__ constexpr const T & min(const T &a, const T &b) noexcept
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept