Garfield++ v2r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
ComponentConstant.cc
Go to the documentation of this file.
1#include <iostream>
2
5
6namespace Garfield {
7
10 m_fx(0.),
11 m_fy(0.),
12 m_fz(0.),
13 m_hasPotential(false),
14 m_x0(0.),
15 m_y0(0.),
16 m_z0(0.),
17 m_v0(0.),
18 m_hasWeightingField(false),
19 m_wfield(""),
20 m_fwx(0.),
21 m_fwy(0.),
22 m_fwz(0.),
23 m_hasWeightingPotential(false),
24 m_wx0(0.),
25 m_wy0(0.),
26 m_wz0(0.),
27 m_w0(0.) {
28
29 m_className = "ComponentConstant";
30}
31
32void ComponentConstant::ElectricField(const double x, const double y,
33 const double z, double& ex, double& ey,
34 double& ez, Medium*& m, int& status) {
35
36 ex = m_fx;
37 ey = m_fy;
38 ez = m_fz;
39 m = GetMedium(x, y, z);
40 if (!m) {
41 if (m_debug) {
42 std::cerr << m_className << "::ElectricField:\n";
43 std::cerr << " (" << x << ", " << y << ", " << z << ")"
44 << " is not inside a medium.\n";
45 }
46 status = -6;
47 return;
48 }
49
50 if (m->IsDriftable()) {
51 status = 0;
52 } else {
53 status = -5;
54 }
55}
56
57void ComponentConstant::ElectricField(const double x, const double y,
58 const double z, double& ex, double& ey,
59 double& ez, double& v, Medium*& m,
60 int& status) {
61
62 ex = m_fx;
63 ey = m_fy;
64 ez = m_fz;
65 if (m_hasPotential) {
66 v = m_v0 - (x - m_x0) * m_fx - (y - m_y0) * m_fy - (z - m_z0) * m_fz;
67 } else {
68 v = 0.;
69 if (m_debug) {
70 std::cerr << m_className << "::ElectricField:\n";
71 std::cerr << " Potential is not defined.\n";
72 }
73 }
74
75 m = GetMedium(x, y, z);
76 if (!m) {
77 if (m_debug) {
78 std::cerr << m_className << "::ElectricField:\n";
79 std::cerr << " (" << x << ", " << y << ", " << z << ")"
80 << " is not inside a medium.\n";
81 }
82 status = -6;
83 return;
84 }
85
86 if (m->IsDriftable()) {
87 status = 0;
88 } else {
89 status = -5;
90 }
91}
92
93bool ComponentConstant::GetVoltageRange(double& vmin, double& vmax) {
94
95 if (!m_hasPotential) return false;
96
97 if (!m_geometry) {
98 std::cerr << m_className << "::GetVoltageRange:\n";
99 std::cerr << " Geometry pointer is null.\n";
100 return false;
101 }
102 double xmin, ymin, zmin;
103 double xmax, ymax, zmax;
104 if (!GetBoundingBox(xmin, ymin, zmin, xmax, ymax, zmax)) {
105 std::cerr << m_className << "::GetVoltageRange:\n";
106 std::cerr << " Could not determine bounding box.\n";
107 return false;
108 }
109 // Calculate potentials at each corner
110 const double pxmin = m_v0 - (xmin - m_x0) * m_fx;
111 const double pxmax = m_v0 - (xmax - m_x0) * m_fx;
112 const double pymin = m_v0 - (ymin - m_y0) * m_fy;
113 const double pymax = m_v0 - (ymax - m_y0) * m_fy;
114 const double pzmin = m_v0 - (zmin - m_z0) * m_fz;
115 const double pzmax = m_v0 - (zmax - m_z0) * m_fz;
116 double p[8];
117 p[0] = pxmin + pymin + pzmin;
118 p[1] = pxmin + pymin + pzmax;
119 p[2] = pxmin + pymax + pzmin;
120 p[3] = pxmin + pymax + pzmax;
121 p[4] = pxmax + pymin + pzmin;
122 p[5] = pxmax + pymin + pzmax;
123 p[6] = pxmax + pymax + pzmin;
124 p[7] = pxmax + pymax + pzmax;
125 vmin = vmax = p[7];
126 for (int i = 7; i--;) {
127 if (p[i] > vmax) vmax = p[i];
128 if (p[i] < vmin) vmin = p[i];
129 }
130
131 return true;
132}
133
134void ComponentConstant::WeightingField(const double x, const double y,
135 const double z, double& wx, double& wy,
136 double& wz, const std::string& label) {
137
138 if (!m_hasWeightingField || label != m_wfield) return;
139
140 Medium* m = GetMedium(x, y, z);
141 if (!m) {
142 wx = wy = wz = 0.;
143 if (m_debug) {
144 std::cout << m_className << "::WeightingField:\n";
145 std::cout << " No medium at (" << x << ", " << y << ", " << z << ")\n";
146 }
147 return;
148 }
149 wx = m_fwx;
150 wy = m_fwy;
151 wz = m_fwz;
152}
153
154double ComponentConstant::WeightingPotential(const double x, const double y,
155 const double z,
156 const std::string& label) {
157
158 if (!m_hasWeightingPotential || label != m_wfield) return 0.;
159
160 Medium* m = GetMedium(x, y, z);
161 if (!m) return 0.;
162
163 return m_w0 - (x - m_wx0) * m_fwx - (y - m_wy0) * m_fwy - (z - m_wz0) * m_fwz;
164}
165
166void ComponentConstant::SetElectricField(const double ex, const double ey,
167 const double ez) {
168
169 m_fx = ex;
170 m_fy = ey;
171 m_fz = ez;
172 if (m_fx * m_fx + m_fy * m_fy + m_fz * m_fz > Small) return;
173
174 std::cerr << m_className << "::SetField:\n";
175 std::cerr << " Electric field is set to zero.\n";
176 m_ready = true;
177}
178
179void ComponentConstant::SetPotential(const double x, const double y,
180 const double z, const double v) {
181
182 m_x0 = x;
183 m_y0 = y;
184 m_z0 = z;
185 m_v0 = v;
186 m_hasPotential = true;
187}
188
189void ComponentConstant::SetWeightingField(const double wx, const double wy,
190 const double wz,
191 const std::string label) {
192
193 m_wfield = label;
194 m_fwx = wx;
195 m_fwy = wy;
196 m_fwz = wz;
197 m_hasWeightingField = true;
198}
199
200void ComponentConstant::SetWeightingPotential(const double x, const double y,
201 const double z, const double v) {
202
203 if (!m_hasWeightingField) {
204 std::cerr << m_className << "::SetWeightingPotential:\n";
205 std::cerr << " Set the weighting field first!\n";
206 return;
207 }
208 m_wx0 = x;
209 m_wy0 = y;
210 m_wz0 = z;
211 m_w0 = v;
212 m_hasWeightingPotential = true;
213}
214
215void ComponentConstant::Reset() {
216
217 m_fx = m_fy = m_fz = 0.;
218 m_hasPotential = false;
219 m_hasWeightingField = false;
220 m_hasWeightingPotential = false;
221 m_wfield = "";
222 m_ready = false;
223}
224
225void ComponentConstant::UpdatePeriodicity() {
226
227 if (m_debug) {
228 std::cerr << m_className << "::UpdatePeriodicity:\n";
229 std::cerr << " Periodicities are not supported.\n";
230 }
231}
232}
Abstract base class for components.
GeometryBase * m_geometry
Pointer to the geometry.
bool m_ready
Ready for use?
virtual bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Get the bounding box coordinates.
std::string m_className
Class name.
bool m_debug
Switch on/off debugging messages.
virtual Medium * GetMedium(const double x, const double y, const double z)
Get the medium at a given location (x, y, z).
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status)
void SetElectricField(const double ex, const double ey, const double ez)
double WeightingPotential(const double x, const double y, const double z, const std::string &label)
bool GetVoltageRange(double &vmin, double &vmax)
Calculate the voltage range [V].
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label)
void SetPotential(const double x, const double y, const double z, const double v=0.)
void SetWeightingPotential(const double x, const double y, const double z, const double v=0.)
void SetWeightingField(const double wx, const double wy, const double wz, const std::string label)
Abstract base class for media.
Definition: Medium.hh:11
bool IsDriftable() const
Definition: Medium.hh:57