Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
AtomDef.cpp
Go to the documentation of this file.
1#include <iomanip>
6/*
71998-2004, I. Smirnov.
8*/
9
10namespace Heed {
11
12void AtomDef::print(std::ostream& file, int l) const {
13 if (l > 0) file << (*this);
14}
15
16void AtomDef::printall(std::ostream& file) {
17 Ifile << "AtomDef::printall:\n";
19 AbsListNode<AtomDef*>* an = NULL;
20 while ((an = logbook.get_next_node(an)) != NULL) {
21 file << (*(an->el));
22 }
23}
24
25AtomDef::AtomDef(void) : nameh("none"), notationh("none") {
26 AtomDef::get_logbook().append(this);
27}
28
29AtomDef::AtomDef(const String& fnameh, const String& fnotationh, int fZh,
30 double fAh)
31 : nameh(fnameh), notationh(fnotationh), Zh(fZh), Ah(fAh) {
32 mfunname("AtomDef::AtomDef(...)");
33 check_econd21(fZh, < 1 ||, > max_poss_atom_z, mcerr);
34 verify();
35 AtomDef::get_logbook().append(this);
36}
37
38double AtomDef::get_A(int fZ) {
39 mfunnamep("double AtomDef::get_A(int fZ)");
41 AbsListNode<AtomDef*>* an = NULL;
42 while ((an = logbook.get_next_node(an)) != NULL) {
43 if (an->el->Z() == fZ) return an->el->A();
44 }
45 funnw.ehdr(mcerr);
46 mcerr << "Atom is not found, Z=" << fZ << '\n';
48 return 0.0; // to quiet compiler
49}
50
52 mfunnamep("AtomDef* AtomDef::get_AtomDef(int fZ)");
54 AbsListNode<AtomDef*>* an = NULL;
55 while ((an = logbook.get_next_node(an)) != NULL) {
56 if (an->el->Z() == fZ) return an->el;
57 }
58 funnw.ehdr(mcerr);
59 mcerr << "Atom is not found, Z=" << fZ << '\n';
61 return NULL; // to quiet compiler
62}
63
64void AtomDef::verify(void) {
65 mfunnamep("void AtomDef::verify(void)");
66 if (nameh == "none" && notationh == "none") return;
68 AbsListNode<AtomDef*>* an = NULL;
69 while ((an = logbook.get_next_node(an)) != NULL) {
70 if (an->el->nameh == nameh || an->el->notationh == notationh) {
71 funnw.ehdr(mcerr);
72 mcerr << "cannot initialize two atoms with the same name or notation\n";
73 mcerr << "name=" << nameh << " notation=" << notationh << '\n';
75 }
76 }
77}
78
79std::ostream& operator<<(std::ostream& file, const AtomDef& f) {
80 Ifile << "AtomDef: name=" << std::setw(10) << f.name()
81 << " notation=" << std::setw(3) << f.notation();
82 Ifile << " Z()=" << std::setw(3) << f.Z()
83 << " A()/(gram/mole)=" << f.A() / (gram / mole) << '\n';
84 return file;
85}
86
88 static AbsList<AtomDef*> logbook;
89 return logbook;
90}
91
93 return AtomDef::get_logbook();
94}
95
98 AbsListNode<AtomDef*>* an = NULL;
99 while ((an = logbook.get_next_node(an)) != NULL) {
100 if (an->el->notation() == fnotation) return an->el;
101 }
102 return NULL;
103}
104
106
107AtomMixDef::AtomMixDef(long fqatom, const DynLinArr<String>& fatom_not,
108 const DynLinArr<double>& fweight_quan)
109 : qatomh(fqatom),
110 atomh(fqatom),
111 weight_quanh(fqatom, 0.0),
112 weight_massh(fqatom, 0.0),
113 Z_meanh(0.0),
114 A_meanh(0.0),
115 inv_A_meanh(0.0),
116 mean_ratio_Z_to_Ah(0.0) {
117 mfunnamep("AtomMixDef::AtomMixDef(...)");
118 check_econd11(fqatom, <= 0, mcerr);
119 check_econd12(fqatom, >, fatom_not.get_qel(), mcerr);
120 check_econd12(fqatom, >, fweight_quan.get_qel(), mcerr);
121
122 long n;
123 for (n = 0; n < qatomh; ++n) {
124 AtomDef* ad = AtomDef::get_AtomDef(fatom_not[n]);
125 if (ad == NULL) {
126 funnw.ehdr(mcerr);
127 mcerr << "cannot find atom with notation " << fatom_not[n]
128 << "\nIn particular, check the sequence of initialization\n";
129 spexit(mcerr);
130 }
131 atomh[n].put(ad);
132 }
133 double s = 0.0;
134 for (n = 0; n < qatomh; n++) {
135 weight_quanh[n] = fweight_quan[n];
136 check_econd11(weight_quanh[n], <= 0, mcerr);
137 s += weight_quanh[n];
138 }
139 check_econd11(s, <= 0, mcerr);
140 if (s != 1.0) {
141 for (n = 0; n < qatomh; n++) {
142 weight_quanh[n] /= s;
143 }
144 }
145 for (n = 0; n < qatomh; n++) {
146 weight_massh[n] = weight_quanh[n] * atomh[n]->A();
147 }
148 s = 0.0;
149 for (n = 0; n < qatomh; n++) {
150 s += weight_massh[n];
151 }
152 check_econd11(s, <= 0, mcerr);
153 if (s != 1.0) {
154 for (n = 0; n < qatomh; n++) {
155 weight_massh[n] /= s;
156 }
157 }
158 for (n = 0; n < qatomh; n++) {
159 Z_meanh += atomh[n]->Z() * weight_quanh[n];
160 A_meanh += atomh[n]->A() * weight_quanh[n];
161 inv_A_meanh += (1.0 / atomh[n]->A()) * weight_quanh[n];
162 }
163 mean_ratio_Z_to_Ah = Z_meanh / A_meanh;
164 NumberOfElectronsInGramh = mean_ratio_Z_to_Ah * (gram / mole) * Avogadro;
165
166}
167
168AtomMixDef::AtomMixDef(long fqatom, const DynLinArr<String>& fatom_not,
169 const DynLinArr<long>& fweight_quan)
170 : qatomh(fqatom),
171 atomh(fqatom),
172 weight_quanh(fqatom, 0.0),
173 weight_massh(fqatom, 0.0),
174 Z_meanh(0.0),
175 A_meanh(0.0),
176 inv_A_meanh(0.0),
177 mean_ratio_Z_to_Ah(0.0) {
178 mfunnamep("AtomMixDef::AtomMixDef(...)");
179 check_econd11(fqatom, <= 0, mcerr);
180 check_econd12(fqatom, >, fatom_not.get_qel(), mcerr);
181 check_econd12(fqatom, >, fweight_quan.get_qel(), mcerr);
182
183 long n;
184 for (n = 0; n < qatomh; ++n) {
185 AtomDef* ad = AtomDef::get_AtomDef(fatom_not[n]);
186 if (ad == NULL) {
187 funnw.ehdr(mcerr);
188 mcerr << "cannot find atom with notation " << fatom_not[n]
189 << "\nIn particular, check the sequence of initialization\n";
190 spexit(mcerr);
191 }
192 atomh[n].put(ad);
193 }
194
195 double s = 0.0;
196 for (n = 0; n < qatomh; n++) {
197 weight_quanh[n] = fweight_quan[n];
198 check_econd11(weight_quanh[n], <= 0, mcerr);
199 s += weight_quanh[n];
200 }
201 check_econd11(s, <= 0, mcerr);
202 if (s != 1.0) {
203 for (n = 0; n < qatomh; n++) {
204 weight_quanh[n] /= s;
205 }
206 }
207 for (n = 0; n < qatomh; n++) {
208 weight_massh[n] = weight_quanh[n] * atomh[n]->A();
209 }
210 s = 0.0;
211 for (n = 0; n < qatomh; n++) {
212 s += weight_massh[n];
213 }
214 check_econd11(s, <= 0, mcerr);
215 if (s != 1.0) {
216 for (n = 0; n < qatomh; n++) {
217 weight_massh[n] /= s;
218 }
219 }
220 for (n = 0; n < qatomh; n++) {
221 Z_meanh += atomh[n]->Z() * weight_quanh[n];
222 A_meanh += atomh[n]->A() * weight_quanh[n];
223 inv_A_meanh += (1.0 / atomh[n]->A()) * weight_quanh[n];
224 }
225 mean_ratio_Z_to_Ah = Z_meanh / A_meanh;
226 NumberOfElectronsInGramh = mean_ratio_Z_to_Ah * (gram / mole) * Avogadro;
227
228}
229
230// one atom in mixture
232 : qatomh(1),
233 atomh(1),
234 weight_quanh(1),
235 weight_massh(1),
236 Z_meanh(0.0),
237 A_meanh(0.0),
238 inv_A_meanh(0.0),
239 mean_ratio_Z_to_Ah(0.0) {
240 mfunnamep("AtomMixDef::AtomMixDef(...)");
241 AtomDef* ad = AtomDef::get_AtomDef(fatom_not);
242 if (ad == NULL) {
243 funnw.ehdr(mcerr);
244 mcerr << "cannot find atom with notation " << fatom_not
245 << "\nIn particular, check the sequence of initialization\n";
246 spexit(mcerr);
247 }
248 atomh[0].put(ad);
249
250 weight_quanh[0] = 1.0;
251 weight_massh[0] = 1.0;
252
253 Z_meanh += atomh[0]->Z();
254 A_meanh += atomh[0]->A();
255 inv_A_meanh += (1.0 / atomh[0]->A());
256 mean_ratio_Z_to_Ah = Z_meanh / A_meanh;
257 NumberOfElectronsInGramh = mean_ratio_Z_to_Ah * (gram / mole) * Avogadro;
258
259}
260
261// two atoms
262AtomMixDef::AtomMixDef(const String& fatom_not1, double fweight_quan1,
263 const String& fatom_not2, double fweight_quan2)
264 : qatomh(2),
265 atomh(2),
266 weight_quanh(2),
267 weight_massh(2),
268 Z_meanh(0.0),
269 A_meanh(0.0),
270 inv_A_meanh(0.0),
271 mean_ratio_Z_to_Ah(0.0) {
272 mfunnamep("AtomMixDef::AtomMixDef(...)");
273 DynLinArr<String> fatom_not(2);
274 fatom_not[0] = fatom_not1;
275 fatom_not[1] = fatom_not2;
276
277 long n;
278 for (n = 0; n < qatomh; ++n) {
279 AtomDef* ad = AtomDef::get_AtomDef(fatom_not[n]);
280 if (ad == NULL) {
281 funnw.ehdr(mcerr);
282 mcerr << "cannot find atom with notation " << fatom_not[n]
283 << "\nIn particular, check the sequence of initialization\n";
284 spexit(mcerr);
285 }
286 atomh[n].put(ad);
287 }
288 weight_quanh[0] = fweight_quan1;
289 weight_quanh[1] = fweight_quan2;
290 double s = 0.0;
291 for (n = 0; n < qatomh; n++) {
292 check_econd11(weight_quanh[n], <= 0, mcerr);
293 s += weight_quanh[n];
294 }
295 check_econd11(s, <= 0, mcerr);
296 if (s != 1.0) {
297 for (n = 0; n < qatomh; n++) {
298 weight_quanh[n] /= s;
299 }
300 }
301 for (n = 0; n < qatomh; n++) {
302 weight_massh[n] = weight_quanh[n] * atomh[n]->A();
303 }
304 s = 0.0;
305 for (n = 0; n < qatomh; n++) {
306 s += weight_massh[n];
307 }
308 check_econd11(s, <= 0, mcerr);
309 if (s != 1.0) {
310 for (n = 0; n < qatomh; n++) {
311 weight_massh[n] /= s;
312 }
313 }
314 for (n = 0; n < qatomh; n++) {
315 Z_meanh += atomh[n]->Z() * weight_quanh[n];
316 A_meanh += atomh[n]->A() * weight_quanh[n];
317 inv_A_meanh += (1.0 / atomh[n]->A()) * weight_quanh[n];
318 }
319 mean_ratio_Z_to_Ah = Z_meanh / A_meanh;
320 NumberOfElectronsInGramh = mean_ratio_Z_to_Ah * (gram / mole) * Avogadro;
321
322}
323
324// three atoms
325AtomMixDef::AtomMixDef(const String& fatom_not1, double fweight_quan1,
326 const String& fatom_not2, double fweight_quan2,
327 const String& fatom_not3, double fweight_quan3)
328 : qatomh(3),
329 atomh(3),
330 weight_quanh(3),
331 weight_massh(3),
332 Z_meanh(0.0),
333 A_meanh(0.0),
334 inv_A_meanh(0.0),
335 mean_ratio_Z_to_Ah(0.0) {
336
337 mfunnamep("AtomMixDef::AtomMixDef(...)");
338 DynLinArr<String> fatom_not(3);
339 fatom_not[0] = fatom_not1;
340 fatom_not[1] = fatom_not2;
341 fatom_not[2] = fatom_not3;
342
343 long n;
344 for (n = 0; n < qatomh; ++n) {
345 AtomDef* ad = AtomDef::get_AtomDef(fatom_not[n]);
346 if (ad == NULL) {
347 funnw.ehdr(mcerr);
348 mcerr << "cannot find atom with notation " << fatom_not[n]
349 << "\nIn particular, check the sequence of initialization\n";
350 spexit(mcerr);
351 }
352 atomh[n].put(ad);
353 }
354 weight_quanh[0] = fweight_quan1;
355 weight_quanh[1] = fweight_quan2;
356 weight_quanh[2] = fweight_quan3;
357 double s = 0.0;
358 for (n = 0; n < qatomh; n++) {
359 check_econd11(weight_quanh[n], <= 0, mcerr);
360 s += weight_quanh[n];
361 }
362 check_econd11(s, <= 0, mcerr);
363 if (s != 1.0) {
364 for (n = 0; n < qatomh; n++) {
365 weight_quanh[n] /= s;
366 }
367 }
368 for (n = 0; n < qatomh; n++) {
369 weight_massh[n] = weight_quanh[n] * atomh[n]->A();
370 }
371 s = 0.0;
372 for (n = 0; n < qatomh; n++) {
373 s += weight_massh[n];
374 }
375 check_econd11(s, <= 0, mcerr);
376 if (s != 1.0) {
377 for (n = 0; n < qatomh; n++) {
378 weight_massh[n] /= s;
379 }
380 }
381 for (n = 0; n < qatomh; n++) {
382 Z_meanh += atomh[n]->Z() * weight_quanh[n];
383 A_meanh += atomh[n]->A() * weight_quanh[n];
384 inv_A_meanh += (1.0 / atomh[n]->A()) * weight_quanh[n];
385 }
386 mean_ratio_Z_to_Ah = Z_meanh / A_meanh;
387 NumberOfElectronsInGramh = mean_ratio_Z_to_Ah * (gram / mole) * Avogadro;
388
389}
390
391// four atoms
392AtomMixDef::AtomMixDef(const String& fatom_not1, double fweight_quan1,
393 const String& fatom_not2, double fweight_quan2,
394 const String& fatom_not3, double fweight_quan3,
395 const String& fatom_not4, double fweight_quan4)
396 : qatomh(4),
397 atomh(4),
398 weight_quanh(4),
399 weight_massh(4),
400 Z_meanh(0.0),
401 A_meanh(0.0),
402 inv_A_meanh(0.0),
403 mean_ratio_Z_to_Ah(0.0) {
404 mfunnamep("AtomMixDef::AtomMixDef(...)");
405 DynLinArr<String> fatom_not(4);
406 fatom_not[0] = fatom_not1;
407 fatom_not[1] = fatom_not2;
408 fatom_not[2] = fatom_not3;
409 fatom_not[3] = fatom_not4;
410
411 long k, n;
412 for (k = 0; k < qatomh; k++) {
413 AtomDef* ad = AtomDef::get_AtomDef(fatom_not[k]);
414 if (ad == NULL) {
415 funnw.ehdr(mcerr);
416 mcerr << "cannot find atom with notation " << fatom_not[k]
417 << "\nIn particular, check the sequence of initialization\n";
418 spexit(mcerr);
419 }
420 atomh[k].put(ad);
421 }
422 weight_quanh[0] = fweight_quan1;
423 weight_quanh[1] = fweight_quan2;
424 weight_quanh[2] = fweight_quan3;
425 weight_quanh[3] = fweight_quan4;
426 double s = 0.0;
427 for (n = 0; n < qatomh; n++) {
428 check_econd11(weight_quanh[n], <= 0, mcerr);
429 s += weight_quanh[n];
430 }
431 check_econd11(s, <= 0, mcerr);
432 if (s != 1.0) {
433 for (n = 0; n < qatomh; n++) {
434 weight_quanh[n] /= s;
435 }
436 }
437 for (n = 0; n < qatomh; n++) {
438 weight_massh[n] = weight_quanh[n] * atomh[n]->A();
439 }
440 s = 0.0;
441 for (n = 0; n < qatomh; n++) {
442 s += weight_massh[n];
443 }
444 check_econd11(s, <= 0, mcerr);
445 if (s != 1.0) {
446 for (n = 0; n < qatomh; n++) {
447 weight_massh[n] /= s;
448 }
449 }
450 for (n = 0; n < qatomh; n++) {
451 Z_meanh += atomh[n]->Z() * weight_quanh[n];
452 A_meanh += atomh[n]->A() * weight_quanh[n];
453 inv_A_meanh += (1.0 / atomh[n]->A()) * weight_quanh[n];
454 }
455 mean_ratio_Z_to_Ah = Z_meanh / A_meanh;
456 NumberOfElectronsInGramh = mean_ratio_Z_to_Ah * (gram / mole) * Avogadro;
457}
458
459void AtomMixDef::print(std::ostream& file, int l) const {
460 if (l > 0) file << (*this);
461}
462
463std::ostream& operator<<(std::ostream& file, const AtomMixDef& f) {
464 mfunname(
465 "std::ostream& operator << (std::ostream& file, const AtomMixDef& f)");
466 Ifile << "AtomMixDef\n";
467 indn.n += 2;
468 Ifile << "Z_mean()=" << std::setw(3) << f.Z_mean()
469 << " A_mean()/(gram/mole)=" << f.A_mean() / (gram / mole) << '\n';
470 Ifile << "inv_A_mean()*(gram/mole)=" << f.inv_A_mean() * (gram / mole)
471 << '\n';
472 Ifile << "mean_ratio_Z_to_A()*(gram/mole)=" << f.mean_ratio_Z_to_A() *
473 (gram / mole) << '\n';
474 Ifile << "NumberOfElectronsInGram()=" << f.NumberOfElectronsInGram() << '\n';
475 // Here above the mass unit is defined,
476 // therefore there is no need to divide by gram.
477 Iprintn(file, f.qatom());
478 indn.n += 2;
479 for (long n = 0; n < f.qatom(); n++) {
480 Ifile << "n=" << n << " atom(n)->notation=" << f.atom(n)->notation()
481 << "\n";
482 indn.n += 2;
483 Ifile << " weight_quan(n)=" << f.weight_quan(n)
484 << " weight_mass(n)=" << f.weight_mass(n) << '\n';
485 indn.n -= 2;
486 }
487 indn.n -= 2;
488 indn.n -= 2;
489 return file;
490}
491
492}
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
Definition: FunNameStack.h:428
#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
AbsListNode< T > * get_next_node(AbsListNode< T > *an) const
Definition: AbsList.h:175
long get_qel(void) const
Definition: AbsArr.h:420
static AbsList< AtomDef * > & get_logbook(void)
Definition: AtomDef.cpp:87
const String & name(void) const
Definition: AtomDef.h:73
int Z(void) const
Definition: AtomDef.h:75
static AtomDef * get_AtomDef(const String &fnotation)
Definition: AtomDef.cpp:96
void print(std::ostream &file, int l=0) const
Definition: AtomDef.cpp:12
double A(void) const
Definition: AtomDef.h:76
const String & notation(void) const
Definition: AtomDef.h:74
static void printall(std::ostream &file)
Definition: AtomDef.cpp:16
static const AbsList< AtomDef * > & get_const_logbook(void)
Definition: AtomDef.cpp:92
void verify(void)
Definition: AtomDef.cpp:64
static double get_A(int fZ)
Definition: AtomDef.cpp:38
AtomDef(void)
Definition: AtomDef.cpp:25
void print(std::ostream &file, int l) const
Definition: AtomDef.cpp:459
double NumberOfElectronsInGram(void) const
Definition: AtomDef.h:153
double A_mean(void) const
Definition: AtomDef.h:150
double inv_A_mean(void) const
Definition: AtomDef.h:151
AtomMixDef(void)
Definition: AtomDef.h:118
double mean_ratio_Z_to_A(void) const
Definition: AtomDef.h:152
long qatom(void) const
Definition: AtomDef.h:142
double Z_mean(void) const
Definition: AtomDef.h:149
const DynLinArr< PassivePtr< AtomDef > > & atom(void) const
Definition: AtomDef.h:143
const DynLinArr< double > & weight_quan(void) const
Definition: AtomDef.h:145
const DynLinArr< double > & weight_mass(void) const
Definition: AtomDef.h:146
Definition: BGMesh.cpp:3
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:22
const int max_poss_atom_z
Definition: AtomDef.h:59
indentation indn
Definition: prstream.cpp:13
#define Ifile
Definition: prstream.h:207
#define mcerr
Definition: prstream.h:135
#define Iprintn(file, name)
Definition: prstream.h:216