Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
Garfield::ComponentGrid Class Reference

Component for interpolating field maps on a regular mesh. More...

#include <ComponentGrid.hh>

+ Inheritance diagram for Garfield::ComponentGrid:

Public Member Functions

 ComponentGrid ()
 Constructor.
 
 ~ComponentGrid ()
 Destructor.
 
void Clear () override
 Reset.
 
void ElectricField (const double x, const double y, const double z, double &ex, double &ey, double &ez, double &v, Medium *&m, int &status) override
 Calculate the drift field [V/cm] and potential [V] at (x, y, z).
 
void ElectricField (const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
 
void WeightingField (const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label) override
 
double WeightingPotential (const double x, const double y, const double z, const std::string &label) override
 
void DelayedWeightingField (const double x, const double y, const double z, const double t, double &wx, double &wy, double &wz, const std::string &label) override
 
void MagneticField (const double x, const double y, const double z, double &bx, double &by, double &bz, int &status) override
 
MediumGetMedium (const double x, const double y, const double z) override
 Get the medium at a given location (x, y, z).
 
bool GetVoltageRange (double &vmin, double &vmax) override
 Calculate the voltage range [V].
 
bool GetElectricFieldRange (double &exmin, double &exmax, double &eymin, double &eymax, double &ezmin, double &ezmax)
 
bool GetBoundingBox (double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
 Get the bounding box coordinates.
 
bool GetElementaryCell (double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
 Get the coordinates of the elementary cell.
 
bool SetMesh (const unsigned int nx, const unsigned int ny, const unsigned int nz, const double xmin, const double xmax, const double ymin, const double ymax, const double zmin, const double zmax)
 
bool GetMesh (unsigned int &nx, unsigned int &ny, unsigned int &nz, double &xmin, double &xmax, double &ymin, double &ymax, double &zmin, double &zmax) const
 Retrieve the parameters of the grid.
 
bool LoadElectricField (const std::string &filename, const std::string &format, const bool withPotential, const bool withFlag, const double scaleX=1., const double scaleE=1., const double scaleP=1.)
 
bool LoadWeightingField (const std::string &filename, const std::string &format, const bool withPotential, const double scaleX=1., const double scaleE=1., const double scaleP=1.)
 Import (prompt) weighting field from file.
 
bool LoadWeightingField (const std::string &filename, const std::string &format, const double time, const bool withPotential, const double scaleX=1., const double scaleE=1., const double scaleP=1.)
 Import delayed weighting field from file.
 
void SetWeightingFieldOffset (const double x, const double y, const double z)
 
bool LoadMagneticField (const std::string &filename, const std::string &format, const double scaleX=1., const double scaleB=1.)
 Import magnetic field values from a file.
 
bool SaveElectricField (Component *cmp, const std::string &filename, const std::string &format)
 
bool SaveWeightingField (Component *cmp, const std::string &id, const std::string &filename, const std::string &format)
 
bool GetElectricField (const unsigned int i, const unsigned int j, const unsigned int k, double &v, double &ex, double &ey, double &ez) const
 Return the field at a given node.
 
void SetMedium (Medium *m)
 Set the medium.
 
MediumGetMedium () const
 Get the medium.
 
void Print ()
 Print information about the mesh and the available data.
 
bool LoadElectronAttachment (const std::string &fname, const std::string &fmt, const unsigned int col, const double scaleX=1.)
 
bool LoadHoleAttachment (const std::string &fname, const std::string &fmt, const unsigned int col, const double scaleX=1.)
 Import hole attachment coefficients from a file.
 
bool HasAttachmentMap () const override
 Does the component have attachment maps?
 
bool ElectronAttachment (const double x, const double y, const double z, double &att) override
 Get the electron attachment coefficient.
 
bool HoleAttachment (const double x, const double y, const double z, double &att) override
 Get the hole attachment coefficient.
 
bool LoadElectronVelocity (const std::string &fname, const std::string &fmt, const double scaleX=1., const double scaleV=1.e-9)
 
bool LoadHoleVelocity (const std::string &fname, const std::string &fmt, const double scaleX=1., const double scaleV=1.e-9)
 Import a map of hole drift velocities from a file.
 
bool HasVelocityMap () const override
 Does the component have velocity maps?
 
bool ElectronVelocity (const double x, const double y, const double z, double &vx, double &vy, double &vz) override
 Get the electron drift velocity.
 
bool HoleVelocity (const double x, const double y, const double z, double &vx, double &vy, double &vz) override
 Get the hole drift velocity.
 
- Public Member Functions inherited from Garfield::Component
 Component ()=delete
 Default constructor.
 
 Component (const std::string &name)
 Constructor.
 
virtual ~Component ()
 Destructor.
 
virtual void SetGeometry (Geometry *geo)
 Define the geometry.
 
virtual void Clear ()
 Reset.
 
virtual MediumGetMedium (const double x, const double y, const double z)
 Get the medium at a given location (x, y, z).
 
virtual void ElectricField (const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status)=0
 
virtual void ElectricField (const double x, const double y, const double z, double &ex, double &ey, double &ez, double &v, Medium *&m, int &status)=0
 Calculate the drift field [V/cm] and potential [V] at (x, y, z).
 
virtual bool GetVoltageRange (double &vmin, double &vmax)=0
 Calculate the voltage range [V].
 
virtual void WeightingField (const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label)
 
virtual double WeightingPotential (const double x, const double y, const double z, const std::string &label)
 
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 double DelayedWeightingPotential (const double x, const double y, const double z, const double t, const std::string &label)
 
virtual void MagneticField (const double x, const double y, const double z, double &bx, double &by, double &bz, int &status)
 
void SetMagneticField (const double bx, const double by, const double bz)
 Set a constant magnetic field.
 
virtual bool IsReady ()
 Ready for use?
 
virtual bool GetBoundingBox (double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
 Get the bounding box coordinates.
 
virtual bool GetElementaryCell (double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
 Get the coordinates of the elementary cell.
 
double IntegrateFluxCircle (const double xc, const double yc, const double r, const unsigned int nI=50)
 
double IntegrateFluxSphere (const double xc, const double yc, const double zc, const double r, const unsigned int nI=20)
 
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)
 
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)
 
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)
 
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)
 
virtual bool IsInTrapRadius (const double q0, const double x0, const double y0, const double z0, double &xw, double &yw, double &rw)
 
void EnablePeriodicityX (const bool on=true)
 Enable simple periodicity in the $x$ direction.
 
void EnablePeriodicityY (const bool on=true)
 Enable simple periodicity in the $y$ direction.
 
void EnablePeriodicityZ (const bool on=true)
 Enable simple periodicity in the $z$ direction.
 
void IsPeriodic (bool &perx, bool &pery, bool &perz)
 Return periodicity flags.
 
void EnableMirrorPeriodicityX (const bool on=true)
 Enable mirror periodicity in the $x$ direction.
 
void EnableMirrorPeriodicityY (const bool on=true)
 Enable mirror periodicity in the $y$ direction.
 
void EnableMirrorPeriodicityZ (const bool on=true)
 Enable mirror periodicity in the $y$ direction.
 
void IsMirrorPeriodic (bool &perx, bool &pery, bool &perz)
 Return mirror periodicity flags.
 
void EnableAxialPeriodicityX (const bool on=true)
 Enable axial periodicity in the $x$ direction.
 
void EnableAxialPeriodicityY (const bool on=true)
 Enable axial periodicity in the $y$ direction.
 
void EnableAxialPeriodicityZ (const bool on=true)
 Enable axial periodicity in the $z$ direction.
 
void IsAxiallyPeriodic (bool &perx, bool &pery, bool &perz)
 Return axial periodicity flags.
 
void EnableRotationSymmetryX (const bool on=true)
 Enable rotation symmetry around the $x$ axis.
 
void EnableRotationSymmetryY (const bool on=true)
 Enable rotation symmetry around the $y$ axis.
 
void EnableRotationSymmetryZ (const bool on=true)
 Enable rotation symmetry around the $z$ axis.
 
void IsRotationSymmetric (bool &rotx, bool &roty, bool &rotz)
 Return rotation symmetry flags.
 
void EnableDebugging ()
 Switch on debugging messages.
 
void DisableDebugging ()
 Switch off debugging messages.
 
virtual bool HasAttachmentMap () const
 Does the component have attachment maps?
 
virtual bool HasVelocityMap () const
 Does the component have velocity maps?
 
virtual bool ElectronAttachment (const double, const double, const double, double &eta)
 Get the electron attachment coefficient.
 
virtual bool HoleAttachment (const double, const double, const double, double &eta)
 Get the hole attachment coefficient.
 
virtual bool ElectronVelocity (const double, const double, const double, double &vx, double &vy, double &vz)
 Get the electron drift velocity.
 
virtual bool HoleVelocity (const double, const double, const double, double &vx, double &vy, double &vz)
 Get the hole drift velocity.
 
virtual bool GetElectronLifetime (const double, const double, const double, double &etau)
 
virtual bool GetHoleLifetime (const double, const double, const double, double &htau)
 

Additional Inherited Members

virtual void Reset ()=0
 Reset the component.
 
virtual void UpdatePeriodicity ()=0
 Verify periodicities.
 
- Protected Attributes inherited from Garfield::Component
std::string m_className = "Component"
 Class name.
 
Geometrym_geometry = nullptr
 Pointer to the geometry.
 
std::array< double, 3 > m_b0 = {{0., 0., 0.}}
 Constant magnetic field.
 
bool m_ready = false
 Ready for use?
 
bool m_debug = false
 Switch on/off debugging messages.
 
std::array< bool, 3 > m_periodic = {{false, false, false}}
 Simple periodicity in x, y, z.
 
std::array< bool, 3 > m_mirrorPeriodic = {{false, false, false}}
 Mirror periodicity in x, y, z.
 
std::array< bool, 3 > m_axiallyPeriodic = {{false, false, false}}
 Axial periodicity in x, y, z.
 
std::array< bool, 3 > m_rotationSymmetric = {{false, false, false}}
 Rotation symmetry around x-axis, y-axis, z-axis.
 

Detailed Description

Component for interpolating field maps on a regular mesh.

Definition at line 12 of file ComponentGrid.hh.

Constructor & Destructor Documentation

◆ ComponentGrid()

Garfield::ComponentGrid::ComponentGrid ( )

Constructor.

Definition at line 54 of file ComponentGrid.cc.

54: Component("Grid") {}
Component()=delete
Default constructor.

◆ ~ComponentGrid()

Garfield::ComponentGrid::~ComponentGrid ( )
inline

Destructor.

Definition at line 17 of file ComponentGrid.hh.

17{}

Member Function Documentation

◆ Clear()

void Garfield::ComponentGrid::Clear ( )
inlineoverridevirtual

Reset.

Reimplemented from Garfield::Component.

Definition at line 19 of file ComponentGrid.hh.

19{ Reset(); }

◆ DelayedWeightingField()

void Garfield::ComponentGrid::DelayedWeightingField ( const double  x,
const double  y,
const double  z,
const double  t,
double &  wx,
double &  wy,
double &  wz,
const std::string &  label 
)
overridevirtual

Calculate the delayed weighting field at a given point and time and for a given electrode.

Parameters
x,y,zcoordinates [cm].
ttime [ns].
wx,wy,wzcomponents of the weighting field [1/cm].
labelname of the electrode

Reimplemented from Garfield::Component.

Definition at line 118 of file ComponentGrid.cc.

121 {
122 wx = wy = wz = 0.;
123 if (m_wdtimes.empty()) return;
124 // Assume no weighting field for times outside the range of available maps.
125 if (t < m_wdtimes.front() || t > m_wdtimes.back()) return;
126
127 const double xx = x - m_wFieldOffset[0];
128 const double yy = y - m_wFieldOffset[1];
129 const double zz = z - m_wFieldOffset[2];
130
131 const auto it1 = std::upper_bound(m_wdtimes.cbegin(), m_wdtimes.cend(), t);
132 const auto it0 = std::prev(it1);
133
134 const double dt = t - *it0;
135 double wp = 0.;
136 const unsigned int i0 = it0 - m_wdtimes.cbegin();
137 double wx0 = 0., wy0 = 0., wz0 = 0.;
138 bool active = true;
139 if (!GetField(xx, yy, zz, m_wdfields[i0], wx0, wy0, wz0, wp, active)) return;
140
141 if (dt < Small || it1 == m_wdtimes.cend()) {
142 wx = wx0;
143 wy = wy0;
144 wz = wz0;
145 return;
146 }
147 const unsigned int i1 = it1 - m_wdtimes.cbegin();
148 double wx1 = 0., wy1 = 0., wz1 = 0.;
149 if (!GetField(xx, yy, zz, m_wdfields[i1], wx1, wy1, wz1, wp, active)) return;
150
151 const double f1 = dt / (*it1 - *it0);
152 const double f0 = 1. - f1;
153 wx = f0 * wx0 + f1 * wx1;
154 wy = f0 * wy0 + f1 * wy1;
155 wz = f0 * wz0 + f1 * wz1;
156}

◆ ElectricField() [1/2]

void Garfield::ComponentGrid::ElectricField ( const double  x,
const double  y,
const double  z,
double &  ex,
double &  ey,
double &  ez,
double &  v,
Medium *&  m,
int &  status 
)
overridevirtual

Calculate the drift field [V/cm] and potential [V] at (x, y, z).

Implements Garfield::Component.

Definition at line 56 of file ComponentGrid.cc.

59 {
60 m = nullptr;
61 status = 0;
62
63 // Make sure the field map has been loaded.
64 if (!m_ready) {
65 PrintNotReady(m_className + "::ElectricField");
66 status = -10;
67 return;
68 }
69
70 status = 0;
71 bool active = true;
72 if (!GetField(x, y, z, m_efields, ex, ey, ez, p, active)) {
73 status = -11;
74 return;
75 }
76 if (!active) {
77 status = -5;
78 return;
79 }
80 m = m_medium;
81 if (!m) status = -5;
82}
std::string m_className
Class name.
Definition: Component.hh:329
bool m_ready
Ready for use?
Definition: Component.hh:338

Referenced by ElectricField().

◆ ElectricField() [2/2]

void Garfield::ComponentGrid::ElectricField ( const double  x,
const double  y,
const double  z,
double &  ex,
double &  ey,
double &  ez,
Medium *&  m,
int &  status 
)
overridevirtual

Calculate the drift field at given point.

Parameters
x,y,zcoordinates [cm].
ex,ey,ezcomponents of the electric field [V/cm].
mpointer to the medium at this location.
statusstatus flag

Status flags:

        0: Inside an active medium
      > 0: Inside a wire of type X
-4 ... -1: On the side of a plane where no wires are
       -5: Inside the mesh but not in an active medium
       -6: Outside the mesh
      -10: Unknown potential type (should not occur)
    other: Other cases (should not occur)

Implements Garfield::Component.

Definition at line 84 of file ComponentGrid.cc.

86 {
87 double v = 0.;
88 ElectricField(x, y, z, ex, ey, ez, v, m, status);
89}
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, double &v, Medium *&m, int &status) override
Calculate the drift field [V/cm] and potential [V] at (x, y, z).

