Commit ee85d853 authored by Heinrich Schindler's avatar Heinrich Schindler
Browse files

Adapt ViewField to be able to plot magnetic fields.

parent 9b8d1ab2
Pipeline #3157353 passed with stage
in 5 minutes and 7 seconds
...@@ -30,6 +30,8 @@ class ViewField : public ViewBase { ...@@ -30,6 +30,8 @@ class ViewField : public ViewBase {
void SetElectricFieldRange(const double emin, const double emax); void SetElectricFieldRange(const double emin, const double emax);
/// Set the plot limits for the weighting field. /// Set the plot limits for the weighting field.
void SetWeightingFieldRange(const double wmin, const double wmax); void SetWeightingFieldRange(const double wmin, const double wmax);
/// Set the plot limits for the magnetic field.
void SetMagneticFieldRange(const double bmin, const double bmax);
/// Set the number of contour levels. /// Set the number of contour levels.
void SetNumberOfContours(const unsigned int n); void SetNumberOfContours(const unsigned int n);
...@@ -38,22 +40,28 @@ class ViewField : public ViewBase { ...@@ -38,22 +40,28 @@ class ViewField : public ViewBase {
/// Set the number of points used for drawing 2D functions. /// Set the number of points used for drawing 2D functions.
void SetNumberOfSamples2d(const unsigned int nx, const unsigned int ny); void SetNumberOfSamples2d(const unsigned int nx, const unsigned int ny);
/** Make a contour plot of the electric potential or field. /** Make a contour plot of the electric potential, electric field,
* or magnetic field.
* \param option quantity to be plotted * \param option quantity to be plotted
* - potential: "v", "voltage", "p", "potential" * - potential: "v", "voltage", "p", "potential"
* - magnitude of the electric field: "e", "field" * - magnitude of the electric field: "emag", "field"
* - x-component of the electric field: "ex" * - x-component of the electric field: "ex"
* - y-component of the electric field: "ey" * - y-component of the electric field: "ey"
* - z-component of the electric field: "ez" * - z-component of the electric field: "ez"
* - magnitude of the magnetic field: "bmag"
* - x-component of the magnetic field: "bx"
* - y-component of the magnetic field: "by"
* - z-component of the magnetic field: "bz"
**/ **/
void PlotContour(const std::string& option = "v"); void PlotContour(const std::string& option = "v");
/** Make a 2D plot of the electric potential or field. /** Make a 2D plot of the electric potential, electric field or
* magnetic field.
* \param option quantity to be plotted (see PlotContour) * \param option quantity to be plotted (see PlotContour)
* \param drawopt option string passed to TF2::Draw * \param drawopt option string passed to TF2::Draw
**/ **/
void Plot(const std::string& option = "v", void Plot(const std::string& option = "v",
const std::string& drawopt = "arr"); const std::string& drawopt = "arr");
/** Make a 1D plot of the electric potential or field along a line. /** Make a 1D plot of the potential or field along a line.
* \param x0,y0,z0 starting point * \param x0,y0,z0 starting point
* \param x1,y1,z1 end point * \param x1,y1,z1 end point
* \param option quantity to be plotted (see PlotContour) * \param option quantity to be plotted (see PlotContour)
...@@ -128,7 +136,17 @@ class ViewField : public ViewBase { ...@@ -128,7 +136,17 @@ class ViewField : public ViewBase {
const double interval = 10.) const; const double interval = 10.) const;
private: private:
enum class Parameter { Potential = 0, Magnitude, Ex, Ey, Ez, Unknown }; enum class Parameter {
Potential = 0,
Emag,
Ex,
Ey,
Ez,
Bmag,
Bx,
By,
Bz,
Unknown };
bool m_useAutoRange = true; bool m_useAutoRange = true;
bool m_samplePotential = true; bool m_samplePotential = true;
...@@ -143,6 +161,7 @@ class ViewField : public ViewBase { ...@@ -143,6 +161,7 @@ class ViewField : public ViewBase {
double m_vmin = 0., m_vmax = 100.; double m_vmin = 0., m_vmax = 100.;
double m_emin = 0., m_emax = 10000.; double m_emin = 0., m_emax = 10000.;
double m_wmin = 0., m_wmax = 100.; double m_wmin = 0., m_wmax = 100.;
double m_bmin = 0., m_bmax = 10.;
// Number of contours // Number of contours
unsigned int m_nContours = 20; unsigned int m_nContours = 20;
...@@ -159,11 +178,14 @@ class ViewField : public ViewBase { ...@@ -159,11 +178,14 @@ class ViewField : public ViewBase {
const double x1, const double y1, const double z1, const double x1, const double y1, const double z1,
const std::string& option, const bool wfield, const std::string& option, const bool wfield,
const std::string& electrode, const bool normalised); const std::string& electrode, const bool normalised);
Parameter GetPar(const std::string& option, std::string& title) const; Parameter GetPar(const std::string& option, std::string& title,
double Field(const double x, const double y, const double z, bool& bfield) const;
const Parameter par) const; double Efield(const double x, const double y, const double z,
const Parameter par) const;
double Wfield(const double x, const double y, const double z, double Wfield(const double x, const double y, const double z,
const Parameter par, const std::string& electrode) const; const Parameter par, const std::string& electrode) const;
double Bfield(const double x, const double y, const double z,
const Parameter par) const;
}; };
} }
......
...@@ -105,6 +105,12 @@ void ViewField::SetWeightingFieldRange(const double wmin, const double wmax) { ...@@ -105,6 +105,12 @@ void ViewField::SetWeightingFieldRange(const double wmin, const double wmax) {
m_useAutoRange = false; m_useAutoRange = false;
} }
void ViewField::SetMagneticFieldRange(const double bmin, const double bmax) {
m_bmin = std::min(bmin, bmax);
m_bmax = std::max(bmin, bmax);
m_useAutoRange = false;
}
void ViewField::SetNumberOfContours(const unsigned int n) { void ViewField::SetNumberOfContours(const unsigned int n) {
if (n > 0) m_nContours = n; if (n > 0) m_nContours = n;
} }
...@@ -162,12 +168,29 @@ void ViewField::PlotProfileWeightingField(const std::string& label, ...@@ -162,12 +168,29 @@ void ViewField::PlotProfileWeightingField(const std::string& label,
ViewField::Parameter ViewField::GetPar(const std::string& option, ViewField::Parameter ViewField::GetPar(const std::string& option,
std::string& title) const { std::string& title, bool& bfield) const {
bfield = false;
std::string opt; std::string opt;
std::transform(option.begin(), option.end(), std::transform(option.begin(), option.end(),
std::back_inserter(opt), toupper); std::back_inserter(opt), toupper);
if (opt == "V" || opt == "P" || opt == "PHI" || if (opt == "BMAG") {
title = "field";
bfield = true;
return Parameter::Bmag;
} else if (opt == "BX") {
title = "field (x-component)";
bfield = true;
return Parameter::Bx;
} else if (opt == "BY") {
title = "field (y-component)";
bfield = true;
return Parameter::By;
} else if (opt == "BZ") {
title = "field (z-component)";
bfield = true;
return Parameter::Bz;
} else if (opt == "V" || opt == "P" || opt == "PHI" ||
opt.find("VOLT") != std::string::npos || opt.find("VOLT") != std::string::npos ||
opt.find("POT") != std::string::npos) { opt.find("POT") != std::string::npos) {
title = "potential"; title = "potential";
...@@ -175,7 +198,7 @@ ViewField::Parameter ViewField::GetPar(const std::string& option, ...@@ -175,7 +198,7 @@ ViewField::Parameter ViewField::GetPar(const std::string& option,
} else if (opt == "E" || opt == "FIELD" || opt == "NORM" || } else if (opt == "E" || opt == "FIELD" || opt == "NORM" ||
opt.find("MAG") != std::string::npos) { opt.find("MAG") != std::string::npos) {
title = "field"; title = "field";
return Parameter::Magnitude; return Parameter::Emag;
} else if (opt.find("X") != std::string::npos) { } else if (opt.find("X") != std::string::npos) {
title = "field (x-component)"; title = "field (x-component)";
return Parameter::Ex; return Parameter::Ex;
...@@ -205,14 +228,16 @@ void ViewField::Draw2d(const std::string& option, const bool contour, ...@@ -205,14 +228,16 @@ void ViewField::Draw2d(const std::string& option, const bool contour,
// Determine the quantity to be plotted. // Determine the quantity to be plotted.
std::string title; std::string title;
const Parameter par = GetPar(option, title); bool bfield = false;
const Parameter par = GetPar(option, title, bfield);
auto eval = [this, par, wfield, electrode](double* u, double* /*p*/) { auto eval = [this, par, wfield, bfield, electrode](double* u, double* /*p*/) {
// Transform to global coordinates. // Transform to global coordinates.
const double x = m_proj[0][0] * u[0] + m_proj[1][0] * u[1] + m_proj[2][0]; const double x = m_proj[0][0] * u[0] + m_proj[1][0] * u[1] + m_proj[2][0];
const double y = m_proj[0][1] * u[0] + m_proj[1][1] * u[1] + m_proj[2][1]; const double y = m_proj[0][1] * u[0] + m_proj[1][1] * u[1] + m_proj[2][1];
const double z = m_proj[0][2] * u[0] + m_proj[1][2] * u[1] + m_proj[2][2]; const double z = m_proj[0][2] * u[0] + m_proj[1][2] * u[1] + m_proj[2][2];
return wfield ? Wfield(x, y, z, par, electrode) : Field(x, y, z, par); return wfield ? Wfield(x, y, z, par, electrode) :
bfield ? Bfield(x, y, z, par) : Efield(x, y, z, par);
}; };
const std::string fname = FindUnusedFunctionName("f2D"); const std::string fname = FindUnusedFunctionName("f2D");
TF2 f2(fname.c_str(), eval, m_xMinPlot, m_xMaxPlot, m_yMinPlot, m_yMaxPlot, 0); TF2 f2(fname.c_str(), eval, m_xMinPlot, m_xMaxPlot, m_yMinPlot, m_yMaxPlot, 0);
...@@ -239,6 +264,19 @@ void ViewField::Draw2d(const std::string& option, const bool contour, ...@@ -239,6 +264,19 @@ void ViewField::Draw2d(const std::string& option, const bool contour,
zmin = m_wmin; zmin = m_wmin;
zmax = m_wmax; zmax = m_wmax;
} }
} else if (bfield) {
if (contour) {
title = "Contours of the magnetic " + title;
} else {
title = "Magnetic " + title;
}
if (m_useAutoRange) {
SampleRange(m_xMinPlot, m_yMinPlot, m_xMaxPlot, m_yMaxPlot,
&f2, zmin, zmax);
} else {
zmin = m_bmin;
zmax = m_bmax;
}
} else { } else {
if (contour) { if (contour) {
title = "Contours of the electric " + title; title = "Contours of the electric " + title;
...@@ -335,7 +373,8 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, ...@@ -335,7 +373,8 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0,
// Determine the quantity to be plotted. // Determine the quantity to be plotted.
std::string title; std::string title;
const Parameter par = GetPar(option, title); bool bfield = false;
const Parameter par = GetPar(option, title, bfield);
double t0 = 0.; double t0 = 0.;
double t1 = 1.; double t1 = 1.;
...@@ -359,7 +398,7 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, ...@@ -359,7 +398,7 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0,
dz /= t1; dz /= t1;
} }
auto eval = [this, par, wfield, electrode, dir, auto eval = [this, par, wfield, bfield, electrode, dir,
x0, y0, z0, dx, dy, dz](double* u, double* /*p*/) { x0, y0, z0, dx, dy, dz](double* u, double* /*p*/) {
// Get the position. // Get the position.
const double t = u[0]; const double t = u[0];
...@@ -371,7 +410,8 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, ...@@ -371,7 +410,8 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0,
y += t * dy; y += t * dy;
z += t * dz; z += t * dz;
} }
return wfield ? Wfield(x, y, z, par, electrode) : Field(x, y, z, par); return wfield ? Wfield(x, y, z, par, electrode) :
bfield ? Bfield(x, y, z, par) : Efield(x, y, z, par);
}; };
const std::string fname = FindUnusedFunctionName("fProfile"); const std::string fname = FindUnusedFunctionName("fProfile");
...@@ -396,6 +436,14 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, ...@@ -396,6 +436,14 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0,
fmax = m_wmax; fmax = m_wmax;
} }
} }
} else if (bfield) {
title = "magnetic " + title;
if (m_useAutoRange) {
SampleRange(&f1, fmin, fmax);
} else {
fmin = m_bmin;
fmax = m_bmax;
}
} else { } else {
title = "electric " + title; title = "electric " + title;
if (par == Parameter::Potential) { if (par == Parameter::Potential) {
...@@ -435,7 +483,17 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, ...@@ -435,7 +483,17 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0,
} else if (!normalised) { } else if (!normalised) {
labels = ";distance [cm];"; labels = ";distance [cm];";
} }
if (par == Parameter::Potential) { if (bfield) {
labels += "#it{B}";
if (par == Parameter::Bx) {
labels += "_{x}";
} else if (par == Parameter::By) {
labels += "_{y}";
} else if (par == Parameter::Bz) {
labels += "_{z}";
}
labels += " [T]";
} else if (par == Parameter::Potential) {
labels += "#phi"; labels += "#phi";
if (wfield) { if (wfield) {
labels += "_w"; labels += "_w";
...@@ -446,8 +504,8 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, ...@@ -446,8 +504,8 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0,
labels += "#it{E}"; labels += "#it{E}";
if (wfield) { if (wfield) {
labels += "_{w"; labels += "_{w";
if (par != Parameter::Magnitude) labels += ","; if (par != Parameter::Emag) labels += ",";
} else if (par != Parameter::Magnitude) { } else if (par != Parameter::Emag) {
labels += "_{"; labels += "_{";
} }
if (par == Parameter::Ex) { if (par == Parameter::Ex) {
...@@ -457,7 +515,7 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, ...@@ -457,7 +515,7 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0,
} else if (par == Parameter::Ez) { } else if (par == Parameter::Ez) {
labels += "z"; labels += "z";
} }
if (wfield || par != Parameter::Magnitude) labels += "}"; if (wfield || par != Parameter::Emag) labels += "}";
if (wfield) { if (wfield) {
labels += " [1/cm]"; labels += " [1/cm]";
} else { } else {
...@@ -505,8 +563,8 @@ bool ViewField::SetPlotLimits() { ...@@ -505,8 +563,8 @@ bool ViewField::SetPlotLimits() {
return ok; return ok;
} }
double ViewField::Field(const double x, const double y, const double z, double ViewField::Efield(const double x, const double y, const double z,
const Parameter par) const { const Parameter par) const {
// Compute the field. // Compute the field.
double ex = 0., ey = 0., ez = 0., volt = 0.; double ex = 0., ey = 0., ez = 0., volt = 0.;
...@@ -521,7 +579,7 @@ double ViewField::Field(const double x, const double y, const double z, ...@@ -521,7 +579,7 @@ double ViewField::Field(const double x, const double y, const double z,
switch (par) { switch (par) {
case Parameter::Potential: case Parameter::Potential:
return volt; return volt;
case Parameter::Magnitude: case Parameter::Emag:
return sqrt(ex * ex + ey * ey + ez * ez); return sqrt(ex * ex + ey * ey + ez * ez);
case Parameter::Ex: case Parameter::Ex:
return ex; return ex;
...@@ -557,7 +615,7 @@ double ViewField::Wfield(const double x, const double y, const double z, ...@@ -557,7 +615,7 @@ double ViewField::Wfield(const double x, const double y, const double z,
} }
switch (par) { switch (par) {
case Parameter::Magnitude: case Parameter::Emag:
return sqrt(ex * ex + ey * ey + ez * ez); return sqrt(ex * ex + ey * ey + ez * ez);
case Parameter::Ex: case Parameter::Ex:
return ex; return ex;
...@@ -571,6 +629,33 @@ double ViewField::Wfield(const double x, const double y, const double z, ...@@ -571,6 +629,33 @@ double ViewField::Wfield(const double x, const double y, const double z,
return 0.; return 0.;
} }
double ViewField::Bfield(const double x, const double y, const double z,
const Parameter par) const {
// Compute the field.
double bx = 0., by = 0., bz = 0.;
int status = 0;
if (!m_sensor) {
m_component->MagneticField(x, y, z, bx, by, bz, status);
} else {
m_sensor->MagneticField(x, y, z, bx, by, bz, status);
}
if (m_useStatus && status != 0) return 0.;
switch (par) {
case Parameter::Bmag:
return sqrt(bx * bx + by * by + bz * bz);
case Parameter::Bx:
return bx;
case Parameter::By:
return by;
case Parameter::Bz:
return bz;
default:
break;
}
return 0.;
}
void ViewField::PlotFieldLines(const std::vector<double>& x0, void ViewField::PlotFieldLines(const std::vector<double>& x0,
const std::vector<double>& y0, const std::vector<double>& y0,
const std::vector<double>& z0, const std::vector<double>& z0,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment