Skip to content

Add nslices auto-refinement helper (refine_slices) #95

Description

@garrekstemo

Summary

Add an exported auto-refinement helper (refine_slices) that increases a graded layer's slice count until R/T converge to a tolerance, returning the converged result and the chosen nslices. This builds on the graded-layer piecewise-uniform expansion and turns the nslices guess into a checkable convergence procedure.

The basic "slice thickness ≪ λ / structural period" guideline is documented in the GradedLayer piecewise-uniform expansion issue (the parent). This issue is specifically the auto-refinement function, which is the required, independently-testable deliverable here.

Context

Depends on the GradedLayer piecewise-uniform expansion issue, which introduces GradedLayer(profile, thickness; nslices) and expands it into nslices homogeneous Layers of thickness thickness / nslices sampled at slice midpoints, then runs them through the standard propagators (_propagate_core at src/general_TMM.jl:339-382, _propagate_full at src/general_TMM.jl:392-433). The piecewise-uniform approximation is only accurate when each slice is optically thin: slice thickness must be small compared to the wavelength inside the medium and to the structural period (e.g. the chiral pitch). Too few slices gives wrong R/T; too many wastes time because every slice adds 4×4 matrix products.

Why

Without guidance, users guess nslices and may silently under-resolve a graded or chiral profile, producing physically wrong spectra. A documented guideline plus an optional auto-refinement loop turns a guess into a checkable convergence procedure, which matters most for the chiral circular-Bragg case where the stopband shape depends on resolving the twist.

Proposed approach

  1. Add a standalone exported helper, e.g. refine_slices(graded, λ, layers; rtol=1e-4, max_nslices=…), that given a GradedLayer, a wavelength (or wavelength grid), and incidence parameters, repeatedly doubles nslices, recomputes via transfer, and stops when the change in the relevant R/T quantities falls below a relative tolerance rtol (with a max_nslices cap). Return the converged result and the chosen nslices. Keep it a thin wrapper over the public transfer API so it needs no propagator changes.
  2. Do not bury auto-refinement inside transfer by default (it would change the cost model silently); keep it an explicit, opt-in function.
  3. Add tests in test/: increasing nslices monotonically reduces the difference from a high-resolution reference; refine_slices returns within rtol of the high-resolution result and respects max_nslices.

Acceptance criteria

  • An exported refine_slices helper increases nslices until R/T converge to a user-specified tolerance, respects a max_nslices cap, and returns both the converged result and the chosen slice count.
  • A test demonstrates convergence vs a high-resolution reference and that max_nslices is honored.

Caveats / risks

  • Convergence criteria differ by observable: a converged R may still have an under-resolved field profile (efield/hfield). Document that the tolerance applies to the chosen R/T quantities only.
  • Auto-refinement doubles work each iteration; the max_nslices cap and a warning on non-convergence are required to avoid runaway cost on thick chiral stacks.
  • Threaded sweeps (sweep_angle/sweep_thickness, threaded by default at src/general_TMM.jl:720-723) call transfer per cell; if auto-refinement is used inside a sweep, ensure it remains thread-safe (no shared mutable state) — prefer refining once to a fixed nslices before sweeping.

References

  • Mackay & Lakhtakia, The Transfer-Matrix Method in Electromagnetics and Optics (2020), DOI 10.1007/978-3-031-02022-3 — accuracy of the piecewise-uniform approximation and slice-thickness requirements.
  • Depends on the GradedLayer piecewise-uniform expansion split issue.
  • Public API used by the refinement wrapper: transfer (src/general_TMM.jl:569).

Metadata

Metadata

Assignees

No one assigned

    Labels

    dependenciesPull requests that update a dependency fileenhancementNew feature or requestgood first issueGood for newcomers

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions