Skip to content

Commit 7a0ab61

Browse files
authored
Developer API Docs (#35)
* new file structure * enable preview for PR, do not forget to disable * fix y-axis typo * reset comments in make.jl * introduce CI dependent eval for sim scripts with worst exec. time * update mirror.md showcase plots * update beamsplitters.md showcase plots * update michelson.md showcase plots * introduce global flag for cond. save * update detectors.md showcase plots * rm take_screenshot helper fct. * update lenses.md showcase plots v1 * fix aspherical surface render bug * update lenses.md showcase plots v2 * add doc dev section for cond include * update rays.md fresnel plots * add iirl schematic * add intersection and interaction section content * update double_gauss.md example * more core API docs * fix some typos * add tip for placeholder enable and disable in devdocs * change dropdown menu structure * more core API docs * misc changes * Part 1 of moving parts of the Optical elements docs to the API section and merging the Optical elements section with the Components section * extend visibility arg interface * Part 2 of moving parts of the Optical elements docs to the API section and merging the Optical elements section with the Components section * delete test.md * Update doublet lens and lens group images for cond. load * sdf api docs * test for zero length dir vector in ray constructors * at 1e-6 default Beam wavelength * fix Intersectable related issues * mesh api docs * Minor changes for clarity * move tracing logic section to core API docs * update systems.md * fix CI issues * add ray tests * fix typos in runtests.jl * try and fix .svg fig * update iirl.svg font to arial * fix polray dir atol testing * reset push_preview to false
1 parent 0a9b281 commit 7a0ab61

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2295
-938
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ using Pkg; Pkg.add("BeamletOptics")
4242

4343
# Examples
4444

45-
For a variety of illustrated examples and tutorials, refer to the **Tutorials** and **Examples** sections of the documentation linked to above.
45+
For a variety of illustrated examples and tutorials, refer to the **Tutorials** and **Examples** in the **Getting started** sections of the documentation linked to above.

docs/make.jl

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ using BeamletOptics
44
using Documenter
55
using DocumenterCitations
66

7-
CairoMakie.activate!()
8-
97
DocMeta.setdocmeta!(BeamletOptics, :DocTestSetup, :(using BeamletOptics); recursive=true)
108

119
bib = CitationBibliography(joinpath(@__DIR__, "src", "refs.bib"))
@@ -22,38 +20,52 @@ makedocs(;
2220
size_threshold_ignore=["reference.md"],
2321
sidebar_sitename = false,
2422
),
23+
pagesonly=true,
2524
pages=[
2625
"Home" => "index.md",
27-
"Tutorials" => Any[
28-
"Beam expander" => "tutorials/expander.md",
29-
"Miniature microscope" => "tutorials/microscope.md",
30-
"Michelson interferometer" => "tutorials/michelson.md"
31-
],
32-
"Examples" => Any[
33-
"Spherical lenses" => "examples/spherical_lenses.md",
34-
"Aspherical lenses" => "examples/aspherical_lenses.md",
35-
"Double Gauss lens" => "examples/double_gauss.md",
36-
"Lens groups" => "examples/lens_groups.md",
26+
"Getting started" => Any[
27+
"Tutorials" => Any[
28+
"Beam expander" => joinpath("tutorials", "expander.md"),
29+
"Miniature microscope" => joinpath("tutorials", "microscope.md"),
30+
"Michelson interferometer" => joinpath("tutorials", "michelson.md"),
31+
],
32+
"Examples" => Any[
33+
"Spherical lenses" => joinpath("examples", "spherical_lenses.md"),
34+
"Aspherical lenses" => joinpath("examples", "aspherical_lenses.md"),
35+
"Double Gauss lens" => joinpath("examples", "double_gauss.md"),
36+
"Lens groups" => joinpath("examples", "lens_groups.md"),
37+
],
3738
],
3839
"Basics" => Any[
39-
"Introduction" => "basics/intro.md",
40-
"Rays" => "basics/rays.md",
41-
"Beams" => "basics/beams.md",
42-
"Optical elements" => "basics/elements.md",
43-
"Optical systems" => "basics/systems.md",
44-
"Visualization" => "basics/render.md"
45-
],
46-
"Components" => Any[
47-
"Overview" => "components/components.md",
48-
"Mirrors" => "components/mirrors.md",
49-
"Lenses" => "components/lenses.md",
50-
"Beamsplitters" => "components/beamsplitters.md",
51-
"Detectors" => "components/detectors.md",
52-
"Polarizers" => "components/polarizers.md",
40+
"Introduction" => joinpath("basics", "intro.md"),
41+
"Rays" => joinpath("basics", "rays.md"),
42+
"Beams" => joinpath("basics", "beams.md"),
43+
"Optical components" => Any[
44+
"Overview" => joinpath("basics", "components", "components.md"),
45+
"Mirrors" => joinpath("basics", "components", "mirrors.md"),
46+
"Lenses" => joinpath("basics", "components", "lenses.md"),
47+
"Beamsplitters" => joinpath("basics", "components", "beamsplitters.md"),
48+
"Detectors" => joinpath("basics", "components", "detectors.md"),
49+
"Polarizing components" => joinpath("basics", "components", "polarizers.md"),
50+
],
51+
"Optical systems" => joinpath("basics", "systems.md"),
52+
"Visualization" => joinpath("basics", "render.md"),
5353
],
5454
"Developer Documentation" => Any[
55-
"Dev. guide" => "guide.md",
56-
"API design" => "design.md",
55+
"Developer guide" => Any[
56+
"Contributing" => joinpath("api", "contribute.md"),
57+
"Documentation development" => joinpath("api", "docdev.md"),
58+
],
59+
"API design" => Any[
60+
"Introduction" => joinpath("api", "api.md"),
61+
"Conventions" => joinpath("api", "conventions.md"),
62+
"Core design" => joinpath("api", "core.md"),
63+
"Geometry" => Any[
64+
"Geometry representation" => joinpath("api", "geometry.md"),
65+
"Meshes" => joinpath("api", "meshes.md"),
66+
"SDFs" => joinpath("api", "sdfs.md"),
67+
],
68+
],
5769
],
5870
"Reference" => "reference.md"
5971
],
@@ -64,4 +76,4 @@ deploydocs(;
6476
repo="github.com/JuliaPhysics/BeamletOptics.jl.git",
6577
devbranch="master",
6678
push_preview=false,
67-
)
79+
)

docs/src/api/api.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# API design
2+
3+
This part of the documentation is intended for users that want to change the internals of BMO. You can develop the package locally by typing `] dev BeamletOptics` in the REPL. An overview of all relevant topics is provided below. The following sections assume that you are in principle familiar with the concept of rays and beams, as well as optical elements -- e.g. mirrors -- in the context of this package. If not, it is recommended that you read the [Rays](@ref), [Beams](@ref) and [Optical components](@ref) sections first.
4+
5+
!!! warning
6+
The developer section is very much WIP...
7+
8+
```@contents
9+
Pages = ["conventions.md", "core.md", "geometry.md", "meshes.md", "sdfs.md"]
10+
Depth = 2
11+
```

docs/src/api/contribute.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Contributing
2+
3+
While not strictly adhering to the [SciML Style Guide](https://github.com/SciML/SciMLStyle), we recommend consulting the guide as a baseline for contributions to this package. Refer to the [SciML Contributors Guide](https://github.com/SciML/ColPrac/blob/master/README.md) as well. Ideally, your contribution features:
4+
5+
- tests for new or changed functionality
6+
- docstrings for relevant functions
7+
- documentation and examples
8+
9+
We would also love to feature your work with this package as part of the **Examples** section.
10+
11+
# Contributors
12+
13+
The following is a list of people who have made significant contributions to the development of BMO:
14+
15+
- Hugo Uittenbosch
16+
- Oliver Kliebisch
17+
- Aurelius Manny

docs/src/api/conventions.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Conventions
2+
3+
In order to ensure implicit and explicit compliance with large parts of the API, the following conventions need to be used. Below you can find some essential conventions that need to be followed. For specific components or parts of the code base, refer to the documentation if certain guidelines need to be followed.
4+
5+
!!! warning
6+
Failure to comply with the following conventions can lead to spurious effects and silent bugs when using the API of this package!
7+
8+
## Global optical axis
9+
10+
Commonly, the z-axis is used as the principal optical axis when defining equations or alignment of optical systems and models. **This is not the case for BMO**, which uses the global y-axis in positive direction as the "global optical axis" in which effects are described. This is motivated by the plotting axes of [Makie](https://docs.makie.org/stable/), which uses a coordinate system where the x- and y-axis form the horizontal plane and the z-axis is orthogonal (upwards).
11+
12+
!!! info
13+
For (optical) equations that are depended on a global coordinate system, use a basis where the **global y-axis (`[0,1,0]`)** is the optical axis and the x-z-axes form the transverse plane. Global propagation along this axis is defined with a direction vector of `[0,1,0]`.
14+
15+
## Right-handedness
16+
17+
All **coordinate systems** are or must be defined **right-handed**! All normal vectors are or must be defined right-handed!
18+
19+
## Counter-clockwise rotation
20+
21+
All **rotations** are or must be performed in a **counter-clockwise** manner for a positive rotation angle ``\theta > 0`` and vice-versa!
22+
For a definition of rotation matrix order, refer to this [article](https://dominicplein.medium.com/extrinsic-intrinsic-rotation-do-i-multiply-from-right-or-left-357c38c1abfd).
23+
24+
## Normal vector direction
25+
26+
For a closed volume BMO assumes that the surface normal vector points outside of the volume.
27+
28+
!!! info "Normal vector direction definition"
29+
Equations to calculate optical effects often rely on the normal vector at the ray intersection location to work correctly and point in a specific direction.
30+
It is important to ensure that this condition is fulfilled when spurious effects occur.

docs/src/api/core.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Core design
2+
3+
The BMO package is intended to provide optical simulation capabilites with as much "out-of-the-box" comfort as possible, meaning that users should not have to worry about e.g. providing the correct optical sequence and exact alignment of objects. The following five design principles are core assumptions of the underlying API:
4+
5+
1. Optical interactions are decoupled from the underlying geometry representation
6+
2. Optical elements are closed volumes or must mimic as such (exceptions apply, e.g. coatings)
7+
3. Elements should be easily moveable and have working interactions for most angles of incidence
8+
3. Without additional knowledge, tracing is performed non-sequentially
9+
4. With additional knowledge, tracing is performed sequentially
10+
11+
## Intersect-Interact-Repeat-Loop
12+
13+
The first two principles will be elaborated upon in more detail in the [Geometry representation](@ref) section. For the latter two design decisions, the following high-level solver schematic can be used to abstract the steps that are performed when calling [`solve_system!`](@ref) with an input system and beam:
14+
15+
```@raw html
16+
<img src="../iir_loop.svg" alt="my figure" style="width:100%; height:auto;"/>
17+
```
18+
19+
This scheme is loosely referred to as the **Intersect-Interact-Repeat-Loop** and consists of the following steps:
20+
21+
1. Calculate the closest **Intersection** between a ray/beam and the objects within the system
22+
2. Calculate the optical **Interaction** that occurs at the surface or within the volume of the element
23+
3. Attach or overwrite the next part of the ray chain or beam tree
24+
4. Use the new information to repeat 1.
25+
26+
Once this procedure has been completed, the alignment of the system or other time-dependent optical properties (e.g. the phase of a Gaussian beamlet) can be updated. When rerunning the solver, the algorithm will try to reuse information about the previously intersected objects to speed up the calculation of the next simulation step. This is described in more detail in the sections: [Tracing systems](@ref) and [Retracing systems](@ref).
27+
28+
The next sections will focus on the **Intersection** and **Interaction** steps.
29+
30+
## Intersections
31+
32+
Calculating intersections between straight lines, i.e. rays, and surfaces is a central challenge for every geometrical optics simulator. This must be done with high numerical precision, since many optical effects are sensitive on the order of the wavelength of the light under consideration with respect to position and direction [Hecht:2018; p. 265 ff](@cite). In order to define this mathematically or algorithmically, many different methods exist [Hanrahan:1989](@cite). The first question is, how is the geometry of the problem defined. This topic is treated in the [Geometry representation](@ref) section. The second question concerns then the algorithm or equation that allows to calculate the point of intersection between a ray and the surface of the element. This function is called `intersect3d` and is, at its core, defined for each `shape` and `ray`:
33+
34+
```@docs; canonical=false
35+
BeamletOptics.intersect3d(::BeamletOptics.AbstractShape, ::BeamletOptics.AbstractRay)
36+
```
37+
38+
Regardless of the underlying concrete implementation, each call of `intersect3d` must return `nothing` or the following type:
39+
40+
```@docs; canonical=false
41+
BeamletOptics.Intersection
42+
```
43+
44+
Since an optical element can consist of multiple joint shapes, the return type must store which specific part of the object was hit.
45+
46+
## Interactions
47+
48+
Optical interactions are performed after the point of intersection has been determined. The `interact3d` interface allows users to implement algorithms that calculate or try to mimic optical effects. The fidelity of the algorithm is effectively only limited by the amount of information that can be passed into the `interact3d` interface. The method is defined as follows:
49+
50+
```@docs; canonical=false
51+
BeamletOptics.interact3d(::BeamletOptics.AbstractSystem, ::BeamletOptics.AbstractObject, ::BeamletOptics.AbstractBeam, ::BeamletOptics.AbstractRay)
52+
```
53+
54+
As with the `intersect3d` method, a predefined return type must be provided in order to make the [`solve_system!`](@ref) interface work. The `AbstractInteraction` is used in order to create "building blocks" from which the output beam is constructed.
55+
56+
```@docs; canonical=false
57+
BeamletOptics.AbstractInteraction
58+
```
59+
60+
The `interact3d` return type limits the interface to only accepting one new `beam` segment per interaction at the moment. The developer needs to take into account that after e.g. a lens surface air-to-glass interaction, the solver "forgets" that the next logical step is to immediatly test against the lens again, since the most likely step will be the refraction at the glass-to-air surface. In order to alleviate this issue, the `Hint` type can be used.
61+
62+
## Hints
63+
64+
As mentioned in the previous section, the [`BeamletOptics.Hint`](@ref) interface allows developers to manipulate the non-sequential solver algorithm into testing against a specific component and shape during the next cycle of the [Intersect-Interact-Repeat-Loop](@ref). This interface has very high priority during intersection testing.
65+
66+
```@docs; canonical=false
67+
BeamletOptics.Hint
68+
```
69+
70+
The main reason for this is the intersection ambiguity encountered at interfaces between air-tight component interfaces, e.g. [Plate beamsplitters](@ref) or cemented [Doublet lenses](@ref). This is caused by the fact that for a ray with a starting point at this interface, technically both shapes are being "touched" at the same time. Additional program logic considering the ray direction of propagation can not always resolve this ambiguity. Therefore the task of providing additional information to the solver via the `Hint` interface is placed as a **burden on the developer**.
71+
72+
!!! tip
73+
Use of the `Hint` interface is primarily intended for multishape objects with joint surfaces.
74+
75+
## Tracing logic
76+
77+
### Tracing systems
78+
79+
In the initial state, is is assumed that the problem consists of `objects <: AbstractObject` (in a system) and a `beam <: AbstractBeam` with a defined starting position and direction. No additional information is provided, and the specific path of the beam is not known beforehand. Consequently, brute force tracing of the optical system is required, involving testing against each individual element to determine the trajectory of the beam.
80+
81+
```@docs; canonical=false
82+
BeamletOptics.trace_system!
83+
```
84+
85+
This non-sequential mode is comparatively safe in determining the "true" beam path, but will scale suboptimally in time-complexity with the amount of optical elements. After solving the system, the beam path is known and can be potentially reused in the future.
86+
87+
!!! info "Object order"
88+
Unlike with classic, surface-based ray tracers, the order in which objects are listed in the [`System`](@ref) object vector/tuple is not considered for the purpose of tracing or retracing.
89+
90+
### Retracing systems
91+
92+
Once a system has been traced for the first time, the system and beam can be solved again. However, this time the solver will try to reuse as much information from the previous run as possible by testing if the previous beam trajectory is still valid in a sequential tracing mode. Retracing systems assumes that the kinematic changes (e.g. optomechanical aligment) between the current tracing procedure and the previous one are small. If an intersection along the beam trajectory becomes invalid, the solver will perform a non-sequential trace for all invalidated parts of the beam.
93+
94+
```@docs; canonical=false
95+
BeamletOptics.retrace_system!
96+
```
97+
98+
## CPU and GPU support
99+
100+
Parallizing the execution of a [`solve_system!`](@ref) call on the CPU is straight-forward for systems that do not feature objects which can be mutated during runtime, e.g. detectors like the [`Photodetector`](@ref). For each beam or ray the solution is independent and the solver can run on multiple threads. Special consideration needs to be taken when implementing mutable elements as mentioned above, since multiple threads might be able to access the underlying memory, leading to race conditions. Specifically, this means ensuring atomic write and read access.
101+
102+
With respect to GPU acceleration, this is not the case. Currently, all available implementations of [`solve_system!`](@ref) are highly branching algorithms which can not be implemented in a parallized way easily. This will most likley require a specific new subtype of the [`BeamletOptics.AbstractSystem`](@ref) with determinable sequential properties. This is not a development goal as of the writing of this section.
103+
104+
105+

0 commit comments

Comments
 (0)