18 std::cerr <<
m_className <<
"::SetGeometry: Null pointer.\n";
43 const double x,
const double y,
const double z) {
44 double ex = 0., ey = 0., ez = 0.;
48 std::array<double, 3> efield = {ex, ey, ez};
54 double ex = 0., ey = 0., ez = 0., v = 0.;
62 const double ,
double& wx,
double& wy,
63 double& wz,
const std::string& ) {
65 std::cerr <<
m_className <<
"::WeightingField: Function not implemented.\n";
71 const double ,
const double ,
72 double& wx,
double& wy,
double& wz,
73 const std::string& ) {
75 std::cerr <<
m_className <<
"::DelayedWeightingField: Not implemented.\n";
82 const std::string& ) {
84 std::cerr <<
m_className <<
"::WeightingPotential: Not implemented.\n";
93 const std::string& ) {
96 <<
"::DelayedWeightingPotential: Not implemented.\n";
103 double& bx,
double& by,
double& bz,
int& status) {
108 std::cout <<
m_className <<
"::MagneticField: Field at (" << x <<
", " << y
109 <<
", " << z <<
") is (" << bx <<
", " << by <<
", " << bz
121 double& xmax,
double& ymax,
double& zmax) {
123 return m_geometry->GetBoundingBox(xmin, ymin, zmin, xmax, ymax, zmax);
127 double& xmax,
double& ymax,
double& zmax) {
132 const double ,
const double ,
const double ,
133 const double ,
const double ,
const double ,
134 double& ,
double& ,
double& ,
135 const bool ,
double& ) {
140 const double y0,
const double ,
double& xw,
141 double& yw,
double& rw) {
149 const double ,
const double ,
const double ,
150 const double ,
const double ,
const double ,
151 double& ,
double& ,
double& ) {
156 return fabs(
m_b0[0]) > Small || fabs(
m_b0[1]) > Small ||
157 fabs(
m_b0[2]) > Small;
161 const double r,
const unsigned int nI) {
164 std::cerr <<
m_className <<
"::IntegrateFluxCircle:\n"
165 <<
" Number of intervals must be > 0.\n";
169 constexpr size_t nG = 6;
174 const double d = TwoPi / nI;
175 const double h = 0.5 * d;
177 double ex = 0., ey = 0., ez = 0.;
182 for (
size_t i = 0; i < nG; ++i) {
183 const double phi0 = h * (1. + tg[i]);
184 for (
unsigned int k = 0; k < nI; ++k) {
185 const double phi = phi0 + k * d;
186 const double cp = cos(phi);
187 const double sp = sin(phi);
188 ElectricField(xc + cp * r, yc + sp * r, 0., ex, ey, ez, m, status);
189 s += wg[i] * r * (ex * cp + ey * sp);
192 return h * s * VacuumPermittivity;
196 const double zc,
const double r,
197 const unsigned int nI) {
200 std::cerr <<
m_className <<
"::IntegrateFluxSphere:\n"
201 <<
" Number of intervals must be > 0.\n";
205 constexpr size_t nG = 6;
209 const double r2 = r * r;
211 const double dt = Pi / nI;
212 const double ht = 0.5 * dt;
214 const double dp = TwoPi / nI;
215 const double hp = 0.5 * dp;
217 double ex = 0., ey = 0., ez = 0.;
223 for (
size_t i = 0; i < nG; ++i) {
224 const double theta0 = ht * (1. + tg[i]) - HalfPi;
225 for (
unsigned int k = 0; k < nI; ++k) {
226 const double theta = theta0 + k * dt;
227 const double ct = cos(theta);
228 const double st = sin(theta);
229 const double z = zc + st * r;
232 for (
size_t ii = 0; ii < nG; ++ii) {
233 const double phi0 = hp * (1. + tg[ii]);
234 for (
unsigned int kk = 0; kk < nI; ++kk) {
235 const double phi = phi0 + kk * dp;
236 const double cp = cos(phi);
237 const double sp = sin(phi);
238 const double x = xc + cp * ct * r;
239 const double y = yc + sp * ct * r;
241 s1 += wg[ii] * ((ex * cp + ey * sp) * ct + ez * st);
244 s2 += wg[i] * r2 * ct * hp * s1;
247 return ht * s2 * VacuumPermittivity;
251 const double x0,
const double y0,
const double z0,
const double dx1,
252 const double dy1,
const double dz1,
const double dx2,
const double dy2,
253 const double dz2,
const unsigned int nU,
const unsigned int nV) {
256 x0, y0, z0, dx1, dy1, dz1, dx2, dy2, dz2, nU, nV,
false,
"");
260 const double x0,
const double y0,
const double z0,
const double dx1,
261 const double dy1,
const double dz1,
const double dx2,
const double dy2,
262 const double dz2,
const unsigned int nU,
const unsigned int nV) {
265 x0, y0, z0, dx1, dy1, dz1, dx2, dy2, dz2, nU, nV,
true,
id);
269 const double x0,
const double y0,
const double z0,
const double dx1,
270 const double dy1,
const double dz1,
const double dx2,
const double dy2,
271 const double dz2,
const unsigned int nU,
const unsigned int nV,
272 const bool wfield,
const std::string& label) {
275 if (nU <= 1 || nV <= 1) {
276 std::cerr <<
m_className <<
"::IntegrateFluxParallelogram:\n"
277 <<
" Number of points to integrate over must be > 1.\n";
281 constexpr size_t nG = 6;
286 const double xn = dy1 * dz2 - dz1 * dy2;
287 const double yn = dz1 * dx2 - dx1 * dz2;
288 const double zn = dx1 * dy2 - dy1 * dx2;
290 std::cout <<
m_className <<
"::IntegrateFluxParallelogram:\n"
291 <<
" Normal vector = " << xn <<
", " << yn <<
", " << zn
295 const double d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1;
296 const double d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2;
297 if (xn * xn + yn * yn + zn * zn < 1.e-10 *
sqrt(d1 * d2) ||
298 d1 < 1.e-10 * d2 || d2 < 1.e-10 * d1) {
299 std::cerr <<
m_className <<
"::IntegrateFluxParallelogram:\n"
300 <<
" Parallelogram does not have non-zero area.\n";
305 const double du = 1. / nU;
306 const double hu = 0.5 * du;
307 const double dv = 1. / nV;
308 const double hv = 0.5 * dv;
310 double fx = 0., fy = 0., fz = 0.;
315 for (
size_t i = 0; i < nG; ++i) {
316 const double v0 = hv * (1. + tg[i]);
317 for (
unsigned int k = 0; k < nV; ++k) {
318 const double v = v0 + k * dv;
320 for (
size_t ii = 0; ii < nG; ++ii) {
321 const double u0 = hu * (1. + tg[ii]);
322 for (
unsigned int kk = 0; kk < nU; ++kk) {
323 const double u = u0 + kk * du;
324 const double x = x0 + u * dx1 + v * dx2;
325 const double y = y0 + u * dy1 + v * dy2;
326 const double z = z0 + u * dz1 + v * dz2;
332 s1 += wg[ii] * (fx * xn + fy * yn + fz * zn);
335 s2 += wg[i] * hu * s1;
342 const double z0,
const double x1,
343 const double y1,
const double z1,
344 const double xp,
const double yp,
345 const double zp,
const unsigned int nI,
349 const double pmag2 = xp * xp + yp * yp + zp * zp;
351 std::cerr <<
m_className <<
"::IntegrateFluxLine:\n"
352 <<
" Normal vector has zero length; flux set to 0.\n";
355 const double pmag = sqrt(pmag2);
356 const double xn = xp / pmag;
357 const double yn = yp / pmag;
358 const double zn = zp / pmag;
362 std::cerr <<
m_className <<
"::IntegrateFluxLine:\n"
363 <<
" Number of points to integrate over must be > 1.\n";
367 const double vx = x1 - x0;
368 const double vy = y1 - y0;
369 const double vz = z1 - z0;
370 const double vmag2 = vx * vx + vy * vy + vz * vz;
372 std::cerr <<
m_className <<
"::IntegrateFluxLine:\n"
373 <<
" Segment has zero length; flux set to 0.\n";
376 const double vmag = sqrt(vmag2);
378 if (fabs(vx * xn + vy * yn + vz * zn) > 1.e-4 * vmag) {
379 std::cerr <<
m_className <<
"::IntegrateFluxLine:\n"
380 <<
" Segment is not perpendicular to norm vector.\n";
385 constexpr size_t nG = 6;
389 const double d = 1. / nI;
390 const double h = 0.5 * d;
392 double ex = 0., ey = 0., ez = 0.;
396 for (
size_t i = 0; i < nG; ++i) {
397 const double u0 = h * (1. + tg[i]);
398 for (
unsigned int k = 0; k < nI; ++k) {
399 const double u = u0 + k * d;
400 const double x = x0 + u * vx;
401 const double y = y0 + u * vy;
402 const double z = z0 + u * vz;
404 double fn = ex * xn + ey * yn + ez * zn;
407 fn = isign * fn > 0 ? fabs(fn) : -1.;
virtual double WeightingPotential(const double x, const double y, const double z, const std::string &label)
virtual bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Get the bounding box coordinates.
std::array< bool, 3 > m_rotationSymmetric
Rotation symmetry around x-axis, y-axis, z-axis.
std::array< bool, 3 > m_mirrorPeriodic
Mirror periodicity in x, y, z.
virtual void Reset()=0
Reset the component.
virtual void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status)=0
virtual Medium * GetMedium(const double x, const double y, const double z)
Get the medium at a given location (x, y, z).
virtual void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label)
virtual bool CrossedWire(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)
bool m_debug
Switch on/off debugging messages.
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)
double IntegrateWeightingFluxParallelogram(const std::string &label, 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)
virtual bool InTrapRadius(const double q0, const double x0, const double y0, const double z0, double &xw, double &yw, double &rw)
virtual bool CrossedPlane(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, double &xc, double &yc, double &zc)
Component()=delete
Default constructor.
std::array< bool, 3 > m_periodic
Simple periodicity in x, y, z.
virtual bool HasMagneticField() const
Does the component have a non-zero magnetic field?
virtual void Clear()
Reset.
virtual double ElectricPotential(const double x, const double y, const double z)
Calculate the (drift) electrostatic potential [V] at (x, y, z).
std::string m_className
Class name.
double IntegrateFluxCircle(const double xc, const double yc, const double r, const unsigned int nI=50)
Geometry * m_geometry
Pointer to the geometry.
double IntegrateFluxSphere(const double xc, const double yc, const double zc, const double r, const unsigned int nI=20)
virtual void MagneticField(const double x, const double y, const double z, double &bx, double &by, double &bz, int &status)
bool m_ready
Ready for use?
void SetMagneticField(const double bx, const double by, const double bz)
Set a constant magnetic field.
std::array< double, 3 > m_b0
Constant magnetic field.
std::array< bool, 3 > m_axiallyPeriodic
Axial periodicity in x, y, z.
virtual bool GetElementaryCell(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Get the coordinates of the elementary cell.
virtual double DelayedWeightingPotential(const double x, const double y, const double z, const double t, const std::string &label)
double IntegrateFluxParallelogram(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)
virtual void SetGeometry(Geometry *geo)
Define the geometry.
double IntegrateFluxLine(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, const double xp, const double yp, const double zp, const unsigned int nI, const int isign=0)
Abstract base class for geometry classes.
Abstract base class for media.
constexpr std::array< double, 6 > GaussLegendreWeights6()
constexpr std::array< double, 6 > GaussLegendreNodes6()
DoubleAc sqrt(const DoubleAc &f)