Garfield++ v2r0
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 time, double fmass)
22 : gparticle(primvol, pt, vel, time),
23 mass(fmass) {
24
25 mfunname("mparticle::mparticle(...)");
26
28 orig_kin_energy = orig_gamma_1 * mass * c_squared;
30 prev_kin_energy = prev_gamma_1 * mass * c_squared;
32 curr_kin_energy = curr_gamma_1 * mass * c_squared;
34}
35
37 mfunname("void mparticle::check_consistency() const");
39 double speed = c_light * lorbeta(orig_gamma_1);
40 check_econd11a(fabs(speed - origin.speed) / (speed + origin.speed), > 1.0e-10,
41 (*this), mcerr);
42 speed = c_light * lorbeta(prev_gamma_1);
43 check_econd11a(fabs(speed - prevpos.speed) / (speed + prevpos.speed),
44 > 1.0e-10, (*this), mcerr);
45 speed = c_light * lorbeta(curr_gamma_1);
46 check_econd11a(fabs(speed - currpos.speed) / (speed + currpos.speed),
47 > 1.0e-10, (*this), mcerr);
48 double kin_ener = orig_gamma_1 * mass * c_squared;
49 if (kin_ener > 1000.0 * DBL_MIN) {
51 fabs(orig_kin_energy - kin_ener) / (orig_kin_energy + kin_ener),
52 > 1.0e-9, "kin_ener=" << kin_ener << '\n' << (*this), mcerr);
53 }
54 kin_ener = prev_gamma_1 * mass * c_squared;
55 if (kin_ener > 1000.0 * DBL_MIN) {
57 fabs(prev_kin_energy - kin_ener) / (prev_kin_energy + kin_ener),
58 > 1.0e-9, "kin_ener=" << kin_ener << '\n' << (*this), mcerr);
59 }
60 kin_ener = curr_gamma_1 * mass * c_squared;
61 if (kin_ener > 1000.0 * DBL_MIN) {
63 fabs(curr_kin_energy - kin_ener) / (curr_kin_energy + kin_ener),
64 > 1.0e-9, "kin_ener=" << kin_ener << '\n' << (*this), mcerr);
65 }
66}
67
68void mparticle::step(std::vector<gparticle*>& secondaries) {
69 // Make step to nextpos and calculate new step to border
70 mfunname("void mparticle::step(...)");
77 nstep++;
78 if (currpos.prange == 0) {
81 "too many zero steps, possible infinite loop\n";
82 print(mcout, 10);, mcerr);
83 } else {
84 n_zero_step = 0;
85 }
86 // Calculate new current speed, direction and time.
87 new_speed();
88 physics_after_new_speed(secondaries);
89
90 if (s_life) {
93 }
94}
95
96void mparticle::curvature(int& fs_cf, vec& frelcen, vfloat& fmrange,
97 vfloat prec) {
98
100 "void mparticle::curvature(int& fs_cf, vec& frelcen, vfloat& fmrange)");
101 vec f;
102 vec f_perp_fl;
103 int i = force(currpos.pt, f, f_perp_fl, fmrange);
104 vec f_perp = currpos.speed * (currpos.dir || f_perp_fl);
105 f += f_perp;
106 if (i == 0 || f == dv0) {
107 fs_cf = 0;
108 frelcen = dv0;
109 if (currpos.dir == dv0) fmrange = 0; // to stay in the place
110 return;
111 }
112 if (currpos.dir == dv0) {
113 // starting to move in the direction of force
114 currpos.dir = unit_vec(f);
115 }
116 const int j = check_par(currpos.dir, f, prec);
117 if (j != 0) {
118 fs_cf = 0;
119 frelcen = dv0;
120 if (j == -1) {
121 // decelerate, search for stop point
122 const double ran = curr_kin_energy / f.length();
123 if (fmrange > ran) fmrange = ran;
124 }
125 } else {
126 fs_cf = 1;
127 vec fn = project_to_plane(f, currpos.dir); // normal component
128 frelcen = unit_vec(fn);
129 double len = fn.length();
130 vfloat rad =
131 (currpos.speed * currpos.speed * (curr_gamma_1 + 1) * mass) / len;
132 frelcen *= rad;
133 }
136}
137
138int mparticle::force(const point& /*pt*/, vec& f, vec& f_perp, vfloat& mrange) {
139 f = vec(0, 0, 0);
140 f_perp = vec(0, 0, 0);
141 mrange = max_vfloat;
142 return 0;
143}
144
146 pvecerror("void mparticle::new_speed(void)");
147 if (currpos.prange == 0.0) {
149 return;
150 }
151 vec f1, f2, f_perp1, f_perp2, f_perp_fl1, f_perp_fl2;
152 vec f_mean;
153 vfloat r1, r2; // ranges, do not need here
154 int i = force(prevpos.pt, f1, f_perp_fl1, r1);
155 int j = force(currpos.pt, f2, f_perp_fl2, r2);
156 check_econd11a(vecerror, != 0, "position 1, after computing force\n", mcerr);
157 f_perp1 = prevpos.speed * (prevpos.dir || f_perp_fl1);
158 f_perp2 = currpos.speed * (currpos.dir || f_perp_fl2);
159 // Later f_perp are ignored since they can not do the work;
160 f_mean = 0.5 * (f1 + f2);
161 check_econd11a(vecerror, != 0, "position 2, after computing f_perp\n", mcerr);
162
163 if ((i == 0 && j == 0) || f_mean == dv0) {
166 // speed is preserved by gparticle
168 } else {
169 vec r = currpos.pt - prevpos.pt;
170 double W = 0; // force * range * cos() = work * cos() (may be negative)
171 if (r != dv0) W = f_mean * r;
172 // This is work which should lead to increase or decrease the speed
173 if (W == 0) {
177 } else {
179 if (curr_kin_energy <= 0) {
180 curr_kin_energy = 0;
181 currpos.speed = 0;
182 curr_gamma_1 = 0;
183 currpos.dir = dv0;
184 } else {
185 double resten = mass * c_squared;
186 curr_gamma_1 = curr_kin_energy / resten;
187 currpos.speed = c_light * lorbeta(curr_gamma_1);
188 }
189 }
190 }
191 if (!(i == 0 && j == 0)) {
192 vec fn1 = project_to_plane(f1, prevpos.dir); // normal component
193 vec fn2 = project_to_plane(f2, currpos.dir); // normal component
194 check_econd11a(vecerror, != 0, "position 3, after computing fn2\n", mcerr);
195 // mean ortogonal component of working force
196 vec mean_fn = 0.5 * (fn1 + fn2);
197 double mean_fn_len = mean_fn.length();
198 vec fdir = prevpos.dir;
199 if (mean_fn_len > 0.0) {
200 vec relcen = unit_vec(mean_fn);
201 double mean_speed = (prevpos.speed + currpos.speed) * 0.5;
202 vfloat new_rad = (mean_speed * mean_speed *
203 ((prev_gamma_1 + curr_gamma_1) * 0.5 + 1) * mass) /
204 mean_fn_len;
205 if (new_rad > 0.0) {
206 vfloat ang = currpos.prange / new_rad; // angle to turn
207 fdir.turn(prevpos.dir || relcen, ang); // direction at the end
208 }
209 }
210 check_econd11a(vecerror, != 0, "position 4\n", mcerr);
211 vec mean_f_perp_fl = 0.5 * (f_perp_fl1 + f_perp_fl2);
212 double len_mean_f_perp_fl = mean_f_perp_fl.length();
213 f_perp2 = currpos.speed * (currpos.dir || f_perp_fl2);
214 double mean_f_perp = 0.5 * (f_perp1.length() + f_perp2.length());
215 check_econd11a(vecerror, != 0, "position 5\n", mcerr);
216 if (len_mean_f_perp_fl > 0.0) {
217 vec fdir_proj = project_to_plane(prevpos.dir, mean_f_perp_fl);
218 if (!apeq(fdir_proj.length(), 0.0)) {
219 check_econd11a(vecerror, != 0, "position 6\n", mcerr);
220 double length_proj = currpos.prange * cos2vec(prevpos.dir, fdir_proj);
221 check_econd11a(vecerror, != 0, "position 7\n", mcerr);
222 double acc =
223 mean_f_perp / (((prev_gamma_1 + curr_gamma_1) * 0.5 + 1) * mass);
224 double mean_speed = (prevpos.speed + currpos.speed) * 0.5;
225 double new_rad = pow(mean_speed * fdir_proj.length(), 2) / acc;
226 double ang = length_proj / new_rad;
227 if (new_rad > 0 && ang > 0) {
228 fdir.turn(mean_f_perp_fl, -ang); // direction at the end
229 check_econd11a(vecerror, != 0, "position 8\n", mcerr);
230 }
231 }
232 }
233 currpos.dir = fdir;
234 check_econd11a(vecerror, != 0, "position 9, after turn\n", mcerr);
235 }
238 currpos.time =
241}
242void mparticle::print(std::ostream& file, int l) const {
243 if (l < 0)
244 Ifile << "mparticle: mass=" << mass << " (" << mass / CLHEP::kg << " kg, "
245 << mass* c_squared / CLHEP::GeV << " GeV)\n";
246 Ifile << "orig_kin_energy=" << orig_kin_energy << " ("
247 << orig_kin_energy / CLHEP::GeV << " GeV)"
248 << " orig_gamma_1=" << orig_gamma_1 << '\n';
249 Ifile << "prev_kin_energy=" << prev_kin_energy << " ("
250 << prev_kin_energy / CLHEP::GeV << " GeV)"
251 << " prev_gamma_1=" << prev_gamma_1 << '\n';
252 Ifile << "curr_kin_energy=" << curr_kin_energy << " ("
253 << curr_kin_energy / CLHEP::GeV << " GeV)"
254 << " curr_gamma_1=" << curr_gamma_1 << '\n';
255 gparticle::print(file, l);
256}
257
258std::ostream& operator<<(std::ostream& file, const mparticle& f) {
259 (&f)->print(file, 10);
260 return file;
261}
262}
#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
Definition: gparticle.cpp:200
static long max_q_zero_step
Definition: gparticle.h:174
stvpoint prevpos
Definition: gparticle.h:176
virtual void change_vol(void)
Definition: gparticle.h:194
virtual void physics_after_new_speed(std::vector< gparticle * > &)
Definition: gparticle.h:207
stvpoint origin
Definition: gparticle.h:175
double total_range_from_origin
Range from origin to currpos.
Definition: gparticle.h:170
virtual stvpoint calc_step_to_bord()
Produces nextpos.
Definition: gparticle.cpp:119
long nstep
Step number.
Definition: gparticle.h:168
stvpoint currpos
Definition: gparticle.h:177
stvpoint nextpos
Definition: gparticle.h:178
long n_zero_step
Number of previous steps with zero range (including this step).
Definition: gparticle.h:172
void up_absref(absref *f)
Definition: volume.cpp:26
Abstract base classs for volume "manipulators".
Definition: volume.h:178
Massive particle. A force can be applied.
Definition: mparticle.h:23
double orig_kin_energy
Definition: mparticle.h:28
double prev_kin_energy
Definition: mparticle.h:30
void check_consistency() const
Check consistency of kin_energy, gamma_1, speed, speed_of_light and mass.
Definition: mparticle.cpp:36
mparticle()
Default constructor.
Definition: mparticle.h:69
virtual int force(const point &pt, vec &f, vec &f_perp, vfloat &mrange)
Definition: mparticle.cpp:138
virtual void step(std::vector< gparticle * > &secondaries)
Definition: mparticle.cpp:68
double curr_kin_energy
Definition: mparticle.h:32
double mass
Mass (not mass * speed_of_light^2)
Definition: mparticle.h:26
virtual void print(std::ostream &file, int l) const
Definition: mparticle.cpp:242
double curr_gamma_1
Definition: mparticle.h:33
double prev_gamma_1
Definition: mparticle.h:31
double orig_gamma_1
Definition: mparticle.h:29
virtual void curvature(int &fs_cf, vec &frelcen, vfloat &fmrange, vfloat prec)
Definition: mparticle.cpp:96
void new_speed()
Set new speed, direction and time for currpos.
Definition: mparticle.cpp:145
Point.
Definition: vec.h:374
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:186
vfloat length() const
Definition: vec.h:205
void turn(const vec &dir, vfloat angle)
Turn this vector.
Definition: vec.cpp:216
Definition: BGMesh.cpp:5
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:36
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:314
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:196
#define mcerr
Definition: prstream.h:128
#define pvecerror(string)
Definition: vec.h:29