Skip to content

Commit ab67608

Browse files
authored
Near field (#11)
* feat: near-field reconstruction (VSWF + external field) Add vector spherical wave functions and Tier-1 external near-field reconstruction from any T-matrix. - src/common/vswf.jl: vswf / vswf_cartesian point evaluation of regular (jₙ) and outgoing (hₙ⁽¹⁾) Mₘₙ, Nₘₙ in the Mishchenko (2002) convention, built from the existing Riccati-Bessel and Wigner-d routines. Verified by the curl identities ∇×M=kN, ∇×N=kM. - src/common/near_field.jl: plane-wave incident coefficients, scattering coefficients (p,q)=T(a,b), and incident_field / scattered_field / total_field. Normalization locked by two independent gates: incident near-field reconstruction matches the analytic plane wave to ~1e-15, and the scattered far field reproduces amplitude_matrix as O(1/R). Exports: vswf, vswf_cartesian, scattering_coefficients, incident_field, scattered_field, total_field. * docs: near-field hotspot example + benchmark group - examples/near_field.jl: Pluto notebook mapping |E|/|E₀| around a Mie sphere (incident + scattered reconstruction), with an axial line cut and the Rayleigh-hypothesis validity note. Registered in docs/make.jl and rendered to docs/src/examples/near_field.md. - benchmark: new 'near_field' group timing scattering_coefficients (the (p,q)=𝐓(a,b) apply) and per-point scattered_field/total_field. * docs: document the near-field API (api.md, usage.md) - api.md: new 'Near-field reconstruction' @autodocs section covering common/vswf.jl and common/near_field.jl (required by checkdocs=:exported now that the field functions are exported). - usage.md: 'Near-field reconstruction' section with the incident / scattered / total field API, the (p,q)-reuse pattern for dense grids, and the Rayleigh-hypothesis region-of-validity warning. - examples/index.md: list the near-field notebook. Verified: full docs build passes (cross-references resolve, checkdocs clean). * feat: internal field for homogeneous spheres (Mie) Reconstruct the field INSIDE a homogeneous sphere from the analytic Mie internal coefficients (Bohren & Huffman 1983), expanded in regular VSWFs at the internal wavenumber k_int = mᵣ·k. - internal_coefficients(x, mᵣ, ϑ, φ, Eθ, Eφ) and internal_field (precomputed- coefficient and one-shot forms); _field_from_coeffs generalized to a complex wavenumber. No change to MieTransitionMatrix. - Validated two independent ways: tangential E and H are continuous with the external total_field across the surface (~1e-11), and the field converges to the Rayleigh static limit 3/(mᵣ²+2)·E₀ as x→0. - usage.md documents the sphere internal field; api.md autodocs cover it. Exports: internal_coefficients, internal_field. * feat: internal field for general axisymmetric particles (EBCM) Extend internal_coefficients/internal_field to any axisymmetric shape via the EBCM matrices: per azimuthal block c = ½ Q⁻¹ a with Q = P + iU, and the ±m M↔N sign symmetry of AxisymmetricTransitionMatrix for the -m blocks. The ½ factor and the symmetry are locked to machine precision by matching the analytic Mie internal field on a degenerate sphere (Spheroid(R,R,mᵣ)), universal across size and refractive index. - src/EBCM/near_field.jl: shape-based internal_coefficients / internal_field (non-invasive — rebuilds P,U via ebcm_matrices_m₀/_m, no solver API change). - Valid only within the inscribed sphere (documented); no self-contained surface check for genuine non-spheres (Rayleigh hypothesis). - Tests: EBCM-vs-Mie on a sphere (<1e-8); spheroid runs finite + two-step == one-shot. api.md/usage.md document it. Full suite 48021/48021; docs green. * docs: correct the EBCM internal-field validity claim Tested nmax-convergence of the interior reconstruction inside vs outside the inscribed sphere. The earlier 'diverges outside the inscribed sphere' claim is wrong: for an aspect-2 spheroid the field converges stably at every interior point, tips included. The actual failure mode is EBCM Q-matrix ill-conditioning at high aspect ratio with high nmax (aspect-5 blows up everywhere — including the core inside the inscribed sphere — by nmax≈32), the same Float64 cancellation the F⁺ 'stable' path addresses for the T-matrix, since c=½Q⁻¹a inherits Q⁻¹. Reword the source comments, docstrings, and usage.md accordingly: the inscribed sphere is the guaranteed region, the binding limit is conditioning (aspect×nmax), and absolute accuracy beyond the inscribed sphere remains unverified for non-spheres. * fix(near-field): handle regular origin fields Normalize near-field example enhancement by the incident field magnitude and document internal-field reconstruction. Add regular VSWF origin limits so internal-field reconstruction stays finite at the Cartesian origin. Include formatting cleanup in generated/example sources.
1 parent 2dd434c commit ab67608

20 files changed

Lines changed: 1346 additions & 54 deletions

benchmark/benchmarks.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# ebcm – EBCM blocks, fixed-order, and auto-converging solves
1414
# iitm – Invariant Imbedding T-Matrix (axisymmetric + N-fold)
1515
# postprocessing – far-field observables from a precomputed T-matrix
16+
# near_field – external field reconstruction (VSWF) from a T-matrix
1617
# linearization – analytical Jacobian (baseline for the inv→lu work)
1718
# precision – Float64 vs Double64 on the same EBCM block
1819

@@ -127,6 +128,22 @@ let g = SUITE["postprocessing"] = BenchmarkGroup(["farfield"])
127128
= 1) seconds=30
128129
end
129130

