Garfield++ 5.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
mparticle.cpp
Go to the documentation of this file.
3/*
4Copyright (c) 2000 Igor B. Smirnov
5
6The file can be used, copied, modified, and distributed
7according to the terms of GNU Lesser General Public License version 2.1
8as published by the Free Software Foundation,
9and provided that the above copyright notice, this permission notice,
10and notices about any modifications of the original text
11appear in all copies and in supporting documentation.
12The file is provided "as is" without express or implied warranty.
13*/
14
15namespace Heed {
16
17using CLHEP::c_light;
18using CLHEP::c_squared;
19
20mparticle::mparticle(manip_absvol* primvol, const point& pt, const vec& vel,
21 vfloat ftime, double fmass)
22 : gparticle(primvol, pt, vel, ftime),
23 m_mass(fmass) {
24
25 mfunname("mparticle::mparticle(...)");
26
27 const double mc2 = m_mass * c_squared;
28 m_orig_gamma_1 = lorgamma_1(m_origin.speed / c_light);
30 m_prev_gamma_1 = lorgamma_1(m_prevpos.speed / c_light);
32 m_curr_gamma_1 = lorgamma_1(m_currpos.speed / c_light);
34 check_consistency();
35}
36
37void mparticle::check_consistency() const {
38 mfunname("void mparticle::check_consistency() const");
40
41 double v0 = c_light * lorbeta(m_orig_gamma_1);
42 double v1 = m_origin.speed;
43 check_econd11a(fabs(v0 - v1) / (v0 + v1), > 1.0e-10, (*this), mcerr);
44
45 v0 = c_light * lorbeta(m_prev_gamma_1);
46 v1 = m_prevpos.speed;
47 check_econd11a(fabs(v0 - v1) / (v0 + v1), > 1.0e-10, (*this), mcerr);
48
49 v0 = c_light * lorbeta(m_curr_gamma_1);
50 v1 = m_currpos.speed;
51 check_econd11a(fabs(v0 - v1) / (v0 + v1), > 1.0e-10, (*this), mcerr);
52
53 const double mc2 = m_mass * c_squared;
54 double ek = m_orig_gamma_1 * mc2;
55 if (ek > 1000.0 * DBL_MIN) {
56 check_econd11a(fabs(m_orig_ekin - ek) / (m_orig_ekin + ek), > 1.0e-9,
57 "ek=" << ek << '\n' << (*this), mcerr);
58 }
59 ek = m_prev_gamma_1 * mc2;
60 if (ek > 1000.0 * DBL_MIN) {
61 check_econd11a(fabs(m_prev_ekin - ek) / (m_prev_ekin + ek), > 1.0e-9,
62 "ek=" << ek << '\n' << (*this), mcerr);
63 }
64 ek = m_curr_gamma_1 * mc2;
65 if (ek > 1000.0 * DBL_MIN) {
66 check_econd11a(fabs(m_curr_ekin - ek) / (m_curr_ekin + ek), > 1.0e-9,
67 "ek=" << ek << '\n' << (*this), mcerr);
68 }
69}
70
71void mparticle::step(std::vector<gparticle*>& secondaries) {
72 // Make step to nextpos and calculate new step to border
73 mfunname("void mparticle::step(...)");
79 m_nstep++;
80 if (m_currpos.prange == 0) {
83 "too many zero steps, possible infinite loop\n";
84 print(mcout, 10);, mcerr);
85 } else {
86 m_nzero_step = 0;
87 }
88 // Calculate new current speed, direction and time.
89 new_speed();
90 physics_after_new_speed(secondaries);
91
92 if (m_alive) {
93 if (m_prevpos.tid != m_currpos.tid) change_vol();
95 }
96}
97
98void mparticle::curvature(bool& curved, vec& frelcen, vfloat& fmrange,
99 vfloat prec) {
100
101 pvecerror("void mparticle::curvature(...)");
102 vec f;
103 vec f_perp_fl;
104 int i = force(m_currpos.pt, f, f_perp_fl, fmrange);
105 vec f_perp = m_currpos.speed * (m_currpos.dir || f_perp_fl);
106 f += f_perp;
107 if (i == 0 || f == dv0) {
108 curved = false;
109 frelcen = dv0;
110 if (m_currpos.dir == dv0) fmrange = 0; // to stay in the place
111 return;
112 }
113 if (m_currpos.dir == dv0) {
114 // starting to move in the direction of force
115 m_currpos.dir = unit_vec(f);
116 }
117 const int j = check_par(m_currpos.dir, f, prec);
118 if (j != 0) {
119 curved = false;
120 frelcen = dv0;
121 if (j == -1) {
122 // decelerate, search for stop point
123 const double ran = m_curr_ekin / f.length();
124 if (fmrange > ran) fmrange = ran;
125 }
126 } else {
127 curved = true;
128 vec fn = project_to_plane(f, m_currpos.dir); // normal component
129 frelcen = unit_vec(fn);
130 double len = fn.length();
131 vfloat rad =
132 (m_currpos.speed * m_currpos.speed * (m_curr_gamma_1 + 1) * m_mass) / len;
133 frelcen *= rad;
134 }
135 m_currpos.dirloc = m_currpos.dir;
136 m_currpos.tid.up_absref(&m_currpos.dirloc);
137}
138
139int mparticle::force(const point& /*pt*/, vec& f, vec& f_perp, vfloat& mrange) {
140 f.x = f_perp.x = 0.;
141 f.y = f_perp.y = 0.;
142 f.z = f_perp.z = 0.;
143 mrange = max_vfloat;
144 return 0;
145}
146
147void mparticle::new_speed() {
148 pvecerror("void mparticle::new_speed(void)");
149 if (m_currpos.prange == 0.0) {
150 check_consistency();
151 return;
152 }
153 vec f1, f2, f_perp1, f_perp2, f_perp_fl1, f_perp_fl2;
154 vfloat r1, r2; // ranges, do not need here
155 int i = force(m_prevpos.pt, f1, f_perp_fl1, r1);
156 int j = force(m_currpos.pt, f2, f_perp_fl2, r2);
157 check_econd11a(vecerror, != 0, "position 1, after computing force\n", mcerr);
158 f_perp1 = m_prevpos.speed * (m_prevpos.dir || f_perp_fl1);
159 f_perp2 = m_currpos.speed * (m_currpos.dir || f_perp_fl2);
160 // Later f_perp are ignored since they can not do the work;
161 vec f_mean = 0.5 * (f1 + f2);
162 check_econd11a(vecerror, != 0, "position 2, after computing f_perp\n", mcerr);
163
164 if ((i == 0 && j == 0) || f_mean == dv0) {
167 // speed is preserved by gparticle
169 } else {
170 vec r = m_currpos.pt - m_prevpos.pt;
171 double W = 0; // force * range * cos() = work * cos() (may be negative)
172 if (r != dv0) W = f_mean * r;
173 // This is work which should lead to increase or decrease the speed
174 if (W == 0) {
177 m_currpos.speed = m_prevpos.speed;
178 } else {
180 if (m_curr_ekin <= 0) {
181 m_curr_ekin = 0;
182 m_currpos.speed = 0;
183 m_curr_gamma_1 = 0;
184 m_currpos.dir = dv0;
185 } else {
186 double resten = m_mass * c_squared;
187 m_curr_gamma_1 = m_curr_ekin / resten;
188 m_currpos.speed = c_light * lorbeta(m_curr_gamma_1);
189 }
190 }
191 }
192 if (!(i == 0 && j == 0)) {
193 vec fn1 = project_to_plane(f1, m_prevpos.dir); // normal component
194 vec fn2 = project_to_plane(f2, m_currpos.dir); // normal component
195 check_econd11a(vecerror, != 0, "position 3, after computing fn2\n", mcerr);
196 // mean ortogonal component of working force
197 vec mean_fn = 0.5 * (fn1 + fn2);
198 double mean_fn_len = mean_fn.length();
199 vec fdir = m_prevpos.dir;
200 if (mean_fn_len > 0.0) {
201 vec relcen = unit_vec(mean_fn);
202 double mean_speed = (m_prevpos.speed + m_currpos.speed) * 0.5;
203 vfloat new_rad = (mean_speed * mean_speed *
204 ((m_prev_gamma_1 + m_curr_gamma_1) * 0.5 + 1) * m_mass) /
205 mean_fn_len;
206 if (new_rad > 0.0) {
207 vfloat ang = m_currpos.prange / new_rad; // angle to turn
208 fdir.turn(m_prevpos.dir || relcen, ang); // direction at the end
209 }
210 }
211 check_econd11a(vecerror, != 0, "position 4\n", mcerr);
212 vec mean_f_perp_fl = 0.5 * (f_perp_fl1 + f_perp_fl2);
213 double len_mean_f_perp_fl = mean_f_perp_fl.length();
214 f_perp2 = m_currpos.speed * (m_currpos.dir || f_perp_fl2);
215 double mean_f_perp = 0.5 * (f_perp1.length() + f_perp2.length());
216 check_econd11a(vecerror, != 0, "position 5\n", mcerr);
217 if (len_mean_f_perp_fl > 0.0) {
218 vec fdir_proj = project_to_plane(m_prevpos.dir, mean_f_perp_fl);
219 if (!apeq(fdir_proj.length(), 0.0)) {
220 check_econd11a(vecerror, != 0, "position 6\n", mcerr);
221 double length_proj = m_currpos.prange * cos2vec(m_prevpos.dir, fdir_proj);
222 check_econd11a(vecerror, != 0, "position 7\n", mcerr);
223 double acc =
224 mean_f_perp / (((m_prev_gamma_1 + m_curr_gamma_1) * 0.5 + 1) * m_mass);
225 double mean_speed = (m_prevpos.speed + m_currpos.speed) * 0.5;
226 double new_rad = pow(mean_speed * fdir_proj.length(), 2) / acc;
227 double ang = length_proj / new_rad;
228 if (new_rad > 0 && ang > 0) {
229 fdir.turn(mean_f_perp_fl, -ang); // direction at the end
230 check_econd11a(vecerror, != 0, "position 8\n", mcerr);
231 }
232 }
233 }
234 m_currpos.dir = fdir;
235 check_econd11a(vecerror, != 0, "position 9, after turn\n", mcerr);
236 }
237 m_currpos.dirloc = m_currpos.dir;
238 m_currpos.tid.up_absref(&m_currpos.dirloc);
239 const double mean_speed = 0.5 * (m_prevpos.speed + m_currpos.speed);
240 m_currpos.time = m_prevpos.time + m_currpos.prange / mean_speed;
241 check_consistency();
242}
243void mparticle::print(std::ostream& file, int l) const {
244 if (l < 0) return;
245 Ifile << "mparticle: mass=" << m_mass << " (" << m_mass / CLHEP::kg << " kg, "
246 << m_mass * c_squared / CLHEP::GeV << " GeV)\n";
247 Ifile << "orig_ekin=" << m_orig_ekin << " ("
248 << m_orig_ekin / CLHEP::GeV << " GeV)"
249 << " orig_gamma_1=" << m_orig_gamma_1 << '\n';
250 Ifile << "prev_ekin=" << m_prev_ekin << " ("
251 << m_prev_ekin / CLHEP::GeV << " GeV)"
252 << " prev_gamma_1=" << m_prev_gamma_1 << '\n';
253 Ifile << "curr_kin_energy=" << m_curr_ekin << " ("
254 << m_curr_ekin / CLHEP::GeV << " GeV)"
255 << " curr_gamma_1=" << m_curr_gamma_1 << '\n';
256 gparticle::print(file, l);
257}
258
259std::ostream& operator<<(std::ostream& file, const mparticle& f) {
260 (&f)->print(file, 10);
261 return file;
262}
263}
#define check_econd11(a, signb, stream)
#define check_econd11a(a, signb, add, stream)
#define check_econd12a(a, sign, b, add, stream)
#define mfunname(string)
virtual void print(std::ostream &file, int l) const
Print-out.
virtual void physics_after_new_speed(std::vector< gparticle * > &)
Apply any other processes (turn the trajectory, kill the particle, ...).
Definition gparticle.h:235
stvpoint m_nextpos
Next point.
Definition gparticle.h:278
double m_total_range_from_origin
Range from origin to current position.
Definition gparticle.h:271
virtual stvpoint calc_step_to_bord()
Determine next position.
stvpoint m_prevpos
Previous point.
Definition gparticle.h:274
static constexpr long m_max_qzero_step
Max. number of zero-steps allowed.
Definition gparticle.h:264
gparticle()=default
Default constructor.
stvpoint m_currpos
Current point.
Definition gparticle.h:276
virtual void change_vol()
Move from one volume to another.
Definition gparticle.h:217
long m_nzero_step
Number of previous steps with zero range (including this step).
Definition gparticle.h:266
stvpoint m_origin
Original point.
Definition gparticle.h:269
bool m_alive
Status flag whether the particle is active.
Definition gparticle.h:259
long m_nstep
Step number.
Definition gparticle.h:262
Abstract base classs for volume "manipulators".
Definition volume.h:128
Massive particle. A force can be applied.
Definition mparticle.h:23
double m_prev_ekin
Previous kinetic energy.
Definition mparticle.h:77
double m_curr_ekin
Current kinetic energy.
Definition mparticle.h:73
virtual int force(const point &pt, vec &f, vec &f_perp, vfloat &mrange)
void step(std::vector< gparticle * > &secondaries) override
Definition mparticle.cpp:71
void print(std::ostream &file, int l) const override
Print-out.
double m_curr_gamma_1
Current .
Definition mparticle.h:80
mparticle()=default
Default constructor.
double m_orig_ekin
Original kinetic energy.
Definition mparticle.h:75
double m_prev_gamma_1
Previous .
Definition mparticle.h:84
double m_orig_gamma_1
Original .
Definition mparticle.h:82
double m_mass
Mass (not mass * speed_of_light^2)
Definition mparticle.h:70
void curvature(bool &curved, vec &frelcen, vfloat &fmrange, vfloat prec) override
Definition mparticle.cpp:98
Point.
Definition vec.h:368
vec dir
Unit vector, in the first system in the tree.
Definition gparticle.h:26
vfloat prange
Range from previous point.
Definition gparticle.h:47
vfloat speed
Longitudinal velocity.
Definition gparticle.h:32
point pt
Coordinates in the first system in the tree.
Definition gparticle.h:24
vfloat x
Definition vec.h:192
vfloat length() const
Definition vec.h:196
vfloat z
Definition vec.h:194
vfloat y
Definition vec.h:193
Definition BGMesh.cpp:6
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition BGMesh.cpp:37
double lorbeta(const double gamma_1)
as function of .
Definition lorgamma.cpp:23
vec project_to_plane(const vec &r, const vec &normal)
Definition vec.cpp:124
DoubleAc pow(const DoubleAc &f, double p)
Definition DoubleAc.cpp:337
vec dv0(0, 0, 0)
Definition vec.h:308
int vecerror
Definition vec.cpp:29
bool apeq(const circumf &f1, const circumf &f2, vfloat prec)
Definition circumf.cpp:44
double lorgamma_1(double beta)
as function of .
Definition lorgamma.cpp:10
vfloat cos2vec(const vec &r1, const vec &r2)
Definition vec.cpp:66
DoubleAc fabs(const DoubleAc &f)
Definition DoubleAc.h:615
double vfloat
Definition vfloat.h:16
#define mcout
Definition prstream.h:126
#define Ifile
Definition prstream.h:195
#define mcerr
Definition prstream.h:128
#define pvecerror(string)
Definition vec.h:28