Garfield++ v2r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
surface.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
17// **** splane ****
18absref absref::*(splane::aref_splane[2]) = {(absref absref::*)&splane::pn,
19 (absref absref::*)&splane::dir_ins};
20
22 aref_tran.pass(new absref_transmit(2, aref_splane));
23}
24
25int splane::check_point_inside(const point& fpt, const vec& dir,
26 vfloat fprec) const {
28 "int splane::check_point_inside(const point& fpt, const vec& dir, "
29 "vfloat fprec)");
30 if (dir == dv0) {
31 // this is not useful
32 if (fpt == pn.Gpiv()) return 1;
33 vec v = fpt - pn.Gpiv();
34 if (cos2vec(dir_ins, v) >= -vprecision) return 1;
35 return 0;
36 }
37 if (pn.check_point_in(fpt, fprec) == 1) {
38 vfloat ca = cos2vec(dir, dir_ins);
39 if (ca < 0) return 0;
40 return 1;
41 }
42 vec v = fpt - pn.Gpiv();
43 if (cos2vec(dir_ins, v) >= 0) return 1;
44 return 0;
45}
46
47int splane::check_point_inside1(const point& fpt, int s_ext,
48 vfloat fprec) const {
49 if (pn.check_point_in(fpt, fprec) == 1) {
50 if (s_ext == 1) return 0;
51 return 1;
52 }
53 vec v = fpt - pn.Gpiv();
54 if (cos2vec(dir_ins, v) > 0) return 1;
55 return 0;
56}
57
58int splane::range(const trajestep& fts, vfloat* crange, point* cpt,
59 int* s_ext) const {
60 mfunname("int splane::range(...)");
61 if (fts.s_range_cf == 0) {
62 // straight line
63 point pt = pn.cross(straight(fts.currpos, fts.dir));
64 if (vecerror != 0) {
65 vecerror = 0;
66 return 0;
67 }
68 vfloat rng = (pt - fts.currpos).length();
69 if (pt == fts.currpos || check_par(pt - fts.currpos, fts.dir, 0.01) == 1) {
70 // looks like not matter ^
71 // otherwise the point is behind plane
72 if (fts.mrange >= rng) {
73 // otherwise it can not reach the plane
74 cpt[0] = pt;
75 crange[0] = rng;
76 vfloat t = cos2vec(fts.dir, dir_ins);
77 if (t < 0)
78 s_ext[0] = 1;
79 else if (t > 0)
80 s_ext[0] = 0;
81 else
82 s_ext[0] = 2;
83 return 1;
84 }
85 return 0;
86 } else
87 return 0;
88 } else {
89 point pt[2];
90 circumf cf(fts.currpos + fts.relcen,
91 fts.dir || fts.relcen, // if to us, moving against clock
92 fts.relcen.length());
93 int q = cf.cross(pn, pt, 0.0);
94 if (q == -1) // total circle lyes in the plane
95 {
96 cpt[0] = fts.currpos;
97 crange[0] = 0.0;
98 s_ext[0] = 2;
99 return 1;
100 }
101 if (q == 0) return 0;
102 if (q == 1) {
103 vec r1 = -fts.relcen;
104 vec r2 = pt[0] - cf.Gpiv();
105 vfloat angle = ang2projvec(r1, r2, cf.Gdir());
106 vfloat rng = cf.Grad() * angle;
107 if (fts.mrange >= rng) {
108 cpt[0] = pt[0];
109 crange[0] = rng;
110 vfloat c = cos2vec(dir_ins, fts.relcen);
111 if (angle == 0.0) {
112 // cross in the current point
113 if (c > 0)
114 s_ext[0] = 0;
115 else if (c < 0)
116 s_ext[0] = 1;
117 else
118 s_ext[0] = 2;
119 } else {
120 if (c > 0)
121 s_ext[0] = 1;
122 else if (c < 0)
123 s_ext[0] = 0;
124 else
125 s_ext[0] = 2;
126 }
127 return 1;
128 } else
129 return 0;
130 }
131 if (q == 2) {
132 int qq = 0;
133 vec r = -fts.relcen;
134 vec vcr[2];
135 vcr[0] = pt[0] - cf.Gpiv();
136 vcr[1] = pt[1] - cf.Gpiv();
137 vfloat angle[2];
138 angle[0] = ang2projvec(r, vcr[0], cf.Gdir());
139 angle[1] = ang2projvec(r, vcr[1], cf.Gdir());
140 if (angle[0] > angle[1]) { // ordering
141 vfloat a = angle[0];
142 angle[0] = angle[1];
143 angle[1] = a;
144 point p = pt[0];
145 pt[0] = pt[1];
146 pt[1] = p;
147 }
148 vfloat rng;
149 rng = cf.Grad() * angle[0];
150 if (fts.mrange >= rng) {
151 // find out what the first point means
152 int ins = 0; // 1 if the point inside and exits
153 vec td = fts.dir;
154 td.turn(cf.Gdir(), angle[0]); // local dir in the crossing point
155 vfloat t = cos2vec(td, dir_ins);
156 if (t < 0)
157 ins = 1; // means the point was inside and now exiting
158 else
159 ins = 0;
160 cpt[0] = pt[0];
161 crange[0] = rng;
162 s_ext[0] = ins;
163 qq++;
164 rng = cf.Grad() * angle[1];
165 if (fts.mrange >= rng) {
166 cpt[1] = pt[1];
167 crange[1] = rng;
168 s_ext[1] = (ins == 0 ? 1 : 0);
169 qq++;
170 }
171 }
172 return qq;
173 }
174 }
175 return 0;
176}
177
178void splane::print(std::ostream& file, int l) const {
179 if (l > 0) {
180 Ifile << "splane:\n";
181 indn.n += 2;
182 file << pn;
183 Ifile << "dir_ins: " << noindent << dir_ins << '\n';
184 indn.n -= 2;
185 }
186}
187
188// **** ulsvolume ****
190 for (int n = 0; n < qsurf; n++) adrsurf[n] = surf[n].get();
191 aref_tran.pass(new absref_transmit(qsurf, (absref**)adrsurf));
192}
193
194int ulsvolume::check_point_inside(const point& fpt, const vec& dir) const {
195 mfunname("ulsvolume::check_point_inside(...)");
196 check_econd11(qsurf, <= 0, mcerr);
197 for (int n = 0; n < qsurf; n++) {
198 if (!(surf[n].get()->check_point_inside(fpt, dir, prec))) {
199 return 0;
200 }
201 }
202#ifdef TRACE_find_embed_vol
203 indn.n++;
204 Imcout << "ulsvolume::check_point_inside: the point is in volume\n";
205 Imcout << "point:" << fpt;
206 print(mcout, 0);
207 indn.n--;
208#endif
209 return 1;
210}
211
212int ulsvolume::range_ext(trajestep& fts, int s_ext) const {
213 mfunnamep("int ulsvolume::range_ext(trajestep& fts, int s_ext) const");
214 check_econd11(qsurf, <= 0, mcerr);
215#ifdef DEBUG_ulsvolume_range_ext
216 mcout << "ulsvolume::range_ext, START, s_ext=" << s_ext << " qsurf=" << qsurf
217 << '\n';
218 mcout << fts;
219#endif
220 vfloat crange[pqcrossurf];
221 point cpt[pqcrossurf];
222 int fs_ext[pqcrossurf];
223 int n, m, nc;
224 int s = 0; // sign of crossing
225 if (s_ext == 1) {
226 for (n = 0; n < qsurf; n++) {
227 int qc = surf[n].get()->range(fts, crange, cpt, fs_ext);
228 for (m = 0; m < qc; m++) {
229 if (fs_ext[m] == 1) {
230 s = 1;
231 // The last minute change, it was 0 somewhy instead of m
232 fts.mrange = crange[m]; // reduce the range
233 fts.mpoint = cpt[m];
234 break; // take only the first exit point, it should be closest
235 } else if (fs_ext[m] == 0) {
236 if (!(surf[n].get()->check_point_inside(fts.currpos, fts.dir,
237 prec))) {
238 funnw.ehdr(mcerr);
239 mcerr << "\nshould never happen\n"
240 << "It may happen if you call this function with s_ext==1\n"
241 << "for point outside the volume\n";
242 spexit(mcerr);
243 }
244 } else if (fs_ext[m] == 2)
245 break; // don't know what to do, safe to ignore
246 }
247 }
248
249 if (s == 1) {
250 fts.s_prec = 0;
251 }
252 return s;
253 } else { // for if(s_ext==1)
254 int ss = 0; // sign that there is cross with any of the surfaces
255 for (n = 0; n < qsurf; n++) {
256#ifdef DEBUG_ulsvolume_range_ext
257 Iprintn(mcout, n);
258#endif
259 int qc = surf[n].get()->range(fts, crange, cpt, fs_ext);
260#ifdef DEBUG_ulsvolume_range_ext
261 mcout << "ulsvolume::range_ext: qc=" << qc << "\n";
262 surf[n]->print(mcout, 1);
263#endif
264 for (nc = 0; nc < qc; nc++) // loop by crossing points
265 {
266#ifdef DEBUG_ulsvolume_range_ext
267 mcout << "nc=" << nc << " fs_ext[nc]=" << fs_ext[nc] << '\n';
268#endif
269 if (fs_ext[nc] == 0) // thus ignoring exitted surfaces
270 {
271 s = 1;
272 for (m = 0; m < qsurf; m++) // scan other surfaces and verify that
273 { // the crossing point is inside
274 if (m != n) {
275 if (surf[m].get()->check_point_inside1(cpt[nc], fs_ext[nc],
276 prec) == 0) {
277#ifdef DEBUG_ulsvolume_range_ext
278 mcout << "m=" << m << '\n';
279 mcout << "Since the point is outside of the other surface, "
280 << "it can not be border of volume\n";
281#endif
282 s = 0;
283 break;
284 }
285 }
286 }
287#ifdef DEBUG_ulsvolume_range_ext
288 Iprintn(mcout, s);
289#endif
290 if (s == 1) {
291#ifdef DEBUG_ulsvolume_range_ext
292 mcout << "The crossing point is inside all other surfaces, \n"
293 << "so it is good crossing point\n";
294#endif
295 ss = 1;
296 fts.mrange = crange[nc];
297 fts.mpoint = cpt[nc];
298 break; // since points are ordered, go to next surface,
299 // may be there is nearer crossing point
300 }
301 }
302 }
303 }
304 if (ss == 1) {
305 fts.s_prec = 0;
306 }
307#ifdef DEBUG_ulsvolume_range_ext
308 mcout << "ulsvolume::range_ext: at the end\n";
309 print(mcout, 1);
310 mcout << "ss=" << ss << '\n';
311#endif
312 return ss;
313 }
314}
315/*
316// Old comment, may be not valid, or not at the right place:
317// Straight track:
318//Two variants of behavior:
319//From outside:
320//1. For each cross section from right side to check if the crossing point is
321// from internal side from each other surfaces
322//2. Find the most father point of cross section for right side
323// and to check if it is from internal side for all other surfaces.
324
325//From inside:
326//1. For each cross section from right side to check if the crossing point is
327// from internal side from each other surfaces
328//2. Find the nearest point of cross section for right side
329//there is no need to check: cross point must exist.
330
331//I choose number 2. Reason: for outside number 1 the number of checking is
332//proportional number_of_surf**2
333*/
334
335ulsvolume::ulsvolume(void) : qsurf(0) {
336 name = std::string("not inited ulsvolume");
337}
338
340 const std::string& fname, vfloat fprec) {
341 prec = fprec;
342 name = fname;
343 if (qsurf > 0) {
344 for (int n = 0; n < qsurf; ++n) surf[n].put(NULL);
345 }
346 qsurf = fqsurf;
347 for (int n = 0; n < qsurf; ++n) {
348 surf[n].put(fsurf[n]);
349 }
350}
351
352ulsvolume::ulsvolume(surface* fsurf[pqqsurf], int fqsurf, char* fname,
353 vfloat fprec)
354 : qsurf(fqsurf), name(fname) {
355 mfunname("ulsvolume::ulsvolume(...)");
356 check_econd12(fqsurf, >, pqqsurf, mcerr);
357 prec = fprec;
358 for (int n = 0; n < qsurf; ++n) surf[n].put(fsurf[n]);
359}
360
362 : absref(f), absvol(f), qsurf(f.qsurf), name(f.name) {
363 mfunname("ulsvolume::ulsvolume(...)");
365 prec = f.prec;
366 for (int n = 0; n < qsurf; ++n) surf[n].put(f.surf[n].get());
367}
368
370 : absref(f), absvol(f), qsurf(f.qsurf), name(f.name) {
371 mfunname("ulsvolume::ulsvolume(...)");
373 prec = f.prec;
374 for (int n = 0; n < qsurf; ++n) surf[n].put(f.surf[n].get());
375}
376
377void ulsvolume::print(std::ostream& file, int l) const {
378 char s[1000];
379 chname(s);
380 Ifile << "ulsvolume::print(l=" << l << "): " << s << '\n';
381 if (l > 0) {
382 indn.n += 2;
383 Ifile << "qsurf=" << qsurf << " prec=" << prec << '\n';
384 for (int n = 0; n < qsurf; ++n) {
385 Ifile << " nsurf=" << n << '\n';
386 surf[n].get()->print(file, l);
387 }
388 absvol::print(file, l);
389 indn.n -= 2;
390 }
391}
392
393/*
394manip_ulsvolume::manip_ulsvolume(manip_ulsvolume& f)
395 // TODO!
396 : absref(f), manip_absvol(f), ulsvolume((ulsvolume&)f) {}
397*/
398
400 : absref(f), manip_absvol(f), ulsvolume(f) {}
401
402void manip_ulsvolume::print(std::ostream& file, int l) const {
403 if (l <= 0) return;
404 char s[1000];
405 chname(s);
406 Ifile << "manip_ulsvolume::print(l=" << l << "): " << s << '\n';
407 l = l - 1;
408 if (l > 0) {
409 indn.n += 2;
410 // If to call this it calls manip_ulsvolume::print again and loop...
411 ulsvolume::print(file, l - 1);
412 indn.n -= 2;
413 }
414}
415}
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
#define mfunnamep(string)
Definition: FunNameStack.h:49
#define spexit(stream)
Definition: FunNameStack.h:256
#define check_econd12(a, sign, b, stream)
Definition: FunNameStack.h:163
#define mfunname(string)
Definition: FunNameStack.h:45
Active pointer or automatic container or controlling pointer.
Definition: AbsPtr.h:199
void pass(X *fptr)
Definition: AbsPtr.h:247
virtual void print(std::ostream &file, int l) const
Definition: volume.cpp:118
vfloat prec
Definition: volume.h:74
Circumference, determined by point (center), normal vector, and radius.
Definition: circumf.h:23
vfloat Grad() const
Definition: circumf.h:46
int cross(const plane &pn, point pt[2], vfloat prec) const
Definition: circumf.cpp:58
vec Gdir() const
Definition: circumf.h:45
point Gpiv() const
Definition: circumf.h:44
Abstract base classs for volume "manipulators".
Definition: volume.h:178
virtual void chname(char *nm) const
Definition: surface.h:187
virtual void print(std::ostream &file, int l) const
Definition: surface.cpp:402
point cross(const straight &sl) const
Definition: plane.cpp:74
point Gpiv(void) const
Definition: plane.h:32
int check_point_in(const point &fp, vfloat prec) const
Definition: plane.cpp:67
Point.
Definition: vec.h:374
plane pn
Definition: surface.h:71
virtual void get_components(ActivePtr< absref_transmit > &aref_tran)
Definition: surface.cpp:21
int range(const trajestep &fts, vfloat *crange, point *cpt, int *s_ext) const
Definition: surface.cpp:58
int check_point_inside1(const point &fpt, int s_ext, vfloat fprec) const
Definition: surface.cpp:47
vec dir_ins
Definition: surface.h:72
virtual void print(std::ostream &file, int l) const
Definition: surface.cpp:178
static absrefabsref::*[2] aref_splane
Definition: surface.h:75
int check_point_inside(const point &fpt, const vec &dir, vfloat fprec) const
Definition: surface.cpp:25
Definition of straight line, as combination of vector and point.
Definition: straight.h:24
Surface base class.
Definition: surface.h:27
vfloat mrange
Maximal possible range.
Definition: trajestep.h:90
vec dir
Unit vector.
Definition: trajestep.h:70
Unlimited surfaces volume.
Definition: surface.h:124
ulsvolume()
Default constructor.
Definition: surface.cpp:335
std::string name
Definition: surface.h:146
surface * adrsurf[pqqsurf]
Definition: surface.h:149
virtual void print(std::ostream &file, int l) const
Definition: surface.cpp:377
virtual void chname(char *nm) const
Definition: surface.h:170
int check_point_inside(const point &fpt, const vec &dir) const
Definition: surface.cpp:194
int range_ext(trajestep &fts, int s_ext) const
Definition: surface.cpp:212
virtual void get_components(ActivePtr< absref_transmit > &aref_tran)
Definition: surface.cpp:189
void ulsvolume_init(surface *fsurf[pqqsurf], int fqsurf, const std::string &fname, vfloat fprec)
Definition: surface.cpp:339
ActivePtr< surface > surf[pqqsurf]
Definition: surface.h:145
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
vfloat ang2projvec(const vec &r1, const vec &r2, const vec &normal)
Definition: vec.cpp:136
std::ostream & noindent(std::ostream &f)
Definition: prstream.cpp:17
vec dv0(0, 0, 0)
Definition: vec.h:314
int vecerror
Definition: vec.cpp:29
vfloat cos2vec(const vec &r1, const vec &r2)
Definition: vec.cpp:66
const int pqqsurf
Definition: surface.h:22
indentation indn
Definition: prstream.cpp:15
const vfloat vprecision
Definition: vfloat.h:17
const int pqcrossurf
Definition: surface.h:23
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 Iprintn(file, name)
Definition: prstream.h:205
#define Imcout
Definition: prstream.h:197