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