◆ ElectronAttachment()

bool Garfield::ComponentGrid::ElectronAttachment ( const double  ,
const double  ,
const double  ,
double &  eta 
)
overridevirtual

Get the electron attachment coefficient.

Reimplemented from Garfield::Component.

Definition at line 1670 of file ComponentGrid.cc.

1671 {
1672 // Make sure the map has been loaded.
1673 if (m_eAttachment.empty()) {
1674 PrintNotReady(m_className + "::ElectronAttachment");
1675 return false;
1676 }
1677 return GetData(x, y, z, m_eAttachment, att);
1678}

◆ ElectronVelocity()

bool Garfield::ComponentGrid::ElectronVelocity ( const double  ,
const double  ,
const double  ,
double &  vx,
double &  vy,
double &  vz 
)
overridevirtual

Get the electron drift velocity.

Reimplemented from Garfield::Component.

Definition at line 1341 of file ComponentGrid.cc.

1343 {
1344 if (m_eVelocity.empty()) {
1345 PrintNotReady(m_className + "::ElectronVelocity");
1346 return false;
1347 }
1348 double p = 0.;
1349 bool active = true;
1350 return GetField(x, y, z, m_eVelocity, vx, vy, vz, p, active);
1351}

◆ GetBoundingBox()

bool Garfield::ComponentGrid::GetBoundingBox ( double &  xmin,
double &  ymin,
double &  zmin,
double &  xmax,
double &  ymax,
double &  zmax 
)
overridevirtual

