Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
parabol.cpp
Go to the documentation of this file.
1/*
2Copyright (c) 2001 I. B. Smirnov
3
4Permission to use, copy, modify, distribute and sell this file
5and its documentation for any purpose is hereby granted without fee,
6provided that the above copyright notice, this permission notice,
7and notices about any modifications of the original text
8appear in all copies and in supporting documentation.
9It is provided "as is" without express or implied warranty.
10*/
17
18namespace Heed {
19
20Parabol::Parabol(const Parabol& f) { *this = f; }
21
22Parabol::Parabol(double x[3], double y[3]) : s_det(0), s_dxzero(0) {
23 mfunname("Parabol::Parabol(double x[3], double y[3])");
24
25 check_econd12a(x[0], ==, x[1], "x[2]=" << x[2] << " y[0]=" << y[0] << " y[1]="
26 << y[1] << " y[2]=" << y[2] << '\n',
27 mcerr);
28 check_econd12a(x[0], ==, x[2], "x[1]=" << x[1] << " y[0]=" << y[0] << " y[1]="
29 << y[1] << " y[2]=" << y[2] << '\n',
30 mcerr);
31 check_econd12a(x[1], ==, x[2], "x[0]=" << x[0] << " y[0]=" << y[0] << " y[1]="
32 << y[1] << " y[2]=" << y[2] << '\n',
33 mcerr);
34 DynArr<DoubleAc> mat(3, 3);
37 for (int i = 0; i < 3; ++i) {
38 f[i] = y[i];
39 mat.ac(i, 2) = 1.0;
40 mat.ac(i, 1) = x[i];
41 mat.ac(i, 0) = x[i] * x[i];
42 }
43 int ierr;
44 int szero;
45 DynArr<DoubleAc> mat_inv;
46 inverse_DynArr_prot(mat, mat_inv, szero, ierr);
47 // check_econd11a( ierr, != 0 , "should never happen\n", mcerr );
48 if (ierr == 0) {
49 par = mat_inv * f;
50 // Iprintdla_DoubleAc(mcout, par, 3);
51 // if(fabs(par[0]) == 0.0)
52 // da=0.0;
53 // else
54 // da=par[0];
55 da = par[0];
56 db = par[1];
57 dc = par[2];
58 } else {
59 da = 0.0;
60 DynLinArr<int> s_var(3);
61 s_var[0] = 0;
62 s_var[1] = 1;
63 s_var[2] = 1;
64 DynArr<DoubleAc> mat_inv1(3, 3);
65 // int ierr1;
66 // inverse_DynArr(mat, s_var, mat_inv, ierr, mat_inv1, ierr1);
67 inverse_DynArr_prot(mat, s_var, mat_inv, szero, ierr);
68 if (ierr != 0) {
69 // what if x1 and x2 are the same but the both differ from x0
70 // Then the following should help:
71 mat.ac(1, 1) = mat.ac(0, 1);
72 mat.ac(1, 2) = mat.ac(0, 2);
73 f[1] = f[0];
74 s_var[0] = 0;
75 s_var[1] = 1;
76 s_var[2] = 1;
77 inverse_DynArr_prot(mat, s_var, mat_inv, szero, ierr);
78 check_econd11a(ierr, != 0,
79 "should never happen\nmat=" << mat << "\ns_var=" << s_var
80 << "\nmat_inv=" << mat_inv,
81 mcerr);
82 }
83 par = mat_inv * f;
84 db = par[1];
85 dc = par[2];
86 }
87}
88
89Parabol::Parabol(double x1, double x2, double x3, double y1, double y2,
90 double y3)
91 : s_det(0), s_dxzero(0) {
92 mfunname("Parabol::Parabol(double x[3], double y[3])");
93
94 check_econd12a(x1, ==, x2, "x3=" << x3 << " y1=" << y1 << " y2=" << y2
95 << " y3=" << y3 << '\n',
96 mcerr);
97 check_econd12a(x1, ==, x3, "x2=" << x2 << " y1=" << y1 << " y2=" << y2
98 << " y3=" << y3 << '\n',
99 mcerr);
100 check_econd12a(x2, ==, x3, "x1=" << x1 << " y1=" << y1 << " y2=" << y2
101 << " y3=" << y3 << '\n',
102 mcerr);
103 DynArr<DoubleAc> mat(3, 3);
104 DynLinArr<DoubleAc> par(3);
106 f[0] = y1;
107 mat.ac(0, 2) = 1.0;
108 mat.ac(0, 1) = x1;
109 mat.ac(0, 0) = x1 * x1;
110 f[1] = y2;
111 mat.ac(1, 2) = 1.0;
112 mat.ac(1, 1) = x2;
113 mat.ac(1, 0) = x2 * x2;
114 f[2] = y3;
115 mat.ac(2, 2) = 1.0;
116 mat.ac(2, 1) = x3;
117 mat.ac(2, 0) = x3 * x3;
118
119 int ierr;
120 int szero;
121 DynArr<DoubleAc> mat_inv;
122 inverse_DynArr_prot(mat, mat_inv, szero, ierr);
123 // check_econd11a( ierr, != 0 , "should never happen\n", mcerr );
124 if (ierr == 0) {
125 par = mat_inv * f;
126 // Iprintdla_DoubleAc(mcout, par, 3);
127 // if(fabs(par[0]) == 0.0)
128 // da=0.0;
129 // else
130 // da=par[0];
131 da = par[0];
132 db = par[1];
133 dc = par[2];
134 } else {
135 da = 0.0;
136 DynLinArr<int> s_var(3);
137 s_var[0] = 0;
138 s_var[1] = 1;
139 s_var[2] = 1;
140 DynArr<DoubleAc> mat_inv1(3, 3);
141 // int ierr1;
142 // inverse_DynArr(mat, s_var, mat_inv, ierr, mat_inv1, ierr1);
143 inverse_DynArr_prot(mat, s_var, mat_inv, szero, ierr);
144 if (ierr != 0) {
145 // what if x1 and x2 are the same but the both differ from x0
146 // Then the following should help:
147 mat.ac(1, 1) = mat.ac(0, 1);
148 mat.ac(1, 2) = mat.ac(0, 2);
149 f[1] = f[0];
150 s_var[0] = 0;
151 s_var[1] = 1;
152 s_var[2] = 1;
153 inverse_DynArr_prot(mat, s_var, mat_inv, szero, ierr);
154 check_econd11a(ierr, != 0,
155 "should never happen\nmat=" << mat << "\ns_var=" << s_var
156 << "\nmat_inv=" << mat_inv,
157 mcerr);
158 }
159 par = mat_inv * f;
160 db = par[1];
161 dc = par[2];
162 }
163}
164
165Parabol::Parabol(double x[3], double y[3], int /*ii*/) : s_det(0), s_dxzero(0) {
166 mfunname("Parabol::Parabol(double x[3], double y[3], int)");
167
168 check_econd12(x[0], ==, x[1], mcerr);
169 // check_econd12( x[0] , == , x[2] , mcerr);
170 // check_econd12( x[1] , == , x[2] , mcerr);
171
172 DynArr<DoubleAc> mat(3, 3);
173 DynLinArr<DoubleAc> par(3);
175 for (int i = 0; i < 3; ++i) f[i] = y[i];
176 for (int i = 0; i < 2; ++i) {
177 mat.ac(i, 2) = 1.0;
178 mat.ac(i, 1) = x[i];
179 // Iprintdan(mcout, mat.ac(i,1));
180 mat.ac(i, 0) = x[i] * x[i];
181 }
182 mat.ac(2, 2) = 0.0;
183 mat.ac(2, 1) = 1.0;
184 mat.ac(2, 0) = 2.0 * x[2];
185 int ierr;
186 int szero;
187 DynArr<DoubleAc> mat_inv;
188 inverse_DynArr_prot(mat, mat_inv, szero, ierr);
189 check_econd11a(ierr, != 0, "should never happen\n", mcerr);
190 /*
191 if (ierr != 0) {
192 da = 0.0;
193 DynLinArr<int> s_var(3);
194 s_var[0] = 0;
195 s_var[1] = 1;
196 s_var[2] = 1;
197 inverse_DynArr(mat, mat_inv, ierr);
198 check_econd11a( ierr, != 0 , "should never happen\n", mcerr );
199 par = mat_inv * f;
200 db=par[1]; dc=par[2];
201 } else {
202 */
203 par = mat_inv * f;
204 if (fabs(par[0]) == 0.0) {
205 da = 0.0;
206 } else {
207 da = par[0];
208 db = par[1];
209 dc = par[2];
210 }
211 /*
212 HepMatrix mat(3,3,0);
213 HepVector par(3,0);
214 HepVector f(3,0);
215 for (int i = 0; i < 3; i++) f[i]=y[i];
216 for (int i = 0; i < 2; i++) {
217 mat[i][2] = 1.0;
218 mat[i][1] = x[i];
219 mat[i][0] = x[i] * x[i];
220 }
221 mat[2][2] = 0.0;
222 mat[2][1] = 1.0;
223 mat[2][0] = 2.0 * x[2];
224 par = solve(mat, f);
225 da = par[0]; db = par[1]; dc = par[2];
226 */
227}
228
229int Parabol::find_zero(double xzero[2]) const {
230 mfunnamep("int Parabol::find_zero(double xzero[2]) const");
231 const Parabol& t = (*this);
232 if (s_dxzero == 0) {
233 // mcout<<"Parabol::find_zero: s_dxzero == 0\n";
234 t.s_dxzero = 1;
235 if (da == 0.0) {
236 if (db == 0.0) {
237 funnw.ehdr(mcerr);
238 mcerr << "can not find zero\n";
239 spexit(mcerr);
240 } else {
241 t.qdxzero = 1;
242 t.dxzero[0] = -dc / db;
243 }
244 } else {
245 if (determinant() < 0.0) {
246 t.qdxzero = 0;
247 t.dxzero[0] = 0;
248 t.dxzero[1] = 0;
249 } else if (determinant() == 0.0) {
250 t.qdxzero = 1;
251 t.dxzero[0] = -db / (2.0 * da);
252 } else {
253 const double sq = sqrt(determinant());
254 t.qdxzero = 2;
255 if (da > 0.0) {
256 t.dxzero[0] = (-db - sq) / (2.0 * da);
257 t.dxzero[1] = (-db + sq) / (2.0 * da);
258 } else {
259 t.dxzero[1] = (-db - sq) / (2.0 * da);
260 t.dxzero[0] = (-db + sq) / (2.0 * da);
261 }
262 // mcout<<"Parabol::find_zero: t.dxzero[0]="<<t.dxzero[0]
263 // <<" dxzero[0]="<<dxzero[0]<<'\n';
264 // mcout<<"Parabol::find_zero: t.dxzero[1]="<<t.dxzero[1]
265 // <<" dxzero[1]="<<dxzero[1]<<'\n';
266 }
267 }
268 }
269 xzero[0] = dxzero[0];
270 xzero[1] = dxzero[1];
271 return qdxzero;
272}
273
275 mfunname("double Parabol::find_maxmin(void)");
276 check_econd11(da, == 0, mcerr);
277 return -db / (2.0 * da);
278}
279
280std::ostream& operator<<(std::ostream& file, const Parabol& f) {
281 double xz[2];
282 int q = f.find_zero(xz);
283 Ifile << "Parabol: a=" << f.a() << " b=" << f.b() << " c=" << f.c()
284 << " qxzero=" << q;
285 if (q > 0) file << " xzero=" << xz[0];
286 if (q > 1) file << ' ' << xz[1];
287 file << '\n';
288 return file;
289}
290}
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:172
#define check_econd12a(a, sign, b, add, stream)
Definition: FunNameStack.h:181
#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
T & ac(long i)
Definition: AbsArr.h:1717
int find_zero(double xzero[2]) const
Definition: parabol.cpp:229
double c() const
Definition: parabol.h:34
double b() const
Definition: parabol.h:33
double find_maxmin()
Definition: parabol.cpp:274
Parabol(void)
Default constructor.
Definition: parabol.h:52
double a() const
Definition: parabol.h:32
double determinant() const
Definition: parabol.h:72
Definition: BGMesh.cpp:6
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:37
void inverse_DynArr_prot(const DynArr< DoubleAc > &mi, DynArr< DoubleAc > &mr, int &szero, int &serr, int s_stop)
Definition: inverse.cpp:17
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:615
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:314
#define Ifile
Definition: prstream.h:196
#define mcerr
Definition: prstream.h:128