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