131+
# --------------------------------------------------------------------------
132+
# Near-field — external field reconstruction from a precomputed T-matrix.
133+
# `scattering_coefficients` is the per-incidence cost (the (p,q)=𝐓(a,b) apply);
134+
# `scattered_field` is the per-point cost that dominates a dense field grid, so
135+
# it is benchmarked with (p,q) precomputed (reused across points in practice).
136+
# --------------------------------------------------------------------------
137+
let g = SUITE["near_field"] = BenchmarkGroup(["nearfield"])
138+
pt = [4.0, 0.0, 3.0] # outside the spheroid's circumscribing sphere (r > 2)
139+
p, q = scattering_coefficients(T_REF, 0.0, 0.0, 1.0 + 0im, 0.0im)
140+
g["scattering_coefficients"] = @benchmarkable scattering_coefficients($T_REF, 0.0, 0.0,
141+
1.0 + 0im, 0.0im)
142+
g["scattered_field_point"] = @benchmarkable scattered_field($p, $q, $λ, $pt)
143+
g["total_field_point"] = @benchmarkable total_field($T_REF, $λ, 0.0, 0.0, 1.0 + 0im,
144+
0.0im, $pt)
145+
end
146+
130147
# --------------------------------------------------------------------------
131148
# Linearization — analytical EBCM Jacobian. This is the direct baseline for
132149
# the planned `inv(𝐐)` → `lu`/factorization-reuse optimization.

docs/make.jl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const NB_DIR = normpath(joinpath(@__DIR__, "..", "examples"))
1313
const NB_OUT = joinpath(@__DIR__, "src", "examples")
1414
const NOTEBOOKS = ["shapes_gallery.jl", "solver_landscape.jl",
1515
"angular_scattering.jl", "orientation_averaging.jl", "spectral_sensitivity.jl",
16-
"rain_radar.jl"]
16+
"rain_radar.jl", "near_field.jl"]
1717

1818
function notebook_title(nb)
1919
in_markdown = false
@@ -33,10 +33,8 @@ function notebook_title(nb)
3333
end
3434

3535
const NB_PAGE_PATHS = ["examples/" * replace(nb, ".jl" => ".md") for nb in NOTEBOOKS]
36-
const NB_PAGES = [
37-
notebook_title(nb) => path
38-
for (nb, path) in zip(NOTEBOOKS, NB_PAGE_PATHS)
39-
]
36+
const NB_PAGES = [notebook_title(nb) => path
37+
for (nb, path) in zip(NOTEBOOKS, NB_PAGE_PATHS)]
4038

4139
function build_examples()
4240
mkpath(NB_OUT)

