BornSim 0.2.7__tar.gz → 0.2.8__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.
Files changed (128) hide show
  1. {bornsim-0.2.7 → bornsim-0.2.8}/.zenodo.json +1 -1
  2. {bornsim-0.2.7 → bornsim-0.2.8/BornSim.egg-info}/PKG-INFO +93 -89
  3. {bornsim-0.2.7 → bornsim-0.2.8}/BornSim.egg-info/SOURCES.txt +12 -6
  4. {bornsim-0.2.7 → bornsim-0.2.8}/CITATION.cff +1 -1
  5. {bornsim-0.2.7/BornSim.egg-info → bornsim-0.2.8}/PKG-INFO +93 -89
  6. {bornsim-0.2.7 → bornsim-0.2.8}/README.rst +92 -88
  7. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/__init__.py +6 -32
  8. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/_archives.py +1 -63
  9. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/_result_plotting.py +8 -17
  10. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/_result_validation.py +1 -4
  11. bornsim-0.2.8/bornsim/_version.py +1 -0
  12. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/angular_data.py +3 -15
  13. bornsim-0.2.8/bornsim/ensemble.py +164 -0
  14. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/ensemble_sampling.py +24 -28
  15. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/geometry.py +14 -30
  16. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/grid.py +5 -26
  17. bornsim-0.2.8/bornsim/medium/__init__.py +7 -0
  18. bornsim-0.2.8/bornsim/medium/base.py +62 -0
  19. bornsim-0.2.8/bornsim/medium/random_medium.py +210 -0
  20. bornsim-0.2.8/bornsim/medium/random_spheres.py +165 -0
  21. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/results.py +14 -104
  22. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/sampling.py +6 -19
  23. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/series.py +15 -25
  24. bornsim-0.2.8/bornsim/solver.py +296 -0
  25. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/volume.py +21 -98
  26. {bornsim-0.2.7 → bornsim-0.2.8}/conda.recipe/meta.yaml +1 -1
  27. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/born_orders/born_interference.py +13 -8
  28. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/born_orders/compare_orders.py +13 -8
  29. bornsim-0.2.8/docs/examples/random_media/README.rst +4 -0
  30. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/random_media/covariance_models.py +76 -8
  31. bornsim-0.2.8/docs/examples/random_media/phase_function.py +161 -0
  32. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/random_media/random_medium.py +9 -4
  33. bornsim-0.2.8/docs/examples/random_media/random_spheres.py +46 -0
  34. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/random_media/theory_random_fields.py +86 -14
  35. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/random_media/wavelength_dependence.py +73 -9
  36. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/results/result_plots.py +14 -11
  37. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/results/save_load_results.py +16 -9
  38. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/structured_media/dielectric_sphere.py +4 -2
  39. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/structured_media/structured_media.py +8 -7
  40. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/structured_media/theory_directional_interference.py +71 -4
  41. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/validation/angular_convergence.py +7 -4
  42. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/validation/ensemble_sampling.py +13 -8
  43. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/validation/finite_size_comparison.py +21 -31
  44. bornsim-0.2.8/docs/source/api.rst +130 -0
  45. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/conf.py +4 -5
  46. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/examples.rst +19 -12
  47. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/getting_started.rst +7 -11
  48. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/medium_visualization.rst +55 -66
  49. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/theory.rst +4 -5
  50. {bornsim-0.2.7 → bornsim-0.2.8}/pyproject.toml +2 -2
  51. bornsim-0.2.8/tests/analytical/reference.py +71 -0
  52. {bornsim-0.2.7 → bornsim-0.2.8}/tests/analytical/test_model.py +37 -45
  53. bornsim-0.2.8/tests/analytical/test_numerical_reference.py +71 -0
  54. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_api.py +36 -34
  55. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_api_keywords.py +14 -58
  56. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_api_ownership.py +24 -49
  57. bornsim-0.2.8/tests/numerical/test_api_scope.py +87 -0
  58. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_configuration.py +68 -81
  59. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_directional_api.py +21 -81
  60. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_engine.py +56 -31
  61. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_explicit_physics.py +11 -14
  62. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_geometry.py +47 -64
  63. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_media.py +92 -155
  64. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_medium_composition.py +48 -59
  65. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_medium_metadata.py +27 -32
  66. bornsim-0.2.8/tests/numerical/test_plot_contract.py +82 -0
  67. bornsim-0.2.8/tests/numerical/test_random_spheres.py +169 -0
  68. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_result.py +72 -216
  69. bornsim-0.2.8/tests/numerical/test_result_contract.py +89 -0
  70. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_series.py +220 -151
  71. bornsim-0.2.8/tests/numerical/test_unit_contract.py +116 -0
  72. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_units.py +173 -305
  73. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_volume_plotting.py +58 -35
  74. {bornsim-0.2.7 → bornsim-0.2.8}/tools/check_wheel.py +7 -2
  75. bornsim-0.2.7/bornsim/_version.py +0 -1
  76. bornsim-0.2.7/bornsim/ensemble.py +0 -253
  77. bornsim-0.2.7/bornsim/media.py +0 -359
  78. bornsim-0.2.7/bornsim/model.py +0 -276
  79. bornsim-0.2.7/bornsim/solver.py +0 -561
  80. bornsim-0.2.7/docs/examples/random_media/README.rst +0 -5
  81. bornsim-0.2.7/docs/examples/random_media/analytical_scattering.py +0 -28
  82. bornsim-0.2.7/docs/examples/random_media/phase_function.py +0 -81
  83. bornsim-0.2.7/docs/source/api.rst +0 -442
  84. bornsim-0.2.7/tests/analytical/test_api.py +0 -363
  85. bornsim-0.2.7/tests/analytical/test_result.py +0 -242
  86. bornsim-0.2.7/tests/analytical/test_units.py +0 -289
  87. {bornsim-0.2.7 → bornsim-0.2.8}/.coveragerc +0 -0
  88. {bornsim-0.2.7 → bornsim-0.2.8}/.pre-commit-config.yaml +0 -0
  89. {bornsim-0.2.7 → bornsim-0.2.8}/BornSim.egg-info/dependency_links.txt +0 -0
  90. {bornsim-0.2.7 → bornsim-0.2.8}/BornSim.egg-info/requires.txt +0 -0
  91. {bornsim-0.2.7 → bornsim-0.2.8}/BornSim.egg-info/top_level.txt +0 -0
  92. {bornsim-0.2.7 → bornsim-0.2.8}/CONTRIBUTING.md +0 -0
  93. {bornsim-0.2.7 → bornsim-0.2.8}/LICENSE +0 -0
  94. {bornsim-0.2.7 → bornsim-0.2.8}/MANIFEST.in +0 -0
  95. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/_validation.py +0 -0
  96. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/_volume_plotting.py +0 -0
  97. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/api.py +0 -0
  98. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/directions.py +0 -0
  99. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/green.py +0 -0
  100. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/material.py +0 -0
  101. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/rotation.py +0 -0
  102. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/source.py +0 -0
  103. {bornsim-0.2.7 → bornsim-0.2.8}/bornsim/units.py +0 -0
  104. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/README.rst +0 -0
  105. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/born_orders/README.rst +0 -0
  106. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/results/README.rst +0 -0
  107. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/structured_media/README.rst +0 -0
  108. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/validation/README.rst +0 -0
  109. {bornsim-0.2.7 → bornsim-0.2.8}/docs/examples/validation/grid_refinement.py +0 -0
  110. {bornsim-0.2.7 → bornsim-0.2.8}/docs/images/branding-prompts.rst +0 -0
  111. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/_static/favicon.png +0 -0
  112. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/_static/logo.png +0 -0
  113. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/_static/phase_function.svg +0 -0
  114. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/development.rst +0 -0
  115. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/gallery_config.py +0 -0
  116. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/guide.rst +0 -0
  117. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/index.rst +0 -0
  118. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/overview.rst +0 -0
  119. {bornsim-0.2.7 → bornsim-0.2.8}/docs/source/resources.rst +0 -0
  120. {bornsim-0.2.7 → bornsim-0.2.8}/makefile +0 -0
  121. {bornsim-0.2.7 → bornsim-0.2.8}/pytest.ini +0 -0
  122. {bornsim-0.2.7 → bornsim-0.2.8}/setup.cfg +0 -0
  123. {bornsim-0.2.7 → bornsim-0.2.8}/tests/conftest.py +0 -0
  124. {bornsim-0.2.7 → bornsim-0.2.8}/tests/numerical/test_directions.py +0 -0
  125. {bornsim-0.2.7 → bornsim-0.2.8}/tests/packaging/test_release_tools.py +0 -0
  126. {bornsim-0.2.7 → bornsim-0.2.8}/tools/check_release.py +0 -0
  127. {bornsim-0.2.7 → bornsim-0.2.8}/tools/next_release_version.py +0 -0
  128. {bornsim-0.2.7 → bornsim-0.2.8}/tools/release_tag.py +0 -0
