How to kill an AvalanceMicroscopic track in user-defined volume


First of all, thanks for developing Garfield++, it’s really well designed and actually fun to use! On to my question.

I’m simulating a Xenon gas chamber that has multiple cells. The cells are separated by cathode wires and have a central anode wire.

At the moment I’m mostly interested in electrons deposited near the boundaries between cells, and which anode the track eventually ends up in. I don’t need to simulate the full avalanche, but I do want to simulate the microscopic physics that may cause an electron to diffuse from one geometric cell to another before drifting to the anode wire. The effective cell boundaries are a bit fuzzy because of this.

As such, I just want to push a bunch of electrons through their initial drift until they definitively reach one cell or another. I don’t need to waste compute cycles on the subsequent drift or avalanche. How can I stop/kill the track when it reaches a certain user-defined volume?

Things I tried:

  • Set a time window using SetTimeWindow(). This mostly works, but some tracks spend a fair amount of time diffusing near the boundary and I would need to set an impractically large time window for all tracks. This ends up not being much of a compute time savings.
  • Add a second ComponentConstant with SolidTube volume of my chosing, superposed on the existing Component. I set gas.EnableDrift(false) hoping that the electron would enter a non-driftable region and terminate. However, the electron kept happily drifting without stopping.
  • I hoped SetUserHandleStep() would let my user function return a not-OK status when the track enters my specified volume, but it does not.

So I think my best hope is to modify the SetUserHandleStep() code to return a status code. But I wanted to make sure I wasn’t missing something.
Craig M

Basic code outline below

  // Gas mixture.
  MediumMagboltz gas("xe", 90.0, "ch4", 10.0);

  // ------------------------------- Set up geometry
  // Define the cell layout.
  ComponentAnalyticField cmp;
  cmp.SetMedium(&gas);        // Gas in cell
  cmp.SetPeriodicityX(cellx); // Periodicity in X

  //  ... add all wires and planes here ...

  Sensor sensor;
  sensor.SetArea(-1.5*cellx,   0.0,   -50.0,
                 +1.5*cellx,   lxy,   +50.0);

  // Create an avalanche object
  AvalancheMicroscopic aval;
  aval.SetCollisionSteps(200); // for plotting, every N steps

  // Perform microscopic avalanche drift
      avstatus = aval.DriftElectron(x0, y0, z0,   t0, ee0,   vx0, vy0, vz0);

Welcome to the ROOT Forum!
I’m sure @hschindl can help

So you want to stop the avalanche as soon as any of its electrons hits the electrode or leaves the sensor, did I understand that correctly? In this case, do you need avalanching for anything? You could probe where electrons end up with DriftLineRKF as it doesn’t include avalanching. Not sure whether using RKF drifting here would modify the dynamics of electron diffusion. If that’s the case then maybe AvalancheMicroscopic with EnableAvalancheSizeLimit(1) could be a solution?

Thanks for your reply. I just want to know definitively which volume the electron is in before killing it, including the effects of diffusion. For that reason I need AvalancheMicroscopic which treats all those microscopic effects. For the current purpose I don’t even need to track the electron to an electrode.

Now that I think of it, I could do time slice windows. Say 20 nanoseconds at a time, and keep iterating until it enters the certain volume of a cell.

the function DriftElectron which is used in the snippet of code you posted actually tracks only the initial electron (not the secondaries produced in the avalanche). Setting a time window seems like a good way to achieve what you described…

You could also limit your sensor area such that it doesn’t include the desired volume. Unless that volume is non-rectangular.

Thanks both @hschindl and @mjag.

@mjag, there are multiple cells so a simple bounding volume check is not enough.

@hschindl, true that a time window works, but unfortunately sometimes electrons take 20 nanoseconds to “pick a side” and other times it takes 500 nano seconds. Since I’m simulating hundreds of thousands of electron tracks, I don’t really want to track everything for 500 nanoseconds.

Here is the code I ended up with.

        double tstart = 0.0;
        double tstep = 20.0;
        int elecstatus = StatusOutsideTimeWindow;
        while (! DefiniteCellVolume(x0, y0, z0, t0, e0, vx0, vy0, vz0) &&
               elecstatus == StatusOutsideTimeWindow) {
          aval.SetTimeWindow(tstart, tstart+tstep);
          avstatus = aval.DriftElectron(x0, y0, z0,   t0, e0,   vx0, vy0, vz0);

          double x1, y1, z1, t1, e1;
                                   x1, y1, z1, t1, e1,
                                   x0, y0, z0, t0, e0,
                                   vx0, vy0, vz0,
          tstart += tstep;

It keeps iterating, 20 nanoseconds at a time, until the track reaches a DefiniteCellVolume(), or some other non-driftable volume. The variables (x0,y0,z0, vx0,vy0,vz0, e0,t0) get reloaded each iteration with the end of the previous iteration’s track.


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