Get the bounding box coordinates.

Reimplemented from Garfield::Component.

Definition at line 987 of file ComponentGrid.cc.

988 {
989 if (!m_ready) return false;
990 if (m_periodic[0] || m_mirrorPeriodic[0]) {
991 xmin = -INFINITY;
992 xmax = +INFINITY;
993 } else {
994 xmin = m_xMin[0];
995 xmax = m_xMax[0];
996 }
997
998 if (m_periodic[1] || m_mirrorPeriodic[1]) {
999 ymin = -INFINITY;
1000 ymax = +INFINITY;
1001 } else {
1002 ymin = m_xMin[1];
1003 ymax = m_xMax[1];
1004 }
1005
1006 if (m_periodic[2] || m_mirrorPeriodic[2]) {
1007 zmin = -INFINITY;
1008 zmax = +INFINITY;
1009 } else {
1010 zmin = m_xMin[2];
1011 zmax = m_xMax[2];
1012 }
1013 return true;
1014}
std::array< bool, 3 > m_mirrorPeriodic
Mirror periodicity in x, y, z.
Definition: Component.hh:346
std::array< bool, 3 > m_periodic
Simple periodicity in x, y, z.
Definition: Component.hh:344

◆ GetElectricField()

bool Garfield::ComponentGrid::GetElectricField ( const unsigned int  i,
const unsigned int  j,
const unsigned int  k,
double &  v,
double &  ex,
double &  ey,
double &  ez 
) const

