Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
PointsRan.cpp
Go to the documentation of this file.
1#include <iomanip>
2#include <cmath>
5/*
6Copyright (c) 2001 I. B. Smirnov
7
8Permission to use, copy, modify, distribute and sell this file
9and its documentation for any purpose is hereby granted without fee,
10provided that the above copyright notice, this permission notice,
11and notices about any modifications of the original text
12appear in all copies and in supporting documentation.
13It is provided "as is" without express or implied warranty.
14*/
15
17 double fxmax)
18 : xmin(fxmin), xmax(fxmax), x(fx), y(fy) {
19 mfunnamep("PointsRan::PointsRan(...)");
20 check_econd12(x.get_qel(), !=, y.get_qel(), mcerr);
21 check_econd11(x.get_qel(), < 2, mcerr);
22 check_econd12(xmin, >=, xmax, mcerr);
23 //check_econd12(xmin , > , x[0] , mcerr);
24 long q = x.get_qel();
25 //check_econd12(xmax , < , x[q-1] , mcerr);
26 long n;
27 for (n = 0; n < q - 1; n++) {
28 check_econd12(x[n], >=, x[n + 1], mcerr);
29 }
30 for (n = 0; n < q; n++) {
31 check_econd11(y[n], < 0.0, mcerr);
32 }
33 iy = DynLinArr<double>(q);
34 a = DynLinArr<double>(q - 1);
35 for (n = 0; n < q - 1; n++) {
36 a[n] = (y[n + 1] - y[n]) / (x[n + 1] - x[n]);
37 }
38 if (xmin < x[0]) {
39 double y0 = y[0] - a[0] * (x[0] - xmin);
40 if (y0 < 0.0) {
41 x[0] = x[0] - y[0] / a[0];
42 check_econd12(xmax, <, x[0], mcerr);
43 xmin = x[0];
44 y[0] = 0.0;
45 } else {
46 y[0] = y0;
47 x[0] = xmin;
48 }
49 }
50 if (xmax > x[q - 1]) {
51 double yq = y[q - 1] + a[q - 2] * (xmax - x[q - 1]);
52 if (yq < 0.0) {
53 x[q - 1] = x[q - 1] - y[q - 1] / a[0];
54 check_econd12(xmin, >, x[q - 1], mcerr);
55 xmax = x[q - 1];
56 y[q - 1] = 0.0;
57 } else {
58 x[q - 1] = xmax;
59 y[q - 1] = yq;
60 }
61 }
62 // now xmin and xmax should be between x[0] and x[q-1]
63 iy[0] = 0.0;
64 integ_start = 0.0;
65 n_start = 0;
66 for (n = 1; n < q; n++) {
67 iy[n] = iy[n - 1] + 0.5 * (x[n] - x[n - 1]) * (y[n - 1] + y[n]);
68 if (xmin >= x[n]) {
69 integ_start = iy[n];
70 n_start = n;
71 } else if (xmin > x[n - 1]) {
72 integ_start +=
73 (xmin - x[n - 1]) * (y[n - 1] + 0.5 * a[n - 1] * (xmin - x[n - 1]));
74 n_start = n - 1;
75 }
76 if (xmax >= x[n]) {
77 integ_finish = iy[n];
78 n_finish = n;
79 } else if (xmax > x[n - 1]) {
80 integ_finish +=
81 (xmax - x[n - 1]) * (y[n - 1] + 0.5 * a[n - 1] * (xmax - x[n - 1]));
82 n_finish = n;
83 }
84 }
85 integ_active = integ_finish - integ_start;
86 /*
87 for( n=0; n<q; n++)
88 {
89 mcout<<std::setw(3)<<n
90 <<' '<<std::setw(12)<<x[n]
91 <<' '<<std::setw(12)<<y[n]
92 <<' '<<std::setw(12)<<iy[n];
93 if(n < q-1)
94 mcout<<' '<<std::setw(12)<<a[n];
95 mcout<<'\n';
96 }
97 */
98 double s = iy[q - 1];
99 integ_total = s;
100 check_econd11(s, <= 0.0, mcerr);
101
102 //s = 1.0 / s;
103 //for( n=0; n<q; n++)
104 //{
105 // y[n] = y[n] * s;
106 // iy[n] = iy[n] * s;
107 // if(n < q-1)
108 // a[n] = a[n] * s;
109 //}
110 //check_econd11(fabs(iy[q-1] - 1.0) , > 1.0e-10 , mcerr);
111 //iy[q-1] = 1.0;
112}
113
114double PointsRan::ran(double flat_ran) const {
115 mfunnamep("double PointsRan::ran(double flat_ran) const");
116 flat_ran = integ_start + integ_active * flat_ran;
117 // long q = x.get_qel();
118 long n1 = n_start;
119 long n2 = n_finish;
120 long n3;
121 while (n2 - n1 > 1) {
122 n3 = n1 + (n2 - n1) / 2;
123 if (flat_ran < iy[n3]) {
124 n2 = n3;
125 } else {
126 n1 = n3;
127 }
128 }
129 double dran = flat_ran - iy[n1];
130 //double dx = sqrt(2.0 * dran);
131 double dx;
132 if (a[n1] != 0.0) {
133 dx = (-y[n1] + sqrt(y[n1] * y[n1] + 2.0 * a[n1] * dran)) / a[n1];
134 } else {
135 dx = (x[n2] - x[n1]) / (iy[n2] - iy[n1]) * dran;
136 }
137 //check_econd11(dx , < 0 , mcerr); // for debug
138 //check_econd11(dx , > x[n2] - x[n1] , mcerr); // for debug
139 double r = x[n1] + dx;
140 return r;
141}
142
143void PointsRan::print(std::ostream& file) const {
144 Ifile << "PointsRan:\n";
145 indn.n += 2;
146 Ifile << "xmin=" << xmin << " xmax=" << xmax << '\n';
147 Ifile << "n_start=" << n_start << " n_finish=" << n_finish << '\n';
148 Ifile << "integ_start=" << integ_start << " integ_finish=" << integ_finish
149 << '\n';
150 Ifile << "integ_total=" << integ_total << " integ_active=" << integ_active
151 << '\n';
152 //Iprintn(file, integ);
153 long q = x.get_qel();
154 Iprintn(file, q);
155 long n;
156 for (n = 0; n < q; n++) {
157 file << std::setw(3) << n << ' ' << std::setw(12) << x[n] << ' '
158 << std::setw(12) << y[n] << ' ' << std::setw(12) << iy[n];
159 if (n < q - 1) file << ' ' << std::setw(12) << a[n];
160 file << '\n';
161 }
162 indn.n -= 2;
163}
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:313
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:366
#define mfunnamep(string)
Definition: FunNameStack.h:77
#define check_econd12(a, sign, b, stream)
Definition: FunNameStack.h:380
long get_qel(void) const
Definition: AbsArr.h:420
double ran(double flat_ran) const
Definition: PointsRan.cpp:114
PointsRan(void)
Definition: PointsRan.h:43
void print(std::ostream &file) const
Definition: PointsRan.cpp:143
indentation indn
Definition: prstream.cpp:13
#define Ifile
Definition: prstream.h:207
#define mcerr
Definition: prstream.h:135
#define Iprintn(file, name)
Definition: prstream.h:216