Garfield++ 5.0
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>
5
6// 1998-2004, I. Smirnov.
7
8namespace Heed {
9
10using CLHEP::gram;
11using CLHEP::mole;
12using CLHEP::Avogadro;
13
14AtomDef::AtomDef(const std::string& fnameh, const std::string& fnotationh,
15 int fZh, double fAh)
16 : nameh(fnameh), notationh(fnotationh), Zh(fZh), Ah(fAh) {
17 mfunname("AtomDef::AtomDef(...)");
18 static constexpr int max_poss_atom_z = 100;
19 check_econd21(fZh, < 1 ||, > max_poss_atom_z, mcerr);
20}
21
22void AtomDef::print(std::ostream& file, int l) const {
23 if (l > 0) file << (*this);
24}
25
26std::ostream& operator<<(std::ostream& file, const AtomDef& f) {
27 Ifile << "AtomDef: name=" << std::setw(10) << f.name()
28 << " notation=" << std::setw(3) << f.notation();
29 Ifile << " Z()=" << std::setw(3) << f.Z()
30 << " A()/(gram/mole)=" << f.A() / (gram / mole) << '\n';
31 return file;
32}
33
34std::list<AtomDef> AtomDefs::atoms;
35
36void AtomDefs::addAtom(const std::string& name, const std::string& notation,
37 int z, double a) {
38 AtomDefs::atoms.push_back(AtomDef(name, notation, z, a));
39}
40
41const std::list<AtomDef>& AtomDefs::getAtoms() {
42 if (!atoms.empty()) return atoms;
43 addAtom("Hydrogen", "H", 1, 1.0);
44 // addAtom("Hydrogen", "H", 1, 1.00794 * gram/mole));
45 addAtom("Helium", "He", 2, 4.002602 * gram / mole);
46 addAtom("Lithium", "Li", 3, 6.941 * gram / mole);
47 addAtom("Beryllium", "Be", 4, 9.012182 * gram / mole);
48 addAtom("Boron", "B", 5, 10.811 * gram / mole);
49 addAtom("Carbon", "C", 6, 12.011 * gram / mole);
50 addAtom("Nitrogen", "N", 7, 14.00674 * gram / mole);
51 addAtom("Oxygen", "O", 8, 15.9994 * gram / mole);
52 addAtom("Fluorine", "F", 9, 18.9984032 * gram / mole);
53 addAtom("Neon", "Ne", 10, 20.1797 * gram / mole);
54 addAtom("Sodium", "Na", 11, 22.989768 * gram / mole);
55 addAtom("Magnesium", "Mg", 12, 24.3050 * gram / mole);
56 addAtom("Aluminium", "Al", 13, 26.981539 * gram / mole);
57 addAtom("Silicon", "Si", 14, 28.0855 * gram / mole);
58 addAtom("Phosphorus", "P", 15, 30.973762 * gram / mole);
59 addAtom("Sulfur", "S", 16, 32.066 * gram / mole);
60 addAtom("Chlorine", "Cl", 17, 35.066 * gram / mole);
61 addAtom("Argon", "Ar", 18, 39.948 * gram / mole);
62 addAtom("Argon_without_K", "Ar_without_K", 16,
63 39.948 * gram / mole);
64 addAtom("Potassium", "K", 19, 39.098 * gram / mole);
65 addAtom("Calcium", "Ca", 20, 40.08 * gram / mole);
66 addAtom("Scandium", "Sc", 21, 44.9559 * gram / mole);
67 addAtom("Titanium", "Ti", 22, 47.867 * gram / mole);
68 addAtom("Vanadium", "V", 23, 50.9414 * gram / mole);
69 addAtom("Chromium", "Cr", 24, 51.996 * gram / mole);
70 addAtom("Manganese", "Mn", 25, 54.9380 * gram / mole);
71 addAtom("Iron", "Fe", 26, 55.845 * gram / mole);
72 addAtom("Cobalt", "Co", 27, 58.9332 * gram / mole);
73 addAtom("Nickel", "Ni", 28, 58.70 * gram / mole);
74 addAtom("Copper", "Cu", 29, 63.546 * gram / mole);
75 addAtom("Zinc", "Zn", 30, 65.38 * gram / mole);
76 addAtom("Gallium", "Ga", 31, 69.72 * gram / mole);
77 addAtom("Germanium", "Ge", 32, 72.59 * gram / mole);
78 addAtom("Arsenic", "As", 33, 74.9216 * gram / mole);
79 addAtom("Selenium", "Se", 34, 78.96 * gram / mole);
80 addAtom("Bromine", "Br", 35, 79.904 * gram / mole);
81 addAtom("Krypton", "Kr", 36, 83.80 * gram / mole);
82 addAtom("Rubidium", "Rb", 37, 85.4673 * gram / mole);
83 addAtom("Strontium", "Sr", 38, 87.62 * gram / mole);
84 addAtom("Yttrium", "Y", 39, 88.9059 * gram / mole);
85 addAtom("Zirconium", "Zr", 40, 91.22 * gram / mole);
86 addAtom("Niobium", "Nb", 41, 92.9064 * gram / mole);
87 addAtom("Molybdenum", "Mo", 42, 95.94 * gram / mole);
88 addAtom("Technetium", "Tc", 43, 98 * gram / mole);
89 addAtom("Ruthenium", "Ru", 44, 101.07 * gram / mole);
90 addAtom("Rhodium", "Rh", 45, 102.9055 * gram / mole);
91 addAtom("Palladium", "Pd", 46, 106.4 * gram / mole);
92 addAtom("Silver", "Ag", 47, 107.868 * gram / mole);
93 addAtom("Cadmium", "Cd", 48, 112.411 * gram / mole);
94 addAtom("Indium", "In", 49, 114.818 * gram / mole);
95 addAtom("Tin", "Sn", 50, 118.710 * gram / mole);
96 addAtom("Antimony", "Sb", 51, 121.760 * gram / mole);
97 addAtom("Tellurium", "Te", 52, 127.60 * gram / mole);
98 addAtom("Iodine", "I", 53, 126.9045 * gram / mole);
99 addAtom("Xenon", "Xe", 54, 131.293 * gram / mole);
100 addAtom("Caesium", "Cs", 55, 132.9054519 * gram / mole);
101 addAtom("Tungsten", "W", 74, 183.85 * gram / mole);
102 addAtom("Mercury", "Hg", 80, 200.59 * gram / mole);
103 addAtom("Bismuth", "Bi", 83, 208.9804 * gram / mole);
104 addAtom("Uranium", "U", 92, 238.0289 * gram / mole);
105 addAtom("Plutonium", "Pu", 94, 244.0 * gram / mole);
106 return atoms;
107}
108
109void AtomDefs::printAtoms(std::ostream& file) {
110 Ifile << "AtomDefs::printAtoms:\n";
111 for (const auto& atom : getAtoms()) file << atom;
112}
113
114const AtomDef* AtomDefs::getAtom(const std::string& fnotation) {
115 for (const auto& atom : getAtoms()) {
116 if (atom.notation() == fnotation) return &atom;
117 }
118 return nullptr;
119}
120
121double AtomDefs::getA(int fZ) {
122 mfunnamep("double AtomDefs::getA(int fZ)");
123 for (const auto& atom : getAtoms()) {
124 if (atom.Z() == fZ) return atom.A();
125 }
126 funnw.ehdr(mcerr);
127 mcerr << "Atom is not found, Z=" << fZ << '\n';
128 spexit(mcerr);
129 return 0.0;
130}
131
133 mfunnamep("AtomDef* AtomDefs::getAtom(int fZ)");
134 for (const auto& atom : getAtoms()) {
135 if (atom.Z() == fZ) return &atom;
136 }
137 funnw.ehdr(mcerr);
138 mcerr << "Atom is not found, Z=" << fZ << '\n';
139 spexit(mcerr);
140 return nullptr;
141}
142
143AtomMixDef::AtomMixDef(unsigned long fqatom,
144 const std::vector<std::string>& fatom_not,
145 const std::vector<double>& fweight_quan)
146 : qatomh(fqatom),
147 atomh(fqatom, nullptr),
148 weight_quanh(fqatom, 0.0),
149 weight_massh(fqatom, 0.0) {
150 mfunnamep("AtomMixDef::AtomMixDef(...)");
151 check_econd11(fqatom, <= 0, mcerr);
152 check_econd12(fqatom, >, fatom_not.size(), mcerr);
153 check_econd12(fqatom, >, fweight_quan.size(), mcerr);
154
155 for (long n = 0; n < qatomh; ++n) {
156 auto ad = AtomDefs::getAtom(fatom_not[n]);
157 if (!ad) {
158 funnw.ehdr(mcerr);
159 mcerr << "cannot find atom with notation " << fatom_not[n]
160 << "\nIn particular, check the sequence of initialization\n";
161 spexit(mcerr);
162 }
163 atomh[n] = ad;
164 }
165 double s = 0.0;
166 for (long n = 0; n < qatomh; n++) {
167 weight_quanh[n] = fweight_quan[n];
168 check_econd11(weight_quanh[n], <= 0, mcerr);
169 s += weight_quanh[n];
170 }
171 check_econd11(s, <= 0, mcerr);
172 if (s != 1.0) {
173 for (long n = 0; n < qatomh; n++) {
174 weight_quanh[n] /= s;
175 }
176 }
177 for (long n = 0; n < qatomh; n++) {
178 weight_massh[n] = weight_quanh[n] * atomh[n]->A();
179 }
180 s = 0.0;
181 for (long n = 0; n < qatomh; n++) {
182 s += weight_massh[n];
183 }
184 check_econd11(s, <= 0, mcerr);
185 if (s != 1.0) {
186 for (long n = 0; n < qatomh; n++) {
187 weight_massh[n] /= s;
188 }
189 }
190 for (long n = 0; n < qatomh; n++) {
191 Z_meanh += atomh[n]->Z() * weight_quanh[n];
192 A_meanh += atomh[n]->A() * weight_quanh[n];
193 inv_A_meanh += (1.0 / atomh[n]->A()) * weight_quanh[n];
194 }
195 mean_ratio_Z_to_Ah = Z_meanh / A_meanh;
196 NumberOfElectronsInGramh = mean_ratio_Z_to_Ah * (gram / mole) * Avogadro;
197}
198
199AtomMixDef::AtomMixDef(unsigned long fqatom,
200 const std::vector<std::string>& fatom_not,
201 const std::vector<long>& fweight_quan)
202 : qatomh(fqatom),
203 atomh(fqatom, nullptr),
204 weight_quanh(fqatom, 0.0),
205 weight_massh(fqatom, 0.0) {
206 mfunnamep("AtomMixDef::AtomMixDef(...)");
207 check_econd11(fqatom, <= 0, mcerr);
208 check_econd12(fqatom, >, fatom_not.size(), mcerr);
209 check_econd12(fqatom, >, fweight_quan.size(), mcerr);
210
211 for (long n = 0; n < qatomh; ++n) {
212 auto ad = AtomDefs::getAtom(fatom_not[n]);
213 if (!ad) {
214 funnw.ehdr(mcerr);
215 mcerr << "cannot find atom with notation " << fatom_not[n]
216 << "\nIn particular, check the sequence of initialization\n";
217 spexit(mcerr);
218 }
219 atomh[n] = ad;
220 }
221 double s = 0.0;
222 for (long n = 0; n < qatomh; n++) {
223 weight_quanh[n] = fweight_quan[n];
224 check_econd11(weight_quanh[n], <= 0, mcerr);
225 s += weight_quanh[n];
226 }
227 check_econd11(s, <= 0, mcerr);
228 if (s != 1.0) {
229 for (long n = 0; n < qatomh; n++) {
230 weight_quanh[n] /= s;
231 }
232 }
233 for (long n = 0; n < qatomh; n++) {
234 weight_massh[n] = weight_quanh[n] * atomh[n]->A();
235 }
236 s = 0.0;
237 for (long n = 0; n < qatomh; n++) {
238 s += weight_massh[n];
239 }
240 check_econd11(s, <= 0, mcerr);
241 if (s != 1.0) {
242 for (long n = 0; n < qatomh; n++) {
243 weight_massh[n] /= s;
244 }
245 }
246 for (long n = 0; n < qatomh; n++) {
247 Z_meanh += atomh[n]->Z() * weight_quanh[n];
248 A_meanh += atomh[n]->A() * weight_quanh[n];
249 inv_A_meanh += (1.0 / atomh[n]->A()) * weight_quanh[n];
250 }
251 mean_ratio_Z_to_Ah = Z_meanh / A_meanh;
252 NumberOfElectronsInGramh = mean_ratio_Z_to_Ah * (gram / mole) * Avogadro;
253}
254
255void AtomMixDef::print(std::ostream& file, int l) const {
256 if (l > 0) file << (*this);
257}
258
259std::ostream& operator<<(std::ostream& file, const AtomMixDef& f) {
260 mfunname("std::ostream& operator << (std::ostream&, const AtomMixDef&)");
261 Ifile << "AtomMixDef\n";
262 indn.n += 2;
263 constexpr double gpm = gram / mole;
264 Ifile << "Z_mean()=" << std::setw(3) << f.Z_mean()
265 << " A_mean()/(gram/mole)=" << f.A_mean() / gpm << '\n';
266 Ifile << "inv_A_mean()*(gram/mole)=" << f.inv_A_mean() * gpm << '\n';
267 Ifile << "mean_ratio_Z_to_A()*(gram/mole)="
268 << f.mean_ratio_Z_to_A() * gpm << '\n';
269 Ifile << "NumberOfElectronsInGram()=" << f.NumberOfElectronsInGram() << '\n';
270 // Here above the mass unit is defined,
271 // therefore there is no need to divide by gram.
272 Iprintn(file, f.qatom());
273 indn.n += 2;
274 for (long n = 0; n < f.qatom(); n++) {
275 Ifile << "n=" << n << " atom(n)->notation=" << f.atom(n)->notation()
276 << "\n";
277 indn.n += 2;
278 Ifile << " weight_quan(n)=" << f.weight_quan(n)
279 << " weight_mass(n)=" << f.weight_mass(n) << '\n';
280 indn.n -= 2;
281 }
282 indn.n -= 2;
283 indn.n -= 2;
284 return file;
285}
286}
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
#define check_econd11(a, signb, stream)
#define mfunnamep(string)
#define spexit(stream)
#define check_econd12(a, sign, b, stream)
#define mfunname(string)
double A() const
Definition AtomDef.h:38
int Z() const
Definition AtomDef.h:37
AtomDef()=default
Default constructor.
const std::string & name() const
Definition AtomDef.h:35
void print(std::ostream &file, int l=0) const
Definition AtomDef.cpp:22
const std::string & notation() const
Definition AtomDef.h:36
static const AtomDef * getAtom(const std::string &fnotation)
Definition AtomDef.cpp:114
static void addAtom(const std::string &name, const std::string &notation, const int z, const double a)
Definition AtomDef.cpp:36
static double getA(int fZ)
Definition AtomDef.cpp:121
static void printAtoms(std::ostream &file)
Print all registered atoms.
Definition AtomDef.cpp:109
static const std::list< AtomDef > & getAtoms()
Definition AtomDef.cpp:41
const std::vector< double > & weight_quan() const
Definition AtomDef.h:104
AtomMixDef()=default
Default constructor.
void print(std::ostream &file, int l) const
Definition AtomDef.cpp:255
const std::vector< double > & weight_mass() const
Definition AtomDef.h:105
long qatom() const
Definition AtomDef.h:101
double mean_ratio_Z_to_A() const
Definition AtomDef.h:111
const std::vector< const AtomDef * > & atom() const
Definition AtomDef.h:102
double Z_mean() const
Definition AtomDef.h:108
double NumberOfElectronsInGram() const
Definition AtomDef.h:112
double inv_A_mean() const
Definition AtomDef.h:110
double A_mean() const
Definition AtomDef.h:109
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