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