Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
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