Skip to content

Surface Grid Refinement#594

Draft
claudiaalvgar wants to merge 4 commits intoJuliaPhysics:mainfrom
claudiaalvgar:RefineSurface_Grid
Draft

Surface Grid Refinement#594
claudiaalvgar wants to merge 4 commits intoJuliaPhysics:mainfrom
claudiaalvgar:RefineSurface_Grid

Conversation

@claudiaalvgar
Copy link
Collaborator

@claudiaalvgar claudiaalvgar commented Feb 17, 2026

This PR introduces surface-only grid refinement for electric potential simulations and fixes boundary-related indexing issues that could lead to segmentation faults at high refinement resolutions e.g for 1e-5m grid spacing. In addition, it also fixes an existent issue when calculating the electric potential with custom grids for small grid spacing. For custom small grid spacing (e.g. 2e-5m), the detector appeared to be undepleted while for bigger grid spacing (1e-4m) the behaviour was correct. This issue was not related to the new RCC layer model since this was also spotted for simulations not including the RCC layer model. See the issue below:
---> With RCC layer custom initial grid:

  • 0.02mm grid spacing: wrong behaviour (I attach the code in case this issue has to be reproduced):
T = Float64 
sim = Simulation{T}(SSD_examples[:IVCIlayer])
calculate_electric_potential!(sim ,max_n_iterations = 10 ,grid= Grid(sim) ,verbose = true ,depletion_handling = true)
g = sim.electric_potential.grid
ax1, ax2, ax3 = g.axes
tick_dis=0.02*mm 
user_additional_ticks_ax1=sort(vcat(ax1.interval.left:tick_dis:ax1.interval.right)) 
user_additional_ticks_ax3=sort(vcat(ax3.interval.left:tick_dis:ax3.interval.right))[2:end] # only support even number of ticks in z-direction 
user_ax1 = typeof(ax1)(ax1.interval, user_additional_ticks_ax1) 
user_ax3 = typeof(ax3)(ax3.interval, user_additional_ticks_ax3) 
user_g = typeof(g)((user_ax1, ax2, user_ax3)) 
calculate_electric_potential!(sim, refinement_limits = [0.2, 0.1, 0.05, 0.02], use_nthreads=8, grid = user_g, depletion_handling = true)
InvertedCoax_PR3_tick0 02mm_refinements * 0.1mm grid spacing custom initial grid: correct behaviour: InvertedCoax_PR3_tick0 1mm_refinements

---> Without RCC layer but using custom grid: same issue was observed:

  • 0.02mm custom grid spacing: wrong behaviour
InvertedCoax_noinactivelayer_PR3_tick0 02mm_refinements * 0.1mm custom grid spacing: correct behaviour InvertedCoax_noinactivelayer_PR3_tick0 1mm_refinements The new implementation checks whether a given slice of point types contains any surface (inactive layer) points and builds a new refined grid across all three axes. Surface refinement is automatically triggered during the electric potential calculation when:
  • A surface impurity model is present

  • At least 3 refinement steps are used in the electric potential calculation

  • Final refinement limit ≤ 0.05

A YAML entry was added to configure spacing_surface_refinement, that controls the biggest grid spacing allowed in the surface for the 3 axis. The new method identifies the surface regions and it just refines in this area as can be seen, for example for a 0.1mm spacing:
Having this spacing_surface_refinement: [1e-4, 1e-4, 1e-4] in the yaml file and running the default: calculate_electric_potential!(sim, use_nthreads=8, grid=g, verbose = true, depletion_handling = true) will now give the correct behaviour for the surface layer, or even: calculate_electric_potential!(sim, refinement_limits = [0.2, 0.1, 0.05, 0.02], use_nthreads=8, grid = user_g, depletion_handling = true) if we want to further refine the bulk:

DeadLayerGrid_norefinements_1e-4min_spacingdeadlayer_surfafter_3rdref_grids DeadLayerGrid_norefinements_1e-4min_spacingdeadlayer_surfafter_3rdref_griddensity DeadLayerGrid_norefinements_1e-4min_spacingdeadlayer_surfafter_3rdref_epot The weighting potential is also well behaved even when passing the custom grid from the surface-refined electric potential: DeadLayerGrid_norefinements_1e-4min_spacingdeadlayer_surfafter_3rdref_wp_customgrid_from_epot

This provides a faster calculation O(3min) than for the custom grid case O(10min) since the initial grid was refined from the very beginning, see old case behaviour for custom grid:

DeadLayerGrid_norefinements_custominitialgrid0 1mm_griddensity Custom_grid_0 1mm_noref_nosurfref_epot The surface refinement is applied after three initial bulk refinements (the default refinement setup for the electric potential calculation) because only at that stage does the surface behaviour become well-resolved. Therefore, this model requires the default bulk refinement setup in order to correctly apply the surface refinement: Default: refinement_limits = [0.2, 0.1, 0.05]) + surface refinement. Applying the surface refinement after the first or second refinement step does not fully capture the surface layer, leading to incomplete refinement, as you can see :
  • Surface Refinement after 2nd refinement uses [0.2, 0.1, -surface ref- 0.05]) and min_spacing = (1e-4, 1e-4, 1e-4)m in surface layer
DeadLayerGrid_norefinements_1e-4min_spacingdeadlayer_surfafter_2ndref
  • Initial surface refinement (this uses -surface ref- + [0.2, 0.1, 0.05]) and min_spacing = (1e-4, 1e-4, 1e-4)m in surface layer
DeadLayerGrid_norefinements_1e-4min_spacingdeadlayer_surfbefore This PR implements the default behaviour (3 refinements) plus the surface refinement, ensuring accurate resolution near surfaces. Additionally, the model now supports refining surface intervals down to 1e-5m, preserving correct physical behaviour and avoiding the incorrect results that can occur with custom grids resulting in undepleted detectors.
  • New method 0.02mm spacing: Correct behaviour
DeadLayerGrid_norefinements_2e-5min_spacingdeadlayer_surfafter_3rdref_grids DeadLayerGrid_norefinements_2e-5min_spacingdeadlayer_surfafter_3rdref_griddensity DeadLayerGrid_norefinements_2e-5min_spacingdeadlayer_surfafter_3rdref_epot

NOTE: this model has not been tested on cartesian grid defined detectors but I wanted to ask for inputs before. I wasn't sure neither if this should have been a Draft PR, so feel free to move it.

@fhagemann
Copy link
Collaborator

fhagemann commented Feb 17, 2026

I need to see when I can find enough time to look at this in detail.
Are there any tests you could add to test the new code for it's correct behavior (When it should be throwing warnings, edge cases, etc.) that you could add here?

@claudiaalvgar
Copy link
Collaborator Author

Sure no problem. This code is yet a bit preliminary since it doesn't handle the 3D case i.e. it won't refine the phi axis (this I found a bit tricky) and I also didn't try the model on cartesian detectors but I think this should work

@fhagemann fhagemann added enhancement Improvement of existing features notation Notation and Interface convenience Improve user-friendliness labels Feb 18, 2026
@fhagemann fhagemann marked this pull request as draft February 18, 2026 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

convenience Improve user-friendliness enhancement Improvement of existing features notation Notation and Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments