Commit 8b1ac3aa authored by Heinrich Schindler's avatar Heinrich Schindler
Browse files

Always use the magnetic field in AvalancheMC.

parent 15873140
......@@ -225,9 +225,10 @@ etched into the foil.
\subsubsection{Field map}
As a first step, we need to calculate the electric field in the GEM.
Currently this calculation has to be performed using an external field
solver like Ansys \cite{ANSYS} or Elmer \cite{Elmer}. In this example,
we use Ansys, but the steps for importing and using an Elmer field map
are very similar.
solver like Ansys \cite{ANSYS}, Elmer \cite{Elmer}, or Comsol \cite{Comsol}.
In this example,
we use Ansys, but the steps for importing field maps from other
programs are very similar.
In the following we assume that the output files resulting from the
Ansys run are located in the current working directory.
......
......@@ -255,7 +255,7 @@ is integrated in a stochastic manner:
a step of length \(\Delta{s} = v_{\text{d}}\Delta{t}\)
in the direction of the
drift velocity \(\mathbf{v}_{\text{d}}\)
at the local field is calculated (with either the
at the local electric and magnetic field is calculated (with either the
time step \(\Delta{t}\) or the distance \(\Delta{s}\)
being specified by the user);
\item
......@@ -284,7 +284,7 @@ with a mean equal to a multiple of the ``collision time''
\begin{equation*}
\tau = \frac{m v_{d}}{q E}.
\end{equation*}
The third method is activated by default.
The third method is activated by default.
Instead of making simple straight-line steps (using the drift velocity
vector at the starting point of a step), the end point of a step
......@@ -330,8 +330,8 @@ bool DriftIon(const double x0, const double y0, const double z0, const double t0
\end{description}
The trajectory can be retrieved using
\begin{lstlisting}
unsigned int GetNumberOfDriftLinePoints() const;
void GetDriftLinePoint(const int i, double& x, double& y, double& z, double& t);
size_t GetNumberOfDriftLinePoints() const;
void GetDriftLinePoint(const size_t i, double& x, double& y, double& z, double& t);
\end{lstlisting}
The calculation of an avalanche initiated by an electron,
......@@ -353,8 +353,8 @@ avalanche should be simulated.
The starting and endpoints of electrons in the avalanche can be
retrieved using
\begin{lstlisting}
unsigned int GetNumberOfElectronEndpoints() const;
void GetElectronEndpoint(const unsigned int i,
size_t GetNumberOfElectronEndpoints() const;
void GetElectronEndpoint(const size_t i,
double& x0, double& y0, double& z0, double& t0,
double& x1, double& y1, double& z1, double& t1, int& status) const;
\end{lstlisting}
......@@ -366,14 +366,6 @@ void GetElectronEndpoint(const unsigned int i,
\end{description}
Analogous functions are available for holes and ions.
The functions
\begin{lstlisting}
void EnableMagneticField();
\end{lstlisting}
instructs the class to consider not only the electric but also the magnetic field
in the evaluation of the transport parameters.
By default, magnetic fields are not taken into account.
For debugging purposes, attachment and diffusion can be switched off using
\begin{lstlisting}
void DisableAttachment();
......
......@@ -53,6 +53,13 @@
key = "Gmsh",
}
% Comsol
@misc{Comsol,
title = "{COMSOL Multiphysics}",
note = "\url{https://www.comsol.com}",
key = "Comsol",
}
% TCAD
@misc{Synopsys,
title = "{Synopsys Sentaurus Device}",
......
......@@ -75,9 +75,6 @@ class AvalancheMC {
/// Retrieve the drift velocity from the component.
void EnableVelocityMap(const bool on = true) { m_useVelocityMap = on; }
/// Enable use of magnetic field in stepping algorithm.
void EnableMagneticField(const bool on = true) { m_useBfield = on; }
/** Set a maximum avalanche size (ignore further multiplication
once this size has been reached). */
void EnableAvalancheSizeLimit(const unsigned int size) { m_sizeCut = size; }
......@@ -115,25 +112,21 @@ class AvalancheMC {
}
/// Return the number of points along the last simulated drift line.
unsigned int GetNumberOfDriftLinePoints() const { return m_drift.size(); }
size_t GetNumberOfDriftLinePoints() const { return m_drift.size(); }
/// Return the coordinates and time of a point along the last drift line.
void GetDriftLinePoint(const unsigned int i, double& x, double& y, double& z,
void GetDriftLinePoint(const size_t i, double& x, double& y, double& z,
double& t) const;
/** Return the number of electron trajectories in the last
* simulated avalanche (including captured electrons). */
unsigned int GetNumberOfElectronEndpoints() const {
size_t GetNumberOfElectronEndpoints() const {
return m_endpointsElectrons.size();
}
/** Return the number of hole trajectories in the last
* simulated avalanche (including captured holes). */
unsigned int GetNumberOfHoleEndpoints() const {
return m_endpointsHoles.size();
}
size_t GetNumberOfHoleEndpoints() const { return m_endpointsHoles.size(); }
/// Return the number of ion trajectories.
unsigned int GetNumberOfIonEndpoints() const {
return m_endpointsIons.size();
}
size_t GetNumberOfIonEndpoints() const { return m_endpointsIons.size(); }
/** Return the coordinates and time of start and end point of a given
* electron drift line.
......@@ -142,13 +135,13 @@ class AvalancheMC {
* \param x1,y1,z1,t1 coordinates and time of the end point
* \param status status code (see GarfieldConstants.hh)
*/
void GetElectronEndpoint(const unsigned int i, double& x0, double& y0,
void GetElectronEndpoint(const size_t i, double& x0, double& y0,
double& z0, double& t0, double& x1, double& y1,
double& z1, double& t1, int& status) const;
void GetHoleEndpoint(const unsigned int i, double& x0, double& y0, double& z0,
void GetHoleEndpoint(const size_t i, double& x0, double& y0, double& z0,
double& t0, double& x1, double& y1, double& z1,
double& t1, int& status) const;
void GetIonEndpoint(const unsigned int i, double& x0, double& y0, double& z0,
void GetIonEndpoint(const size_t i, double& x0, double& y0, double& z0,
double& t0, double& x1, double& y1, double& z1,
double& t1, int& status) const;
......@@ -252,7 +245,6 @@ class AvalancheMC {
bool m_doRKF = false;
bool m_useDiffusion = true;
bool m_useAttachment = true;
bool m_useBfield = false;
/// Scaling factor for electron signals.
double m_scaleE = 1.;
/// Scaling factor for hole signals.
......
......@@ -130,7 +130,7 @@ void AvalancheMC::SetTimeWindow(const double t0, const double t1) {
m_hasTimeWindow = true;
}
void AvalancheMC::GetDriftLinePoint(const unsigned int i, double& x, double& y,
void AvalancheMC::GetDriftLinePoint(const size_t i, double& x, double& y,
double& z, double& t) const {
if (i >= m_drift.size()) {
std::cerr << m_className << "::GetDriftLinePoint: Index out of range.\n";
......@@ -143,7 +143,7 @@ void AvalancheMC::GetDriftLinePoint(const unsigned int i, double& x, double& y,
t = m_drift[i].t;
}
void AvalancheMC::GetHoleEndpoint(const unsigned int i, double& x0, double& y0,
void AvalancheMC::GetHoleEndpoint(const size_t i, double& x0, double& y0,
double& z0, double& t0, double& x1,
double& y1, double& z1, double& t1,
int& status) const {
......@@ -163,7 +163,7 @@ void AvalancheMC::GetHoleEndpoint(const unsigned int i, double& x0, double& y0,
status = m_endpointsHoles[i].status;
}
void AvalancheMC::GetIonEndpoint(const unsigned int i, double& x0, double& y0,
void AvalancheMC::GetIonEndpoint(const size_t i, double& x0, double& y0,
double& z0, double& t0, double& x1, double& y1,
double& z1, double& t1, int& status) const {
if (i >= m_endpointsIons.size()) {
......@@ -182,7 +182,7 @@ void AvalancheMC::GetIonEndpoint(const unsigned int i, double& x0, double& y0,
status = m_endpointsIons[i].status;
}
void AvalancheMC::GetElectronEndpoint(const unsigned int i, double& x0,
void AvalancheMC::GetElectronEndpoint(const size_t i, double& x0,
double& y0, double& z0, double& t0,
double& x1, double& y1, double& z1,
double& t1, int& status) const {
......@@ -675,18 +675,16 @@ int AvalancheMC::GetField(const std::array<double, 3>& x,
Medium*& medium) const {
e.fill(0.);
b.fill(0.);
// Get the electric field.
int status = 0;
// Get the magnetic field.
m_sensor->MagneticField(x[0], x[1], x[2], b[0], b[1], b[2], status);
// Get the electric field.
m_sensor->ElectricField(x[0], x[1], x[2], e[0], e[1], e[2], medium, status);
// Make sure the point is inside a drift medium.
if (status != 0 || !medium) return StatusLeftDriftMedium;
// Make sure the point is inside the drift area.
if (!m_sensor->IsInArea(x[0], x[1], x[2])) return StatusLeftDriftArea;
// Get the magnetic field, if requested.
if (m_useBfield) {
m_sensor->MagneticField(x[0], x[1], x[2], b[0], b[1], b[2], status);
}
return 0;
}
......
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