|
8 | 8 | #include "utils/error.h" |
9 | 9 | #include "utils/numeric.h" |
10 | 10 |
|
| 11 | +#include "framework/containers/particles.h" |
11 | 12 |
|
12 | 13 | namespace kernel::QED{ |
13 | 14 | using namespace ntt; |
14 | | - |
| 15 | + |
| 16 | + template <Dimension D, Coord::type C> |
15 | 17 | class CurvatureEmission_kernel{ |
16 | | - array_t<real_t*> ux1, ux2, ux3; |
17 | | - array_t<int*> i1; |
18 | | - array_t<prtldx_t*> dx1; |
19 | | - array_t<real_t*> weight; |
20 | | - array_t<short*> tag; |
21 | | - array_t<real_t*> ux1_ph, ux2_ph, ux3_ph; |
22 | | - arrat_t<int*> i1_ph; |
23 | | - array_t<prtldx_t*> dx1_ph; |
24 | | - array_t<real_t*> weight_ph; |
25 | | - array_t<short*> tag_ph; |
26 | | - const real_t p_min; |
| 18 | + static_assert(D == Dim::_1D, "Curvature emission is only implemented in 1D"); |
| 19 | + static_assert(C == Coord::Cart, "Curvature emission is only implemented in cartesian coordinates"); |
| 20 | + |
| 21 | + Particles<D, C> spec; |
| 22 | + Particles<D, C> spec_ph; |
27 | 23 | const real_t e_min; |
28 | | - const real_t coeff_cdf; |
29 | | - const short Nmax_ph; |
30 | | - const short Nbin; |
31 | | - const short res_cdf; |
32 | | - const real_t dzeta; |
33 | | - array_t<real_t*> cdf_table; |
| 24 | + const real_t coeff; |
34 | 25 | const real_t gamma_emit; |
35 | | - const real_t gamma_rad; |
36 | | - const real_t gamma_pc; |
37 | 26 | const real_t rho; |
38 | 27 | random_number_pool_t random_pool; |
39 | 28 |
|
40 | 29 |
|
41 | 30 | public: |
42 | | - CurvatureEmission_kernel() = default; |
| 31 | + CurvatureEmission_kernel(Particles<D, C>& spec_, |
| 32 | + Particles<D, C>& spec_ph_, |
| 33 | + const real_t e_min_, |
| 34 | + const real_t coeff_, |
| 35 | + const real_t gamma_emit_, |
| 36 | + const real_t rho_, |
| 37 | + random_number_pool_t& random_pool_) |
| 38 | + : spec(spec_), |
| 39 | + spec_ph(spec_ph_), |
| 40 | + e_min(e_min_), |
| 41 | + coeff(coeff_), |
| 42 | + gamma_emit(gamma_emit_), |
| 43 | + rho(rho_), |
| 44 | + random_pool(random_pool_){ |
| 45 | + if (spec.charge() == 0){ |
| 46 | + raise::KernelError(HERE, "The first species must be charged."); |
| 47 | + } |
| 48 | + if (spec_ph.mass()!= 0){ |
| 49 | + raise::KernelError(HERE, "The second species must be photon."); |
| 50 | + } |
| 51 | + } |
43 | 52 | ~CurvatureEmission_kernel() = default; |
44 | 53 |
|
45 | 54 | Inline auto CDF(real_t zeta_) const -> real_t{ |
46 | | - return ONE - math::exp(-zeta_); |
| 55 | + return math::exp(-zeta_); |
47 | 56 | } |
48 | 57 |
|
49 | 58 | Inline auto inverseCDF(real_t u) const -> real_t{ |
50 | | - return -math::log(ONE - u); |
51 | | - } |
52 | | - |
53 | | - Inline auto rand_uniform(short mean) const -> short{ |
54 | | - auto rand_gen = random_pool.get_state(); |
55 | | - return static_cast<short>(mean * TWO * Random<real_t>(rand_gen)); |
| 59 | + return -math::log(u); |
56 | 60 | } |
57 | 61 |
|
58 | | - Inline void sample_photon(short N, |
59 | | - real_t zeta_, |
60 | | - array_t<real_t*> ux1_ph_, |
61 | | - array_t<real_t*> ux2_ph_, |
62 | | - array_t<real_t*> ux3_ph_, |
63 | | - array_t<int*> i1_ph_, |
64 | | - array_t<prtldx_t*> dx1_ph_, |
65 | | - array_t<real_t*> weight_ph_, |
66 | | - array_t<short*> tag_ph_) const; |
67 | | - |
68 | 62 | void operator()(index_t p) const{ |
69 | 63 | if(tag(p) != ParticleTag::alive){ |
70 | 64 | if(tag(p) != ParticleTag::dead){ |
71 | 65 | raise::KernelError(HERE, "Invalid particle tag in pusher"); |
72 | 66 | } |
73 | 67 | return; |
74 | 68 | } |
75 | | - const real_t pp = math::sqrt(ONE + NORM_SQR(ux1(p), ux2(p), ux3(p))); |
76 | | - //if particle energy is less than p_min, no emission |
77 | | - if(pp < p_min){ |
78 | | - return; |
79 | | - } |
| 69 | + const real_t pp = math::sqrt(ONE + NORM_SQR(spec.ux1(p), spec.ux2(p), spec.ux3(p))); |
80 | 70 | const real_t zeta = e_min * rho * CUBE(gamma_emit / pp); |
81 | | - auto N_ph = static_cast<short>(coeff_cdf * CDF(zeta) / SQR(pp)); |
| 71 | + auto N_ph = static_cast<size_t>(coeff * CDF(zeta) / SQR(pp)); |
82 | 72 | //if N_ph is less than 1, no emission. |
83 | 73 | if (N_ph < 1){ |
84 | 74 | return; |
85 | 75 | } |
86 | | - sample_photon(N_ph, zeta, ux1_ph, ux2_ph, ux3_ph, i1_ph, dx1_ph, weight_ph, tag_ph); |
| 76 | + auto n_ph = spec_ph.npart(); |
| 77 | + spec_ph.set_npart(n_ph + N_ph); |
| 78 | + for (short i = 0; i < N_ph; ++i){ |
| 79 | + auto rand_gen = random_pool.get_state(); |
| 80 | + |
| 81 | + spec_ph.ux1(n_ph + i) = SIGN(spec.ux1(p)) * ONE; |
| 82 | + spec_ph.pld(n_ph + i) = inverseCDF(CDF(zeta) * Random<real_t>(rand_gen)) |
| 83 | + * CUBE(pp / gamma_emit) / rho; |
| 84 | + spec_ph.i1(n_ph + i) = spec.i1(p); |
| 85 | + spec_ph.dx1(n_ph + i) = spec.dx1(p); |
| 86 | + spec_ph.weight(n_ph + i) = spec.weight(p); |
| 87 | + spec_ph.tag(n_ph + i) = ParticleTag::alive; |
| 88 | + |
| 89 | + random_pool.free_state(rand_gen); |
| 90 | + } |
87 | 91 | } |
88 | 92 | }; |
89 | 93 | } // namespace QED |
|
0 commit comments