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