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.cpp
Go to the documentation of this file.
1#include <iomanip>
2#include <numeric>
13
14// 2003-2008, I. Smirnov
15
16namespace Heed {
17
18using CLHEP::c_light;
19using CLHEP::c_squared;
20using CLHEP::cm;
21using CLHEP::MeV;
22using CLHEP::electron_mass_c2;
23
25 const vec& vel, vfloat ftime, particle_def* fpardef,
26 HeedFieldMap* fieldmap,
27 const bool fcoulomb_scattering,
28 const bool floss_only,
29 const bool fprint_listing)
30 : eparticle(primvol, pt, vel, ftime, fpardef, fieldmap),
31 m_coulomb_scattering(fcoulomb_scattering),
32 m_loss_only(floss_only),
33 m_print_listing(fprint_listing),
34 m_particle_number(s_counter++) {}
35
36void HeedParticle::physics(std::vector<gparticle*>& secondaries) {
37 mfunname("void HeedParticle::physics()");
38 if (m_print_listing) {
39 mcout << "HeedParticle::physics is started\n";
40 Iprintn(mcout, m_currpos.prange);
41 }
42 // Get the step.
43 if (m_currpos.prange <= 0.0) return;
44 const double stp = m_currpos.prange / cm;
45 const vec dir = unit_vec(m_currpos.pt - m_prevpos.pt);
46 const double range = (m_currpos.pt - m_prevpos.pt).length();
47 if (m_print_listing) Iprint3n(mcout, m_prevpos.pt, dir, range);
48 // Get local volume.
49 const absvol* av = m_currpos.volume();
50 auto etcs = dynamic_cast<const EnTransfCS*>(av);
51 if (!etcs) return;
52 HeedMatterDef* hmd = etcs->hmd;
53 MatterDef* matter = hmd->matter;
54 EnergyMesh* emesh = hmd->energy_mesh;
55 const double* aetemp = emesh->get_ae();
56 PointCoorMesh<double, const double*> pcm(emesh->get_q() + 1, &(aetemp));
57 basis tempbas(m_currpos.dir, "tempbas");
58 // Particle mass and energy.
59 const double mp = m_mass * c_squared;
60 const double ep = mp + m_curr_ekin;
61 // Electron mass.
62 const double mt = electron_mass_c2;
63 // Particle velocity.
64 const double invSpeed = 1. / m_prevpos.speed;
65 // Shorthand.
66 const auto sampleTransfer = t_hisran_step_ar<double, std::vector<double>,
68 const long qa = matter->qatom();
69 if (m_print_listing) Iprintn(mcout, qa);
70 for (long na = 0; na < qa; ++na) {
71 if (m_print_listing) Iprintn(mcout, na);
72 const long qs = hmd->apacs[na]->get_qshell();
73 for (long ns = 0; ns < qs; ++ns) {
74 if (m_print_listing) Iprintn(mcout, ns);
75 if (etcs->quan[na][ns] <= 0.0) continue;
76 // Sample the number of collisions for this shell.
77 const long qt = pois(etcs->quan[na][ns] * stp);
78 if (m_print_listing) Iprintn(mcout, qt);
79 if (qt <= 0) continue;
80 for (long nt = 0; nt < qt; ++nt) {
81 // Sample the energy transfer in this collision.
82 const double r = sampleTransfer(pcm, etcs->fadda[na][ns], SRANLUX());
83 // Convert to internal units.
84 const double et = r * MeV;
85 m_edep += et;
86 if (m_print_listing) Iprint2n(mcout, nt, et);
87 // Sample the position of the collision.
88 const double arange = SRANLUX() * range;
89 point pt = m_prevpos.pt + dir * arange;
90 if (m_loss_only) continue;
91 if (m_print_listing) mcout << "generating new cluster\n";
92 if (m_store_clusters) {
93 m_clusterBank.emplace_back(HeedCluster(et, pt, na, ns));
94 }
95 // Generate a virtual photon.
96 double theta_p, theta_t;
97 theta_two_part(ep, ep - et, mp, mt, theta_p, theta_t);
98 vec vel;
99 vel.random_conic_vec(fabs(theta_t));
100 vel.down(&tempbas); // direction is OK
101 vel *= c_light;
102 const double t = m_prevpos.time + arange * invSpeed;
103 if (m_print_listing) mcout << "generating new virtual photon\n";
104 HeedPhoton* hp = new HeedPhoton(m_currpos.tid.eid[0], pt, vel, t,
105 m_particle_number, et, m_fieldMap);
106 if (!hp->alive()) {
107 delete hp;
108 continue;
109 }
110 hp->m_photon_absorbed = true;
111 hp->m_delta_generated = false;
112 hp->m_na_absorbing = na;
113 hp->m_ns_absorbing = ns;
114 secondaries.push_back(hp);
115 }
116 }
117 }
118
119 if (m_edep >= m_curr_ekin) {
120 // Accumulated energy loss exceeds the particle's kinetic energy.
121 m_alive = false;
122 }
123
124 if (m_coulomb_scattering) {
125 if (hmd->radiation_length > 0.) {
126 const double x = range / hmd->radiation_length;
127 const double sigma = etcs->sigma_ms * sqrt(x);
128 double theta = sigma * rnorm_improved();
129 turn(cos(theta), sin(theta));
130 }
131 }
132 if (m_print_listing) {
133 Iprintn(mcout, m_edep);
134 mcout << "Exiting HeedParticle::physics\n";
135 }
136}
137
138void HeedParticle::physics_mrange(double& fmrange) {
139 if (!m_coulomb_scattering) return;
140 // Get local volume and convert it to a cross-section object.
141 const absvol* av = m_currpos.volume();
142 auto etcs = dynamic_cast<const EnTransfCS*>(av);
143 if (!etcs) return;
144 if (etcs->quanC > 0.) {
145 // Make sure the step is smaller than the mean free path between
146 // ionising collisions.
147 fmrange = std::min(fmrange, 0.1 / etcs->quanC);
148 }
149}
150
151void HeedParticle::print(std::ostream& file, int l) const {
152 if (l < 0) return;
153 file << "HeedParticle: particle_number=" << m_particle_number << " type=";
154 if (!m_pardef) {
155 file << "none";
156 } else {
157 file << m_pardef->notation;
158 }
159 file << "\n edep=" << m_edep << "\n";
160 if (l <= 1) return;
161 mparticle::print(file, l - 1);
162}
163}
#define mfunname(string)
long qatom() const
Definition AtomDef.h:101
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
double radiation_length
Radiation Length.
EnergyMesh * energy_mesh
void print(std::ostream &file, int l) const override
Print-out.
void physics_mrange(double &fmrange) override
void physics(std::vector< gparticle * > &secondaries) override
Apply any other processes (turn the trajectory, kill the particle, ...).
HeedParticle()
Default constructor.
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
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
void turn(const double ctheta, const double stheta)
Change the direction of the particle.
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_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
DoubleAc cos(const DoubleAc &f)
Definition DoubleAc.cpp:432
double rnorm_improved()
Definition rnorm.h:11
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 sin(const DoubleAc &f)
Definition DoubleAc.cpp:384
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 Iprintn(file, name)
Definition prstream.h:204
#define Iprint2n(file, name1, name2)
Definition prstream.h:219