[docs] document scattering conventions and frozen-basis workflows
Update examples for sampled-interface tapers, explicit physical CPML spacing, copied SCPML widths, and the consolidated complex mode solver. Document breaking API changes, overlap measures, and PML convergence.
This commit is contained in:
parent
153536ee91
commit
7e407dd1ac
10 changed files with 152 additions and 29 deletions
|
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
|||
import numpy
|
||||
|
||||
from meanas.fdmath import vec
|
||||
from meanas.fdfd import eme, scpml, waveguide_2d_complex
|
||||
from meanas.fdfd import eme, scpml, waveguide_2d
|
||||
|
||||
|
||||
WAVELENGTH = 1.55
|
||||
|
|
@ -34,6 +34,7 @@ def build_grids() -> tuple[list[list[numpy.ndarray]], list[list[numpy.ndarray]]]
|
|||
omega=OMEGA,
|
||||
epsilon_effective=EPS_CLADDING,
|
||||
thickness=PML_CELLS,
|
||||
max_imag_ratio=1.0,
|
||||
)
|
||||
return physical, stretched
|
||||
|
||||
|
|
@ -61,29 +62,48 @@ def main() -> None:
|
|||
"""Solve, track, and summarize the sampled complex modal bases."""
|
||||
physical_dxes, solve_dxes = build_grids()
|
||||
z_coords = numpy.array([0.0, 5.0, 10.0])
|
||||
bases = [
|
||||
waveguide_2d_complex.solve_modes_near(
|
||||
epsilon_samples = [build_epsilon(edge_fill) for edge_fill in (0.30, 0.35, 0.40)]
|
||||
solved = [
|
||||
waveguide_2d.solve_modes_near(
|
||||
OMEGA,
|
||||
solve_dxes,
|
||||
build_epsilon(edge_fill),
|
||||
epsilon,
|
||||
target_wavenumbers=[1.45 * OMEGA],
|
||||
modes_per_target=3,
|
||||
candidate_margin=3,
|
||||
overlap_dxes=physical_dxes,
|
||||
)
|
||||
for edge_fill in (0.30, 0.35, 0.40)
|
||||
for epsilon in epsilon_samples
|
||||
]
|
||||
bases = [basis for basis, _diagnostics in solved]
|
||||
tracked = waveguide_2d.track_mode_path(bases, overlap_dxes=physical_dxes)
|
||||
tracked_diagnostics = [
|
||||
waveguide_2d.compute_mode_diagnostics(
|
||||
basis,
|
||||
OMEGA,
|
||||
solve_dxes,
|
||||
epsilon,
|
||||
target_wavenumbers=[1.45 * OMEGA],
|
||||
overlap_dxes=physical_dxes,
|
||||
)
|
||||
for basis, epsilon in zip(tracked, epsilon_samples, strict=True)
|
||||
]
|
||||
tracked = waveguide_2d_complex.track_mode_path(bases)
|
||||
sections = eme.mode_sections_from_bases(z_coords, tracked)
|
||||
prepared = eme.prepare_taper(sections, physical_dxes)
|
||||
# Fields and interface overlaps are reused: these are frozen-basis length
|
||||
# sweeps. Wavelength-dependent beta overrides would also freeze the fields.
|
||||
length_sweep = [eme.evaluate_taper_s(prepared, z_coords=z_coords * scale)
|
||||
for scale in (0.8, 1.0, 1.2)]
|
||||
|
||||
for z_coord, basis in zip(z_coords, tracked, strict=True):
|
||||
for z_coord, basis, diagnostics in zip(z_coords, tracked, tracked_diagnostics, strict=True):
|
||||
print(
|
||||
f'z={z_coord:5.1f}: '
|
||||
f'beta={basis.wavenumbers[0]:.6g}, '
|
||||
f'PML participation={basis.diagnostics.pml_participation[0]:.3f}, '
|
||||
f'right residual={basis.diagnostics.right_residuals[0]:.2e}',
|
||||
f'PML participation={diagnostics.pml_participation[0]:.3f}, '
|
||||
f'right residual={diagnostics.right_residuals[0]:.2e}',
|
||||
)
|
||||
print(f'constructed {len(sections)} tracked EME sections with {len(sections[0].modes)} modes each')
|
||||
print('frozen-basis length sweep |T_00|:', [float(abs(ss[len(tracked[0]), 0])) for ss in length_sweep])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
Loading…
Reference in a new issue