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
- 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.
- Do not bury auto-refinement inside
transfer by default (it would change the cost model silently); keep it an explicit, opt-in function.
- 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).
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 chosennslices. This builds on the graded-layer piecewise-uniform expansion and turns thenslicesguess into a checkable convergence procedure.Context
Depends on the
GradedLayerpiecewise-uniform expansion issue, which introducesGradedLayer(profile, thickness; nslices)and expands it intonsliceshomogeneousLayers of thicknessthickness / nslicessampled at slice midpoints, then runs them through the standard propagators (_propagate_coreatsrc/general_TMM.jl:339-382,_propagate_fullatsrc/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
nslicesand 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
refine_slices(graded, λ, layers; rtol=1e-4, max_nslices=…), that given aGradedLayer, a wavelength (or wavelength grid), and incidence parameters, repeatedly doublesnslices, recomputes viatransfer, and stops when the change in the relevant R/T quantities falls below a relative tolerancertol(with amax_nslicescap). Return the converged result and the chosennslices. Keep it a thin wrapper over the publictransferAPI so it needs no propagator changes.transferby default (it would change the cost model silently); keep it an explicit, opt-in function.test/: increasingnslicesmonotonically reduces the difference from a high-resolution reference;refine_slicesreturns withinrtolof the high-resolution result and respectsmax_nslices.Acceptance criteria
refine_sliceshelper increasesnslicesuntil R/T converge to a user-specified tolerance, respects amax_nslicescap, and returns both the converged result and the chosen slice count.max_nslicesis honored.Caveats / risks
efield/hfield). Document that the tolerance applies to the chosen R/T quantities only.max_nslicescap and a warning on non-convergence are required to avoid runaway cost on thick chiral stacks.sweep_angle/sweep_thickness, threaded by default atsrc/general_TMM.jl:720-723) calltransferper cell; if auto-refinement is used inside a sweep, ensure it remains thread-safe (no shared mutable state) — prefer refining once to a fixednslicesbefore sweeping.References
GradedLayerpiecewise-uniform expansion split issue.transfer(src/general_TMM.jl:569).