Garfield++ 4.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;
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) {
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 =
133 frelcen *= rad;
134 }
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) {
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;
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 }
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)
Definition: FunNameStack.h:155
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:172
#define check_econd12a(a, sign, b, add, stream)
Definition: FunNameStack.h:181
#define mfunname(string)
Definition: FunNameStack.h:45
virtual void print(std::ostream &file, int l) const
Print-out.
Definition: gparticle.cpp:192
virtual void physics_after_new_speed(std::vector< gparticle * > &)
Apply any other processes (turn the trajectory, kill the particle, ...).
Definition: gparticle.h:229
stvpoint m_nextpos
Next point.
Definition: gparticle.h:266
double m_total_range_from_origin
Range from origin to current position.
Definition: gparticle.h:259
virtual stvpoint calc_step_to_bord()
Determine next position.
Definition: gparticle.cpp:110
stvpoint m_prevpos
Previous point.
Definition: gparticle.h:262
static constexpr long m_max_qzero_step
Max. number of zero-steps allowed.
Definition: gparticle.h:252
stvpoint m_currpos
Current point.
Definition: gparticle.h:264
virtual void change_vol()
Move from one volume to another.
Definition: gparticle.h:211
long m_nzero_step
Number of previous steps with zero range (including this step).
Definition: gparticle.h:254
stvpoint m_origin
Original point.
Definition: gparticle.h:257
bool m_alive
Status flag whether the particle is active.
Definition: gparticle.h:247
long m_nstep
Step number.
Definition: gparticle.h:250
void up_absref(absref *f)
Definition: volume.cpp:27
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)
Definition: mparticle.cpp:139
void step(std::vector< gparticle * > &secondaries) override
Definition: mparticle.cpp:71
void print(std::ostream &file, int l) const override
Print-out.
Definition: mparticle.cpp:243
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
vfloat time
Definition: gparticle.h:47
vec dirloc
Unit vector, in the local system (last system in the tree).
Definition: gparticle.h:29
vec dir
Unit vector, in the first system in the tree.
Definition: gparticle.h:25
vfloat prange
Range from previous point.
Definition: gparticle.h:46
vfloat speed
Longitudinal velocity.
Definition: gparticle.h:31
point pt
Coordinates in the first system in the tree.
Definition: gparticle.h:23
manip_absvol_treeid tid
Definition: gparticle.h:32
Definition: vec.h:179
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