14 std::cerr <<
m_className <<
"::SetGeometry: Null pointer.\n";
33 const double ,
double& wx,
double& wy,
34 double& wz,
const std::string& ) {
36 std::cerr <<
m_className <<
"::WeightingField: Function not implemented.\n";
45 double& wx,
double& wy,
double& wz,
46 const std::string& ) {
48 std::cerr <<
m_className <<
"::DelayedWeightingField: "
49 <<
"Function not implemented.\n";
56 const std::string& ) {
58 std::cerr <<
m_className <<
"::WeightingPotential: "
59 <<
"Function not implemented.\n";
65 const double z,
double& bx,
double& by,
66 double& bz,
int& status) {
71 std::cout <<
m_className <<
"::MagneticField: Field at (" << x <<
", " << y
72 <<
", " << z <<
") is (" << bx <<
", " << by <<
", " << bz
86 double& xmax,
double& ymax,
double& zmax) {
92 const double ,
const double ,
93 const double ,
const double ,
95 double& ,
const bool ,
101 const double y0,
const double ,
102 double& xw,
double& yw,
double& rw) {
111 const unsigned int nI) {
115 <<
" Number of intervals must be > 0.\n";
119 constexpr unsigned int nG = 6;
120 constexpr std::array<double, nG> t = {
121 -0.932469514203152028, -0.661209386466264514, -0.238619186083196909,
122 0.238619186083196909, 0.661209386466264514, 0.932469514203152028};
123 constexpr std::array<double, nG> w = {
124 0.171324492379170345, 0.360761573048138608, 0.467913934572691047,
125 0.467913934572691047, 0.360761573048138608, 0.171324492379170345};
128 const double d = TwoPi / nI;
129 const double h = 0.5 * d;
131 double ex = 0., ey = 0., ez = 0.;
136 for (
unsigned int i = 0; i < nG; ++i) {
137 const double phi0 = h * (1. + t[i]);
138 for (
unsigned int k = 0; k < nI; ++k) {
139 const double phi = phi0 + k * d;
140 const double cp = cos(phi);
141 const double sp = sin(phi);
142 ElectricField(xc + cp * r, yc + sp * r, 0., ex, ey, ez, m, status);
143 s += w[i] * r * (ex * cp + ey * sp);
146 return h * s * VacuumPermittivity;
150 const double zc,
const double r,
151 const unsigned int nI) {
155 <<
" Number of intervals must be > 0.\n";
159 constexpr unsigned int nG = 6;
160 constexpr std::array<double, nG> t = {
161 -0.932469514203152028, -0.661209386466264514, -0.238619186083196909,
162 0.238619186083196909, 0.661209386466264514, 0.932469514203152028};
163 constexpr std::array<double, nG> w = {
164 0.171324492379170345, 0.360761573048138608, 0.467913934572691047,
165 0.467913934572691047, 0.360761573048138608, 0.171324492379170345};
167 const double r2 = r * r;
169 const double dt = Pi / nI;
170 const double ht = 0.5 * dt;
172 const double dp = TwoPi / nI;
173 const double hp = 0.5 * dp;
175 double ex = 0., ey = 0., ez = 0.;
181 for (
unsigned int i = 0; i < nG; ++i) {
182 const double theta0 = ht * (1. + t[i]) - HalfPi;
183 for (
unsigned int k = 0; k < nI; ++k) {
184 const double theta = theta0 + k * dt;
185 const double ct = cos(theta);
186 const double st = sin(theta);
187 const double z = zc + st * r;
190 for (
unsigned int ii = 0; ii < nG; ++ii) {
191 const double phi0 = hp * (1. + t[ii]);
192 for (
unsigned int kk = 0; kk < nI; ++kk) {
193 const double phi = phi0 + kk * dp;
194 const double cp = cos(phi);
195 const double sp = sin(phi);
196 const double x = xc + cp * ct * r;
197 const double y = yc + sp * ct * r;
199 s1 += w[ii] * ((ex * cp + ey * sp) * ct + ez * st);
202 s2 += w[i] * r2 * ct * hp * s1;
205 return ht * s2 * VacuumPermittivity;
209 const double x0,
const double y0,
const double z0,
210 const double dx1,
const double dy1,
const double dz1,
211 const double dx2,
const double dy2,
const double dz2,
212 const unsigned int nU,
const unsigned int nV) {
215 if (nU <= 1 || nV <= 1) {
217 <<
" Number of points to integrate over must be > 1.\n";
221 constexpr unsigned int nG = 6;
222 constexpr std::array<double, nG> t = {
223 -0.932469514203152028, -0.661209386466264514, -0.238619186083196909,
224 0.238619186083196909, 0.661209386466264514, 0.932469514203152028};
225 constexpr std::array<double, nG> w = {
226 0.171324492379170345, 0.360761573048138608, 0.467913934572691047,
227 0.467913934572691047, 0.360761573048138608, 0.171324492379170345};
230 const double xn = dy1 * dz2 - dz1 * dy2;
231 const double yn = dz1 * dx2 - dx1 * dz2;
232 const double zn = dx1 * dy2 - dy1 * dx2;
234 std::cout <<
m_className <<
"::IntegrateFlux: Normal vector = "
235 << xn <<
", " << yn <<
", " << zn <<
".\n";
238 const double d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1;
239 const double d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2;
240 if (xn * xn + yn * yn + zn * zn < 1.e-10 * sqrt(d1 * d2) ||
241 d1 < 1.e-10 * d2 || d2 < 1.e-10 * d1) {
243 <<
" Parallelogram does not have non-zero area.\n";
248 const double du = 1. / nU;
249 const double hu = 0.5 * du;
250 const double dv = 1. / nV;
251 const double hv = 0.5 * dv;
253 double ex = 0., ey = 0., ez = 0.;
258 for (
unsigned int i = 0; i < nG; ++i) {
259 const double v0 = hv * (1. + t[i]);
260 for (
unsigned int k = 0; k < nV; ++k) {
261 const double v = v0 + k * dv;
263 for (
unsigned int ii = 0; ii < nG; ++ii) {
264 const double u0 = hu * (1. + t[ii]);
265 for (
unsigned int kk = 0; kk < nU; ++kk) {
266 const double u = u0 + kk * du;
267 const double x = x0 + u * dx1 + v * dx2;
268 const double y = y0 + u * dy1 + v * dy2;
269 const double z = z0 + u * dz1 + v * dz2;
271 s1 += w[ii] * (ex * xn + ey * yn + ez * zn);
274 s2 += w[i] * hu * s1;
double IntegrateFluxSphere(const double xc, const double yc, const double zc, const double r, const unsigned int nI=20)
virtual void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status)=0
ComponentBase()
Constructor.
double IntegrateFluxCircle(const double xc, const double yc, const double r, const unsigned int nI=50)
virtual double WeightingPotential(const double x, const double y, const double z, const std::string &label)
virtual void Clear()
Reset.
virtual bool IsWireCrossed(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, double &xc, double &yc, double &zc, const bool centre, double &rc)
GeometryBase * m_geometry
Pointer to the geometry.
void SetMagneticField(const double bx, const double by, const double bz)
Set a constant magnetic field.
virtual void Reset()=0
Reset the component.
virtual void MagneticField(const double x, const double y, const double z, double &bx, double &by, double &bz, int &status)
virtual void DelayedWeightingField(const double x, const double y, const double z, const double t, double &wx, double &wy, double &wz, const std::string &label)
virtual bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Get the bounding box coordinates.
virtual void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label)
double IntegrateFlux(const double x0, const double y0, const double z0, const double dx1, const double dy1, const double dz1, const double dx2, const double dy2, const double dz2, const unsigned int nU=20, const unsigned int nV=20)
std::string m_className
Class name.
virtual void SetGeometry(GeometryBase *geo)
Define the geometry.
virtual bool IsInTrapRadius(const double q0, const double x0, const double y0, const double z0, double &xw, double &yw, double &rw)
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).
Abstract base class for geometry classes.
virtual Medium * GetMedium(const double x, const double y, const double z) const =0
Retrieve the medium at a given point.
virtual bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)=0
Get the bounding box (envelope of the geometry).
Abstract base class for media.