Import electric field values on a 3d grid


I have a question for garfield++.
I have a txt file. In this txt file, the grid points contain the electric field values for a sphere, and a small irregular 3d domain in the centre of the sphere should have electric field undefined (this is how it is designed). For example, for coordinates with x = 0, y=0, |z|<2.1, electric field values are undefined so this txt file doesn’t contain the electric field values for these coordinates, and the electric field at roughly (x=0,y=0,z=2.1) should reach its maximum.

I have successfully imported electric field on a 3-d grid from this txt file using
and I also used function
prior to reading the electric field.

What I found is that after I imported those 3d grid points and try to probe the electric field at (0,0,2.0), the electric field is nonzero, which is expected to be undefined as I just discussed. I found the electric field become undefined only for z<1.34 (x=y=0). The electric field will get closer to zero if I decrease the |z| value from 2.1 to 1.34. The electric field at (0,0,2.1) get its maximum but is still quite smaller than what it should be, but the larger the z value is, the more accurate the probed electric field will be. What I’m saying is for coordinates (x=0,y=0,z>4.1), the probed electric field matches the expected values. I think this may have to do with how garfield++ retrieve the field at a given position on “edge”.

Is there a proper way to import the electric field so that it will NOT create a decreasing field region from z = 2.1 to z = 1.34 (x = y = 0)? Region (z = 2.1 to 1.34) should be identified as undefined so that electrons should stop drifting in those area, and the electric field values can become accurate on “edges”.
BTW, This irregular region cannot be described by an analytical solution.

Thanks in advance for any help you can give! Please let me know if those descriptions have cause any confusions!

Maybe you can try the following: add an extra column to your txt file which has a non-zero (integer) value for the “valid” points and 0 for the points where the electric field is undefined. Make sure that your txt file includes all points in the grid (not just the ones with a valid field). When importing the data, set the fourth argument (withFlag) of LoadElectricField to true. ComponentGrid will/should then consider all points with a zero in the extra column as outside the active region and will not use them for interpolating the potential or electric field.
Let me know if that works…

Thanks for the reply! I have tried what you said but unfortunately the problem still exists. I suspect that it is because the resolution is too low on the edge (only 4 points are undefined). I also tried to import a grid that has high resolution near the edge so that the grid points are not evenly spaced (i.e. formulate logarithmic variables as a way of eliminating mesh resolution problems), but it seems garfield++ cannot read unevenly spaced grid points properly.

Now I imported field map instead of 3D grid points. It is working well so far. I will also try to formulate logarithmic variables to increase the resolution for mesh and potential field when importing field map. I will let you know if I encounter any issues on that.

indeed, ComponentGrid only supports meshes with evenly spaced grid points.


Currently I encountered some problems when trying to plot the trajectories for electron avalanche using this field map.
I load the field map using function ComponentComsol. Three txt files are imported, which will generate the field map inside a 3D sphere. The field map is assumed to be imported properly, because I probed the electric field at different coordinates and the values seem correct. The anode is located at centre. I create one single electron at position (0,0,5) [cm] at time zero, and start to calculate an electron avalanche. By using function GetNumberOfElectronEndpoints(), I know that this electron drifts towards the anode as expected and avalanche drift lines are calculated as well. The problem is no trajectories are shown when plotting drift lines. Can you give me some suggestions of what I can try to make it work?

I have attached the code in case you want to have a look:
Sphere_aval.C (4.2 KB)

Thank you!

you need call



aval.AvalancheElectron(x0, y0, z0, t0, e0, dx0, dy0, dz0);

Thank you! It works as you said.


