Garfield++ 4.0
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
6/*
7Copyright (c) 2001 I. B. Smirnov
8
9Permission to use, copy, modify, distribute and sell this file
10and its documentation for any purpose is hereby granted without fee,
11provided that the above copyright notice, this permission notice,
12and notices about any modifications of the original text
13appear in all copies and in supporting documentation.
14It is provided "as is" without express or implied warranty.
15*/
16
17namespace Heed {
18
19PointsRan::PointsRan(const std::vector<double>& fx,
20 const std::vector<double>& fy, double fxmin, double fxmax)
21 : xmin(fxmin), xmax(fxmax), x(fx), y(fy) {
22 mfunnamep("PointsRan::PointsRan(...)");
23 check_econd12(x.size(), !=, y.size(), mcerr);
24 check_econd11(x.size(), < 2, mcerr);
25 check_econd12(xmin, >=, xmax, mcerr);
26 const long q = x.size();
27 for (long n = 0; n < q - 1; n++) {
28 check_econd12(x[n], >=, x[n + 1], mcerr);
29 }
30 for (long n = 0; n < q; n++) {
31 check_econd11(y[n], < 0.0, mcerr);
32 }
33 iy.resize(q);
34 a.resize(q - 1);
35 for (long 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 (long 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 double s = iy[q - 1];
87 integ_total = s;
88 check_econd11(s, <= 0.0, mcerr);
89}
90
91double PointsRan::ran(double flat_ran) const {
92 mfunnamep("double PointsRan::ran(double flat_ran) const");
93 flat_ran = integ_start + integ_active * flat_ran;
94 // long q = x.get_qel();
95 long n1 = n_start;
96 long n2 = n_finish;
97 long n3;
98 while (n2 - n1 > 1) {
99 n3 = n1 + (n2 - n1) / 2;
100 if (flat_ran < iy[n3]) {
101 n2 = n3;
102 } else {
103 n1 = n3;
104 }
105 }
106 double dran = flat_ran - iy[n1];
107 // double dx = sqrt(2.0 * dran);
108 double dx;
109 if (a[n1] != 0.0) {
110 dx = (-y[n1] + sqrt(y[n1] * y[n1] + 2.0 * a[n1] * dran)) / a[n1];
111 } else {
112 dx = (x[n2] - x[n1]) / (iy[n2] - iy[n1]) * dran;
113 }
114 // check_econd11(dx , < 0 , mcerr); // for debug
115 // check_econd11(dx , > x[n2] - x[n1] , mcerr); // for debug
116 double r = x[n1] + dx;
117 return r;
118}
119
120void PointsRan::print(std::ostream& file) const {
121 Ifile << "PointsRan:\n";
122 indn.n += 2;
123 Ifile << "xmin=" << xmin << " xmax=" << xmax << '\n';
124 Ifile << "n_start=" << n_start << " n_finish=" << n_finish << '\n';
125 Ifile << "integ_start=" << integ_start << " integ_finish=" << integ_finish
126 << '\n';
127 Ifile << "integ_total=" << integ_total << " integ_active=" << integ_active
128 << '\n';
129 // Iprintn(file, integ);
130 const long q = x.size();
131 Iprintn(file, q);
132 for (long n = 0; n < q; n++) {
133 file << std::setw(3) << n << ' ' << std::setw(12) << x[n] << ' '
134 << std::setw(12) << y[n] << ' ' << std::setw(12) << iy[n];
135 if (n < q - 1) file << ' ' << std::setw(12) << a[n];
136 file << '\n';
137 }
138 indn.n -= 2;
139}
140}
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
#define mfunnamep(string)
Definition: FunNameStack.h:49
#define check_econd12(a, sign, b, stream)
Definition: FunNameStack.h:163
void print(std::ostream &file) const
Definition: PointsRan.cpp:120
double ran(double flat_ran) const
Definition: PointsRan.cpp:91
Definition: BGMesh.cpp:6
indentation indn
Definition: prstream.cpp:15
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:314
#define Ifile
Definition: prstream.h:195
#define mcerr
Definition: prstream.h:128
#define Iprintn(file, name)
Definition: prstream.h:204