Garfield++ v1r0
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
17mparticle::mparticle(gparticle const& gp, double fmass)
18 : gparticle(gp), mass(fmass) {
19
21 orig_kin_energy = orig_gamma_1 * mass * c_squared;
23 prev_kin_energy = prev_gamma_1 * mass * c_squared;
25 curr_kin_energy = curr_gamma_1 * mass * c_squared;
26
27}
28
29mparticle::mparticle(gparticle const& gp, double fmass, double gamma_1)
30 : gparticle(gp),
31 mass(fmass),
32 orig_gamma_1(gamma_1),
33 prev_kin_energy(0.0),
34 prev_gamma_1(0.0),
35 curr_gamma_1(gamma_1) {
36
37 curr_kin_energy = curr_gamma_1 * mass * c_squared;
40
41}
42
43mparticle::mparticle(manip_absvol* primvol, const point& pt, const vec& vel,
44 vfloat time, double fmass, double gamma_1)
45 : gparticle(),
46 mass(fmass),
47 orig_gamma_1(gamma_1),
48 prev_kin_energy(0.0),
49 prev_gamma_1(0.0),
50 curr_gamma_1(gamma_1) {
51
52 mfunname("mparticle::mparticle(...)");
53 origin.tid.eid[0].nembed = 0; // just to clear
54 primvol->m_find_embed_vol(pt, vel, &origin.tid);
55 origin.pt = pt;
56 if (vel == dv0) {
57 check_econd11(gamma_1, != 0.0, mcerr);
58 origin.dir = dv0;
59 origin.speed = 0.0;
60 } else {
61 origin.dir = unit_vec(vel);
62 origin.speed = c_light * lorbeta(gamma_1);
63 }
68 origin.time = time;
69 origin.sb = 0;
70 origin.s_ent = 1;
71 if (origin.tid.qeid == 0) return;
72 s_life = 1;
75 nextpos.s_ent = 0;
76 curr_kin_energy = curr_gamma_1 * mass * c_squared;
79}
80
82 mfunname("void mparticle::check_consistency(double speed) const");
84 double speed = c_light * lorbeta(orig_gamma_1);
85 check_econd11a(fabs(speed - origin.speed) / (speed + origin.speed), > 1.0e-10,
86 (*this), mcerr);
87 speed = c_light * lorbeta(prev_gamma_1);
89 fabs(speed - prevpos.speed) / (speed + prevpos.speed), > 1.0e-10, (*this),
90 mcerr);
91 speed = c_light * lorbeta(curr_gamma_1);
93 fabs(speed - currpos.speed) / (speed + currpos.speed), > 1.0e-10, (*this),
94 mcerr);
95 double kin_ener = orig_gamma_1 * mass * c_squared;
96 if (kin_ener > 1000.0 * DBL_MIN) {
98 fabs(orig_kin_energy - kin_ener) / (orig_kin_energy + kin_ener), > 1.0e-9,
99 "kin_ener=" << kin_ener << '\n' << (*this), mcerr);
100 }
101 kin_ener = prev_gamma_1 * mass * c_squared;
102 if (kin_ener > 1000.0 * DBL_MIN) {
104 fabs(prev_kin_energy - kin_ener) / (prev_kin_energy + kin_ener), > 1.0e-9,
105 "kin_ener=" << kin_ener << '\n' << (*this), mcerr);
106 }
107 kin_ener = curr_gamma_1 * mass * c_squared;
108 if (kin_ener > 1000.0 * DBL_MIN) {
110 fabs(curr_kin_energy - kin_ener) / (curr_kin_energy + kin_ener), > 1.0e-9,
111 "kin_ener=" << kin_ener << '\n' << (*this), mcerr);
112 }
113}
114
116 // Make step to nextpos and calculate new step to border
117 mfunname("void mparticle::step(void)");
124 nstep++;
125 if (currpos.prange == 0) {
126 n_zero_step++;
128 "too much zero steps, possible infinite loop\n";
129 print(mcout, 10);, mcerr);
130 } else {
131 n_zero_step = 0;
132 }
133 // Calculate new current speed, direction and time.
134 new_speed();
136
137 if (s_life == 1) {
138 if (prevpos.tid != currpos.tid) change_vol();
140 }
141}
142
143void mparticle::curvature(int& fs_cf, vec& frelcen, vfloat& fmrange,
144 vfloat prec) {
145
146 pvecerror(
147 "void mparticle::curvature(int& fs_cf, vec& frelcen, vfloat& fmrange)");
148 vec f;
149 vec f_perp_fl;
150 int i = force(currpos.pt, f, f_perp_fl, fmrange);
151 vec f_perp = currpos.speed * (currpos.dir || f_perp_fl);
152 f += f_perp;
153 if (i == 0 || f == dv0) {
154 fs_cf = 0;
155 frelcen = dv0;
156 if (currpos.dir == dv0) fmrange = 0; // to stay in the place
157 return;
158 }
159 if (currpos.dir == dv0) {
160 // starting to move in the direction of force
161 currpos.dir = unit_vec(f);
162 }
163 int j;
164 if ((j = check_par(currpos.dir, f, prec)) != 0) {
165 fs_cf = 0;
166 frelcen = dv0;
167 if (j == -1) {
168 // decelerate, search for stop point
169 const double ran = curr_kin_energy / length(f);
170 if (fmrange > ran) fmrange = ran;
171 }
172 } else {
173 fs_cf = 1;
174 vec fn = project_to_plane(f, currpos.dir); // normal component
175 frelcen = unit_vec(fn);
176 double len = length(fn);
177 vfloat rad =
178 (currpos.speed * currpos.speed * (curr_gamma_1 + 1) * mass) / len;
179 frelcen *= rad;
180 }
183
184}
185
186int mparticle::force(const point& /*pt*/, vec& f, vec& f_perp, vfloat& mrange) {
187 f = vec(0, 0, 0);
188 f_perp = vec(0, 0, 0);
189 mrange = max_vfloat;
190 return 0;
191}
192
194 pvecerror("void mparticle::new_speed(void)");
195 if (currpos.prange == 0.0) {
197 return;
198 }
199 vec f1, f2, f_perp1, f_perp2, f_perp_fl1, f_perp_fl2;
200 vec f_mean;
201 vfloat r1, r2; // ranges, do not need here
202 int i = force(prevpos.pt, f1, f_perp_fl1, r1);
203 int j = force(currpos.pt, f2, f_perp_fl2, r2);
204 check_econd11a(vecerror, != 0, "position 1, after computing force\n", mcerr);
205 f_perp1 = prevpos.speed * (prevpos.dir || f_perp_fl1);
206 f_perp2 = currpos.speed * (currpos.dir || f_perp_fl2);
207 // Later f_perp are ignored since they can not do the work;
208 f_mean = (f1 + f2) / 2.0;
209 check_econd11a(vecerror, != 0, "position 2, after computing f_perp\n", mcerr);
210
211 if ((i == 0 && j == 0) || f_mean == dv0) {
214 currpos.speed = prevpos.speed; // new change
215 // speed is preserved by gparticle
216 //return;
217 } else {
218 vec r = currpos.pt - prevpos.pt;
219 double W = 0; // force * range * cos() = work * cos() ( may be negative )
220 if (r != dv0) W = f_mean * r;
221 //W=f1*unit_vec(r) * currpos.prange;
222 // prange should be more exact than difference- no, this is not correct
223 // This is work which should lead to increse or decrease the speed
224 if (W == 0) {
227 currpos.speed = prevpos.speed; // new change
228 // speed is preserved by gparticle
229 //return;
230 } else {
232 if (curr_kin_energy <= 0) {
233 curr_kin_energy = 0;
234 currpos.speed = 0;
235 curr_gamma_1 = 0;
236 //if(f2==dv0) // temporary staying. May be field changes...
237 //{
238 currpos.dir = dv0;
239 //}
240 //else
241 //{
242 //currpos.dir=unit_vec(f2);
243 //}
244 } else {
245 double resten = mass * c_squared;
246 curr_gamma_1 = curr_kin_energy / resten;
247 currpos.speed = c_light * lorbeta(curr_gamma_1);
248 }
249 }
250 }
251 if (!(i == 0 && j == 0)) {
252 //double f_p_len=
253 vec fn1 = project_to_plane(f1, prevpos.dir); // normal component
254 //frelcen1=unit_vec(fn1);
255 //double len1=length(fn1);
256 vec fn2 = project_to_plane(f2, currpos.dir); // normal component
257 check_econd11a(vecerror, != 0, "position 3, after computing fn2\n", mcerr);
258 vec mean_fn =
259 0.5 * (fn1 + fn2); // mean ortogonal component of working force
260 //frelcen2=unit_vec(fn2);
261 //double len2=length(fn2);
262 double mean_fn_len = length(mean_fn);
263 vec fdir = prevpos.dir;
264 if (mean_fn_len > 0.0) {
265 vec relcen = unit_vec(mean_fn);
266 double mean_speed = (prevpos.speed + currpos.speed) * 0.5;
267 vfloat new_rad =
268 (mean_speed * mean_speed * ((prev_gamma_1 + curr_gamma_1) * 0.5 + 1) *
269 mass) / mean_fn_len;
270 if (new_rad > 0.0) {
271 vfloat ang = currpos.prange / new_rad; // angle to turn
272 fdir.turn(prevpos.dir || relcen, ang); // direction at the end
273 }
274 }
275 check_econd11a(vecerror, != 0, "position 4\n", mcerr);
276 vec mean_f_perp_fl = 0.5 * (f_perp_fl1 + f_perp_fl2);
277 double len_mean_f_perp_fl = length(mean_f_perp_fl);
278 f_perp2 = currpos.speed * (currpos.dir || f_perp_fl2);
279 double mean_f_perp = 0.5 * (length(f_perp1) + length(f_perp2));
280 check_econd11a(vecerror, != 0, "position 5\n", mcerr);
281 if (len_mean_f_perp_fl > 0.0) {
282 vec fdir_proj = project_to_plane(prevpos.dir, mean_f_perp_fl);
283 if (not_apeq(length(fdir_proj), 0.0) == 1) {
284 check_econd11a(vecerror, != 0, "position 6\n", mcerr);
285 double length_proj = currpos.prange * cos2vec(prevpos.dir, fdir_proj);
286 check_econd11a(vecerror, != 0, "position 7\n", mcerr);
287 double acc =
288 mean_f_perp / (((prev_gamma_1 + curr_gamma_1) * 0.5 + 1) * mass);
289 double mean_speed = (prevpos.speed + currpos.speed) * 0.5;
290 double new_rad = pow(mean_speed * length(fdir_proj), 2.0) / acc;
291 double ang = length_proj / new_rad;
292 if (new_rad > 0 && ang > 0) {
293 fdir.turn(mean_f_perp_fl, -ang); // direction at the end
294 check_econd11a(vecerror, != 0, "position 8\n", mcerr);
295 }
296 }
297 }
298 currpos.dir = fdir;
299 check_econd11a(vecerror, != 0, "position 9, after turn\n", mcerr);
300
301 }
304 currpos.time =
307}
308void mparticle::print(std::ostream& file, int l) const {
309 if (l >= 0) {
310 Ifile << "mparticle: mass=" << mass << " (" << mass / kg << " kg, "
311 << mass* c_squared / GeV << " GeV)\n";
312 Ifile << "orig_kin_energy=" << orig_kin_energy << " ("
313 << orig_kin_energy / GeV << " GeV)"
314 << " orig_gamma_1=" << orig_gamma_1 << '\n';
315 Ifile << "prev_kin_energy=" << prev_kin_energy << " ("
316 << prev_kin_energy / GeV << " GeV)"
317 << " prev_gamma_1=" << prev_gamma_1 << '\n';
318 Ifile << "curr_kin_energy=" << curr_kin_energy << " ("
319 << curr_kin_energy / GeV << " GeV)"
320 << " curr_gamma_1=" << curr_gamma_1 << '\n';
321 gparticle::print(file, l);
322 }
323}
324
325std::ostream& operator<<(std::ostream& file, const mparticle& f) {
326 (&f)->print(file, 10);
327 return file;
328}
329
330}
DoubleAc pow(const DoubleAc &f, double p)
Definition: DoubleAc.cpp:336
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:616
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:366
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:395
#define check_econd12a(a, sign, b, add, stream)
Definition: FunNameStack.h:411
#define mfunname(string)
Definition: FunNameStack.h:67
virtual void physics_after_new_speed(void)
Definition: mparticle.h:50
double orig_kin_energy
Definition: mparticle.h:27
void check_consistency(void) const
Definition: mparticle.cpp:81
double prev_kin_energy
Definition: mparticle.h:29
virtual int force(const point &pt, vec &f, vec &f_perp, vfloat &mrange)
Definition: mparticle.cpp:186
double curr_kin_energy
Definition: mparticle.h:31
double mass
Mass (not mass * speed_of_light^2)
Definition: mparticle.h:25
virtual void print(std::ostream &file, int l) const
Definition: mparticle.cpp:308
double curr_gamma_1
Definition: mparticle.h:32
double prev_gamma_1
Definition: mparticle.h:30
virtual void step(void)
Definition: mparticle.cpp:115
double orig_gamma_1
Definition: mparticle.h:28
void new_speed(void)
Definition: mparticle.cpp:193
virtual void curvature(int &fs_cf, vec &frelcen, vfloat &fmrange, vfloat prec)
Definition: mparticle.cpp:143
mparticle(void)
Definition: mparticle.h:79
stvpoint currpos
Definition: gparticle.h:188
vec curr_relcen
Definition: gparticle.h:190
long n_zero_step
Definition: gparticle.h:183
virtual void print(std::ostream &file, int l) const
Definition: gparticle.cpp:312
virtual stvpoint calc_step_to_bord()
Definition: gparticle.cpp:132
double total_range_from_origin
Definition: gparticle.h:182
stvpoint origin
Definition: gparticle.h:186
stvpoint prevpos
Definition: gparticle.h:187
long nstep
Definition: gparticle.h:181
int s_life
Definition: gparticle.h:180
virtual void change_vol(void)
Definition: gparticle.h:218
static long max_q_zero_step
Definition: gparticle.h:185
stvpoint nextpos
Definition: gparticle.h:189
manip_absvol_eid eid[pqamvol]
Definition: volume.h:52
void up_absref(absref *f)
Definition: volume.cpp:37
virtual int m_find_embed_vol(const point &fpt, const vec &fdir, manip_absvol_treeid *atid) const
Definition: vec.h:477
int sb
Definition: gparticle.h:46
point pt
Definition: gparticle.h:33
point ptloc
Definition: gparticle.h:37
vec dirloc
Definition: gparticle.h:39
int s_ent
Definition: gparticle.h:49
vfloat prange
Definition: gparticle.h:54
manip_absvol_treeid tid
Definition: gparticle.h:43
vfloat time
Definition: gparticle.h:55
vec dir
Definition: gparticle.h:35
vfloat speed
Definition: gparticle.h:41
Definition: vec.h:248
void turn(const vec &dir, vfloat angle)
Definition: vec.cpp:298
Definition: BGMesh.cpp:3
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:22
double lorbeta(const double gamma_1)
Definition: lorgamma.cpp:22
int not_apeq(vfloat f1, vfloat f2, vfloat prec=vprecision)
Definition: vfloat.h:41
double lorgamma_1(double beta)
Definition: lorgamma.cpp:9
#define mcout
Definition: prstream.h:133
#define Ifile
Definition: prstream.h:207
#define mcerr
Definition: prstream.h:135
vec dv0(0, 0, 0)
vec project_to_plane(const vec &r, const vec &normal)
Definition: vec.cpp:200
vfloat cos2vec(const vec &r1, const vec &r2)
Definition: vec.cpp:142
int vecerror
Definition: vec.cpp:31
#define pvecerror(string)
Definition: vec.h:52
double vfloat
Definition: vfloat.h:15
#define max_vfloat
Definition: vfloat.h:14