Return the field at a given node.

Definition at line 1158 of file ComponentGrid.cc.

1160 {
1161 v = ex = ey = ez = 0.;
1162 if (!m_ready) {
1163 if (!m_hasMesh) {
1164 std::cerr << m_className << "::GetElectricField: Mesh not set.\n";
1165 return false;
1166 }
1167 PrintNotReady(m_className + "::GetElectricField");
1168 return false;
1169 }
1170 if (i >= m_nX[0] || j >= m_nX[1] || k >= m_nX[2]) {
1171 std::cerr << m_className << "::GetElectricField: Index out of range.\n";
1172 return false;
1173 }
1174 const Node& node = m_efields[i][j][k];
1175 v = node.v;
1176 ex = node.fx;
1177 ey = node.fy;
1178 ez = node.fz;
1179 return true;
1180}

◆ GetElectricFieldRange()

bool Garfield::ComponentGrid::GetElectricFieldRange ( double &  exmin,
double &  exmax,
double &  eymin,
double &  eymax,
double &  ezmin,
double &  ezmax 
)

Definition at line 1037 of file ComponentGrid.cc.

1039 {
1040 if (!m_ready) {
1041 PrintNotReady(m_className + "::GetElectricFieldRange");
1042 return false;
1043 }
1044
1045 exmin = exmax = m_efields[0][0][0].fx;
1046 eymin = eymax = m_efields[0][0][0].fy;
1047 ezmin = ezmax = m_efields[0][0][0].fz;
1048 for (unsigned int i = 0; i < m_nX[0]; ++i) {
1049 for (unsigned int j = 0; j < m_nX[1]; ++j) {
1050 for (unsigned int k = 0; k < m_nX[2]; ++k) {
1051 const Node& node = m_efields[i][j][k];
1052 if (node.fx < exmin) exmin = node.fx;
1053 if (node.fx > exmax) exmax = node.fx;
1054 if (node.fy < eymin) eymin = node.fy;
1055 if (node.fy > eymax) eymax = node.fy;
1056 if (node.fz < ezmin) ezmin = node.fz;
1057 if (node.fz > ezmax) ezmax = node.fz;
1058 }
1059 }
1060 }
1061 return true;
1062}

◆ GetElementaryCell()

bool Garfield::ComponentGrid::GetElementaryCell ( double &  xmin,
double &  ymin,
double &  zmin,
double &  xmax,
double &  ymax,
double &  zmax 
)
overridevirtual

Get the coordinates of the elementary cell.

Reimplemented from Garfield::Component.

Definition at line 1016 of file ComponentGrid.cc.

1018 {
1019
1020 if (!m_ready) return false;
1021 xmin = m_xMin[0];
1022 xmax = m_xMax[0];
1023 ymin = m_xMin[1];
1024 ymax = m_xMax[1];
1025 zmin = m_xMin[2];
1026 zmax = m_xMax[2];
1027 return true;
1028}

◆ GetMedium() [1/2]

Medium * Garfield::ComponentGrid::GetMedium ( ) const
inline

Get the medium.

Definition at line 129 of file ComponentGrid.hh.

129{ return m_medium; }

◆ GetMedium() [2/2]

Medium * Garfield::ComponentGrid::GetMedium ( const double  x,
const double  y,
const double  z 
)
overridevirtual

Get the medium at a given location (x, y, z).

Reimplemented from Garfield::Component.

Definition at line 178 of file ComponentGrid.cc.

179 {
180 // Make sure the field map has been loaded.
181 if (!m_ready) {
182 PrintNotReady(m_className + "::GetMedium");
183 return nullptr;
184 }
185
186 std::array<double, 3> xx = {x, y, z};
187 for (size_t i = 0; i < 3; ++i) {
188 if (m_periodic[i] || m_mirrorPeriodic[i]) continue;
189 if (xx[i] < m_xMin[i] || xx[i] > m_xMax[i]) {
190 return nullptr;
191 }
192 }
193 if (m_active.empty()) return m_medium;
194 for (size_t i = 0; i < 3; ++i) {
195 bool mirrored = false;
196 xx[i] = Reduce(xx[i], m_xMin[i], m_xMax[i],
197 m_periodic[i], m_mirrorPeriodic[i], mirrored);
198 }
199 // Get the indices.
200 const double sx = (xx[0] - m_xMin[0]) * m_sX[0];
201 const double sy = (xx[1] - m_xMin[1]) * m_sX[1];
202 const double sz = (xx[2] - m_xMin[2]) * m_sX[2];
203 const unsigned int i0 = static_cast<unsigned int>(std::floor(sx));
204 const unsigned int j0 = static_cast<unsigned int>(std::floor(sy));
205 const unsigned int k0 = static_cast<unsigned int>(std::floor(sz));
206 const unsigned int i1 = std::min(i0 + 1, m_nX[0] - 1);
207 const unsigned int j1 = std::min(j0 + 1, m_nX[1] - 1);
208 const unsigned int k1 = std::min(k0 + 1, m_nX[2] - 1);
209 if (m_active[i0][j0][k0] && m_active[i0][j0][k1] && m_active[i0][j1][k0] &&
210 m_active[i0][j1][k1] && m_active[i1][j0][k0] && m_active[i1][j0][k1] &&
211 m_active[i1][j1][k0] && m_active[i1][j1][k1]) {
212 return m_medium;
213 }
214 return nullptr;
215}

◆ GetMesh()

bool Garfield::ComponentGrid::GetMesh ( unsigned int &  nx,
unsigned int &  ny,
unsigned int &  nz,
double &  xmin,
double &  xmax,
double &  ymin,
double &  ymax,
double &  zmin,
double &  zmax 
) const

Retrieve the parameters of the grid.

Definition at line 259 of file ComponentGrid.cc.

262 {
263 if (!m_hasMesh) return false;
264 nx = m_nX[0];
265 ny = m_nX[1];
266 nz = m_nX[2];
267 xmin = m_xMin[0];
268 ymin = m_xMin[1];
269 zmin = m_xMin[2];
270 xmax = m_xMax[0];
271 ymax = m_xMax[1];
272 zmax = m_xMax[2];
273 return true;
274}

