Skip to content

feat: Add multipath sequential modeling via PathSpec builder API - #372

Merged
kmdouglass merged 4 commits into
mainfrom
multipath_modeling
Jun 8, 2026
Merged

feat: Add multipath sequential modeling via PathSpec builder API#372
kmdouglass merged 4 commits into
mainfrom
multipath_modeling

Conversation

@kmdouglass

@kmdouglass kmdouglass commented Jun 8, 2026

Copy link
Copy Markdown
Owner

This feature introduces a second way to build a SequentialModel alongside the existing from_surface_specs() convenience constructor: the PathSpec builder API.

SequentialModelBuilder::new()
    .paths(vec![path_t, path_r])
    .wavelengths(wavelengths.to_vec())
    .build()

Each PathSpec holds an ordered sequence of PathSurfaceRef entries, either New(SurfaceSpec) to introduce a surface into a shared SurfaceStore, or Shared(i) to reference a surface already committed by an earlier path. This allows multiple optical paths to share surfaces (e.g. both arms of a beam splitter share the same physical BS surface object and its placement).

PathSpec is a plain struct with public fields:

PathSpec {
    surface_refs: vec![
        PathSurfaceRef::New(SurfaceSpec::Object),
        PathSurfaceRef::New(SurfaceSpec::BeamSplitter { ... }),
        PathSurfaceRef::New(SurfaceSpec::Image { ... }),
    ],
    gaps: vec![
        GapSpec { thickness: f64::INFINITY, refractive_index: n_air.clone() },
        GapSpec { thickness: 100.0, refractive_index: n_air },
    ],
    beam_splitter_arms: vec![BeamSplitterPathKind::Transmitting],
}

BeamSplitter is now purely geometric: path_kind is removed from both SurfaceSpec::BeamSplitter and the BeamSplitter struct. Arm selection (Transmitting vs. Reflecting) is declared per traversal in PathSpec::beam_splitter_arms and exposed per iterator step via Step::bs_arm. The beam_splitter_arms field in the example above lists whether beam splitters should be transmitting or reflecting for this particular path. They are evaluated in order of the beam splitters specified

The existing from_surface_specs() constructor and all single-path models are unchanged. The GUI continues to use the convenience path.

For the moment, the feature isn't so useful as the Views only operate on the first path found. This is intended as a first step in an incremental implementation.

@kmdouglass
kmdouglass merged commit 6f3f397 into main Jun 8, 2026
2 checks passed
@kmdouglass
kmdouglass deleted the multipath_modeling branch June 8, 2026 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant