DriftNegativeIon hangs at certain point even in valid region

Dear all,
I’m currently simulating negative ion drift using AvalancheMC::DriftNegativeIon with a field map from COMSOL (ComponentComsol). The simulation generally works well, but for certain starting points, the drift appears to hang — the function never returns, memory usage increases continuously, and the program does not proceed beyond that call.

Here are some details:

  1. I tried to debug what happened
std::cout<<(*x_s)[i]/10<<" "<<(*y_s)[i]/10<<" "<<(*z_s)[i]/10+250<<" "<<i<<std::endl;
drift.DriftNegativeIon((*x_s)[i]/10,(*y_s)[i]/10,(*z_s)[i]/10+250,0);
std::cout<<"Drift done"<<std::endl;

The terminal shows

......
50.1142 -16.9341 160.907 1180
Drift done
50.1145 -17 160.832 1181
Drift done
50.122 -17.0694 160.761 1182

So (x, y, z) = (50.122, -17.0694, 160.761) caused the problem.

  1. Step size configuration
auto step = [](double x, double y, double z) {
                if (z>3.) return 1.;
                else return 1e-3;
        };
        drift.SetStepDistanceFunction(step);

No error message is shown, but DriftNegativeIon(…) does not complete.

  1. I attempted to check the drift region using:
sensor.IsInside(x, y, z)

and it returns true.

Questions:

  1. What could cause DriftNegativeIon to hang even when the point seems inside the drift region?
  2. Is there any built-in timeout or maximum step count mechanism in AvalancheMC to prevent infinite loops?
  3. Is there a way to safely skip problematic points during simulation?

I guess @hschindl can help you.

Could anyone help me?

Hi,
sorry for the late reply! Can you try to plot the drift line for this starting point?
By default, AvalancheMC does not apply a maximum number of steps or timeout. You can set a time window though.

Sorry, the DriftNegativeIon() does not complete, I could not get the drift line. How to set time window? Could it be done in Garfield++? Or using C++? ( std::async + std::future_status::timeout)

You can set the time window in the sensor class: sensor. SetTimeWindow(). Instead the driftline you should setup a ViewDrift object and associate it to a canvas before launching the driftline, this way you should be able to plot the driftline while the calculation is ongoing. Of course if you are just stuck in a single point from the beginning, then you will likely see just a single point.

Hi Piet,
I think we have a misunderstanding. I know sensor. SetTimeWindow(). The time range of simulation could be set by this function. The problem is that when DriftNegativeIon() running with the certain point, it stuck.

        Sensor sensor(&fm);
        sensor.AddElectrode(&fm,"anode");
        const unsigned int nBins = 1e5;
        double tend = 5e10;
        sensor.SetTimeWindow(0, tend/nBins, nBins);



       AvalancheMC drift;
        drift.SetSensor(&sensor);
        drift.UseWeightingPotential(true);
        drift.DisableDiffusion();
        drift.EnableSignalCalculation();

        ViewDrift driftView;
        constexpr bool plotdrift = true;
        if (plotdrift){
                TCanvas* c2 = new TCanvas("c2", "Drift Path", 600, 600);
                driftView.SetCanvas(c2);
                drift.EnableSignalCalculation();
                drift.EnablePlotting(&driftView);
                driftView.Plot();
        }


drift.DriftNegativeIon(50.122 -17.0694 160.761,0);

If I’m not mistaken, the coordinates of drift line could be stored after drift.DriftNegativeIon() finishing and called by drift.GetNegativeIons(). But the drift.DriftNegativeIon() could not be finished :sob:

  • Indeed, Sensor::SetTimeWindow sets the range and binning for the signal calculation. You can use the function SetTimeWindow of AvalancheMC to impose a time limit for the drift line calculation.
  • You’re right, the plotting happens after the drift line is terminated; so my suggestion to plot it was indeed not very helpful… Could you switch on debugging in AvalancheMC (EnableDebugging) and send the output for the starting point that causes the calculation to hang?

Hi hschindl
I use EnableDebugging, and terminal is loopy printing

    Next point: (49.907523, -17.059318, 1.607878).
AvalancheMC::GetVelocity: Velocity at (49.907523, -17.059318, 1.607878) = -6.1624e-10, 1.28349e-09, -1.79169e-10
AvalancheMC::GetVelocity: Velocity at (49.907094, -17.058424, 1.607754) = 2.83941e-08, -5.81179e-08, 8.24161e-09
AvalancheMC::GetVelocity: Velocity at (49.907308, -17.058871, 1.607816) = 2.83481e-08, -5.86053e-08, 8.23616e-09
Avalan^CcheMC::GetVelocity: Velocity at (49.907416, -17.059095, 1.607847) = 2.83251e-08, -5.88489e-08, 8.23344e-09
    Next point: (49.907469, -17.059207, 1.607863).
AvalancheMC::GetVelocity: Velocity at (49.907469, -17.059207, 1.607863) = 2.83136e-08, -5.89708e-08, 8.23207e-09
AvalancheMC::GetVelocity: Velocity at (49.907899, -17.060101, 1.607988) = -4.58455e-10, -4.31539e-11, -6.31958e-10
AvalancheMC::GetVelocity: Velocity at (49.907684, -17.059654, 1.607925) = -5.48618e-10, 7.14927e-10, -3.73222e-10
AvalancheMC::GetVelocity: Velocity at (49.907577, -17.059430, 1.607894) = -5.937e-10, 1.09397e-09, -2.43853e-10

It seems that (49.907523, -17.059318, 1.607878) and (49.907469, -17.059207, 1.607863) fall in infinite loop.

Oh, maybe I found the solution. The step length must be suitable. A non integer step length should be used which could skip the oscillation points. That may caused by the accurate of mesh file from COMSOL.