Garfield++ 5.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
HeedParticle_BGM.cpp
Go to the documentation of this file.
1#include <iomanip>
2#include <numeric>
12
13// 2003-2008, I. Smirnov
14
15namespace Heed {
16
17using CLHEP::c_light;
18using CLHEP::c_squared;
19using CLHEP::cm;
20using CLHEP::MeV;
21using CLHEP::electron_mass_c2;
22
24 const vec& vel, vfloat ftime,
25 particle_def* fpardef,
26 HeedFieldMap* fieldmap,
27 const bool floss_only,
28 const bool fprint_listing)
29 : eparticle(primvol, pt, vel, ftime, fpardef, fieldmap),
30 m_print_listing(fprint_listing),
31 m_loss_only(floss_only),
32 m_particle_number(s_counter++) {}
33
34void HeedParticle_BGM::physics(std::vector<gparticle*>& secondaries) {
35 mfunname("void HeedParticle_BGM::physics()");
36 if (m_print_listing) {
37 mcout << "HeedParticle_BGM::physics is started\n";
38 Iprintn(mcout, m_currpos.prange);
39 }
40 // Get the step.
41 if (m_currpos.prange <= 0.0) return;
42 const double stp = m_currpos.prange / cm;
43 const vec dir = unit_vec(m_currpos.pt - m_prevpos.pt);
44 // This approximation ignores curvature
45 const double range = (m_currpos.pt - m_prevpos.pt).length();
46 if (m_print_listing) Iprint3n(mcout, m_prevpos.pt, dir, range);
47 // Get local volume.
48 const absvol* av = m_currpos.volume();
49 auto etcs = dynamic_cast<const EnTransfCS_BGM*>(av);
50 if (!etcs) return;
51 HeedMatterDef* hmd = etcs->hmd;
52 MatterDef* matter = hmd->matter;
53 EnergyMesh* emesh = hmd->energy_mesh;
54 const double* aetemp = hmd->energy_mesh->get_ae();
55 PointCoorMesh<double, const double*> pcm_e(emesh->get_q() + 1, &(aetemp));
56 // Particle mass, energy and momentum.
57 const double mp = m_mass * c_squared;
58 const double ep = mp + m_curr_ekin;
59 const double bg = sqrt(m_curr_gamma_1 * (m_curr_gamma_1 + 2.0));
60 // Electron mass.
61 const double mt = electron_mass_c2;
62 // Particle velocity.
63 const double invSpeed = 1. / m_prevpos.speed;
65 &(etcs->mesh->x));
66 long n1, n2;
67 double b1, b2;
68 int s_ret = pcm.get_interval(bg, n1, b1, n2, b2);
69 if (s_ret != 1) {
70 mcerr << "ERROR in void HeedParticle_BGM::physics()\n";
71 mcerr << "beta*gamma is outside range of cross-section table\n";
72 std::streamsize old_prec = mcerr.precision(15);
74 mcerr.precision(old_prec);
75 Iprint2n(mcerr, n1, n2);
76 Iprint2n(mcerr, b1, b2);
77 Iprintn(mcerr, etcs->mesh);
78 mcerr << "This particle is:\n";
79 print(mcerr, 2);
80 mcerr << "This volume is:\n";
81 av->print(mcerr, 2);
83 return;
84 }
85
86 const double f2 = (bg - b1) * (b2 - b1);
87 const double f1 = 1. - f2;
88 const long qa = matter->qatom();
89 if (m_print_listing) Iprintn(mcout, qa);
90 basis tempbas(m_currpos.dir, "tempbas");
91 // Shorthand.
92 const auto sampleTransfer = t_hisran_step_ar<double, std::vector<double>,
94 for (long na = 0; na < qa; ++na) {
95 if (m_print_listing) Iprintn(mcout, na);
96 long qs = hmd->apacs[na]->get_qshell();
97 for (long ns = 0; ns < qs; ++ns) {
98 if (m_print_listing) Iprintn(mcout, ns);
99 const double y1 = etcs->etcs_bgm[n1].quan[na][ns];
100 const double y2 = etcs->etcs_bgm[n2].quan[na][ns];
101 const double mean_pois = f1 * y1 + f2 * y2;
102 if (mean_pois <= 0.) continue;
103 const long qt = pois(mean_pois * stp);
104 if (m_print_listing) Iprintn(mcout, qt);
105 if (qt <= 0) continue;
106 for (long nt = 0; nt < qt; nt++) {
107 // Sample the energy transfer in this collision.
108 const double rn = SRANLUX();
109 const double r1 = sampleTransfer(pcm_e, etcs->etcs_bgm[n1].fadda[na][ns], rn);
110 const double r2 = sampleTransfer(pcm_e, etcs->etcs_bgm[n2].fadda[na][ns], rn);
111 const double r = f1 * r1 + f2 * r2;
112 if (m_print_listing) {
113 Iprintn(mcout, rn);
114 Iprint3n(mcout, r1, r2, r);
115 }
116 // Convert to internal units.
117 const double et = r * MeV;
118 m_edep += et;
119 if (m_print_listing) Iprint2n(mcout, nt, et);
120 // Sample the position of the collision.
121 const double arange = SRANLUX() * range;
122 point pt = m_prevpos.pt + dir * arange;
123 if (m_loss_only) continue;
124 if (m_print_listing) mcout << "generating new cluster\n";
125 m_clusterBank.push_back(HeedCluster(et, pt, na, ns));
126 // Generate a virtual photon.
127 double theta_p, theta_t;
128 theta_two_part(ep, ep - et, mp, mt, theta_p, theta_t);
129 vec vel;
130 vel.random_conic_vec(fabs(theta_t));
131 vel.down(&tempbas); // direction is OK
132 vel *= c_light;
133 const double t = m_prevpos.time + arange * invSpeed;
134 if (m_print_listing) mcout << "generating new virtual photon\n";
135 HeedPhoton* hp = new HeedPhoton(m_currpos.tid.eid[0], pt, vel, t,
136 m_particle_number, et, m_fieldMap);
137 if (!hp->alive()) {
138 delete hp;
139 continue;
140 }
141 hp->m_photon_absorbed = true;
142 hp->m_delta_generated = false;
143 hp->m_na_absorbing = na;
144 hp->m_ns_absorbing = ns;
145 secondaries.push_back(hp);
146 }
147 }
148 }
149 if (m_edep >= m_curr_ekin) {
150 // Accumulated energy loss exceeds the particle's kinetic energy.
151 m_alive = false;
152 }
153
154 if (m_print_listing) {
155 Iprintn(mcout, m_edep);
156 mcout << "Exiting HeedParticle_BGM::physics\n";
157 }
158}
159
160void HeedParticle_BGM::print(std::ostream& file, int l) const {
161 if (l < 0) return;
162 Ifile << "HeedParticle_BGM (l=" << l
163 << "): particle_number=" << m_particle_number << " type=";
164 if (!m_pardef) {
165 file << "none";
166 } else {
167 file << m_pardef->notation;
168 }
169 file << std::endl;
170 if (l == 1) return;
171 mparticle::print(file, l - 1);
172 Iprintn(mcout, m_edep);
173}
174}
#define spexit(stream)
#define mfunname(string)
long qatom() const
Definition AtomDef.h:101
Energy transfer cross-section.
const double * get_ae(void) const
Return all left sides.
Definition EnergyMesh.h:52
long get_q() const
Return number of bins.
Definition EnergyMesh.h:42
Retrieve electric and magnetic field from Sensor.
std::vector< const AtomPhotoAbsCS * > apacs
EnergyMesh * energy_mesh
HeedParticle_BGM()
Default constructor.
void print(std::ostream &file, int l) const override
Print-out.
void physics(std::vector< gparticle * > &secondaries) override
Apply any other processes (turn the trajectory, kill the particle, ...).
long m_na_absorbing
Index of absorbing atom.
Definition HeedPhoton.h:41
long m_ns_absorbing
Index of absorbing shell.
Definition HeedPhoton.h:43
bool m_delta_generated
Flag that delta-electrons are already generated (or cannot be created).
Definition HeedPhoton.h:50
virtual int get_interval(long n, T &b1, T &b2) const
Definition tline.h:401
virtual void print(std::ostream &file, int l) const
Definition volume.cpp:120
Basis.
Definition vec.h:313
particle_def * m_pardef
Definition eparticle.h:32
eparticle()=default
Default constructor.
HeedFieldMap * m_fieldMap
Pointer to field map.
Definition eparticle.h:34
stvpoint m_prevpos
Previous point.
Definition gparticle.h:274
bool alive() const
Alive?
Definition gparticle.h:195
stvpoint m_currpos
Current point.
Definition gparticle.h:276
bool m_alive
Status flag whether the particle is active.
Definition gparticle.h:259
static std::atomic< long > s_counter
Instance counter.
Definition gparticle.h:256
Abstract base classs for volume "manipulators".
Definition volume.h:128
double m_curr_ekin
Current kinetic energy.
Definition mparticle.h:73
void print(std::ostream &file, int l) const override
Print-out.
double m_curr_gamma_1
Current .
Definition mparticle.h:80
double m_mass
Mass (not mass * speed_of_light^2)
Definition mparticle.h:70
Point.
Definition vec.h:368
void random_conic_vec(double theta)
Definition vec.cpp:236
void down(const basis *fabas)
Definition vec.cpp:168
Definition BGMesh.cpp:6
void theta_two_part(const double Ep0, const double Ep1, const double Mp, const double Mt, double &theta_p, double &theta_t)
Scattering angles as function of incident and final projectile energy.
Definition kinem.cpp:28
long pois(const double amu)
Definition pois.cpp:9
T t_hisran_step_ar(const M &mesh, const D &integ_y, T rannum)
Definition tline.h:1412
DoubleAc fabs(const DoubleAc &f)
Definition DoubleAc.h:615
DoubleAc sqrt(const DoubleAc &f)
Definition DoubleAc.cpp:314
double vfloat
Definition vfloat.h:16
#define mcout
Definition prstream.h:126
#define Iprint3n(file, name1, name2, name3)
Definition prstream.h:232
#define Ifile
Definition prstream.h:195
#define mcerr
Definition prstream.h:128
#define Iprintn(file, name)
Definition prstream.h:204
#define Iprint2n(file, name1, name2)
Definition prstream.h:219