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