Commit ee85d853 by Heinrich Schindler

### 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 { void SetElectricFieldRange(const double emin, const double emax); /// Set the plot limits for the weighting field. 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. void SetNumberOfContours(const unsigned int n); ... ... @@ -38,22 +40,28 @@ class ViewField : public ViewBase { /// Set the number of points used for drawing 2D functions. 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 * - 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" * - y-component of the electric field: "ey" * - 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"); /** 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 drawopt option string passed to TF2::Draw **/ void Plot(const std::string& option = "v", 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 x1,y1,z1 end point * \param option quantity to be plotted (see PlotContour) ... ... @@ -128,7 +136,17 @@ class ViewField : public ViewBase { const double interval = 10.) const; 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_samplePotential = true; ... ... @@ -143,6 +161,7 @@ class ViewField : public ViewBase { double m_vmin = 0., m_vmax = 100.; double m_emin = 0., m_emax = 10000.; double m_wmin = 0., m_wmax = 100.; double m_bmin = 0., m_bmax = 10.; // Number of contours unsigned int m_nContours = 20; ... ... @@ -159,11 +178,14 @@ class ViewField : public ViewBase { const double x1, const double y1, const double z1, const std::string& option, const bool wfield, const std::string& electrode, const bool normalised); Parameter GetPar(const std::string& option, std::string& title) const; double Field(const double x, const double y, const double z, Parameter GetPar(const std::string& option, std::string& title, bool& bfield) 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, 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) { 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) { if (n > 0) m_nContours = n; } ... ... @@ -162,12 +168,29 @@ void ViewField::PlotProfileWeightingField(const std::string& label, ViewField::Parameter ViewField::GetPar(const std::string& option, std::string& title) const { std::string& title, bool& bfield) const { bfield = false; std::string opt; std::transform(option.begin(), option.end(), 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("POT") != std::string::npos) { title = "potential"; ... ... @@ -175,7 +198,7 @@ ViewField::Parameter ViewField::GetPar(const std::string& option, } else if (opt == "E" || opt == "FIELD" || opt == "NORM" || opt.find("MAG") != std::string::npos) { title = "field"; return Parameter::Magnitude; return Parameter::Emag; } else if (opt.find("X") != std::string::npos) { title = "field (x-component)"; return Parameter::Ex; ... ... @@ -205,14 +228,16 @@ void ViewField::Draw2d(const std::string& option, const bool contour, // Determine the quantity to be plotted. 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. 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 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"); 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, zmin = m_wmin; 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 { if (contour) { title = "Contours of the electric " + title; ... ... @@ -335,7 +373,8 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, // Determine the quantity to be plotted. std::string title; const Parameter par = GetPar(option, title); bool bfield = false; const Parameter par = GetPar(option, title, bfield); double t0 = 0.; double t1 = 1.; ... ... @@ -359,7 +398,7 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, 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*/) { // Get the position. const double t = u[0]; ... ... @@ -371,7 +410,8 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, y += t * dy; 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"); ... ... @@ -396,6 +436,14 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, fmax = m_wmax; } } } else if (bfield) { title = "magnetic " + title; if (m_useAutoRange) { SampleRange(&f1, fmin, fmax); } else { fmin = m_bmin; fmax = m_bmax; } } else { title = "electric " + title; if (par == Parameter::Potential) { ... ... @@ -435,7 +483,17 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, } else if (!normalised) { 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"; if (wfield) { labels += "_w"; ... ... @@ -446,8 +504,8 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, labels += "#it{E}"; if (wfield) { labels += "_{w"; if (par != Parameter::Magnitude) labels += ","; } else if (par != Parameter::Magnitude) { if (par != Parameter::Emag) labels += ","; } else if (par != Parameter::Emag) { labels += "_{"; } if (par == Parameter::Ex) { ... ... @@ -457,7 +515,7 @@ void ViewField::DrawProfile(const double x0, const double y0, const double z0, } else if (par == Parameter::Ez) { labels += "z"; } if (wfield || par != Parameter::Magnitude) labels += "}"; if (wfield || par != Parameter::Emag) labels += "}"; if (wfield) { labels += " [1/cm]"; } else { ... ... @@ -505,7 +563,7 @@ bool ViewField::SetPlotLimits() { 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 { // Compute the field. ... ... @@ -521,7 +579,7 @@ double ViewField::Field(const double x, const double y, const double z, switch (par) { case Parameter::Potential: return volt; case Parameter::Magnitude: case Parameter::Emag: return sqrt(ex * ex + ey * ey + ez * ez); case Parameter::Ex: return ex; ... ... @@ -557,7 +615,7 @@ double ViewField::Wfield(const double x, const double y, const double z, } switch (par) { case Parameter::Magnitude: case Parameter::Emag: return sqrt(ex * ex + ey * ey + ez * ez); case Parameter::Ex: return ex; ... ... @@ -571,6 +629,33 @@ double ViewField::Wfield(const double x, const double y, const double z, 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& x0, const std::vector& y0, const std::vector& 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