docs/src/api.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ Pages = ["common/index.jl", "common/AbstractTransitionMatrix.jl",
5151
Filter = t -> !startswith(string(Base.nameof(t)), "_")
5252
```
5353

54+
## Near-field reconstruction
55+
56+
Vector spherical wave functions and the external electromagnetic field
57+
(incident, scattered, total) reconstructed from any transition matrix (see the
58+
[Near-field maps from a T-matrix](examples/near_field.md) example).
59+
60+
```@autodocs
61+
Modules = [TransitionMatrices]
62+
Pages = ["common/vswf.jl", "common/near_field.jl", "EBCM/near_field.jl"]
63+
Filter = t -> !startswith(string(Base.nameof(t)), "_")
64+
```
65+
5466
## Linearization
5567

5668
The differentiation framework and its backends (see

docs/src/examples/index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ directory of the repository.
2828
radiative-transfer prototype: spheroidal IITM T-matrices, a rain-drop
2929
axis-ratio model, water/ice refractive-index fits, and a drop-size distribution
3030
feeding dual-pol radar moments and brightness-temperature integrals.
31+
- [**Near-field maps from a T-matrix**](near_field.md) — reconstruct the external
32+
electromagnetic field (incident + scattered) from any T-matrix; a
33+
field-enhancement ``|E|/|E_0|`` map and axial cut around a Mie sphere, with the
34+
Rayleigh-hypothesis region-of-validity note.
3135

3236
## Running them locally
3337

docs/src/examples/near_field.md

Lines changed: 124 additions & 0 deletions
Large diffs are not rendered by default.

docs/src/usage.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,91 @@ angles ``\Theta``:
240240
𝐅 = scattering_matrix(𝐓, 2π, θs) # one matrix per angle
241241
```
242242

243+
## Near-field reconstruction
244+
245+
Beyond the far field, the **electromagnetic field around the particle** can be
246+
reconstructed from any T-matrix. For an incident plane wave the scattered field
247+
is expanded in radiating vector spherical wave functions with coefficients
248+
``(p, q) = \mathbf{T}\,(a, b)``, where ``(a, b)`` are the plane-wave coefficients;
249+
the total external field is ``\mathbf{E}_\text{inc} + \mathbf{E}_\text{sca}``.
250+
251+
The incident plane wave propagates along ``\hat{\mathbf n} = (\vartheta_\text{inc},
252+
\varphi_\text{inc})`` with a Jones polarization `(Eθ, Eφ)` in the spherical basis
253+
``(\hat{\boldsymbol\vartheta}, \hat{\boldsymbol\varphi})`` at that direction. Field
254+
points are Cartesian (any `AbstractVector` of length 3); the polar axis is `+z`.
255+
256+
```julia
257+
𝐓 = transition_matrix(spheroid, 2π)
258+
λ = 2π
259+
260+
# +z propagation, x-polarized (θ̂ at ϑ=0 is x̂):
261+
ϑ_inc, φ_inc, Eθ, Eφ = 0.0, 0.0, 1.0 + 0im, 0.0im
262+
r⃗ = [4.0, 0.0, 3.0] # a point outside the particle
263+
264+
E_inc = incident_field(λ, ϑ_inc, φ_inc, Eθ, Eφ, r⃗) # analytic plane wave
265+
E_sca = scattered_field(𝐓, λ, ϑ_inc, φ_inc, Eθ, Eφ, r⃗)
266+
E_tot = total_field(𝐓, λ, ϑ_inc, φ_inc, Eθ, Eφ, r⃗) # = E_inc + E_sca
267+
```
268+
269+
When evaluating a **dense grid** of field points, compute the scattered
270+
coefficients once and reuse them:
271+
272+
```julia
273+
p, q = scattering_coefficients(𝐓, ϑ_inc, φ_inc, Eθ, Eφ)
274+
field = [scattered_field(p, q, λ, [x, 0.0, z]) for z in zs, x in xs]
275+
```
276+
277+
The underlying VSWFs are available directly as [`vswf`](@ref) / [`vswf_cartesian`](@ref).
278+
279+
!!! warning "Region of validity"
280+
The radiating (scattered) expansion converges only **outside the smallest
281+
sphere circumscribing the particle** (the Rayleigh hypothesis). For a sphere
282+
that boundary is the surface; for a non-spherical particle, evaluate only
283+
outside its circumscribing sphere.
284+
285+
For the field **inside** a homogeneous sphere, [`internal_field`](@ref)
286+
reconstructs it from the analytic Mie internal coefficients (at the internal
287+
wavenumber ``k_\text{int} = m_r k``); it is continuous, tangentially, with the
288+
external [`total_field`](@ref) across the surface:
289+
290+
```julia
291+
x, mᵣ = 3.0, 1.5 + 0.05im # size parameter and index
292+
r⃗ = [0.3, 0.2, 0.5] # a point inside the sphere
293+
294+
E_in = internal_field(x, mᵣ, λ, ϑ_inc, φ_inc, Eθ, Eφ, r⃗)
295+
296+
# reuse the coefficients across a dense interior grid:
297+
c, d = internal_coefficients(x, mᵣ, ϑ_inc, φ_inc, Eθ, Eφ)
298+
E_in = internal_field(c, d, mᵣ, λ, r⃗)
299+
```
300+
301+
For a general **axisymmetric** particle the internal field is reconstructed from
302+
the EBCM matrices (``\mathbf{c} = \tfrac{1}{2}\mathbf{Q}^{-1}\mathbf{a}`` per
303+
azimuthal block), via the shape-based methods:
304+
305+
```julia
306+
spheroid = Spheroid(1.0, 2.0, 1.4 + 0.02im)
307+
E_in = internal_field(spheroid, λ, nmax, Ng, ϑ_inc, φ_inc, Eθ, Eφ, r⃗)
308+
# or, reused across a grid:
309+
c, d = internal_coefficients(spheroid, λ, nmax, Ng, ϑ_inc, φ_inc, Eθ, Eφ)
310+
E_in = internal_field(c, d, spheroid.m, λ, r⃗)
311+
```
312+
313+
!!! note "Region of validity and conditioning"
314+
The interior expansion is mathematically guaranteed within the inscribed sphere
315+
(radius `rmin(shape)`); empirically it stays stable and physical throughout the
316+
interior (it does **not** diverge past the inscribed sphere). The binding limit
317+
is instead EBCM ``\mathbf{Q}``-matrix conditioning at high aspect ratio with
318+
high `nmax` — since ``\mathbf{c} = \tfrac12\mathbf{Q}^{-1}\mathbf{a}`` inherits
319+
``\mathbf{Q}^{-1}``, the same Float64 cancellation that limits the T-matrix
320+
corrupts the coefficients everywhere — so keep `nmax`/aspect where the T-matrix
321+
is reliable. The convention is validated against Mie on the degenerate sphere
322+
(`Spheroid(R, R, mᵣ)`); absolute accuracy beyond the inscribed sphere for
323+
non-spherical shapes is not independently verified.
324+
325+
See the [Near-field maps from a T-matrix](examples/near_field.md) example for a
326+
field-enhancement map.
327+
243328
## Orientation averaging
244329

245330
For randomly oriented particles you usually want orientation-averaged

examples/near_field.jl

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
### A Pluto.jl notebook ###
2+
# v1.0.1
3+
4+
using Markdown
5+
using InteractiveUtils
6+
7+
# ╔═╡ 7a1f0001-0000-4000-8000-000000000001
8+
begin
9+
import Pkg
10+
Pkg.activate(@__DIR__) # the examples/ environment
11+
Pkg.develop(; path = dirname(@__DIR__)) # point TransitionMatrices at this repo
12+
Pkg.instantiate()
13+
using TransitionMatrices, Plots, LinearAlgebra
14+
end
15+
16+
# ╔═╡ 7a1f0002-0000-4000-8000-000000000002
17+
md"""
18+
# Near-field maps from a T-matrix
19+
20+
`TransitionMatrices.jl` reconstructs the electromagnetic field *around* a particle
21+
— not just the far-field cross sections — from any computed T-matrix. Given an
22+
incident plane wave, the scattered field is expanded in radiating vector spherical
23+
wave functions (VSWFs) with coefficients ``(p, q) = \mathbf{T}\,(a, b)``, where
24+
``(a, b)`` are the plane-wave expansion coefficients. The total external field is
25+
26+
```math
27+
\mathbf{E}_\text{tot}(\mathbf r) = \mathbf{E}_\text{inc}(\mathbf r) + \mathbf{E}_\text{sca}(\mathbf r),
28+
\qquad
29+
\mathbf{E}_\text{sca}(\mathbf r) = \sum_{n,m} p_{mn}\mathbf{M}_{mn}(k\mathbf r) + q_{mn}\mathbf{N}_{mn}(k\mathbf r).
30+
```
31+
32+
This works for **any** T-matrix (Mie, EBCM, IITM, Sh-matrix). Here we map the field
33+
enhancement ``|\mathbf{E}_\text{tot}|/|\mathbf{E}_\text{inc}|`` around a dielectric
34+
sphere.
35+
36+
!!! note "Region of validity"
37+
The radiating expansion converges only **outside the sphere circumscribing the
38+
particle** (the Rayleigh hypothesis). For a sphere that boundary *is* the
39+
surface, so the map is valid right down to it; for a non-spherical particle,
40+
evaluate only outside the circumscribing sphere.
41+
"""
42+
43+
# ╔═╡ 7a1f0003-0000-4000-8000-000000000003
44+
md"""
45+
## 1. A scatterer and its incidence
46+
47+
A dielectric sphere of size parameter ``x = k a = 2.5`` and refractive index
48+
``m_r = 1.5``, illuminated by an ``x``-polarized plane wave propagating along
49+
``+z``. With ``\lambda = 2\pi`` the size parameter equals the radius, so ``a = 2.5``.
50+
51+
The incidence direction is ``(\vartheta_\text{inc}, \varphi_\text{inc}) = (0, 0)``;
52+
the polarization ``(E_\vartheta, E_\varphi) = (1, 0)`` is ``\hat{\mathbf x}`` because
53+
``\hat{\boldsymbol\vartheta}(0,0) = \hat{\mathbf x}``.
54+
"""
55+
56+
# ╔═╡ 7a1f0004-0000-4000-8000-000000000004
57+
begin
58+
λ = 2π
59+
k = 2π / λ
60+
a = 2.5
61+
mᵣ = 1.5 + 0.0im
62+
x = k * a
63+
N = ceil(Int, x + 4 * cbrt(x) + 2)
64+
𝐓 = TransitionMatrices.MieTransitionMatrix{ComplexF64, N}(x, mᵣ)
65+
66+
# Incident plane wave: +z propagation, x-polarized.
67+
ϑ_inc, φ_inc = 0.0, 0.0
68+
Eθ, Eφ = 1.0 + 0im, 0.0im
69+
70+
# The scattered coefficients (p, q) = 𝐓 (a, b) depend only on the incidence,
71+
# so compute them once and reuse them at every field point.
72+
p, q = scattering_coefficients(𝐓, ϑ_inc, φ_inc, Eθ, Eφ)
73+
nothing
74+
end
75+
76+
# ╔═╡ 7a1f0005-0000-4000-8000-000000000005
77+
md"""
78+
## 2. Sample the total field on a grid
79+
80+
We evaluate ``|\mathbf{E}_\text{tot}|`` in the ``x``–``z`` plane (the plane of
81+
incidence and polarization). Points inside the sphere are masked — the external
82+
expansion is not meant to represent the interior field (that is the *internal*
83+
field, a separate reconstruction).
84+
"""
85+
86+
# ╔═╡ 7a1f0006-0000-4000-8000-000000000006
87+
begin
88+
xs = range(-3a, 3a; length = 161)
89+
zs = range(-3a, 3a; length = 161)
90+
enhancement = fill(NaN, length(zs), length(xs))
91+
for (i, zz) in enumerate(zs), (j, xx) in enumerate(xs)
92+
93+
r = hypot(xx, zz)
94+
r a && continue # inside the sphere: masked
95+
pos = [xx, 0.0, zz]
96+
E_inc = incident_field(λ, ϑ_inc, φ_inc, Eθ, Eφ, pos)
97+
E = E_inc + scattered_field(p, q, λ, pos)
98+
enhancement[i, j] = norm(E) / norm(E_inc)
99+
end
100+
nothing
101+
end
102+
103+
# ╔═╡ 7a1f0007-0000-4000-8000-000000000007
104+
md"""
105+
## 3. The field-enhancement map
106+
107+
The incident wave travels upward (``+z``). The map shows the standing-wave
108+
interference of the incident and scattered fields, the forward-scattering
109+
concentration on the far (``+z``) side, and the shadow on the near side.
110+
"""
111+
112+
# ╔═╡ 7a1f0008-0000-4000-8000-000000000008
113+
let
114+
hm = heatmap(xs, zs, enhancement;
115+
aspect_ratio = 1, c = :inferno, clims = (0, maximum(filter(isfinite, enhancement))),
116+
xlabel = "x", ylabel = "z", colorbar_title = "|E| / |E₀|",
117+
title = "dielectric sphere, x = $(round(x; digits = 2)), mᵣ = 1.5",
118+
size = (640, 560))
119+
# outline the sphere
120+
θ = range(0, 2π; length = 200)
121+
plot!(hm, a .* cos.(θ), a .* sin.(θ); label = "", lw = 1.5, lc = :cyan)
122+
end
123+
124+
# ╔═╡ 7a1f0009-0000-4000-8000-000000000009
125+
md"""
126+
## 4. A line cut along the optical axis
127+
128+
Along ``x = 0`` the field shows the shadow/illumination asymmetry and the
129+
forward enhancement directly.
130+
"""
131+
132+
# ╔═╡ 7a1f000a-0000-4000-8000-00000000000a
133+
let
134+
zline = range(-3a, 3a; length = 400)
135+
amp = map(zline) do zz
136+
abs(zz) a && return NaN
137+
pos = [0.0, 0.0, zz]
138+
E_inc = incident_field(λ, ϑ_inc, φ_inc, Eθ, Eφ, pos)
139+
E = E_inc + scattered_field(p, q, λ, pos)
140+
norm(E) / norm(E_inc)
141+
end
142+
plot(zline, amp; lw = 2, xlabel = "z (optical axis)", ylabel = "|E| / |E₀|",
143+
label = "", title = "axial cut (x = y = 0)", size = (720, 320))
144+
vspan!([-a, a]; alpha = 0.15, c = :gray, label = "sphere")
145+
end
146+
147+
# ╔═╡ 7a1f000b-0000-4000-8000-00000000000b
148+
md"""
149+
## Takeaway
150+
151+
`scattering_coefficients` once, then `scattered_field` / `total_field` at any point
152+
gives the full external field for any T-matrix — sphere, spheroid, cylinder,
153+
Chebyshev, or a general particle. Reusing the precomputed `(p, q)` keeps a dense
154+
field grid cheap.
155+
156+
For the field **inside** the particle, use `internal_field`, which reconstructs
157+
the regular internal solution from `internal_coefficients`. Those coefficients
158+
are the VSWF expansion amplitudes for the field inside the particle; compute them
159+
once and reuse them just like `(p, q)`:
160+
161+
```julia
162+
c, d = internal_coefficients(x, mᵣ, ϑ_inc, φ_inc, Eθ, Eφ; nmax = N)
163+
E_inside = internal_field(c, d, mᵣ, λ, [0.2a, 0.0, 0.0])
164+
```
165+
166+
The Tier-2 implementations live in `src/common/near_field.jl` for homogeneous
167+
spheres and `src/EBCM/near_field.jl` for axisymmetric particles.
168+
"""
169+
170+
# ╔═╡ Cell order:
171+
# ╟─7a1f0002-0000-4000-8000-000000000002
172+
# ╠═7a1f0001-0000-4000-8000-000000000001
173+
# ╟─7a1f0003-0000-4000-8000-000000000003
174+
# ╠═7a1f0004-0000-4000-8000-000000000004
175+
# ╟─7a1f0005-0000-4000-8000-000000000005
176+
# ╠═7a1f0006-0000-4000-8000-000000000006
177+
# ╟─7a1f0007-0000-4000-8000-000000000007
178+
# ╠═7a1f0008-0000-4000-8000-000000000008
179+
# ╟─7a1f0009-0000-4000-8000-000000000009
180+
# ╠═7a1f000a-0000-4000-8000-00000000000a
181+
# ╟─7a1f000b-0000-4000-8000-00000000000b

examples/orientation_averaging.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ begin
5858
(; method = "analytic (Mishchenko)", Qsca = calc_Csca(Tanalytic, λ),
5959
Qext = calc_Cext(Tanalytic, λ), g = asymmetry_parameter(Tanalytic, λ)),
6060
(; method = "numerical (20³ grid)", Qsca = calc_Csca(Tnumeric, λ),
61-
Qext = calc_Cext(Tnumeric, λ), g = asymmetry_parameter(Tnumeric, λ)),
61+
Qext = calc_Cext(Tnumeric, λ), g = asymmetry_parameter(Tnumeric, λ))
6262
]
6363
end
6464

@@ -74,7 +74,8 @@ the analytic closed form gives it directly, at a fraction of the cost.
7474
begin
7575
Qref = calc_Csca(Tanalytic, λ)
7676
Ns = 4:2:18
77-
errs = [abs(calc_Csca(orientation_average(T, uniform; Nα = 2, Nβ = N, Nγ = 2), λ) - Qref) / Qref
77+
errs = [abs(calc_Csca(orientation_average(T, uniform; Nα = 2, Nβ = N, Nγ = 2), λ) -
78+
Qref) / Qref
7879
for N in Ns]
7980
nothing
8081
end

examples/radiative_transfer/generate_fake_wrf.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ function synthetic_fields(nx, ny, nz, nt)
7777

7878
for t in 1:nt
7979
for j in 1:ny, i in 1:nx
80+
8081
xlat[i, j, t] = 34.0f0 + 0.04f0 * Float32(j - 1)
8182
xlon[i, j, t] = -98.0f0 + 0.04f0 * Float32(i - 1)
8283
end

0 commit comments

Comments
 (0)