◆ GetVoltageRange()

bool Garfield::ComponentGrid::GetVoltageRange ( double &  vmin,
double &  vmax 
)
overridevirtual

Calculate the voltage range [V].

Implements Garfield::Component.

Definition at line 1030 of file ComponentGrid.cc.

1030 {
1031 if (!m_ready) return false;
1032 vmin = m_pMin;
1033 vmax = m_pMax;
1034 return true;
1035}

◆ HasAttachmentMap()

bool Garfield::ComponentGrid::HasAttachmentMap ( ) const
inlineoverridevirtual

Does the component have attachment maps?

Reimplemented from Garfield::Component.

Definition at line 150 of file ComponentGrid.hh.

150 {
151 return !(m_eAttachment.empty() && m_hAttachment.empty());
152 }

◆ HasVelocityMap()

bool Garfield::ComponentGrid::HasVelocityMap ( ) const
inlineoverridevirtual

Does the component have velocity maps?

Reimplemented from Garfield::Component.

Definition at line 174 of file ComponentGrid.hh.

174 {
175 return !(m_eVelocity.empty() && m_hVelocity.empty());
176 }

◆ HoleAttachment()

bool Garfield::ComponentGrid::HoleAttachment ( const double  ,
const double  ,
const double  ,
double &  eta 
)
overridevirtual

Get the hole attachment coefficient.

Reimplemented from Garfield::Component.

Definition at line 1680 of file ComponentGrid.cc.

1681 {
1682 // Make sure the map has been loaded.
1683 if (m_hAttachment.empty()) {
1684 PrintNotReady(m_className + "::HoleAttachment");
1685 return false;
1686 }
1687 return GetData(x, y, z, m_hAttachment, att);
1688}

◆ HoleVelocity()

bool Garfield::ComponentGrid::HoleVelocity ( const double  ,
const double  ,
const double  ,
double &  vx,
double &  vy,
double &  vz 
)
overridevirtual

Get the hole drift velocity.

Reimplemented from Garfield::Component.

Definition at line 1353 of file ComponentGrid.cc.

1355 {
1356 if (m_hVelocity.empty()) {
1357 PrintNotReady(m_className + "::HoleVelocity");
1358 return false;
1359 }
1360 double p = 0.;
1361 bool active = true;
1362 return GetField(x, y, z, m_hVelocity, vx, vy, vz, p, active);
1363}

◆ LoadElectricField()

bool Garfield::ComponentGrid::LoadElectricField ( const std::string &  filename,
const std::string &  format,
const bool  withPotential,
const bool  withFlag,
const double  scaleX = 1.,
const double  scaleE = 1.,
const double  scaleP = 1. 
)

Import electric field and potential values from a file. The file is supposed to contain one line for each grid point starting with

  • either two or three floating point numbers, specifying the coordinates (in cm) of the grid node or
  • two or three integers specifying the index of the node,

followed by

  • two or three floating point numbers for the electric field (in V/cm), and (depending on the value of withPotential and withFlag),
  • a floating point number specifying the potential (in V), and
  • an integer flag indicating whether the point is in an active region (1) or not (0).

Format types are:

  • "xy", "xyz": nodes are specified by their coordinates
  • "ij", "ijk": nodes are specified by their indices

Definition at line 276 of file ComponentGrid.cc.

280 {
281 m_ready = false;
282 m_hasPotential = false;
283 m_active.assign(m_nX[0], std::vector<std::vector<bool> >(
284 m_nX[1], std::vector<bool>(m_nX[2], true)));
285 // Read the file.
286 m_pMin = withP ? +1. : 0.;
287 m_pMax = withP ? -1. : 0.;
288 if (!LoadData(fname, fmt, withP, withFlag, scaleX, scaleE, scaleP,
289 m_efields)) {
290 m_efields.clear();
291 return false;
292 }
293 m_ready = true;
294 if (withP) m_hasPotential = true;
295 return true;
296}

◆ LoadElectronAttachment()

bool Garfield::ComponentGrid::LoadElectronAttachment ( const std::string &  fname,
const std::string &  fmt,
const unsigned int  col,
const double  scaleX = 1. 
)

Import electron attachment coefficients from a file.

Parameters
fnamename of the text file.
fmtformat string ("XY", "XYZ", "IJ", "IJK").
colcolumn in the file which has the attachment coefficient.
scaleXscaling factor to be applied to the coordinates.

Definition at line 1365 of file ComponentGrid.cc.

1368 {
1369 // Read the file.
1370 return LoadData(fname, fmt, scaleX, m_eAttachment, col);
1371}

◆ LoadElectronVelocity()

bool Garfield::ComponentGrid::LoadElectronVelocity ( const std::string &  fname,
const std::string &  fmt,
const double  scaleX = 1.,
const double  scaleV = 1.e-9 
)

Import a map of electron drift velocities from a file.

Parameters
fnamename of the text file.
fmtformat string ("XY", "XYZ", "IJ", "IJK").
scaleXscaling factor to be applied to the coordinates.
scaleVscaling factor to be applied to the velocity components.

Definition at line 1319 of file ComponentGrid.cc.

1322 {
1323 // Read the file.
1324 if (!LoadData(fname, fmt, false, false, scaleX, scaleV, 1., m_eVelocity)) {
1325 return false;
1326 }
1327 return true;
1328}

◆ LoadHoleAttachment()

bool Garfield::ComponentGrid::LoadHoleAttachment ( const std::string &  fname,
const std::string &  fmt,
const unsigned int  col,
const double  scaleX = 1. 
)

Import hole attachment coefficients from a file.

Definition at line 1373 of file ComponentGrid.cc.

1376 {
1377 // Read the file.
1378 return LoadData(fname, fmt, scaleX, m_hAttachment, col);
1379}

◆ LoadHoleVelocity()

bool Garfield::ComponentGrid::LoadHoleVelocity ( const std::string &  fname,
const std::string &  fmt,
const double  scaleX = 1.,
const double  scaleV = 1.e-9 
)