@@ -8,7 +8,7 @@
8
8
  }
9
9
  ],
10
10
  "license": "mit",
11
- "version": "0.2.7",
11
+ "version": "0.2.8",
12
12
  "keywords": [
13
13
  "Born approximation",
14
14
  "light scattering",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BornSim
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: Vector Born-series scattering from continuous random dielectric media
5
5
  Author-email: Martin Poinsinet de Sivry-Houle <martin.poinsinet.de.sivry@gmail.com>
6
6
  License-Expression: MIT
@@ -93,7 +93,8 @@ The Python API accepts TypedUnit quantities; dimensional inputs require explicit
93
93
  .. code-block:: python
94
94
 
95
95
  import matplotlib.pyplot as plt
96
- from bornsim import EnsembleSampling, Grid, RandomMedium, Source, Solver
96
+ from bornsim import EnsembleSampling, Grid, Source, Solver
97
+ from bornsim.medium.random_medium import GaussianMedium
97
98
  from bornsim.units import ureg
98
99
 
99
100
  grid = Grid(
@@ -101,39 +102,38 @@ The Python API accepts TypedUnit quantities; dimensional inputs require explicit
101
102
  spacing=50 * ureg.nanometer,
102
103
  )
103
104
 
104
- medium = RandomMedium(
105
+ medium = GaussianMedium(
105
106
  background_refractive_index=1.33,
106
107
  refractive_index_std=0.01,
107
108
  correlation_length=100 * ureg.nanometer,
108
- correlation="gaussian",
109
109
  )
110
110
 
111
+ source_configuration_1 = Source(wavelength=633 * ureg.nanometer)
112
+
111
113
  solver = Solver(
112
- source=Source(wavelength=633 * ureg.nanometer),
114
+ source=source_configuration_1,
113
115
  order=3,
114
116
  )
115
117
 
118
+ ensemble_sampling_configuration_1 = EnsembleSampling(
119
+ realizations=4,
120
+ seed=42,
121
+ )
122
+
116
123
  result = solver.ensemble(
117
124
  medium=medium,
118
125
  grid=grid,
119
- ensemble_sampling=EnsembleSampling(
120
- realizations=4,
121
- seed=42,
122
- ),
126
+ ensemble_sampling=ensemble_sampling_configuration_1,
123
127
  )
124
128
 
125
- print(
126
- f"mu_s = {result.mu_s.to('1 / millimeter')}, "
127
- f"g = {result.g}, "
128
- f"mu_s_prime = {result.mu_s_prime.to('1 / millimeter')}"
129
- )
129
+ print(f"mu_s = {result.mu_s.to('1 / millimeter')}, g = {result.g}, mu_s_prime = {result.mu_s_prime.to('1 / millimeter')}")
130
130
 
131
131
  result.plot()
132
132
 
133
133
  plt.show()
134
134
 
135
135
  ``Source`` describes the supported unpolarized plane wave propagating along +z.
136
- ``RandomMedium`` defines numerical random-field statistics.
136
+ ``GaussianMedium`` defines numerical random-field statistics.
137
137
  ``Grid`` defines spatial shape and spacing once, and is shared by
138
138
  ``medium.to_volume(grid=grid)`` and ``solver.ensemble(grid=grid, ...)``.
139
139
  Every ``Volume`` retains its grid. ``AngularSampling`` groups output polar
@@ -211,8 +211,7 @@ field norms are dimensionless. Use ``.to("unit")`` to convert and
211
211
  ``.magnitude`` to retrieve an array. Plots convert to degrees and SI
212
212
  scattering units explicitly, including uncertainty bars.
213
213
 
214
- Analytical functions return unit-bearing scattering coefficients.
215
- ``random_volume`` retains unit-bearing voxel spacing and coordinates.
214
+ ``medium.to_volume(grid=grid)`` generates unit-bearing voxel samples.
216
215
  The low-level Born and ensemble kernels document their numeric SI outputs.
217
216
 
218
217
 
@@ -221,9 +220,9 @@ Physical model
221
220
 
222
221
  Real-valued refractive index fluctuations are linearized as δε ≈ 2 n₀ δn. For an unpolarized incident wave, the differential scattering coefficient is k₀⁴ Φε(q) (1 + cos²θ)/(32π²), where q = 2 n₀ k₀ sin(θ/2), k₀ = 2π/λvac and Φε is the three-dimensional Fourier transform of the dielectric covariance without a Fourier normalization prefactor.
223
222
 
224
- The refractive index covariance is σn² exp(−r²/(2ℓ²)) for the Gaussian model and σn² exp(−r/ℓ) for the exponential model. These definitions matter when comparing correlation lengths between publications. Gauss–Legendre quadrature integrates over solid angle. Increase ``quadrature_order`` to check convergence for strongly forward-peaked scattering.
223
+ The refractive index covariance is σn² exp(−r²/(2ℓ²)) for the Gaussian model and σn² exp(−r/ℓ) for the exponential model. These definitions matter when comparing correlation lengths between publications. Gauss–Legendre quadrature integrates over solid angle. Increase the angular sampling quadrature to check convergence for strongly forward-peaked scattering.
225
224
 
226
- The analytical solver is a first-order, single-scattering model. The numerical solver includes repeated interactions through the chosen Born order. No slab-transmission observable or particle-packing generator is provided;
225
+ BornSim includes repeated interactions through the chosen Born order. Infinite-medium first-order formulas live only in the test references. No slab-transmission observable or particle-packing generator is provided;
227
226
  fixed particle configurations can be composed and propagated numerically. A dense medium can still have weak fluctuations; density alone does not establish Born validity. Contrast, correlation length, wavelength, and propagation distance matter. Decreasing Born terms do not certify convergence.
228
227
 
229
228
  Scientific references:
@@ -244,14 +243,19 @@ Tests cover the analytic short-correlation limit, contrast scaling, independent
244
243
  Numerical media and geometry
245
244
  ----------------------------
246
245
 
247
- ``RandomMedium`` generates numerical Gaussian random fields with Gaussian,
248
- exponential, or Whittle–Matérn spatial covariance. Matérn ``smoothness`` uses
249
- the convention ``x = sqrt(2 * nu) * r / correlation_length``; ``nu = 0.5``
250
- reproduces exponential covariance. ``Medium`` is an abstract base class;
251
- instantiate ``RandomMedium`` or ``StructuredMedium`` and call ``to_volume()``.
252
- The existing analytical statistics class is named ``AnalyticalMedium``.
253
- Old ``Medium(...)`` calls must be replaced; choose ``correlation="gaussian"``
254
- for the analytical Gaussian model. Choose the covariance family explicitly. Matérn models also require smoothness.
246
+ ``GaussianMedium``, ``ExponentialMedium``, and ``WhittleMaternMedium`` generate
247
+ Gaussian random refractive index fields with distinct spatial covariance models.
248
+ Import them from ``bornsim.medium.random_medium``. Choose the covariance by
249
+ choosing the class; there is no covariance-string constructor argument.
250
+ Whittle–Matérn requires explicit ``smoothness``, with the convention
251
+ ``x = sqrt(2 * nu) * r / correlation_length``. Smoothness 0.5 reproduces
252
+ exponential covariance at the same length parameter.
253
+
254
+ ``RandomSphereMedium`` in ``bornsim.medium.random_spheres`` generates a seeded
255
+ collection of identical nonoverlapping spheres fully contained in the grid box.
256
+ Supply the sphere count, radius, and both refractive indices. Sequential rejection
257
+ sampling raises if it cannot place every sphere within its attempt limit.
258
+ All concrete media implement ``to_volume(grid=..., seed=...)``; ``Medium`` is abstract.
255
259
 
256
260
  ``StructuredMedium`` voxelizes ordered ``Layer``, ``Sphere``, ``Ellipsoid``,
257
261
  ``Box``, and ``Cylinder`` regions. Regions specify absolute indices; later
@@ -261,23 +265,24 @@ to the box, with a uniform background outside the sample.
261
265
  .. code-block:: python
262
266
 
263
267
  from bornsim.units import ureg
264
-
265
- from bornsim import Grid, RandomMedium, Layer, Sphere, StructuredMedium
266
- from bornsim.media import random_volume
268
+ from bornsim import Grid, Layer, Sphere, StructuredMedium
269
+ from bornsim.medium.random_medium import WhittleMaternMedium
267
270
  from bornsim import Solver, Source
268
271
 
269
- random_sample = random_volume(
270
- medium=RandomMedium(
271
- correlation="matern",
272
- smoothness=1.5,
273
- background_refractive_index=1.33,
274
- refractive_index_std=0.01,
275
- correlation_length=100e-9 * ureg.meter,
276
- ),
277
- grid=Grid(
278
- shape=(12, 12, 12),
279
- spacing=3e-08 * ureg.meter,
280
- ),
272
+ random_medium_configuration_1 = WhittleMaternMedium(
273
+ smoothness=1.5,
274
+ background_refractive_index=1.33,
275
+ refractive_index_std=0.01,
276
+ correlation_length=1e-07 * ureg.meter,
277
+ )
278
+
279
+ grid_configuration_1 = Grid(
280
+ shape=(12, 12, 12),
281
+ spacing=3e-08 * ureg.meter,
282
+ )
283
+
284
+ random_sample = random_medium_configuration_1.to_volume(
285
+ grid=grid_configuration_1,
281
286
  seed=42,
282
287
  )
283
288
 
@@ -297,22 +302,19 @@ to the box, with a uniform background outside the sample.
297
302
  centre=(0, 0, 4e-08) * ureg.meter,
298
303
  )
299
304
 
300
- structure.add_structures(
301
- layer,
302
- sphere,
303
- )
305
+ structure.add_structures(layer, sphere)
304
306
 
305
- structured_sample = structure.to_volume(
306
- grid=Grid(
307
- shape=(12, 12, 12),
308
- spacing=3e-08 * ureg.meter,
309
- ),
307
+ grid_configuration_2 = Grid(
308
+ shape=(12, 12, 12),
309
+ spacing=3e-08 * ureg.meter,
310
310
  )
311
311
 
312
+ structured_sample = structure.to_volume(grid=grid_configuration_2)
313
+
314
+ source_configuration_1 = Source(wavelength=6.33e-07 * ureg.meter)
315
+
312
316
  solver = Solver(
313
- source=Source(
314
- wavelength=633e-9 * ureg.meter,
315
- ),
317
+ source=source_configuration_1,
316
318
  order=3,
317
319
  )
318
320
 
@@ -339,29 +341,30 @@ slices, or sampled voxel geometry such as spheres.
339
341
  .. code-block:: python
340
342
 
341
343
  from bornsim.units import ureg
344
+ from bornsim import Grid
345
+ from bornsim.medium.random_medium import WhittleMaternMedium
342
346
 
343
- from bornsim import Grid, RandomMedium
344
-
345
- medium = RandomMedium(
347
+ medium = WhittleMaternMedium(
346
348
  background_refractive_index=1.33,
347
349
  refractive_index_std=0.01,
348
- correlation_length=100e-9 * ureg.meter,
349
- correlation="matern",
350
+ correlation_length=1e-07 * ureg.meter,
350
351
  smoothness=1.5,
351
352
  )
352
353
 
354
+ grid_configuration_1 = Grid(
355
+ shape=(16, 16, 16),
356
+ spacing=2.5e-08 * ureg.meter,
357
+ )
358
+
353
359
  volume = medium.to_volume(
354
- grid=Grid(
355
- shape=(16, 16, 16),
356
- spacing=2.5e-08 * ureg.meter,
357
- ),
360
+ grid=grid_configuration_1,
358
361
  seed=42,
359
362
  )
360
363
 
361
364
  figure = volume.plot_3d(
362
- field="refractive_index",
363
- opacity_scale="increasing",
364
- length_unit="nanometer",
365
+ field='refractive_index',
366
+ opacity_scale='increasing',
367
+ length_unit='nanometer',
365
368
  )
366
369
 
367
370
  figure.show()
@@ -381,33 +384,30 @@ Generate a seeded random volume and evaluate cumulative Born orders, or average
381
384
  .. code-block:: python
382
385
 
383
386
  from bornsim.units import ureg
384
-
385
387
  import numpy as np
386
- from bornsim import Directions, EnsembleSampling, Grid, RandomMedium
388
+ from bornsim import Directions, EnsembleSampling, Grid
389
+ from bornsim.medium.random_medium import GaussianMedium
387
390
  from bornsim.series import BornSeries
388
- from bornsim.media import random_volume
389
391
  from bornsim.ensemble import ensemble_scattering
390
392
 
391
- medium = RandomMedium(
393
+ medium = GaussianMedium(
392
394
  refractive_index_std=0.01,
393
395
  correlation_length=1e-07 * ureg.meter,
394
- correlation="gaussian",
395
396
  background_refractive_index=1.33,
396
397
  )
397
398
 
398
- volume = random_volume(
399
- medium=medium,
400
- grid=Grid(
401
- shape=(12, 12, 12),
402
- spacing=5e-08 * ureg.meter,
403
- ),
399
+ grid_configuration_1 = Grid(
400
+ shape=(12, 12, 12),
401
+ spacing=5e-08 * ureg.meter,
402
+ )
403
+
404
+ volume = medium.to_volume(
405
+ grid=grid_configuration_1,
404
406
  seed=42,
405
407
  )
406
408
 
407
409
  directions = Directions(vectors=[[0.0, 0.0, 1.0], [1.0, 0.0, 0.0]])
408
410
 
409
- # directions.vectors is the immutable Cartesian array.
410
-
411
411
  engine = BornSeries(
412
412
  grid=volume.grid,
413
413
  background_refractive_index=volume.background_refractive_index,
@@ -418,18 +418,22 @@ Generate a seeded random volume and evaluate cumulative Born orders, or average
418
418
 
419
419
  result = engine.solve(volume=volume)
420
420
 
421
- # result.amplitudes[j] is the (j+1)-th term, in metres.
422
- # result.differential[j] includes amplitude interference through order j+1.
421
+ ensemble_sampling_configuration_1 = EnsembleSampling(
422
+ realizations=4,
423
+ seed=42,
424
+ )
425
+
426
+ grid_configuration_2 = Grid(
427
+ shape=(12, 12, 12),
428
+ spacing=5e-08 * ureg.meter,
429
+ )
430
+
423
431
  ensemble = ensemble_scattering(
424
432
  medium=medium,
425
433
  wavelength=6.33e-07 * ureg.meter,
426
434
  order=3,
427
- ensemble_sampling=EnsembleSampling(
428
- realizations=4,
429
- seed=42,
430
- ),
431
- shape=(12, 12, 12),
432
- spacing=50e-9 * ureg.meter,
435
+ ensemble_sampling=ensemble_sampling_configuration_1,
436
+ grid=grid_configuration_2,
433
437
  )
434
438
 
435
439
  The API supports orders 1–12. Work limits bound synchronous calculations. Random fields have a **Gaussian probability distribution**, with Gaussian, exponential or Whittle–Matérn spatial covariance. Those are distinct choices. A spectral generator samples a doubled periodic box and crops it; ensemble point variance is normalized, but individual samples retain their random means and variances. Finite resolution truncates the spectrum, particularly for exponential covariance, and finite synthesis boxes approximate the continuum statistics.
@@ -479,13 +483,13 @@ Development
479
483
 
480
484
  See ``CONTRIBUTING.md`` for development and release instructions. The package
481
485
  uses the MIT license in ``LICENSE``; software citation metadata is provided in
482
- ``CITATION.cff``. The repository currently has no configured GitHub remote.
486
+ ``CITATION.cff``.
483
487
 
484
488
  API configuration and data ownership
485
489
  ------------------------------------
486
490
 
487
491
  Use Grid, AngularSampling and EnsembleSampling to define spatial, angular and
488
- realization settings. Legacy individual configuration keywords are deprecated.
492
+ realization settings. Configuration objects are required in place of individual compatibility keywords.
489
493
  EnsembleSampling accepts consecutive seeds or an explicit list of distinct
490
494
  seeds. Material objects share a real absolute refractive index across shapes.
491
495
  Results and their arrays are read-only; StructuredMedium remains mutable.
@@ -30,8 +30,6 @@ bornsim/geometry.py
30
30
  bornsim/green.py
31
31
  bornsim/grid.py
32
32
  bornsim/material.py
33
- bornsim/media.py
34
- bornsim/model.py
35
33
  bornsim/results.py
36
34
  bornsim/rotation.py
37
35
  bornsim/sampling.py
@@ -40,16 +38,20 @@ bornsim/solver.py
40
38
  bornsim/source.py
41
39
  bornsim/units.py
42
40
  bornsim/volume.py
41
+ bornsim/medium/__init__.py
42
+ bornsim/medium/base.py
43
+ bornsim/medium/random_medium.py
44
+ bornsim/medium/random_spheres.py
43
45
  conda.recipe/meta.yaml
44
46
  docs/examples/README.rst
45
47
  docs/examples/born_orders/README.rst
46
48
  docs/examples/born_orders/born_interference.py
47
49
  docs/examples/born_orders/compare_orders.py
48
50
  docs/examples/random_media/README.rst
49
- docs/examples/random_media/analytical_scattering.py
50
51
  docs/examples/random_media/covariance_models.py
51
52
  docs/examples/random_media/phase_function.py
52
53
  docs/examples/random_media/random_medium.py
54
+ docs/examples/random_media/random_spheres.py
53
55
  docs/examples/random_media/theory_random_fields.py
54
56
  docs/examples/random_media/wavelength_dependence.py
55
57
  docs/examples/results/README.rst
@@ -81,13 +83,13 @@ docs/source/_static/favicon.png
81
83
  docs/source/_static/logo.png
82
84
  docs/source/_static/phase_function.svg
83
85
  tests/conftest.py
84
- tests/analytical/test_api.py
86
+ tests/analytical/reference.py
85
87
  tests/analytical/test_model.py
86
- tests/analytical/test_result.py
87
- tests/analytical/test_units.py
88
+ tests/analytical/test_numerical_reference.py
88
89
  tests/numerical/test_api.py
89
90
  tests/numerical/test_api_keywords.py
90
91
  tests/numerical/test_api_ownership.py
92
+ tests/numerical/test_api_scope.py
91
93
  tests/numerical/test_configuration.py
92
94
  tests/numerical/test_directional_api.py
93
95
  tests/numerical/test_directions.py
@@ -97,8 +99,12 @@ tests/numerical/test_geometry.py
97
99
  tests/numerical/test_media.py
98
100
  tests/numerical/test_medium_composition.py
99
101
  tests/numerical/test_medium_metadata.py
102
+ tests/numerical/test_plot_contract.py
103
+ tests/numerical/test_random_spheres.py
100
104
  tests/numerical/test_result.py
105
+ tests/numerical/test_result_contract.py
101
106
  tests/numerical/test_series.py
107
+ tests/numerical/test_unit_contract.py
102
108
  tests/numerical/test_units.py
103
109
  tests/numerical/test_volume_plotting.py
104
110
  tests/packaging/test_release_tools.py
@@ -2,7 +2,7 @@ cff-version: 1.2.0
2
2
  message: "If you use BornSim in research, please cite the software version used."
3
3
  title: "BornSim"
4
4
  type: software
5
- version: "0.2.7"
5
+ version: "0.2.8"
6
6
  authors:
7
7
  - family-names: "Poinsinet de Sivry-Houle"
8
8
  given-names: "Martin"