JuliaPhysics/SolidStateDetectors.jl

Convergence, overshooting for small object in large grid spacing

leenderthayen opened this issue · 4 comments

Hello,

In our geometry we have a number of very thin layers compared to the overall dimensions of the system. One such thin layer is a pspray/pstop p+ layer which separates n+ pixels on n-type bulk. We would like to investigate what the behaviour of the system and pulse shapes is near pixel edges, which requires us to zoom into this region.

In doing preliminary testing, I tried to see what the code did when the physical size of a contact is much smaller than the anticipated grid spacing. As an example, I constructed a 10mm long tube with a 1um radius, with a grounded contact on one end and -1500V on the other, with a grid size of 30x30x30mm. Applying the initial conditions shows a large blot at the contact location with the correct voltage, which is fine. Performing the calculation with a number of refinements, however, a number of problems appear. Even with the convergence limit set to 1e-3, the process becomes extremely slow. More worryingly, it does not seem to reach convergence before stopping with no clear indication as to why. Finally, however, the potential obtained does not make sense, and the electric potential shows the tube having potentials of more than tens of thousands of positive voltage, with higher voltages obtained for larger grid spacings.

This raises a number of questions, some of which have been on our minds already a bit longer

  • How is the convergence determined, and when does the algorithm decide to stop (and go to another refinement)? Is there a way to force it to continue?
  • What does the 'value' stand for when the calculation is ongoing?
  • Is this overshooting situation avoidable? Given that the initial state recovers the correct voltage for a very crude grid, I assume this is possible in principle
  • Is it possible to have an adaptive (ie unequal spacings depending on the geometry in that location) grid?
  • If not, is it possible for the user to define a custom grid with unequal spacings?

Thank you!
Leendert

tt_bt_comp

lmh91 commented

So, first of all I want to mention that the current adaptive refinement is very simple. I have already some ideas how to improve the general refinement, but this will be done in the refactoring of the CSG which is currently ongoing.

The convergence value is basically the absolute value of the maximum difference between two iteration steps (update of the potentials) of all grid points divided by the bias voltage (1500V in your case). You can set the convergence limit to 0 and increase the number of maximum iterations: max_n_iterations. A further refinement is done when either the convergence limit is reached or the number of maximum iterations is reached (then a warning is also thrown. This however, is not always a problem.)

The overshooting is strange and should not appear if you do not have a charge/impurity density.
Can you give me your config file?

Yes, it is possible to provide a custom grid via the grid-keyword:
update_till_convergence!( ..., grid = Grid())...
So you would need to create the Grid first by yourself:
E.g.: grid = CartesianGrid3D{T}( (ax_x, ax_y, ax_z) )
Here, ax_x/y/z are DistrecteAxis you will have to create. They hold the ticks and the boundary conditions of the axis
(reflecting, periodic, ...). You can have a look under src/SolidStateDetector/DetectorGeometries how the default grids are
generated.

But I would suggest to first try out some individualized refining:

apply_initial_state!(sim, ElectricPotential) # here you could also give a grid as a third argument
update_till_convergence!( sim, ElectricPotential, 1e-6, max_n_iterations = 50000) # 1e-6 = convergence limit
grid_size = (1, 1, 1) # size(sim.electric_potential.grid)

begin
    # First do a "coarse"-refinement: 10% allowed potential difference between two grid points:
    max_diffs = ((1e-1, 1e-1, 1e-1) .* bias_voltage) # maximum allowed potential difference between two grid points (per axis)
    # in your case that should lead to a higher grid point density around the tube 
    while grid_size != size(sim.electric_potential.grid)
        @show size(sim.electric_potential.grid)
        grid_size = size(sim.electric_potential.grid)
        refine!(sim, ElectricPotential, max_diffs)
        update_till_convergence!( sim, ElectricPotential, 1e-3, max_n_iterations = 50000) # 1e-3 = convergence limit
        # Here, the convergence limit does not be to be that low.
    end
end
# repeat the begin-blog with smaller maximum allowed potential differences

Thanks Lukas for your detailed and fast answer! I am wondering whether the bug fix regarding the asymmetry in electric potential calculations, as I cannot reproduce the overshooting results shown in the left picture using the newest version. The calculation of the tiny tube seems to have also been sped up tremendously. I have included the json files for both. The only difference between them was the radius of the contacts and semiconductor, all of which are the same.

big_tube.txt
tiny_tube.txt

The update_till_convergence and refine methods are extremely useful. It would be nice for us outsiders to have a set of best practices on how to most efficiently use the package, particularly with regards to performance. We are also simulating a large number of energy depositions obtained from Geant4 simulations, for example, and knowing how to speed things up there would also be very useful.

lmh91 commented

Yes, we have to work on our documentation. We were a bit short on man-power lately, but this has changed now a bit.
After the CSG is refactored we really want to improve the documentation.
Also adding more detailed and advanced examples.

lmh91 commented

So if the overshooting is gone with the current version, can this be closed?