Import a map of hole drift velocities from a file.

Definition at line 1330 of file ComponentGrid.cc.

1333 {
1334 // Read the file.
1335 if (!LoadData(fname, fmt, false, false, scaleX, scaleV, 1., m_hVelocity)) {
1336 return false;
1337 }
1338 return true;
1339}

◆ LoadMagneticField()

bool Garfield::ComponentGrid::LoadMagneticField ( const std::string &  filename,
const std::string &  format,
const double  scaleX = 1.,
const double  scaleB = 1. 
)

Import magnetic field values from a file.

Definition at line 332 of file ComponentGrid.cc.

335 {
336 // Read the file.
337 if (!LoadData(fname, fmt, false, false, scaleX, scaleB, 1., m_bfields)) {
338 m_bfields.clear();
339 return false;
340 }
341 return true;
342}

◆ LoadWeightingField() [1/2]

bool Garfield::ComponentGrid::LoadWeightingField ( const std::string &  filename,
const std::string &  format,
const bool  withPotential,
const double  scaleX = 1.,
const double  scaleE = 1.,
const double  scaleP = 1. 
)

Import (prompt) weighting field from file.

Definition at line 298 of file ComponentGrid.cc.

301 {
302 // Read the file.
303 if (!LoadData(fname, fmt, withP, false, scaleX, scaleE, scaleP, m_wfields)) {
304 m_wfields.clear();
305 return false;
306 }
307 return true;
308}

Referenced by main().

◆ LoadWeightingField() [2/2]

bool Garfield::ComponentGrid::LoadWeightingField ( const std::string &  filename,
const std::string &  format,
const double  time,
const bool  withPotential,
const double  scaleX = 1.,
const double  scaleE = 1.,
const double  scaleP = 1. 
)

Import delayed weighting field from file.

Definition at line 310 of file ComponentGrid.cc.

314 {
315 std::vector<std::vector<std::vector<Node> > > wfield;
316 // Read the file.
317 if (!LoadData(fname, fmt, withP, false, scaleX, scaleE, scaleP, wfield)) {
318 return false;
319 }
320 if (m_wdtimes.empty() || t > m_wdtimes.back()) {
321 m_wdtimes.push_back(t);
322 m_wdfields.push_back(std::move(wfield));
323 } else {
324 const auto it = std::upper_bound(m_wdtimes.begin(), m_wdtimes.end(), t);
325 const auto n = std::distance(m_wdtimes.begin(), it);
326 m_wdtimes.insert(it, t);
327 m_wdfields.insert( m_wdfields.begin() + n, std::move(wfield));
328 }
329 return true;
330}

◆ MagneticField()

void Garfield::ComponentGrid::MagneticField ( const double  x,
const double  y,
const double  z,
double &  bx,
double &  by,
double &  bz,
int &  status 
)
overridevirtual

Calculate the magnetic field at a given point.

Parameters
x,y,zcoordinates [cm].
bx,by,bzcomponents of the magnetic field [Tesla].
statusstatus flag.

Reimplemented from Garfield::Component.

Definition at line 163 of file ComponentGrid.cc.

165 {
166 status = 0;
167 if (m_bfields.empty()) {
168 return Component::MagneticField(x, y, z, bx, by, bz, status);
169 }
170
171 double p = 0.;
172 bool active = true;
173 if (!GetField(x, y, z, m_bfields, bx, by, bz, p, active)) {
174 status = -11;
175 }
176}
virtual void MagneticField(const double x, const double y, const double z, double &bx, double &by, double &bz, int &status)
Definition: Component.cc:81

◆ Print()

void Garfield::ComponentGrid::Print ( )

Print information about the mesh and the available data.

Definition at line 1182 of file ComponentGrid.cc.

1182 {
1183
1184 std::cout << m_className << "::Print:\n";
1185 if (!m_hasMesh) {
1186 std::cout << " Mesh not set.\n";
1187 return;
1188 }
1189 std::printf(" %15.8f < x [cm] < %15.8f, %10u nodes\n",
1190 m_xMin[0], m_xMax[0], m_nX[0]);
1191 std::printf(" %15.8f < y [cm] < %15.8f, %10u nodes\n",
1192 m_xMin[1], m_xMax[1], m_nX[1]);
1193 std::printf(" %15.8f < z [cm] < %15.8f, %10u nodes\n",
1194 m_xMin[2], m_xMax[2], m_nX[2]);
1195 if (m_efields.empty() && m_bfields.empty() &&
1196 m_wfields.empty() && m_wdfields.empty() &&
1197 m_eAttachment.empty() && m_hAttachment.empty() &&
1198 m_eVelocity.empty() && m_hVelocity.empty()) {
1199 std::cout << " Available data: None.\n";
1200 return;
1201 }
1202 std::cout << " Available data:\n";
1203 if (!m_efields.empty()) std::cout << " Electric field.\n";
1204 if (!m_bfields.empty()) std::cout << " Magnetic field.\n";
1205 if (!m_wfields.empty()) std::cout << " Weighting field.\n";
1206 if (!m_wdfields.empty()) {
1207 std::cout << " Delayed weighting field.\n";
1208 }
1209 if (!m_eVelocity.empty()) {
1210 std::cout << " Electron drift velocity.\n";
1211 }
1212 if (!m_hVelocity.empty()) {
1213 std::cout << " Hole drift velocity.\n";
1214 }
1215 if (!m_eAttachment.empty()) {
1216 std::cout << " Electron attachment coefficient.\n";
1217 }
1218 if (!m_hAttachment.empty()) {
1219 std::cout << " Hole attachment coefficient.\n";
1220 }
1221}

Referenced by main().

◆ SaveElectricField()

bool Garfield::ComponentGrid::SaveElectricField ( Component cmp,
const std::string &  filename,
const std::string &  format 
)

Export the electric field and potential of a component to a text file.

Parameters
cmpComponent object for which to export the field/potential
filenamename of the text file
format"xy", "xyz", "ij" or "ijk", see LoadElectricField

