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