lsurf 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lsurf/__init__.py +471 -0
- lsurf/analysis/__init__.py +107 -0
- lsurf/analysis/healpix_utils.py +418 -0
- lsurf/analysis/sphere_viz.py +1280 -0
- lsurf/cli/__init__.py +48 -0
- lsurf/cli/build.py +398 -0
- lsurf/cli/config_schema.py +318 -0
- lsurf/cli/gui_cmd.py +76 -0
- lsurf/cli/interactive.py +850 -0
- lsurf/cli/main.py +81 -0
- lsurf/cli/run.py +806 -0
- lsurf/detectors/__init__.py +266 -0
- lsurf/detectors/analysis.py +289 -0
- lsurf/detectors/base.py +284 -0
- lsurf/detectors/constant_size_rings.py +485 -0
- lsurf/detectors/directional.py +45 -0
- lsurf/detectors/extended/__init__.py +73 -0
- lsurf/detectors/extended/local_sphere.py +353 -0
- lsurf/detectors/extended/recording_sphere.py +368 -0
- lsurf/detectors/planar.py +45 -0
- lsurf/detectors/protocol.py +187 -0
- lsurf/detectors/recording_spheres.py +63 -0
- lsurf/detectors/results.py +1140 -0
- lsurf/detectors/small/__init__.py +79 -0
- lsurf/detectors/small/directional.py +330 -0
- lsurf/detectors/small/planar.py +401 -0
- lsurf/detectors/small/spherical.py +450 -0
- lsurf/detectors/spherical.py +45 -0
- lsurf/geometry/__init__.py +199 -0
- lsurf/geometry/builder.py +478 -0
- lsurf/geometry/cell.py +228 -0
- lsurf/geometry/cell_geometry.py +247 -0
- lsurf/geometry/detector_arrays.py +1785 -0
- lsurf/geometry/geometry.py +222 -0
- lsurf/geometry/surface_analysis.py +375 -0
- lsurf/geometry/validation.py +91 -0
- lsurf/gui/__init__.py +51 -0
- lsurf/gui/app.py +903 -0
- lsurf/gui/core/__init__.py +39 -0
- lsurf/gui/core/scene.py +343 -0
- lsurf/gui/core/simulation.py +264 -0
- lsurf/gui/renderers/__init__.py +40 -0
- lsurf/gui/renderers/ray_renderer.py +353 -0
- lsurf/gui/renderers/source_renderer.py +505 -0
- lsurf/gui/renderers/surface_renderer.py +477 -0
- lsurf/gui/views/__init__.py +48 -0
- lsurf/gui/views/config_editor.py +3199 -0
- lsurf/gui/views/properties.py +257 -0
- lsurf/gui/views/results.py +291 -0
- lsurf/gui/views/scene_tree.py +180 -0
- lsurf/gui/views/viewport_3d.py +555 -0
- lsurf/gui/views/visualizations.py +712 -0
- lsurf/materials/__init__.py +169 -0
- lsurf/materials/base/__init__.py +64 -0
- lsurf/materials/base/full_inhomogeneous.py +208 -0
- lsurf/materials/base/grid_inhomogeneous.py +319 -0
- lsurf/materials/base/homogeneous.py +342 -0
- lsurf/materials/base/material_field.py +527 -0
- lsurf/materials/base/simple_inhomogeneous.py +418 -0
- lsurf/materials/base/spectral_inhomogeneous.py +497 -0
- lsurf/materials/implementations/__init__.py +120 -0
- lsurf/materials/implementations/data/alpha_values_typical_atmosphere_updated.txt +24 -0
- lsurf/materials/implementations/duct_atmosphere.py +390 -0
- lsurf/materials/implementations/exponential_atmosphere.py +435 -0
- lsurf/materials/implementations/gaussian_lens.py +120 -0
- lsurf/materials/implementations/interpolated_data.py +123 -0
- lsurf/materials/implementations/layered_atmosphere.py +134 -0
- lsurf/materials/implementations/linear_gradient.py +109 -0
- lsurf/materials/implementations/linsley_atmosphere.py +764 -0
- lsurf/materials/implementations/standard_materials.py +126 -0
- lsurf/materials/implementations/turbulent_atmosphere.py +135 -0
- lsurf/materials/implementations/us_standard_atmosphere.py +149 -0
- lsurf/materials/utils/__init__.py +77 -0
- lsurf/materials/utils/constants.py +45 -0
- lsurf/materials/utils/device_functions.py +117 -0
- lsurf/materials/utils/dispersion.py +160 -0
- lsurf/materials/utils/factories.py +142 -0
- lsurf/propagation/__init__.py +91 -0
- lsurf/propagation/detector_gpu.py +67 -0
- lsurf/propagation/gpu_device_rays.py +294 -0
- lsurf/propagation/kernels/__init__.py +175 -0
- lsurf/propagation/kernels/absorption/__init__.py +61 -0
- lsurf/propagation/kernels/absorption/grid.py +240 -0
- lsurf/propagation/kernels/absorption/simple.py +232 -0
- lsurf/propagation/kernels/absorption/spectral.py +410 -0
- lsurf/propagation/kernels/detection/__init__.py +64 -0
- lsurf/propagation/kernels/detection/protocol.py +102 -0
- lsurf/propagation/kernels/detection/spherical.py +255 -0
- lsurf/propagation/kernels/device_functions.py +790 -0
- lsurf/propagation/kernels/fresnel/__init__.py +64 -0
- lsurf/propagation/kernels/fresnel/protocol.py +97 -0
- lsurf/propagation/kernels/fresnel/standard.py +258 -0
- lsurf/propagation/kernels/intersection/__init__.py +79 -0
- lsurf/propagation/kernels/intersection/annular_plane.py +207 -0
- lsurf/propagation/kernels/intersection/bounded_plane.py +205 -0
- lsurf/propagation/kernels/intersection/plane.py +166 -0
- lsurf/propagation/kernels/intersection/protocol.py +95 -0
- lsurf/propagation/kernels/intersection/signed_distance.py +742 -0
- lsurf/propagation/kernels/intersection/sphere.py +190 -0
- lsurf/propagation/kernels/propagation/__init__.py +85 -0
- lsurf/propagation/kernels/propagation/grid.py +527 -0
- lsurf/propagation/kernels/propagation/protocol.py +105 -0
- lsurf/propagation/kernels/propagation/simple.py +460 -0
- lsurf/propagation/kernels/propagation/spectral.py +875 -0
- lsurf/propagation/kernels/registry.py +331 -0
- lsurf/propagation/kernels/surface/__init__.py +72 -0
- lsurf/propagation/kernels/surface/bisection.py +232 -0
- lsurf/propagation/kernels/surface/detection.py +402 -0
- lsurf/propagation/kernels/surface/reduction.py +166 -0
- lsurf/propagation/propagator_protocol.py +222 -0
- lsurf/propagation/propagators/__init__.py +101 -0
- lsurf/propagation/propagators/detector_handler.py +354 -0
- lsurf/propagation/propagators/factory.py +200 -0
- lsurf/propagation/propagators/fresnel_handler.py +305 -0
- lsurf/propagation/propagators/gpu_gradient.py +566 -0
- lsurf/propagation/propagators/gpu_surface_propagator.py +707 -0
- lsurf/propagation/propagators/gradient.py +429 -0
- lsurf/propagation/propagators/intersection_handler.py +327 -0
- lsurf/propagation/propagators/material_propagator.py +398 -0
- lsurf/propagation/propagators/signed_distance_handler.py +522 -0
- lsurf/propagation/propagators/spectral_gpu_gradient.py +553 -0
- lsurf/propagation/propagators/surface_interaction.py +616 -0
- lsurf/propagation/propagators/surface_propagator.py +719 -0
- lsurf/py.typed +1 -0
- lsurf/simulation/__init__.py +70 -0
- lsurf/simulation/config.py +164 -0
- lsurf/simulation/orchestrator.py +462 -0
- lsurf/simulation/result.py +299 -0
- lsurf/simulation/simulation.py +262 -0
- lsurf/sources/__init__.py +128 -0
- lsurf/sources/base.py +264 -0
- lsurf/sources/collimated.py +252 -0
- lsurf/sources/custom.py +409 -0
- lsurf/sources/diverging.py +228 -0
- lsurf/sources/gaussian.py +272 -0
- lsurf/sources/parallel_from_positions.py +197 -0
- lsurf/sources/point.py +172 -0
- lsurf/sources/uniform_diverging.py +258 -0
- lsurf/surfaces/__init__.py +184 -0
- lsurf/surfaces/cpu/__init__.py +50 -0
- lsurf/surfaces/cpu/curved_wave.py +463 -0
- lsurf/surfaces/cpu/gerstner_wave.py +381 -0
- lsurf/surfaces/cpu/wave_params.py +118 -0
- lsurf/surfaces/gpu/__init__.py +72 -0
- lsurf/surfaces/gpu/annular_plane.py +453 -0
- lsurf/surfaces/gpu/bounded_plane.py +390 -0
- lsurf/surfaces/gpu/curved_wave.py +483 -0
- lsurf/surfaces/gpu/gerstner_wave.py +377 -0
- lsurf/surfaces/gpu/multi_curved_wave.py +520 -0
- lsurf/surfaces/gpu/plane.py +299 -0
- lsurf/surfaces/gpu/recording_sphere.py +587 -0
- lsurf/surfaces/gpu/sphere.py +311 -0
- lsurf/surfaces/protocol.py +336 -0
- lsurf/surfaces/registry.py +373 -0
- lsurf/utilities/__init__.py +175 -0
- lsurf/utilities/detector_analysis.py +814 -0
- lsurf/utilities/fresnel.py +628 -0
- lsurf/utilities/interactions.py +1215 -0
- lsurf/utilities/propagation.py +602 -0
- lsurf/utilities/ray_data.py +532 -0
- lsurf/utilities/recording_sphere.py +745 -0
- lsurf/utilities/time_spread.py +463 -0
- lsurf/visualization/__init__.py +329 -0
- lsurf/visualization/absorption_plots.py +334 -0
- lsurf/visualization/atmospheric_plots.py +754 -0
- lsurf/visualization/common.py +348 -0
- lsurf/visualization/detector_plots.py +1350 -0
- lsurf/visualization/detector_sphere_plots.py +1173 -0
- lsurf/visualization/fresnel_plots.py +1061 -0
- lsurf/visualization/ocean_simulation_plots.py +999 -0
- lsurf/visualization/polarization_plots.py +916 -0
- lsurf/visualization/raytracing_plots.py +1521 -0
- lsurf/visualization/ring_detector_plots.py +1867 -0
- lsurf/visualization/time_spread_plots.py +531 -0
- lsurf-1.0.0.dist-info/METADATA +381 -0
- lsurf-1.0.0.dist-info/RECORD +180 -0
- lsurf-1.0.0.dist-info/WHEEL +5 -0
- lsurf-1.0.0.dist-info/entry_points.txt +2 -0
- lsurf-1.0.0.dist-info/licenses/LICENSE +32 -0
- lsurf-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# The Clear BSD License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2026 Tobias Heibges
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
8
|
+
# below) provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# * Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from this
|
|
19
|
+
# software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
22
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
23
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
26
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
27
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
28
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
29
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
30
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
Standard Material Constants
|
|
36
|
+
|
|
37
|
+
Pre-defined materials for common optical media.
|
|
38
|
+
|
|
39
|
+
Standard Materials
|
|
40
|
+
------------------
|
|
41
|
+
- VACUUM: n = 1.0 (by definition)
|
|
42
|
+
- AIR_STP: n = 1.000293 (standard temperature and pressure)
|
|
43
|
+
- WATER: n = 1.333, with absorption
|
|
44
|
+
- BK7_GLASS: n = 1.5168, Schott optical glass
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
from ..base import HomogeneousMaterial
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
VACUUM = HomogeneousMaterial(
|
|
51
|
+
name="Vacuum",
|
|
52
|
+
refractive_index=1.0,
|
|
53
|
+
absorption_coef=0.0,
|
|
54
|
+
scattering_coef=0.0,
|
|
55
|
+
anisotropy=0.0,
|
|
56
|
+
)
|
|
57
|
+
"""
|
|
58
|
+
Perfect vacuum with n = 1.0 (by definition).
|
|
59
|
+
|
|
60
|
+
The refractive index of vacuum is exactly 1 by definition of the
|
|
61
|
+
speed of light. No absorption or scattering.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
AIR_STP = HomogeneousMaterial(
|
|
65
|
+
name="Air (STP)",
|
|
66
|
+
refractive_index=1.000293,
|
|
67
|
+
absorption_coef=0.0,
|
|
68
|
+
scattering_coef=0.0,
|
|
69
|
+
anisotropy=0.0,
|
|
70
|
+
)
|
|
71
|
+
"""
|
|
72
|
+
Air at standard temperature (273.15 K) and pressure (101.325 kPa).
|
|
73
|
+
|
|
74
|
+
Refractive index from Ciddor (1996) for visible light.
|
|
75
|
+
Dispersion is negligible for most applications.
|
|
76
|
+
|
|
77
|
+
References
|
|
78
|
+
----------
|
|
79
|
+
.. [1] Ciddor, P. E. (1996). Appl. Opt., 35(9), 1566-1573.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
WATER = HomogeneousMaterial(
|
|
83
|
+
name="Water",
|
|
84
|
+
refractive_index=1.333,
|
|
85
|
+
absorption_coef=0.0045, # ~0.045 per 10m at 550nm
|
|
86
|
+
scattering_coef=0.0,
|
|
87
|
+
anisotropy=0.0,
|
|
88
|
+
)
|
|
89
|
+
"""
|
|
90
|
+
Pure water at 20°C.
|
|
91
|
+
|
|
92
|
+
Refractive index is average for visible wavelengths.
|
|
93
|
+
Absorption coefficient is approximate for green light (550 nm).
|
|
94
|
+
Real water absorption is strongly wavelength-dependent.
|
|
95
|
+
|
|
96
|
+
References
|
|
97
|
+
----------
|
|
98
|
+
.. [1] Hale & Querry (1973). Appl. Opt., 12(3), 555-563.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
BK7_GLASS = HomogeneousMaterial(
|
|
102
|
+
name="BK7 Glass",
|
|
103
|
+
refractive_index=1.5168,
|
|
104
|
+
absorption_coef=0.0,
|
|
105
|
+
scattering_coef=0.0,
|
|
106
|
+
anisotropy=0.0,
|
|
107
|
+
)
|
|
108
|
+
"""
|
|
109
|
+
Schott N-BK7 borosilicate crown glass.
|
|
110
|
+
|
|
111
|
+
Standard optical glass with excellent homogeneity.
|
|
112
|
+
Refractive index given at 587.6 nm (d-line).
|
|
113
|
+
For accurate work, use Sellmeier coefficients.
|
|
114
|
+
|
|
115
|
+
References
|
|
116
|
+
----------
|
|
117
|
+
.. [1] Schott AG. Optical Glass Data Sheets.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
__all__ = [
|
|
122
|
+
"VACUUM",
|
|
123
|
+
"AIR_STP",
|
|
124
|
+
"WATER",
|
|
125
|
+
"BK7_GLASS",
|
|
126
|
+
]
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# The Clear BSD License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2026 Tobias Heibges
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
8
|
+
# below) provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# * Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from this
|
|
19
|
+
# software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
22
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
23
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
26
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
27
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
28
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
29
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
30
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
Turbulent Atmosphere Implementation
|
|
36
|
+
|
|
37
|
+
Atmosphere with Kolmogorov-like turbulence perturbations on a 3D grid.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
import numpy as np
|
|
41
|
+
|
|
42
|
+
from ..base import GridInhomogeneousModel
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class TurbulentAtmosphere(GridInhomogeneousModel):
|
|
46
|
+
"""
|
|
47
|
+
Atmosphere with Kolmogorov-like turbulence perturbations.
|
|
48
|
+
|
|
49
|
+
Creates a 3D grid of refractive index values with random turbulent
|
|
50
|
+
perturbations superimposed on an exponential baseline profile.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
bounds : tuple
|
|
55
|
+
((x_min, x_max), (y_min, y_max), (z_min, z_max)) in meters
|
|
56
|
+
grid_resolution : tuple
|
|
57
|
+
(nx, ny, nz) grid points
|
|
58
|
+
baseline_n : float
|
|
59
|
+
Sea-level refractive index for baseline. Default 1.000293.
|
|
60
|
+
scale_height : float
|
|
61
|
+
Scale height for baseline exponential. Default 8500 m.
|
|
62
|
+
turbulence_strength : float
|
|
63
|
+
Strength of turbulent perturbations (relative). Default 1e-6.
|
|
64
|
+
outer_scale : float
|
|
65
|
+
Outer scale of turbulence in meters. Default 100 m.
|
|
66
|
+
seed : int, optional
|
|
67
|
+
Random seed for reproducibility.
|
|
68
|
+
|
|
69
|
+
Example
|
|
70
|
+
-------
|
|
71
|
+
>>> turb = TurbulentAtmosphere(
|
|
72
|
+
... bounds=((-5000, 5000), (-5000, 5000), (0, 20000)),
|
|
73
|
+
... grid_resolution=(64, 64, 32),
|
|
74
|
+
... turbulence_strength=1e-5,
|
|
75
|
+
... )
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
def __init__(
|
|
79
|
+
self,
|
|
80
|
+
bounds: tuple[tuple[float, float], ...],
|
|
81
|
+
grid_resolution: tuple[int, int, int] = (64, 64, 32),
|
|
82
|
+
baseline_n: float = 1.000293,
|
|
83
|
+
scale_height: float = 8500.0,
|
|
84
|
+
turbulence_strength: float = 1e-6,
|
|
85
|
+
outer_scale: float = 100.0,
|
|
86
|
+
seed: int | None = None,
|
|
87
|
+
):
|
|
88
|
+
nx, ny, nz = grid_resolution
|
|
89
|
+
(x_min, x_max), (y_min, y_max), (z_min, z_max) = bounds
|
|
90
|
+
|
|
91
|
+
# Create coordinate grids
|
|
92
|
+
# x = np.linspace(x_min, x_max, nx)
|
|
93
|
+
# y = np.linspace(y_min, y_max, ny)
|
|
94
|
+
z = np.linspace(z_min, z_max, nz)
|
|
95
|
+
Z = np.zeros((nx, ny, nz))
|
|
96
|
+
for k in range(nz):
|
|
97
|
+
Z[:, :, k] = z[k]
|
|
98
|
+
|
|
99
|
+
# Baseline exponential profile
|
|
100
|
+
delta_n = baseline_n - 1.0
|
|
101
|
+
n_grid = 1.0 + delta_n * np.exp(-Z / scale_height)
|
|
102
|
+
|
|
103
|
+
# Add turbulent perturbations
|
|
104
|
+
if seed is not None:
|
|
105
|
+
np.random.seed(seed)
|
|
106
|
+
|
|
107
|
+
# Simple turbulence model using filtered noise
|
|
108
|
+
# (Real Kolmogorov turbulence would use proper power spectrum)
|
|
109
|
+
noise = np.random.randn(nx, ny, nz)
|
|
110
|
+
|
|
111
|
+
# Smooth with Gaussian filter to create correlated structure
|
|
112
|
+
from scipy.ndimage import gaussian_filter
|
|
113
|
+
|
|
114
|
+
dx = (x_max - x_min) / (nx - 1)
|
|
115
|
+
sigma = outer_scale / dx / 2.0 # Filter scale in grid units
|
|
116
|
+
turbulence = gaussian_filter(noise, sigma=sigma, mode="wrap")
|
|
117
|
+
|
|
118
|
+
# Normalize and scale turbulence
|
|
119
|
+
turbulence = turbulence / np.std(turbulence) * turbulence_strength
|
|
120
|
+
|
|
121
|
+
# Add to baseline (scaled by local n-1 to preserve physics)
|
|
122
|
+
n_grid = n_grid + turbulence * (n_grid - 1.0)
|
|
123
|
+
|
|
124
|
+
super().__init__(
|
|
125
|
+
name="Turbulent Atmosphere",
|
|
126
|
+
n_grid=n_grid.astype(np.float32),
|
|
127
|
+
bounds=bounds,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
self.baseline_n = baseline_n
|
|
131
|
+
self.scale_height = scale_height
|
|
132
|
+
self.turbulence_strength = turbulence_strength
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
__all__ = ["TurbulentAtmosphere"]
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# The Clear BSD License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2026 Tobias Heibges
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
8
|
+
# below) provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# * Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from this
|
|
19
|
+
# software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
22
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
23
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
26
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
27
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
28
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
29
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
30
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
US Standard Atmosphere (1976) Implementation
|
|
36
|
+
|
|
37
|
+
Implements a piecewise atmosphere model with:
|
|
38
|
+
- Troposphere (0-11 km): Temperature lapse rate
|
|
39
|
+
- Stratosphere (11-20 km): Isothermal
|
|
40
|
+
- Upper stratosphere (20-32 km): Temperature inversion
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
import math
|
|
44
|
+
|
|
45
|
+
from ..base import SimpleInhomogeneousModel
|
|
46
|
+
from ..utils.constants import EARTH_RADIUS
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class USStandardAtmosphere(SimpleInhomogeneousModel):
|
|
50
|
+
"""
|
|
51
|
+
US Standard Atmosphere (1976) approximation.
|
|
52
|
+
|
|
53
|
+
Implements a piecewise atmosphere model with:
|
|
54
|
+
- Troposphere (0-11 km): Temperature lapse rate
|
|
55
|
+
- Stratosphere (11-20 km): Isothermal
|
|
56
|
+
- Upper stratosphere (20-32 km): Temperature inversion
|
|
57
|
+
|
|
58
|
+
This is more realistic than a simple exponential model but still
|
|
59
|
+
radially symmetric, making it a good fit for SimpleInhomogeneousModel.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
earth_center : tuple, optional
|
|
64
|
+
Center of Earth. Default is (0, 0, 0).
|
|
65
|
+
earth_radius : float, optional
|
|
66
|
+
Radius of Earth in meters. Default is 6,371,000 m.
|
|
67
|
+
|
|
68
|
+
Example
|
|
69
|
+
-------
|
|
70
|
+
>>> atm = USStandardAtmosphere()
|
|
71
|
+
>>> n = atm.get_refractive_index(0, 0, EARTH_RADIUS + 10000, 532e-9)
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
# US Standard Atmosphere constants
|
|
75
|
+
T0 = 288.15 # Sea level temperature (K)
|
|
76
|
+
P0 = 101325.0 # Sea level pressure (Pa)
|
|
77
|
+
L0 = -0.0065 # Temperature lapse rate in troposphere (K/m)
|
|
78
|
+
H_TROPOPAUSE = 11000.0 # Tropopause altitude (m)
|
|
79
|
+
T_TROPOPAUSE = 216.65 # Tropopause temperature (K)
|
|
80
|
+
|
|
81
|
+
def __init__(
|
|
82
|
+
self,
|
|
83
|
+
earth_center: tuple[float, float, float] = (0.0, 0.0, 0.0),
|
|
84
|
+
earth_radius: float = EARTH_RADIUS,
|
|
85
|
+
):
|
|
86
|
+
super().__init__(
|
|
87
|
+
name="US Standard Atmosphere",
|
|
88
|
+
center=earth_center,
|
|
89
|
+
reference_radius=earth_radius,
|
|
90
|
+
altitude_range=(0.0, 100_000.0),
|
|
91
|
+
lut_resolution=20000,
|
|
92
|
+
)
|
|
93
|
+
self.earth_center = earth_center
|
|
94
|
+
self.earth_radius = earth_radius
|
|
95
|
+
|
|
96
|
+
def n_at_altitude(self, altitude: float, wavelength: float | None = None) -> float:
|
|
97
|
+
"""
|
|
98
|
+
Compute refractive index using US Standard Atmosphere model.
|
|
99
|
+
|
|
100
|
+
Uses the Edlen formula approximation: n - 1 ∝ P/T
|
|
101
|
+
"""
|
|
102
|
+
altitude = max(altitude, 0.0)
|
|
103
|
+
|
|
104
|
+
if altitude <= self.H_TROPOPAUSE:
|
|
105
|
+
# Troposphere: linear temperature decrease
|
|
106
|
+
T = self.T0 + self.L0 * altitude
|
|
107
|
+
P = self.P0 * (T / self.T0) ** (-9.80665 / (self.L0 * 287.053))
|
|
108
|
+
elif altitude <= 20000:
|
|
109
|
+
# Lower stratosphere: isothermal
|
|
110
|
+
T = self.T_TROPOPAUSE
|
|
111
|
+
P_trop = self.P0 * (self.T_TROPOPAUSE / self.T0) ** (
|
|
112
|
+
-9.80665 / (self.L0 * 287.053)
|
|
113
|
+
)
|
|
114
|
+
P = P_trop * math.exp(
|
|
115
|
+
-9.80665 * (altitude - self.H_TROPOPAUSE) / (287.053 * T)
|
|
116
|
+
)
|
|
117
|
+
else:
|
|
118
|
+
# Upper stratosphere: simplified
|
|
119
|
+
T = self.T_TROPOPAUSE + 0.001 * (altitude - 20000)
|
|
120
|
+
P_20km = (
|
|
121
|
+
self.P0
|
|
122
|
+
* (self.T_TROPOPAUSE / self.T0) ** (-9.80665 / (self.L0 * 287.053))
|
|
123
|
+
* math.exp(-9.80665 * 9000 / (287.053 * self.T_TROPOPAUSE))
|
|
124
|
+
)
|
|
125
|
+
P = P_20km * math.exp(-9.80665 * (altitude - 20000) / (287.053 * T))
|
|
126
|
+
|
|
127
|
+
# Edlen formula approximation for dry air
|
|
128
|
+
# n - 1 = 0.000293 * (P/P0) * (T0/T)
|
|
129
|
+
refractivity = 0.000293 * (P / self.P0) * (self.T0 / T)
|
|
130
|
+
return 1.0 + refractivity
|
|
131
|
+
|
|
132
|
+
def dn_dh_at_altitude(
|
|
133
|
+
self, altitude: float, wavelength: float | None = None
|
|
134
|
+
) -> float:
|
|
135
|
+
"""Numerical derivative (accurate enough given model complexity)."""
|
|
136
|
+
eps = 10.0 # 10 meter step
|
|
137
|
+
h_plus = max(altitude + eps, 0.0)
|
|
138
|
+
h_minus = max(altitude - eps, 0.0)
|
|
139
|
+
|
|
140
|
+
if h_plus == h_minus:
|
|
141
|
+
return 0.0
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
self.n_at_altitude(h_plus, wavelength)
|
|
145
|
+
- self.n_at_altitude(h_minus, wavelength)
|
|
146
|
+
) / (h_plus - h_minus)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
__all__ = ["USStandardAtmosphere"]
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# The Clear BSD License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2026 Tobias Heibges
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
8
|
+
# below) provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# * Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from this
|
|
19
|
+
# software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
22
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
23
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
26
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
27
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
28
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
29
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
30
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
Utilities for Materials Module
|
|
36
|
+
|
|
37
|
+
This submodule contains utility functions for the materials system:
|
|
38
|
+
|
|
39
|
+
- Dispersion functions (Sellmeier, Cauchy)
|
|
40
|
+
- Factory functions for creating dispersive materials
|
|
41
|
+
- GPU device functions for CUDA kernels
|
|
42
|
+
- Physical constants
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from .constants import (
|
|
46
|
+
EARTH_RADIUS,
|
|
47
|
+
SCALE_HEIGHT_DEFAULT,
|
|
48
|
+
N_SEA_LEVEL,
|
|
49
|
+
)
|
|
50
|
+
from .dispersion import (
|
|
51
|
+
sellmeier_refractive_index,
|
|
52
|
+
cauchy_refractive_index,
|
|
53
|
+
)
|
|
54
|
+
from .factories import (
|
|
55
|
+
create_sellmeier_material,
|
|
56
|
+
create_cauchy_material,
|
|
57
|
+
)
|
|
58
|
+
from .device_functions import (
|
|
59
|
+
device_sellmeier_equation,
|
|
60
|
+
device_cauchy_equation,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
__all__ = [
|
|
64
|
+
# Constants
|
|
65
|
+
"EARTH_RADIUS",
|
|
66
|
+
"SCALE_HEIGHT_DEFAULT",
|
|
67
|
+
"N_SEA_LEVEL",
|
|
68
|
+
# Dispersion functions
|
|
69
|
+
"sellmeier_refractive_index",
|
|
70
|
+
"cauchy_refractive_index",
|
|
71
|
+
# Factory functions
|
|
72
|
+
"create_sellmeier_material",
|
|
73
|
+
"create_cauchy_material",
|
|
74
|
+
# GPU device functions
|
|
75
|
+
"device_sellmeier_equation",
|
|
76
|
+
"device_cauchy_equation",
|
|
77
|
+
]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# The Clear BSD License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2026 Tobias Heibges
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
8
|
+
# below) provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# * Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from this
|
|
19
|
+
# software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
22
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
23
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
26
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
27
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
28
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
29
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
30
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
Physical Constants for Materials Module
|
|
36
|
+
|
|
37
|
+
Contains commonly used physical constants for atmospheric and optical calculations.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
# Earth parameters
|
|
41
|
+
EARTH_RADIUS = 6_371_000.0 # meters
|
|
42
|
+
|
|
43
|
+
# Atmospheric constants
|
|
44
|
+
SCALE_HEIGHT_DEFAULT = 8500.0 # meters (typical for troposphere)
|
|
45
|
+
N_SEA_LEVEL = 1.000293 # Refractive index of air at STP
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# The Clear BSD License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2026 Tobias Heibges
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
8
|
+
# below) provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# * Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from this
|
|
19
|
+
# software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
22
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
23
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
26
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
27
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
28
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
29
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
30
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
GPU Device Functions (Numba CUDA compatible)
|
|
36
|
+
|
|
37
|
+
Contains functions designed to be used in Numba CUDA kernels.
|
|
38
|
+
These should be compiled with @cuda.jit(device=True) in GPU modules.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
import math
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def device_sellmeier_equation(
|
|
45
|
+
wl_um: float,
|
|
46
|
+
B1: float,
|
|
47
|
+
B2: float,
|
|
48
|
+
B3: float,
|
|
49
|
+
C1: float,
|
|
50
|
+
C2: float,
|
|
51
|
+
C3: float,
|
|
52
|
+
) -> float:
|
|
53
|
+
"""
|
|
54
|
+
GPU-compatible Sellmeier equation.
|
|
55
|
+
|
|
56
|
+
For use in Numba CUDA kernels. Computes refractive index
|
|
57
|
+
from wavelength and Sellmeier coefficients.
|
|
58
|
+
|
|
59
|
+
Parameters
|
|
60
|
+
----------
|
|
61
|
+
wl_um : float
|
|
62
|
+
Wavelength in micrometers.
|
|
63
|
+
B1, B2, B3 : float
|
|
64
|
+
Sellmeier B coefficients.
|
|
65
|
+
C1, C2, C3 : float
|
|
66
|
+
Sellmeier C coefficients in μm².
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
n : float
|
|
71
|
+
Refractive index.
|
|
72
|
+
|
|
73
|
+
Notes
|
|
74
|
+
-----
|
|
75
|
+
This function is designed to be compiled with @cuda.jit(device=True).
|
|
76
|
+
Import and compile in your GPU module.
|
|
77
|
+
"""
|
|
78
|
+
wl2 = wl_um * wl_um
|
|
79
|
+
n2_minus_1 = B1 * wl2 / (wl2 - C1) + B2 * wl2 / (wl2 - C2) + B3 * wl2 / (wl2 - C3)
|
|
80
|
+
return math.sqrt(1.0 + n2_minus_1)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def device_cauchy_equation(
|
|
84
|
+
wl_um: float,
|
|
85
|
+
A: float,
|
|
86
|
+
B: float,
|
|
87
|
+
C: float,
|
|
88
|
+
) -> float:
|
|
89
|
+
"""
|
|
90
|
+
GPU-compatible Cauchy equation.
|
|
91
|
+
|
|
92
|
+
For use in Numba CUDA kernels. Computes refractive index
|
|
93
|
+
from wavelength and Cauchy coefficients.
|
|
94
|
+
|
|
95
|
+
Parameters
|
|
96
|
+
----------
|
|
97
|
+
wl_um : float
|
|
98
|
+
Wavelength in micrometers.
|
|
99
|
+
A : float
|
|
100
|
+
Constant term.
|
|
101
|
+
B : float
|
|
102
|
+
First-order dispersion coefficient in μm².
|
|
103
|
+
C : float
|
|
104
|
+
Second-order dispersion coefficient in μm⁴.
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
n : float
|
|
109
|
+
Refractive index.
|
|
110
|
+
|
|
111
|
+
Notes
|
|
112
|
+
-----
|
|
113
|
+
This function is designed to be compiled with @cuda.jit(device=True).
|
|
114
|
+
Import and compile in your GPU module.
|
|
115
|
+
"""
|
|
116
|
+
wl2 = wl_um * wl_um
|
|
117
|
+
return A + B / wl2 + C / (wl2 * wl2)
|