Definition at line 344 of file ComponentGrid.cc.

346 {
347 if (!cmp) {
348 std::cerr << m_className << "::SaveElectricField: Null pointer.\n";
349 return false;
350 }
351 if (!m_hasMesh) {
352 std::cerr << m_className << "::SaveElectricField: Mesh not set.\n";
353 return false;
354 }
355 const auto fmt = GetFormat(format);
356 if (fmt == Format::Unknown) {
357 std::cerr << m_className << "::SaveElectricField:\n"
358 << " Unknown format (" << format << ").\n";
359 return false;
360 }
361 std::ofstream outfile;
362 outfile.open(filename.c_str(), std::ios::out);
363 if (!outfile) {
364 std::cerr << m_className << "::SaveElectricField:\n"
365 << " Could not open file " << filename << ".\n";
366 return false;
367 }
368 std::cout << m_className << "::SaveElectricField:\n"
369 << " Exporting field/potential to " << filename << ".\n"
370 << " Be patient...\n";
371 PrintProgress(0.);
372 outfile << "# XMIN = " << m_xMin[0] << ", XMAX = " << m_xMax[0]
373 << ", NX = " << m_nX[0] << "\n";
374 outfile << "# YMIN = " << m_xMin[1] << ", YMAX = " << m_xMax[1]
375 << ", NY = " << m_nX[1] << "\n";
376 outfile << "# ZMIN = " << m_xMin[2] << ", ZMAX = " << m_xMax[2]
377 << ", NZ = " << m_nX[2] << "\n";
378
379 const unsigned int nValues = m_nX[0] * m_nX[1] * m_nX[2];
380 const unsigned int nPrint =
381 std::pow(10, static_cast<unsigned int>(
382 std::max(std::floor(std::log10(nValues)) - 1, 1.)));
383 unsigned int nLines = 0;
384 Medium* medium = nullptr;
385 int status = 0;
386 const double dx = (m_xMax[0] - m_xMin[0]) / std::max(m_nX[0] - 1., 1.);
387 const double dy = (m_xMax[1] - m_xMin[1]) / std::max(m_nX[1] - 1., 1.);
388 const double dz = (m_xMax[2] - m_xMin[2]) / std::max(m_nX[2] - 1., 1.);
389 for (unsigned int i = 0; i < m_nX[0]; ++i) {
390 const double x = m_xMin[0] + i * dx;
391 for (unsigned int j = 0; j < m_nX[1]; ++j) {
392 const double y = m_xMin[1] + j * dy;
393 for (unsigned int k = 0; k < m_nX[2]; ++k) {
394 const double z = m_xMin[2] + k * dz;
395 if (fmt == Format::XY) {
396 outfile << x << " " << y << " ";
397 } else if (fmt == Format::XYZ) {
398 outfile << x << " " << y << " " << z << " ";
399 } else if (fmt == Format::IJ) {
400 outfile << i << " " << j << " ";
401 } else if (fmt == Format::IJK) {
402 outfile << i << " " << j << " " << k << " ";
403 } else if (fmt == Format::YXZ) {
404 outfile << y << " " << x << " " << z << " ";
405 }
406 double ex = 0., ey = 0., ez = 0., v = 0.;
407 cmp->ElectricField(x, y, z, ex, ey, ez, v, medium, status);
408 outfile << ex << " " << ey << " " << ez << " " << v << "\n";
409 ++nLines;
410 if (nLines % nPrint == 0) PrintProgress(double(nLines) / nValues);
411 }
412 }
413 }
414 outfile.close();
415 std::cout << std::endl << m_className << "::SaveElectricField: Done.\n";
416 return true;
417}

◆ SaveWeightingField()

bool Garfield::ComponentGrid::SaveWeightingField ( Component cmp,
const std::string &  id,
const std::string &  filename,
const std::string &  format 
)

Export the weighting field and potential of a component to a text file.

Parameters
cmpComponent object for which to export the field/potential
ididentifier of the weighting field
filenamename of the text file
format"xy", "xyz", "ij" or "ijk", see LoadElectricField

Definition at line 419 of file ComponentGrid.cc.

422 {
423 if (!cmp) {
424 std::cerr << m_className << "::SaveWeightingField: Null pointer.\n";
425 return false;
426 }
427 if (!m_hasMesh) {
428 std::cerr << m_className << "::SaveWeightingField: Mesh not set.\n";
429 return false;
430 }
431 const auto fmt = GetFormat(format);
432 if (fmt == Format::Unknown) {
433 std::cerr << m_className << "::SaveWeightingField:\n"
434 << " Unknown format (" << format << ").\n";
435 return false;
436 }
437 std::ofstream outfile;
438 outfile.open(filename.c_str(), std::ios::out);
439 if (!outfile) {
440 std::cerr << m_className << "::SaveWeightingField:\n"
441 << " Could not open file " << filename << ".\n";
442 return false;
443 }
444 std::cout << m_className << "::SaveWeightingField:\n"
445 << " Exporting field/potential to " << filename << ".\n"
446 << " Be patient...\n";
447 PrintProgress(0.);
448 outfile << "# XMIN = " << m_xMin[0] << ", XMAX = " << m_xMax[0]
449 << ", NX = " << m_nX[0] << "\n";
450 outfile << "# YMIN = " << m_xMin[1] << ", YMAX = " << m_xMax[1]
451 << ", NY = " << m_nX[1] << "\n";
452 outfile << "# ZMIN = " << m_xMin[2] << ", ZMAX = " << m_xMax[2]
453 << ", NZ = " << m_nX[2] << "\n";
454 const unsigned int nValues = m_nX[0] * m_nX[1] * m_nX[2];
455 const unsigned int nPrint =
456 std::pow(10, static_cast<unsigned int>(
457 std::max(std::floor(std::log10(nValues)) - 1, 1.)));
458 unsigned int nLines = 0;
459 const double dx = (m_xMax[0] - m_xMin[0]) / std::max(m_nX[0] - 1., 1.);
460 const double dy = (m_xMax[1] - m_xMin[1]) / std::max(m_nX[1] - 1., 1.);
461 const double dz = (m_xMax[2] - m_xMin[2]) / std::max(m_nX[2] - 1., 1.);
462 for (unsigned int i = 0; i < m_nX[0]; ++i) {
463 const double x = m_xMin[0] + i * dx;
464 for (unsigned int j = 0; j < m_nX[1]; ++j) {
465 const double y = m_xMin[1] + j * dy;
466 for (unsigned int k = 0; k < m_nX[2]; ++k) {
467 const double z = m_xMin[2] + k * dz;
468 if (fmt == Format::XY) {
469 outfile << x << " " << y << " ";
470 } else if (fmt == Format::XYZ) {
471 outfile << x << " " << y << " " << z << " ";
472 } else if (fmt == Format::IJ) {
473 outfile << i << " " << j << " ";
474 } else if (fmt == Format::IJK) {
475 outfile << i << " " << j << " " << k << " ";
476 } else if (fmt == Format::YXZ) {
477 outfile << y << " " << x << " " << z << " ";
478 }
479 double wx = 0., wy = 0., wz = 0.;
480 cmp->WeightingField(x, y, z, wx, wy, wz, id);
481 const double v = cmp->WeightingPotential(x, y, z, id);
482 outfile << wx << " " << wy << " " << wz << " " << v << "\n";
483 ++nLines;
484 if (nLines % nPrint == 0) PrintProgress(double(nLines) / nValues);
485 }
486 }
487 }
488 outfile.close();
489 std::cout << std::endl << m_className << "::SaveWeightingField: Done.\n";
490 return true;
491}

