Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
GasDef.cpp
Go to the documentation of this file.
1#include <iomanip>
5
6namespace Heed {
7
8using CLHEP::Avogadro;
9using CLHEP::k_Boltzmann;
10
12
13GasDef::GasDef(const std::string& fname, const std::string& fnotation,
14 long fqmolec, const std::vector<std::string>& fmolec_not,
15 const std::vector<double>& fweight_quan_molec, double fpressure,
16 double ftemperature, double fdensity)
17 : pressureh(fpressure),
18 qmolech(fqmolec),
19 molech(fqmolec, nullptr),
20 weight_quan_molech(fqmolec),
21 weight_mass_molech(fqmolec) {
22 mfunname("GasDef::GasDef(...many molecules...)");
23
24 // Finding pointers to all molec. by notations
25 for (long k = 0; k < fqmolec; ++k) {
26 MoleculeDef* amd = MoleculeDef::get_MoleculeDef(fmolec_not[k]);
27 check_econd11a(amd, == NULL,
28 "No molecule with such notation: " << fmolec_not[k] << '\n',
29 mcerr)
30 if (!amd) {
31 mcerr << "cannot find molecule with notation " << fmolec_not[k]
32 << "\nIn particular, check the sequence of initialization\n";
34 }
35 molech[k] = amd;
36 }
37 double s = 0.0;
38 for (long n = 0; n < fqmolec; ++n) {
39 weight_quan_molech[n] = fweight_quan_molec[n];
40 check_econd11(weight_quan_molech[n], <= 0, mcerr);
41 s += weight_quan_molech[n];
42 }
43 check_econd11(s, <= 0, mcerr);
44 if (s != 1.0) {
45 for (long n = 0; n < fqmolec; ++n) {
46 weight_quan_molech[n] /= s;
47 }
48 }
49 for (long n = 0; n < fqmolec; ++n) {
50 weight_mass_molech[n] = weight_quan_molech[n] * molech[n]->A_total();
51 }
52 s = 0.0;
53 for (long n = 0; n < fqmolec; ++n) {
54 s += weight_mass_molech[n];
55 }
56 check_econd11(s, <= 0, mcerr);
57 if (s != 1.0) {
58 for (long n = 0; n < fqmolec; ++n) {
59 weight_mass_molech[n] /= s;
60 }
61 }
62
63 long qat = 0;
64 std::vector<std::string> fatom_not(1000);
65 std::vector<double> weight_qa(1000, 0.0);
66 for (long k = 0; k < fqmolec; ++k) {
67 for (long n = 0; n < molech[k]->qatom(); ++n) {
68 /*
69 This is originally designed to avoid duplication of an atom
70 in the list if it presents twice in different moleculas.
71 But it appears that the same atom in different moleculas
72 can have different features related to position and sensitivity
73 of external shell. In particular it affects on ionization.
74 This difference can be used in inherited and
75 related classes. Therefore such reduction of the list can produce
76 problems. Therefore this is excluded by commenting off this passage,
77 and also by commenting off mark2.
78 for (i = 0; i < qat; i++) {
79 if (molech[k]->atom(n)->notation() == fatom_not[i]) {
80 weight_qa[i] += fweight_quan_molec[k] * molech[k]->weight_quan(n);
81 goto mark2;
82 }
83 }
84 */
85 fatom_not[qat] = molech[k]->atom(n)->notation();
86 weight_qa[qat] = fweight_quan_molec[k] * molech[k]->qatom_ps(n);
87 // mcout << "qat=" << qat << " fatom_not[qat]=" << fatom_not[qat]
88 // << " weight_qa[qat]=" << weight_qa[qat] << '\n';
89 ++qat;
90 // mark2: ;
91 }
92 }
93 if (fdensity < 0.0) {
94 double sw = 0.0;
95 double sa = 0.0;
96 for (long n = 0; n < qmolech; ++n) {
97 sa += weight_quan_molech[n] * molech[n]->A_total();
98 sw += weight_quan_molech[n];
99 }
100 const double rydberg = k_Boltzmann * Avogadro;
101 fdensity = sa * fpressure / (rydberg * ftemperature * sw);
102 }
103 verify(fname, fnotation);
104 {
105 *((MatterDef*)this) = MatterDef(fname, fnotation, qat, fatom_not, weight_qa,
106 fdensity, ftemperature);
107 }
108}
109
110GasDef::GasDef(const std::string& fname, const std::string& fnotation,
111 long fqmolec, const std::vector<std::string>& fmolec_not,
112 const std::vector<double>& fweight_volume_molec,
113 double fpressure, double ftemperature, int /*s1*/, int /*s2*/) {
114 // s1 and s2 are to distinguish the constructor
115 mfunname("GasDef::GasDef(...many molecules... Waals)");
116 std::vector<MoleculeDef*> amolec(fqmolec);
117 for (long n = 0; n < fqmolec; ++n) {
118 amolec[n] = MoleculeDef::get_MoleculeDef(fmolec_not[n]);
119 check_econd11a(amolec[n], == NULL,
120 "No molecule with such notation: " << fmolec_not[n] << '\n',
121 mcerr)
122 // Van der Waals correction currently not used.
123 // VanDerWaals* aw = amolec[n]->vdw().get();
124 }
125 // first normalize volumes to total unity
126 std::vector<double> fw(fqmolec);
127 // normalized volume weights
128 double s = 0.0;
129 for (long n = 0; n < fqmolec; ++n) {
130 s += fweight_volume_molec[n];
131 }
132 check_econd11(s, <= 0, mcerr);
133 for (long n = 0; n < fqmolec; ++n) {
134 fw[n] = fweight_volume_molec[n] / s;
135 }
136
137 // calculate number of molecules or moles and mass of each component
138 std::vector<double> fweight_quan_molec(fqmolec);
139 double mass_t = 0.0;
140 constexpr double rydberg = k_Boltzmann * Avogadro;
141 for (long n = 0; n < fqmolec; ++n) {
142 VanDerWaals* aw = amolec[n]->vdw().get();
143 if (!aw) {
144 // ideal gas case
145 fweight_quan_molec[n] = fw[n] * fpressure / (rydberg * ftemperature);
146 double ms = fweight_quan_molec[n] * amolec[n]->A_total();
147 // Iprint2n(mcout, fweight_quan_molec[n], ms/gram);
148 mass_t += ms;
149 } else {
150 // van der Waals gas case
151 int s_not_single;
152 double number_of_moles =
153 fw[n] * 1.0 / aw->volume_of_mole(ftemperature, // relative to T_k
154 fpressure, s_not_single);
155 check_econd11(s_not_single, == 1, mcerr);
156 fweight_quan_molec[n] = number_of_moles;
157 double ms = fweight_quan_molec[n] * amolec[n]->A_total();
158 // Iprint2n(mcout, fweight_quan_molec[n], ms/gram);
159 mass_t += ms;
160 }
161 }
162 double density_t = mass_t;
163 *this = GasDef(fname, fnotation, fqmolec, fmolec_not, fweight_quan_molec,
164 fpressure, ftemperature, density_t);
165}
166
167GasDef::GasDef(const std::string& fname, const std::string& fnotation,
168 const std::string& fmolec_not, double fpressure,
169 double ftemperature, double fdensity) {
170 mfunname("GasDef::GasDef(...1 molecule...)");
171 std::vector<std::string> fmolec_noth(1, fmolec_not);
172 std::vector<double> fweight_quan_molec(1, 1.0);
173 {
174 *this = GasDef(fname, fnotation, 1, fmolec_noth, fweight_quan_molec,
175 fpressure, ftemperature, fdensity);
176 }
177}
178
179GasDef::GasDef(const std::string& fname, const std::string& fnotation,
180 const std::string& fmolec_not, double fpressure,
181 double ftemperature, int s1, int s2) {
182 mfunname("GasDef::GasDef(...1 molecule...)");
183 std::vector<std::string> fmolec_noth(1, fmolec_not);
184 std::vector<double> fweight_volume_molec(1, 1.0);
185 {
186 *this = GasDef(fname, fnotation, 1, fmolec_noth, fweight_volume_molec,
187 fpressure, ftemperature, s1, s2);
188 }
189}
190
191GasDef::GasDef(const std::string& fname, const std::string& fnotation,
192 const std::string& fmolec_not1, double fweight_quan_molec1,
193 const std::string& fmolec_not2, double fweight_quan_molec2,
194 double fpressure, double ftemperature, double fdensity) {
195 mfunname("GasDef::GasDef(...2 molecules...)");
196 std::vector<std::string> fmolec_noth(2);
197 std::vector<double> fweight_quan_molec(2, 0.0);
198 fmolec_noth[0] = fmolec_not1;
199 fmolec_noth[1] = fmolec_not2;
200 fweight_quan_molec[0] = fweight_quan_molec1;
201 fweight_quan_molec[1] = fweight_quan_molec2;
202 {
203 *this = GasDef(fname, fnotation, 2, fmolec_noth, fweight_quan_molec,
204 fpressure, ftemperature, fdensity);
205 }
206}
207
208GasDef::GasDef(const std::string& fname, const std::string& fnotation,
209 const std::string& fmolec_not1, double fweight_volume_molec1,
210 const std::string& fmolec_not2, double fweight_volume_molec2,
211 double fpressure, double ftemperature, int s1, int s2) {
212 mfunname("GasDef::GasDef(...2 molecules...)");
213 std::vector<std::string> fmolec_noth(2);
214 std::vector<double> fweight_volume_molec(2, 0.0);
215 fmolec_noth[0] = fmolec_not1;
216 fmolec_noth[1] = fmolec_not2;
217 fweight_volume_molec[0] = fweight_volume_molec1;
218 fweight_volume_molec[1] = fweight_volume_molec2;
219 {
220 *this = GasDef(fname, fnotation, 2, fmolec_noth, fweight_volume_molec,
221 fpressure, ftemperature, s1, s2);
222 }
223}
224
225GasDef::GasDef(const std::string& fname, const std::string& fnotation,
226 const std::string& fmolec_not1, double fweight_quan_molec1,
227 const std::string& fmolec_not2, double fweight_quan_molec2,
228 const std::string& fmolec_not3, double fweight_quan_molec3,
229 double fpressure, double ftemperature, double fdensity) {
230 mfunname("GasDef::GasDef(...3 molecules...)");
231 std::vector<std::string> fmolec_noth(3);
232 std::vector<double> fweight_quan_molec(3, 0.0);
233 fmolec_noth[0] = fmolec_not1;
234 fmolec_noth[1] = fmolec_not2;
235 fmolec_noth[2] = fmolec_not3;
236 fweight_quan_molec[0] = fweight_quan_molec1;
237 fweight_quan_molec[1] = fweight_quan_molec2;
238 fweight_quan_molec[2] = fweight_quan_molec3;
239 {
240 *this = GasDef(fname, fnotation, 3, fmolec_noth, fweight_quan_molec,
241 fpressure, ftemperature, fdensity);
242 }
243}
244
245GasDef::GasDef(const std::string& fname, const std::string& fnotation,
246 const std::string& fmolec_not1, double fweight_volume_molec1,
247 const std::string& fmolec_not2, double fweight_volume_molec2,
248 const std::string& fmolec_not3, double fweight_volume_molec3,
249 double fpressure, double ftemperature, int s1, int s2) {
250 mfunname("GasDef::GasDef(...3 molecules...)");
251 std::vector<std::string> fmolec_noth(3);
252 std::vector<double> fweight_volume_molec(3, 0.0);
253 fmolec_noth[0] = fmolec_not1;
254 fmolec_noth[1] = fmolec_not2;
255 fmolec_noth[2] = fmolec_not3;
256 fweight_volume_molec[0] = fweight_volume_molec1;
257 fweight_volume_molec[1] = fweight_volume_molec2;
258 fweight_volume_molec[2] = fweight_volume_molec3;
259 {
260 *this = GasDef(fname, fnotation, 3, fmolec_noth, fweight_volume_molec,
261 fpressure, ftemperature, s1, s2);
262 }
263}
264
265GasDef::GasDef(const std::string& fname, const std::string& fnotation,
266 const GasDef& gd, double fpressure, double ftemperature,
267 double fdensity) {
268 mfunname("GasDef::GasDef( another GasDef with different pres)");
269 long fqmolec = gd.qmolec();
270 std::vector<std::string> fmolec_not(fqmolec);
271 std::vector<double> fweight_quan_molec(fqmolec);
272 for (long n = 0; n < fqmolec; ++n) {
273 fmolec_not[n] = gd.molec(n)->notation();
274 fweight_quan_molec[n] = gd.weight_quan_molec(n);
275 }
276 *this = GasDef(fname, fnotation, fqmolec, fmolec_not, fweight_quan_molec,
277 fpressure, ftemperature, fdensity);
278}
279
280// mean charge of molecule
281double GasDef::Z_mean_molec(void) const {
282 mfunname("double GasDef::Z_mean_molec(void) const ");
283 double s = 0.0;
284 for (long n = 0; n < qmolech; ++n) {
285 s += molech[n]->Z_total() * weight_quan_molech[n];
286 }
287 return s;
288}
289
290void GasDef::print(std::ostream& file, int l) const {
291 if (l > 0) file << (*this);
292}
293
294std::ostream& operator<<(std::ostream& file, const GasDef& f) {
295 mfunname("std::ostream& operator << (std::ostream& file, const GasDef& f)");
296 Ifile << "GasDef: \n";
297 indn.n += 2;
298 indn.n += 2;
299 file << ((MatterDef&)f);
300 indn.n -= 2;
301 constexpr double mm_rt_st_in_atmosphere = 760.;
302 // This corresponds to 133.322 pascal in one mm
303 //( 101325 pascal in one atmosphere )
304 const double patm = f.pressure() / CLHEP::atmosphere;
305 Ifile << "pressure/atmosphere=" << patm
306 << " pressure/atmosphere * mm_rt_st_in_atmosphere = "
307 << patm * mm_rt_st_in_atmosphere << '\n';
308 Ifile << "Z_mean_molec=" << f.Z_mean_molec() << '\n';
309
310 file << "qmolec()=" << f.qmolec() << '\n';
311 indn.n += 2;
312 for (long n = 0; n < f.qmolec(); ++n) {
313 Ifile << "n=" << n << " molec(n)->notation=" << f.molec(n)->notation()
314 << '\n';
315 indn.n += 2;
316 Ifile << "weight_quan_molec(n)=" << f.weight_quan_molec(n)
317 << " weight_mass_molec(n)=" << f.weight_mass_molec(n) << '\n';
318 Ifile << "Z_total=" << f.molec(n)->Z_total()
319 << " A_total/(gram/mole)=" << f.molec(n)->A_total() / (CLHEP::gram / CLHEP::mole)
320 << '\n';
321 indn.n -= 2;
322 }
323 indn.n -= 2;
324 indn.n -= 2;
325 return file;
326}
327
328}
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:172
#define spexit(stream)
Definition: FunNameStack.h:256
#define mfunname(string)
Definition: FunNameStack.h:45
double Z_mean_molec() const
Mean charge of molecules in this gas.
Definition: GasDef.cpp:281
void print(std::ostream &file, int l=0) const
Definition: GasDef.cpp:290
long qmolec() const
Definition: GasDef.h:47
const std::vector< double > & weight_quan_molec() const
Definition: GasDef.h:52
const std::vector< double > & weight_mass_molec() const
Definition: GasDef.h:55
const std::vector< MoleculeDef * > & molec() const
Definition: GasDef.h:48
double pressure() const
Definition: GasDef.h:46
void verify()
Check that there is no matter with the same name in the container.
Definition: MatterDef.cpp:77
static MoleculeDef * get_MoleculeDef(const std::string &fnotation)
Helper class for Van-der-Waals equation.
Definition: MoleculeDef.h:10
double volume_of_mole(double T, double p, int &s_not_single)
Definition: MoleculeDef.cpp:26
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:196
#define mcerr
Definition: prstream.h:128