I have several more questions here and hoping I can ask them all at once:

  1. I used GetAvalancheSize(ne, ni) to get the number of electrons and ions in the avalanche, and used np = GetNumberOfElectronsEndpoints() to get the number of electrons drift lines. Here’s what I got for one single primary electron avalanche: ne, ni, np = 32836, 32854, 32874. I’m expecting ne = ni = np because each ionization should create one electron and one ion, and each time a new electron is created a new drift line should be added. Do you know why ne, ni, np give me different values?
  2. I used two different approaches: DriftElectron() in AvalancheMC and AvalancheElectron() in AvalancheMicroscopic, to drift the electron from cathode to anode (same starting position and almost the same end position). I found the drift time using microscopic tracking is larger than Monte Carlo Integration by 16%. Shouldn’t we expect these two methods give close values?
  3. The material file I imported to Garfield++ has 6 materials including the material for anode. When plotting with meshView, only electron drift lines are plotted. Shouldn’t the geometry of the anode be also plotted? (Please refer to Sphere_aval.C I attached previously if you want to have a look.) Do you know what can cause this problem? I can provide more information if needed.
  4. When simulating avalanche with class AvalancheMicroscopic, is there a way for me to save the information or keep track of the energy of the primary electron along with its corresponding position, time and direction?

Thanks again for any information that you can give!


  1. I suspect it’s because of attachment. The electrons that were lost due to attachment are counted in np but not in ne, np.
  2. Yes, the drift times from the two methods should be statistically compatible. How many electrons did you simulate? Out of curiosity, why did you use DriftElectron with one class and AvalancheElectron with the other?
  3. I’ll need to take a look. Can you upload/send the Comsol files?
  4. You can retrieve the trajectory using the function GetElectronDriftLinePoint (you will need to call EnableDriftLines before simulating the avalanche for this to work). There is no function to retrieve the energy and direction at the moment, we would need to implement this.


  1. Thank you! Regarding the number of electrons and ions created in avalanche, shouldn’t ne = ni? I got different numbers.
  2. With Monte Carlo Integration method (AvalancheMC), I simulated 1000 primary electrons and found a resulting mean drift time. When using AvalancheElectron() in AvalancheMicroscopic class, I only simulated 4 primary electrons because of the large computational cost, and the drift times for all 4 electrons are roughly 16% larger than the mean drift time I found previously with Monte Carlo.
    The reason why I use different classes: In my experiments, I need to know the drift times and also the secondary pairs created in avalanche. I need to simulate the drift times for a large number of electrons so I need to use Monte Carlo method or RKF method which are much faster than microscopic tracking method. To study avalanche, I don’t think function AvalancheElectron() in class AvalancheMC can perform equally well as microscopic tracking so I use class AvalancheMicoscopic instead of AvalancheMC.
  3. The following link contains all the files needed for running simulation, including dielectrics, mesh, potential field txt files exported from COMSOL and gas files generated from the Garfield++ built in Magboltz. Please use the Sphere_aval.C I attached previously and ignore the Sphere_aval.C from this link.
    Dropbox - - Simplify your life
    (Please let me know if there’s any issue)
  4. Do you think I can extract the energy and direction by properly modifying the source code if I can understand it?

Thank you!

thanks a lot for the files! I can’t reproduce the discrepancy between AvalancheMicroscopic and MC/RKF integration though.

To calculate the drift time using AvalancheMicroscopic I did something like this:

double tsum = 0.;
for (unsigned int i = 0; i < nEvents; ++i) {
  aval.DriftElectron(x0, y0, z0, t0, 0.1, dx0, dy0, dz0);
  double x1, y1, z1, t1, e1, x2, y2, z2, t2, e2;
  int status = 0;
  aval.GetElectronEndpoint(0, x1, y1, z1, t1, e1, x2, y2, z2, t2, e2, status);
  tsum += t2;
std::cout << "Average: " << tsum / nEvents << "\n";

Averaging over 1000 “events”, I get about 428.15 ns, which is statistically compatible with the DriftLineRKF result (428.256 ns).

Regarding your first question: CH4 has a small attachment cross-section. Some electrons can be lost due to attachment before they reach the target electrode, and are therefore not counted in the avalanche size.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.