PyFiberModes 0.14.1__tar.gz → 0.14.3__tar.gz
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.
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.github/workflows/deploy_anaconda.yml +5 -2
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.zenodo.json +1 -1
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/CHANGELOG.md +23 -1
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PKG-INFO +1 -1
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/_version.py +2 -2
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/two_layer/effective_index.py +7 -8
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes.egg-info/PKG-INFO +1 -1
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes.egg-info/SOURCES.txt +7 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/conda.recipe/meta.yaml +1 -1
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/conf.py +4 -0
- pyfibermodes-0.14.3/docs/source/getting_started.rst +69 -0
- pyfibermodes-0.14.3/docs/source/index.rst +57 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/theory.rst +30 -0
- pyfibermodes-0.14.3/docs/source/user_guide/fibers.rst +78 -0
- pyfibermodes-0.14.3/docs/source/user_guide/fields.rst +71 -0
- pyfibermodes-0.14.3/docs/source/user_guide/index.rst +24 -0
- pyfibermodes-0.14.3/docs/source/user_guide/modes.rst +70 -0
- pyfibermodes-0.14.3/docs/source/user_guide/reproducibility.rst +53 -0
- pyfibermodes-0.14.3/docs/source/user_guide/sweeps.rst +101 -0
- pyfibermodes-0.14.3/docs/source/user_guide/units.rst +59 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/pyproject.toml +1 -1
- pyfibermodes-0.14.1/docs/source/getting_started.rst +0 -34
- pyfibermodes-0.14.1/docs/source/index.rst +0 -25
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.coveragerc +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.github/dependabot.yml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.github/workflows/deploy_PyPi.yml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.github/workflows/deploy_coverage.yml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.github/workflows/deploy_documentation.yml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.github/workflows/quality.yml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.github/workflows/tests.yml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/.gitignore +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/CITATION.cff +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/CONTRIBUTING.md +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/LICENSE +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/MANIFEST.in +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/Makefile +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/__init__.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/analysis.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/coordinates.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/directories.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/exceptions.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/factory.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/1550BHP.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/DCF13.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/DCF1300S_20.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/DCF1300S_26.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/DCF1300S_33.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/DCF1300S_42.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/F2028M12.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/F2028M21.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/F2028M24.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/F2058G1.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/F2058L1.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/HI1060.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/HP630.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/SM1950.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/SMF28.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/fluorine_doped_1%_capillary.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/fluorine_doped_2%_capillary.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/test_fiber.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fiber_files/test_multimode_fiber.yaml +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/field.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/fundamentals.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/loader.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/materials.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/mode.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/mode_instances.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/models.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/optimization.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/plotting.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/propagation.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/services.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/__init__.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/base_solver.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/multilayer/__init__.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/multilayer/effective_index.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/protocols.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/results.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/three_layer/__init__.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/three_layer/cutoff.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/two_layer/__init__.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/two_layer/cutoff.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/source.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/stepindex.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes.egg-info/dependency_links.txt +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes.egg-info/requires.txt +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes.egg-info/top_level.txt +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/README.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/benchmarks/README.md +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/benchmarks/test_field_performance.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/Makefile +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/README.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/SMF28/README.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/SMF28/plot_smf28.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/SMF28/plot_smf28_dispersion_vs_wavelength.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/SMF28/plot_smf28_group_index_vs_wavelength.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/analysis/README.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/analysis/plot_coupled_mode_exchange.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/analysis/plot_guided_mode_discovery.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/analysis/plot_structured_wavelength_sweep.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/README.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_U_vs_V.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_comparison_solvers.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_dispersion.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_effective_index.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_fiber_LP_modes.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_group_index.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_mode_field.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_mode_field_1.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_mode_field_2.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/basic/plot_neff_tapered_fiber.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/benchmarks/README.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/benchmarks/plot_component_batching_speedup.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/benchmarks/plot_field_grid_scaling.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/benchmarks/plot_modal_cache_speedup.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/fields/README.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/fields/plot_confinement_by_radius.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/fields/plot_polarization_rotation.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/fields/plot_vector_components.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/specialty_fibers/README.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/specialty_fibers/plot_refractive_index_profile.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/specialty_fibers/plot_specialty_fiber_catalog.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/specialty_fibers/plot_specialty_mode_indices.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/validation/README.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/validation/plot_effective_index_bounds.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/validation/plot_field_area_convergence.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/examples/validation/plot_normalized_effective_index.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/make.bat +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/_static/default.css +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/_static/favicon.png +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/_static/logo.png +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/_static/thumbnail.png +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/api_policy.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/architecture.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/code/analysis.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/code/fibers.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/code/fields.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/code/fundamentals.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/code.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/examples.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/migration_guide.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/performance.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/references.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/troubleshooting.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/docs/source/workflows.rst +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/pytest.ini +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/setup.cfg +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/__init__.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/api_snapshot.json +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/helpers.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_advanced_features.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_api.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_architecture.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_architecture_enhancements.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_coordinates.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_docstrings.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_fiber.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_field.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_file_loading.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_physics_regression.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_public_api.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_release_tools.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_three_layer_solver.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_two_layer_solver.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tests/test_validation.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tools/check_release.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tools/next_release_version.py +0 -0
- {pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/tools/release_tag.py +0 -0
|
@@ -23,8 +23,11 @@ jobs:
|
|
|
23
23
|
needs: validate-release
|
|
24
24
|
uses: MartinPdeS/MPSActions/.github/workflows/publish_compiled_package_to_anaconda.yml@v5
|
|
25
25
|
with:
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
# The recipe is ``noarch: python``. Building it in a platform/version
|
|
27
|
+
# matrix creates several artifacts with the same archive path, which
|
|
28
|
+
# collide when the reusable workflow merges them before upload.
|
|
29
|
+
python_versions: '["3.11"]'
|
|
30
|
+
os_list: '["ubuntu-latest"]'
|
|
28
31
|
package_name: pyfibermodes
|
|
29
32
|
recipe_path: conda.recipe
|
|
30
33
|
test_import: PyFiberModes
|
|
@@ -6,6 +6,26 @@ use [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.14.3] - 2026-09-23
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Build the noarch Conda package once instead of merging nine identically
|
|
14
|
+
named matrix artifacts, preventing corrupted archives during Anaconda
|
|
15
|
+
upload.
|
|
16
|
+
|
|
17
|
+
## [0.14.2] - 2026-09-23
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Rebuilt the documentation around a connected user guide covering units and
|
|
22
|
+
conventions, fiber and material definitions, mode selection, field
|
|
23
|
+
convergence, parameter sweeps, inverse design, coupled-mode propagation,
|
|
24
|
+
validation, and reproducibility.
|
|
25
|
+
- Expanded the getting-started and theory pages with installation variants,
|
|
26
|
+
numerical checks, normalized propagation quantities, and guidance near
|
|
27
|
+
cutoff.
|
|
28
|
+
|
|
9
29
|
## [0.14.1] - 2026-09-23
|
|
10
30
|
|
|
11
31
|
## [0.14.0] - 2026-09-23
|
|
@@ -103,7 +123,9 @@ use [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
103
123
|
|
|
104
124
|
- Established the current tagged baseline for subsequent documented releases.
|
|
105
125
|
|
|
106
|
-
[Unreleased]: https://github.com/MartinPdeS/PyFiberModes/compare/v0.14.
|
|
126
|
+
[Unreleased]: https://github.com/MartinPdeS/PyFiberModes/compare/v0.14.3...HEAD
|
|
127
|
+
[0.14.3]: https://github.com/MartinPdeS/PyFiberModes/releases/tag/v0.14.3
|
|
128
|
+
[0.14.2]: https://github.com/MartinPdeS/PyFiberModes/releases/tag/v0.14.2
|
|
107
129
|
[0.14.1]: https://github.com/MartinPdeS/PyFiberModes/releases/tag/v0.14.1
|
|
108
130
|
[0.14.0]: https://github.com/MartinPdeS/PyFiberModes/releases/tag/v0.14.0
|
|
109
131
|
[0.13.2]: https://github.com/MartinPdeS/PyFiberModes/releases/tag/v0.13.2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyFiberModes
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.3
|
|
4
4
|
Summary: Guided-mode analysis and design for circular optical fibers.
|
|
5
5
|
Author-email: Martin Poinsinet de Sivry-Houle <martin.poinsinet.de.sivry@gmail.com>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.14.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 14,
|
|
21
|
+
__version__ = version = '0.14.3'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 14, 3)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
{pyfibermodes-0.14.1 → pyfibermodes-0.14.3}/PyFiberModes/solver/two_layer/effective_index.py
RENAMED
|
@@ -515,14 +515,12 @@ class EffectiveIndexSolver(BaseSolver):
|
|
|
515
515
|
return U, W, V
|
|
516
516
|
|
|
517
517
|
def get_LP_equation(self, neff: float, nu: int) -> float:
|
|
518
|
-
"""
|
|
518
|
+
r"""Return the LP-mode characteristic equation residual.
|
|
519
519
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
u}(U) * k_{
|
|
525
|
-
u - 1}(W)
|
|
520
|
+
.. math::
|
|
521
|
+
|
|
522
|
+
U J_{\nu-1}(U) K_{\nu}(W)
|
|
523
|
+
+ W J_{\nu}(U) K_{\nu-1}(W)
|
|
526
524
|
|
|
527
525
|
Parameters
|
|
528
526
|
----------
|
|
@@ -534,7 +532,8 @@ class EffectiveIndexSolver(BaseSolver):
|
|
|
534
532
|
Returns
|
|
535
533
|
-------
|
|
536
534
|
float
|
|
537
|
-
|
|
535
|
+
Characteristic-equation residual; a mode solution occurs at a
|
|
536
|
+
root.
|
|
538
537
|
"""
|
|
539
538
|
u, w, _ = self.get_U_W_V_parameter(neff=neff)
|
|
540
539
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyFiberModes
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.3
|
|
4
4
|
Summary: Guided-mode analysis and design for circular optical fibers.
|
|
5
5
|
Author-email: Martin Poinsinet de Sivry-Houle <martin.poinsinet.de.sivry@gmail.com>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -135,6 +135,13 @@ docs/source/code/analysis.rst
|
|
|
135
135
|
docs/source/code/fibers.rst
|
|
136
136
|
docs/source/code/fields.rst
|
|
137
137
|
docs/source/code/fundamentals.rst
|
|
138
|
+
docs/source/user_guide/fibers.rst
|
|
139
|
+
docs/source/user_guide/fields.rst
|
|
140
|
+
docs/source/user_guide/index.rst
|
|
141
|
+
docs/source/user_guide/modes.rst
|
|
142
|
+
docs/source/user_guide/reproducibility.rst
|
|
143
|
+
docs/source/user_guide/sweeps.rst
|
|
144
|
+
docs/source/user_guide/units.rst
|
|
138
145
|
tests/__init__.py
|
|
139
146
|
tests/api_snapshot.json
|
|
140
147
|
tests/helpers.py
|
|
@@ -99,6 +99,10 @@ language = "en"
|
|
|
99
99
|
highlight_language = "python3"
|
|
100
100
|
html_theme = "pydata_sphinx_theme"
|
|
101
101
|
|
|
102
|
+
# ``sphinx_gallery_conf`` intentionally contains the ``reset_mpl`` callback,
|
|
103
|
+
# which cannot be pickled into Sphinx's environment cache.
|
|
104
|
+
suppress_warnings = ["config.cache"]
|
|
105
|
+
|
|
102
106
|
# -- Options for HTML output -------------------------------------------------
|
|
103
107
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
|
104
108
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Getting started
|
|
2
|
+
===============
|
|
3
|
+
|
|
4
|
+
PyFiberModes requires Python 3.11 or newer. Create an isolated environment,
|
|
5
|
+
install the package from PyPI, and verify the interpreter that will run your
|
|
6
|
+
analysis:
|
|
7
|
+
|
|
8
|
+
.. code-block:: bash
|
|
9
|
+
|
|
10
|
+
python -m pip install PyFiberModes
|
|
11
|
+
python -c "import PyFiberModes; print(PyFiberModes.__version__)"
|
|
12
|
+
|
|
13
|
+
Install the optional plotting dependency if you intend to render field maps:
|
|
14
|
+
|
|
15
|
+
.. code-block:: bash
|
|
16
|
+
|
|
17
|
+
python -m pip install "PyFiberModes[plotting]"
|
|
18
|
+
|
|
19
|
+
Your first guided mode
|
|
20
|
+
----------------------
|
|
21
|
+
|
|
22
|
+
Fiber dimensions and wavelengths use SI units. Load a bundled definition,
|
|
23
|
+
solve the fundamental LP mode, and inspect its effective index:
|
|
24
|
+
|
|
25
|
+
.. code-block:: python
|
|
26
|
+
|
|
27
|
+
from PyFiberModes import LP01
|
|
28
|
+
from PyFiberModes.fiber import load_fiber
|
|
29
|
+
|
|
30
|
+
fiber = load_fiber("SMF28", wavelength=1550e-9)
|
|
31
|
+
neff = fiber.get_effective_index(LP01)
|
|
32
|
+
field = fiber.get_mode_field(LP01, limit=15e-6, n_point=151)
|
|
33
|
+
|
|
34
|
+
print(neff)
|
|
35
|
+
print(field.get_effective_area())
|
|
36
|
+
|
|
37
|
+
``LP01`` identifies the scalar fundamental mode. ``limit`` is the positive
|
|
38
|
+
half-width of the square sampling window in metres, and ``n_point`` is the
|
|
39
|
+
number of samples along each Cartesian axis.
|
|
40
|
+
|
|
41
|
+
Check the result
|
|
42
|
+
----------------
|
|
43
|
+
|
|
44
|
+
A useful calculation includes a physical and a numerical check:
|
|
45
|
+
|
|
46
|
+
.. code-block:: python
|
|
47
|
+
|
|
48
|
+
n_cladding = fiber.last_layer.refractive_index
|
|
49
|
+
n_core = fiber.maximum_index
|
|
50
|
+
assert n_cladding < neff < n_core
|
|
51
|
+
|
|
52
|
+
coarse = fiber.get_mode_field(LP01, limit=15e-6, n_point=151)
|
|
53
|
+
fine = fiber.get_mode_field(LP01, limit=20e-6, n_point=251)
|
|
54
|
+
relative_change = abs(
|
|
55
|
+
fine.get_effective_area() / coarse.get_effective_area() - 1
|
|
56
|
+
)
|
|
57
|
+
print(f"effective-area change: {relative_change:.2%}")
|
|
58
|
+
|
|
59
|
+
Increase the window until the field decays before its boundary, then increase
|
|
60
|
+
the resolution until the derived quantity changes less than the accuracy your
|
|
61
|
+
application requires.
|
|
62
|
+
|
|
63
|
+
Where to go next
|
|
64
|
+
----------------
|
|
65
|
+
|
|
66
|
+
Continue with :doc:`user_guide/fibers` to define a fiber,
|
|
67
|
+
:doc:`user_guide/modes` to calculate modal properties, or
|
|
68
|
+
:doc:`user_guide/fields` to analyze vector fields. Use :doc:`examples` for
|
|
69
|
+
downloadable examples and :doc:`code` for the complete API.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
**Date**: |today|, **Version**: |version|
|
|
2
|
+
|
|
3
|
+
.. image:: _static/logo.png
|
|
4
|
+
:width: 620
|
|
5
|
+
:align: center
|
|
6
|
+
:alt: PyFiberModes logo
|
|
7
|
+
|
|
8
|
+
.. include:: ../../README.rst
|
|
9
|
+
:start-line: 5
|
|
10
|
+
|
|
11
|
+
.. toctree::
|
|
12
|
+
:maxdepth: 2
|
|
13
|
+
:hidden:
|
|
14
|
+
|
|
15
|
+
Getting started <getting_started.rst>
|
|
16
|
+
User guide <user_guide/index.rst>
|
|
17
|
+
Theory <theory.rst>
|
|
18
|
+
Architecture <architecture.rst>
|
|
19
|
+
API policy <api_policy.rst>
|
|
20
|
+
Migration <migration_guide.rst>
|
|
21
|
+
Workflows <workflows.rst>
|
|
22
|
+
Performance <performance.rst>
|
|
23
|
+
Troubleshooting <troubleshooting.rst>
|
|
24
|
+
Examples <examples.rst>
|
|
25
|
+
API reference <code.rst>
|
|
26
|
+
References <references.rst>
|
|
27
|
+
|
|
28
|
+
Choose your path
|
|
29
|
+
----------------
|
|
30
|
+
|
|
31
|
+
.. grid:: 3
|
|
32
|
+
:gutter: 2
|
|
33
|
+
|
|
34
|
+
.. grid-item-card:: New to PyFiberModes?
|
|
35
|
+
:link: getting_started
|
|
36
|
+
:link-type: doc
|
|
37
|
+
|
|
38
|
+
Install the package and complete a guided mode calculation in a few
|
|
39
|
+
minutes.
|
|
40
|
+
|
|
41
|
+
.. grid-item-card:: Solving a real problem?
|
|
42
|
+
:link: user_guide/index
|
|
43
|
+
:link-type: doc
|
|
44
|
+
|
|
45
|
+
Follow task-oriented guides for fiber models, modal properties, fields,
|
|
46
|
+
sweeps, optimization, and propagation.
|
|
47
|
+
|
|
48
|
+
.. grid-item-card:: Looking up an object?
|
|
49
|
+
:link: code
|
|
50
|
+
:link-type: doc
|
|
51
|
+
|
|
52
|
+
Browse the generated API reference, signatures, and source links.
|
|
53
|
+
|
|
54
|
+
PyFiberModes uses SI units throughout. Wavelengths and radii are in metres,
|
|
55
|
+
propagation constants are in radians per metre, and the dispersion helper
|
|
56
|
+
returns ps/(nm km). See :doc:`user_guide/units` for a complete conventions
|
|
57
|
+
table.
|
|
@@ -13,6 +13,16 @@ Mode families
|
|
|
13
13
|
vector modes, while ``TE`` and ``TM`` are the transverse families. A mode is
|
|
14
14
|
identified by its family, azimuthal order ``nu``, and radial order ``m``.
|
|
15
15
|
|
|
16
|
+
The effective index and propagation constant are related by
|
|
17
|
+
|
|
18
|
+
.. math::
|
|
19
|
+
|
|
20
|
+
\beta = k_0 n_\mathrm{eff}, \qquad k_0 = \frac{2\pi}{\lambda}.
|
|
21
|
+
|
|
22
|
+
Under weak guidance, a vector-mode group may be represented by one LP mode.
|
|
23
|
+
LP labels are consequently an approximation and not an additional independent
|
|
24
|
+
set of physical solutions alongside HE, EH, TE, and TM labels.
|
|
25
|
+
|
|
16
26
|
Normalized frequency
|
|
17
27
|
--------------------
|
|
18
28
|
|
|
@@ -25,6 +35,26 @@ For a two-layer fiber, the normalized frequency is
|
|
|
25
35
|
where :math:`a` is the core radius and :math:`k_0=2\pi/\lambda`. Guided
|
|
26
36
|
solutions satisfy :math:`n_\mathrm{clad} < n_\mathrm{eff} < n_\mathrm{core}`.
|
|
27
37
|
|
|
38
|
+
The normalized propagation constant is commonly written
|
|
39
|
+
|
|
40
|
+
.. math::
|
|
41
|
+
|
|
42
|
+
b = \frac{n_\mathrm{eff}^2-n_\mathrm{clad}^2}
|
|
43
|
+
{n_\mathrm{core}^2-n_\mathrm{clad}^2},
|
|
44
|
+
|
|
45
|
+
so guided two-layer solutions lie between zero and one. Multilayer fibers use
|
|
46
|
+
the actual ordered interfaces and do not in general reduce to a single
|
|
47
|
+
core-cladding :math:`V` value.
|
|
48
|
+
|
|
49
|
+
Wavelength derivatives
|
|
50
|
+
----------------------
|
|
51
|
+
|
|
52
|
+
Group index, group-velocity dispersion, chromatic dispersion, and dispersion
|
|
53
|
+
slope depend on numerical derivatives of the solved propagation constant.
|
|
54
|
+
They are less robust than a single effective-index evaluation near cutoff or
|
|
55
|
+
an avoided crossing. Validate them by changing the wavelength sampling and by
|
|
56
|
+
checking that the same modal branch is followed.
|
|
57
|
+
|
|
28
58
|
Field normalization
|
|
29
59
|
-------------------
|
|
30
60
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
Defining fibers and materials
|
|
2
|
+
=============================
|
|
3
|
+
|
|
4
|
+
Bundled definitions
|
|
5
|
+
-------------------
|
|
6
|
+
|
|
7
|
+
The simplest route is :func:`~PyFiberModes.fiber.load_fiber`. Pass a bundled
|
|
8
|
+
YAML filename without its extension and always provide the wavelength when a
|
|
9
|
+
layer uses a dispersive material:
|
|
10
|
+
|
|
11
|
+
.. code-block:: python
|
|
12
|
+
|
|
13
|
+
from PyFiberModes import load_fiber
|
|
14
|
+
|
|
15
|
+
fiber = load_fiber("SMF28", wavelength=1.55e-6)
|
|
16
|
+
for layer in fiber.layers:
|
|
17
|
+
print(layer.name, layer.radius_in, layer.radius_out, layer.refractive_index)
|
|
18
|
+
|
|
19
|
+
The bundled catalog lives in ``PyFiberModes/fiber_files``. Definitions may use
|
|
20
|
+
an explicit ``index``, a registered ``material``, or a numerical aperture
|
|
21
|
+
relative to the adjacent outer layer. A compact two-layer definition is:
|
|
22
|
+
|
|
23
|
+
.. code-block:: yaml
|
|
24
|
+
|
|
25
|
+
# Layers are listed from outside to inside.
|
|
26
|
+
layers:
|
|
27
|
+
cladding:
|
|
28
|
+
name: cladding
|
|
29
|
+
radius: 62.5e-6
|
|
30
|
+
material: fused_silica
|
|
31
|
+
core:
|
|
32
|
+
name: core
|
|
33
|
+
radius: 4.1e-6
|
|
34
|
+
NA: 0.14
|
|
35
|
+
|
|
36
|
+
Custom material models
|
|
37
|
+
----------------------
|
|
38
|
+
|
|
39
|
+
Use :class:`~PyFiberModes.materials.MaterialRegistry` when a definition names a
|
|
40
|
+
material that is not built in. A model can be any callable receiving wavelength
|
|
41
|
+
in metres and returning refractive index:
|
|
42
|
+
|
|
43
|
+
.. code-block:: python
|
|
44
|
+
|
|
45
|
+
from PyFiberModes import MaterialRegistry, load_fiber
|
|
46
|
+
|
|
47
|
+
materials = MaterialRegistry({
|
|
48
|
+
"my_glass": lambda wavelength: 1.46 - 0.003 * (wavelength / 1e-6 - 1.0),
|
|
49
|
+
})
|
|
50
|
+
fiber = load_fiber("my_fiber", wavelength=1.55e-6, materials=materials)
|
|
51
|
+
|
|
52
|
+
Programmatic construction
|
|
53
|
+
--------------------------
|
|
54
|
+
|
|
55
|
+
For a single structure, create a :class:`~PyFiberModes.fiber.Fiber`, add layers
|
|
56
|
+
from the center outward, and initialize it once all interfaces are defined:
|
|
57
|
+
|
|
58
|
+
.. code-block:: python
|
|
59
|
+
|
|
60
|
+
from PyFiberModes import Fiber
|
|
61
|
+
|
|
62
|
+
fiber = Fiber(wavelength=1.55e-6)
|
|
63
|
+
fiber.add_layer(name="core", radius=4.1e-6, index=1.450)
|
|
64
|
+
fiber.add_layer(name="cladding", radius=62.5e-6, index=1.444)
|
|
65
|
+
fiber.initialize_layers()
|
|
66
|
+
|
|
67
|
+
Use :class:`~PyFiberModes.factory.FiberFactory` when radii or indices are
|
|
68
|
+
iterables and you want the Cartesian product of several designs.
|
|
69
|
+
|
|
70
|
+
Mutation and caches
|
|
71
|
+
-------------------
|
|
72
|
+
|
|
73
|
+
Call :meth:`~PyFiberModes.fiber.Fiber.update_wavelength` when changing
|
|
74
|
+
wavelength; it updates dependent state and clears cached modal and radial-field
|
|
75
|
+
solutions. After directly changing a layer radius or refractive index, call
|
|
76
|
+
:meth:`~PyFiberModes.fiber.Fiber.clear_caches`. Prefer
|
|
77
|
+
:meth:`~PyFiberModes.fiber.Fiber.sweep` or the optimization helpers for repeated
|
|
78
|
+
calculations because they work on copies and keep the input fiber unchanged.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Fields, power, and overlap
|
|
2
|
+
==========================
|
|
3
|
+
|
|
4
|
+
Sampling a field
|
|
5
|
+
----------------
|
|
6
|
+
|
|
7
|
+
A :class:`~PyFiberModes.field.Field` samples an analytical radial solution on a
|
|
8
|
+
square Cartesian grid:
|
|
9
|
+
|
|
10
|
+
.. code-block:: python
|
|
11
|
+
|
|
12
|
+
from PyFiberModes import LP01, load_fiber
|
|
13
|
+
|
|
14
|
+
fiber = load_fiber("SMF28", wavelength=1.55e-6)
|
|
15
|
+
field = fiber.get_mode_field(LP01, limit=20e-6, n_point=251)
|
|
16
|
+
components = field.get_components(("Ex", "Ey", "Ez", "Hx", "Hy", "Hz"))
|
|
17
|
+
|
|
18
|
+
Use an odd ``n_point`` to include the fiber axis. ``limit`` is the positive
|
|
19
|
+
half-width, so the full domain is twice that value. Request related components
|
|
20
|
+
together with ``get_components`` and reuse the same ``Field`` instance; radial
|
|
21
|
+
solutions and interpolated arrays are cached.
|
|
22
|
+
|
|
23
|
+
Derived quantities
|
|
24
|
+
------------------
|
|
25
|
+
|
|
26
|
+
.. code-block:: python
|
|
27
|
+
|
|
28
|
+
area_um2 = field.get_effective_area() * 1e12
|
|
29
|
+
core_fraction = field.get_confinement_factor(radius=4.1e-6)
|
|
30
|
+
sx, sy, sz = field.get_poynting_vector()
|
|
31
|
+
guided_power = field.get_power()
|
|
32
|
+
|
|
33
|
+
Field amplitudes represent modal shapes rather than a launched absolute power.
|
|
34
|
+
Normalized overlap and confinement are therefore usually more portable than
|
|
35
|
+
raw amplitudes. Power-like integrals depend on the sampled window and grid.
|
|
36
|
+
|
|
37
|
+
Convergence procedure
|
|
38
|
+
---------------------
|
|
39
|
+
|
|
40
|
+
For any reported field integral:
|
|
41
|
+
|
|
42
|
+
#. Increase ``limit`` until the field is negligible at all four boundaries.
|
|
43
|
+
#. Hold that window fixed and increase ``n_point``.
|
|
44
|
+
#. Compare the final quantity, not only the image, between refinements.
|
|
45
|
+
#. Apply the same grid to both fields in an overlap calculation.
|
|
46
|
+
|
|
47
|
+
A smooth-looking plot can still have a biased integral if the domain clips the
|
|
48
|
+
evanescent tail. Near a material interface, resolution must also be sufficient
|
|
49
|
+
to represent the discontinuity.
|
|
50
|
+
|
|
51
|
+
Overlap and coupling
|
|
52
|
+
--------------------
|
|
53
|
+
|
|
54
|
+
The convenience method ``field_a.overlap(field_b)`` returns normalized complex
|
|
55
|
+
electric-field overlap. The standalone :func:`~PyFiberModes.propagation.overlap`
|
|
56
|
+
also supports an unnormalized result. Both fields must have identical grid
|
|
57
|
+
shapes and spacing. :func:`~PyFiberModes.propagation.coupling_matrix` constructs
|
|
58
|
+
a Hermitian matrix from several fields and accepts an optional scalar or
|
|
59
|
+
sampled spatial perturbation.
|
|
60
|
+
|
|
61
|
+
Plotting
|
|
62
|
+
--------
|
|
63
|
+
|
|
64
|
+
Install the ``plotting`` extra, then render one or more named components:
|
|
65
|
+
|
|
66
|
+
.. code-block:: python
|
|
67
|
+
|
|
68
|
+
figure = field.plot(plot_type=["Ex", "Ey", "Emod"], show=False)
|
|
69
|
+
figure.savefig("mode-field.png", dpi=200, bbox_inches="tight")
|
|
70
|
+
|
|
71
|
+
Use ``show=False`` in scripts, tests, and headless environments.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
User guide
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
This guide connects the short examples to the complete API reference. It
|
|
5
|
+
follows the lifecycle of a fiber calculation: define the structure, choose and
|
|
6
|
+
solve modes, validate sampled fields, explore parameters, and preserve enough
|
|
7
|
+
context to reproduce the result.
|
|
8
|
+
|
|
9
|
+
.. toctree::
|
|
10
|
+
:maxdepth: 2
|
|
11
|
+
|
|
12
|
+
units
|
|
13
|
+
fibers
|
|
14
|
+
modes
|
|
15
|
+
fields
|
|
16
|
+
sweeps
|
|
17
|
+
reproducibility
|
|
18
|
+
|
|
19
|
+
The package is designed for circularly symmetric, concentric step-index
|
|
20
|
+
structures. It is not a general-purpose solver for non-circular cores,
|
|
21
|
+
longitudinally varying cross-sections, stress birefringence, or arbitrary
|
|
22
|
+
anisotropic materials. Those cases require a numerical full-vector solver;
|
|
23
|
+
PyFiberModes can still provide reference solutions or input modes for a larger
|
|
24
|
+
workflow.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
Modes and modal properties
|
|
2
|
+
==========================
|
|
3
|
+
|
|
4
|
+
Choosing a family
|
|
5
|
+
-----------------
|
|
6
|
+
|
|
7
|
+
LP modes are appropriate for weakly guiding fibers, where the refractive-index
|
|
8
|
+
contrast is small and a scalar description is sufficient. HE, EH, TE, and TM
|
|
9
|
+
modes retain the vector family structure and are the better choice for higher
|
|
10
|
+
contrast or when longitudinal field components matter.
|
|
11
|
+
|
|
12
|
+
Create arbitrary identifiers with :class:`~PyFiberModes.mode.Mode`, or import
|
|
13
|
+
common instances from the package root:
|
|
14
|
+
|
|
15
|
+
.. code-block:: python
|
|
16
|
+
|
|
17
|
+
from PyFiberModes import HE11, LP01, Mode
|
|
18
|
+
|
|
19
|
+
lp21 = Mode("LP", nu=2, m=1)
|
|
20
|
+
assert LP01.nu == 0
|
|
21
|
+
|
|
22
|
+
Solving one mode
|
|
23
|
+
----------------
|
|
24
|
+
|
|
25
|
+
The effective index is the central solved quantity. Other longitudinal modal
|
|
26
|
+
properties derive from it and its wavelength dependence:
|
|
27
|
+
|
|
28
|
+
.. code-block:: python
|
|
29
|
+
|
|
30
|
+
from PyFiberModes import LP01, load_fiber
|
|
31
|
+
|
|
32
|
+
fiber = load_fiber("SMF28", wavelength=1.55e-6)
|
|
33
|
+
values = {
|
|
34
|
+
"effective index": fiber.get_effective_index(LP01),
|
|
35
|
+
"propagation constant": fiber.get_propagation_constant(LP01),
|
|
36
|
+
"group index": fiber.get_group_index(LP01),
|
|
37
|
+
"dispersion": fiber.get_dispersion(LP01),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
A guided solution should have an effective index between the exterior index
|
|
41
|
+
and the largest layer index. Close to cutoff, repeat the calculation at nearby
|
|
42
|
+
wavelengths because derivative-based group and dispersion quantities become
|
|
43
|
+
sensitive to step size and a mode may disappear.
|
|
44
|
+
|
|
45
|
+
Discovering supported modes
|
|
46
|
+
---------------------------
|
|
47
|
+
|
|
48
|
+
Use :meth:`~PyFiberModes.fiber.Fiber.find_modes` when the supported set is not
|
|
49
|
+
known in advance:
|
|
50
|
+
|
|
51
|
+
.. code-block:: python
|
|
52
|
+
|
|
53
|
+
modes = fiber.find_modes(families=("LP",), max_nu=4, max_m=3)
|
|
54
|
+
for mode in modes:
|
|
55
|
+
print(mode, fiber.get_effective_index(mode))
|
|
56
|
+
|
|
57
|
+
The bounds describe candidate orders, not the number of returned modes. Keep
|
|
58
|
+
them close to the physical range of interest: every candidate requires a root
|
|
59
|
+
search. Search scalar and vector families separately to avoid interpreting two
|
|
60
|
+
representations of the same weak-guidance mode as independent solutions.
|
|
61
|
+
|
|
62
|
+
Cutoff and normalized quantities
|
|
63
|
+
--------------------------------
|
|
64
|
+
|
|
65
|
+
For two-layer fibers, :meth:`~PyFiberModes.fiber.Fiber.V_number` describes the
|
|
66
|
+
normalized frequency and :meth:`~PyFiberModes.fiber.Fiber.get_normalized_beta`
|
|
67
|
+
places the propagation constant between the core and cladding limits.
|
|
68
|
+
``get_mode_cutoff_v0`` and ``get_mode_cutoff_wavelength`` expose the analytical
|
|
69
|
+
cutoff supported by the applicable solver. See :doc:`../theory` for equations
|
|
70
|
+
and assumptions.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Validation and reproducibility
|
|
2
|
+
==============================
|
|
3
|
+
|
|
4
|
+
Numerical output is most useful when its assumptions can be reconstructed.
|
|
5
|
+
Record the following with published or shared results:
|
|
6
|
+
|
|
7
|
+
* the exact PyFiberModes version and Python version;
|
|
8
|
+
* the fiber YAML file or every layer radius, index, and material model;
|
|
9
|
+
* vacuum wavelength and selected mode family and orders;
|
|
10
|
+
* field window, grid resolution, and polarization angles;
|
|
11
|
+
* sweep spacing or derivative settings near cutoff;
|
|
12
|
+
* optimization method, bounds, constraints, seed, and termination message.
|
|
13
|
+
|
|
14
|
+
Minimum validation checklist
|
|
15
|
+
----------------------------
|
|
16
|
+
|
|
17
|
+
#. Confirm ``n_cladding < n_effective <= n_max`` for every guided mode.
|
|
18
|
+
#. Repeat field integrals with a larger window and a finer grid.
|
|
19
|
+
#. Repeat derivative-based quantities with a different wavelength sampling.
|
|
20
|
+
#. Check expected limiting behavior, symmetry, and conservation laws.
|
|
21
|
+
#. Compare a simple two-layer case with an analytical reference before using a
|
|
22
|
+
complicated multilayer structure.
|
|
23
|
+
|
|
24
|
+
Failure handling
|
|
25
|
+
----------------
|
|
26
|
+
|
|
27
|
+
Automatic discovery and sweeps represent unavailable modes with omission or
|
|
28
|
+
``NaN`` so that a broad exploration can continue. A single requested mode may
|
|
29
|
+
instead raise :class:`~PyFiberModes.exceptions.SolverError` or
|
|
30
|
+
:class:`~PyFiberModes.exceptions.ConvergenceError`. Catch these specific
|
|
31
|
+
exceptions only when a missing point is an expected outcome:
|
|
32
|
+
|
|
33
|
+
.. code-block:: python
|
|
34
|
+
|
|
35
|
+
import numpy as np
|
|
36
|
+
from PyFiberModes import ConvergenceError, SolverError
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
effective_index = fiber.get_effective_index(mode)
|
|
40
|
+
except (SolverError, ConvergenceError):
|
|
41
|
+
effective_index = np.nan
|
|
42
|
+
|
|
43
|
+
Do not replace all exceptions with ``NaN``: invalid geometry, units, or array
|
|
44
|
+
shapes should remain visible and be corrected.
|
|
45
|
+
|
|
46
|
+
Archiving results
|
|
47
|
+
-----------------
|
|
48
|
+
|
|
49
|
+
``ModeSweepResult.as_records`` produces plain row-oriented dictionaries useful
|
|
50
|
+
for CSV or dataframe export. Preserve the original parameter array as well as
|
|
51
|
+
the records, and save configuration and environment metadata beside numerical
|
|
52
|
+
data. Cite the software using :doc:`../references` and use a tagged release,
|
|
53
|
+
not a moving branch, when preparing long-lived results.
|