◆ SetMedium()

void Garfield::ComponentGrid::SetMedium ( Medium m)

Set the medium.

Definition at line 1064 of file ComponentGrid.cc.

1064 {
1065 if (!m) {
1066 std::cerr << m_className << "::SetMedium: Null pointer.\n";
1067 }
1068 m_medium = m;
1069}

◆ SetMesh()

bool Garfield::ComponentGrid::SetMesh ( const unsigned int  nx,
const unsigned int  ny,
const unsigned int  nz,
const double  xmin,
const double  xmax,
const double  ymin,
const double  ymax,
const double  zmin,
const double  zmax 
)

Define the grid.

Parameters
nx,ny,nznumber of nodes along $x, y, z$.
xmin,xmaxrange along $x$.
ymin,ymaxrange along $y$.
zmin,zmaxrange along $z$.

Definition at line 217 of file ComponentGrid.cc.

221 {
222 Reset();
223 if (nx == 0 || ny == 0 || nz == 0) {
224 std::cerr << m_className << "::SetMesh:\n"
225 << " Number of mesh elements must be positive.\n";
226 return false;
227 }
228 if (xmin >= xmax) {
229 std::cerr << m_className << "::SetMesh: Invalid x range.\n";
230 return false;
231 } else if (ymin >= ymax) {
232 std::cerr << m_className << "::SetMesh: Invalid y range.\n";
233 return false;
234 } else if (zmin >= zmax) {
235 std::cerr << m_className << "::SetMesh: Invalid z range.\n";
236 return false;
237 }
238 m_nX[0] = nx;
239 m_nX[1] = ny;
240 m_nX[2] = nz;
241 m_xMin[0] = xmin;
242 m_xMin[1] = ymin;
243 m_xMin[2] = zmin;
244 m_xMax[0] = xmax;
245 m_xMax[1] = ymax;
246 m_xMax[2] = zmax;
247 constexpr double tol = 1.e-10;
248 for (size_t i = 0; i < 3; ++i) {
249 if (m_xMax[i] - m_xMin[i] > tol) {
250 m_sX[i] = std::max(m_nX[i] - 1., 1.) / (m_xMax[i] - m_xMin[i]);
251 } else {
252 m_sX[i] = 0.;
253 }
254 }
255 m_hasMesh = true;
256 return true;
257}

◆ SetWeightingFieldOffset()

void Garfield::ComponentGrid::SetWeightingFieldOffset ( const double  x,
const double  y,
const double  z 
)

Offset coordinates in the weighting field, such that the same numerical weighting field map can be used for electrodes at different positions.

Definition at line 158 of file ComponentGrid.cc.

159 {
160 m_wFieldOffset = {x, y, z};
161}

◆ WeightingField()

void Garfield::ComponentGrid::WeightingField ( const double  x,
const double  y,
const double  z,
double &  wx,
double &  wy,
double &  wz,
const std::string &  label 
)
overridevirtual

Calculate the weighting field at a given point and for a given electrode.

Parameters
x,y,zcoordinates [cm].
wx,wy,wzcomponents of the weighting field [1/cm].
labelname of the electrode

Reimplemented from Garfield::Component.

Definition at line 91 of file ComponentGrid.cc.

93 {
94 wx = wy = wz = 0.;
95 if (m_wfields.empty()) return;
96 const double xx = x - m_wFieldOffset[0];
97 const double yy = y - m_wFieldOffset[1];
98 const double zz = z - m_wFieldOffset[2];
99 double wp = 0.;
100 bool active = true;
101 GetField(xx, yy, zz, m_wfields, wx, wy, wz, wp, active);
102}

◆ WeightingPotential()

double Garfield::ComponentGrid::WeightingPotential ( const double  x,
const double  y,
const double  z,
const std::string &  label 
)
overridevirtual

Calculate the weighting potential at a given point.

Parameters
x,y,zcoordinates [cm].
labelname of the electrode.
Returns
weighting potential [dimensionless].

Reimplemented from Garfield::Component.

Definition at line 104 of file ComponentGrid.cc.

106 {
107 if (m_wfields.empty()) return 0.;
108 const double xx = x - m_wFieldOffset[0];
109 const double yy = y - m_wFieldOffset[1];
110 const double zz = z - m_wFieldOffset[2];
111 double wx = 0., wy = 0., wz = 0.;
112 double wp = 0.;
113 bool active = true;
114 if (!GetField(xx, yy, zz, m_wfields, wx, wy, wz, wp, active)) return 0.;
115 return wp;
116}

The documentation for this class was generated from the following files: