Skip to content

Near field - #11

Merged
lucifer1004 merged 7 commits into
mainfrom
near-field
Jun 6, 2026
Merged

Near field#11
lucifer1004 merged 7 commits into
mainfrom
near-field

Conversation

@lucifer1004

@lucifer1004 lucifer1004 commented Jun 6, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Near-field reconstruction: compute incident, scattered, total fields and internal fields from transition matrices for field mapping and analysis.
  • Documentation

    • Comprehensive near-field guide added, including theory, usage notes, and validity/conditioning guidance.
  • Examples

    • Interactive notebook demonstrating near-field visualization, enhancement heatmaps, and axial cuts.
  • Benchmarks & Tests

    • New near-field benchmark group and validation tests ensuring accuracy and continuity.

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.
- 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.
- 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).
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.
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.
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.
@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8c09494f-cdf8-4de9-b7ca-ccc734647f02

📥 Commits

Reviewing files that changed from the base of the PR and between ef48d89 and 3b1fc65.

📒 Files selected for processing (12)
  • docs/make.jl
  • examples/near_field.jl
  • examples/orientation_averaging.jl
  • examples/radiative_transfer/generate_fake_wrf.jl
  • examples/radiative_transfer/wrf_dualpol_radar.jl
  • examples/rain_radar.jl
  • examples/shapes_gallery.jl
  • examples/solver_landscape.jl
  • examples/spectral_sensitivity.jl
  • src/EBCM/near_field.jl
  • src/common/near_field.jl
  • src/common/vswf.jl
✅ Files skipped from review due to trivial changes (7)
  • examples/radiative_transfer/wrf_dualpol_radar.jl
  • examples/spectral_sensitivity.jl
  • examples/radiative_transfer/generate_fake_wrf.jl
  • examples/solver_landscape.jl
  • examples/shapes_gallery.jl
  • examples/rain_radar.jl
  • examples/orientation_averaging.jl
🚧 Files skipped from review as they are similar to previous changes (4)
  • docs/make.jl
  • examples/near_field.jl
  • src/EBCM/near_field.jl
  • src/common/near_field.jl

📝 Walkthrough

Walkthrough

Adds VSWF implementations and near-field reconstruction APIs: external scattered/total-field reconstruction from T-matrices, analytic Mie internal coefficients, EBCM interior solves for axisymmetric shapes, tests, docs, a Pluto example, and benchmark group additions.

Changes

Near-field Electromagnetic Field Reconstruction

Layer / File(s) Summary
Vector spherical wave functions foundation
src/common/vswf.jl
Implements vswf/vswf_cartesian, regular-origin handling, radial-factor generators for regular/outgoing kinds, spherical unit-vector helpers, and tests verifying curl identities and origin limits.
External field reconstruction and scattering
src/common/near_field.jl
Adds plane-wave expansion (a,b), scattering_coefficients(𝐓,...)(p,q), _field_from_coeffs, scattered_field, incident_field, and total_field APIs; includes far-zone and reconstruction tests.
Analytic Mie internal coefficients & interior reconstruction
src/common/near_field.jl
Implements per-order Mie internal (cₙ,dₙ) and assembles full internal (c,d) arrays; provides internal_field reconstruction from regular VSWFs and tests for boundary continuity and Rayleigh-limit convergence.
EBCM-based interior field for axisymmetric particles
src/EBCM/near_field.jl
Adds internal_coefficients(shape, ...) performing per-m EBCM solves (Q = P + iU), applies ±m symmetry via diagonal sign-flip, assembles OffsetArray (c,d), and adds internal_field(shape,...) overload with regression tests (sphere vs Mie and non-spherical consistency).
Module integration and exports
src/common/index.jl, src/EBCM/index.jl, src/TransitionMatrices.jl
Includes new modules and exposes vswf, vswf_cartesian, scattering_coefficients, incident_field, scattered_field, total_field, internal_coefficients, internal_field from the main package exports.
Benchmark suite
benchmark/benchmarks.jl
Adds SUITE["near_field"] group benchmarking scattering_coefficients precompute, pointwise scattered_field, and total_field evaluations using shared T_REF.
Documentation and example notebook
docs/src/api.md, docs/src/usage.md, docs/src/examples/index.md, examples/near_field.jl, docs/make.jl
Adds API/autodocs and usage sections for near-field reconstruction, registers the Pluto notebook for docs builds, and provides examples/near_field.jl demonstrating precompute-and-reuse workflow with a 2D enhancement heatmap and 1D axial cut.
Examples & formatting edits (misc)
examples/*, small scripts
Non-functional formatting, reflow, and cell-order edits across multiple example notebooks and scripts.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

A rabbit hops through spherical waves,
Precomputes coefficients in tidy saves—
From T-matrices the fields unfurl,
Heatmaps glow and axials swirl. 🐰✨
Inside, EBCM quietly peeks, revealing hidden pearls.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Near field' is vague and generic, using a non-descriptive term that lacks context about what was added or changed. Use a more specific title that describes the main contribution, such as 'Add near-field electromagnetic field reconstruction' or 'Implement near-field VSWF-based field evaluation'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch near-field

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Jun 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.83282% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.78%. Comparing base (2dd434c) to head (3b1fc65).

Files with missing lines Patch % Lines
src/common/near_field.jl 97.29% 5 Missing ⚠️
src/EBCM/near_field.jl 97.72% 1 Missing ⚠️
src/common/vswf.jl 98.93% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #11      +/-   ##
==========================================
+ Coverage   95.63%   95.78%   +0.14%     
==========================================
  Files          32       35       +3     
  Lines        4403     4726     +323     
==========================================
+ Hits         4211     4527     +316     
- Misses        192      199       +7     
Flag Coverage Δ
julia-1-macos-latest 97.00% <98.10%> (+0.08%) ⬆️
julia-1-ubuntu-latest 97.00% <98.10%> (+0.08%) ⬆️
julia-1-windows-latest 97.00% <98.10%> (+0.08%) ⬆️
julia-1.10-ubuntu-latest 95.71% <97.81%> (+0.15%) ⬆️
julia-nightly-ubuntu-latest 96.94% <97.49%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
examples/near_field.jl (1)

154-155: ⚡ Quick win

Remove or resolve the user-facing TODO before publishing the notebook.

The rendered docs currently expose a placeholder (TODO, Tier 2), which looks unfinished.

I can draft a concise replacement paragraph referencing internal_field / internal_coefficients if you want.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/near_field.jl` around lines 154 - 155, Replace the user-facing
"TODO" placeholder with a concise explanatory paragraph describing the
internal-field reconstruction: mention that internal_field is the function that
reconstructs the field inside the particle using the computed
internal_coefficients (stored by the solver), briefly state what
internal_coefficients represent (expansion coefficients for the internal
solution), and include a short usage example or pointer to the Tier-2
internal-field reconstruction implementation; remove the literal "TODO" text so
the notebook no longer exposes an unfinished placeholder.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/near_field.jl`:
- Around line 95-98: The code currently sets enhancement[i,j] to the magnitude
of the total field E computed from incident_field(λ, ϑ_inc, φ_inc, Eθ, Eφ, pos)
+ scattered_field(p, q, λ, pos), which only equals |E|/|E₀| when the incident
polarization amplitude is (Eθ=1,Eφ=0); instead compute the incident field vector
separately (call incident_field(...) → E_inc) at the same pos and normalize the
enhancement by dividing the total-field magnitude by the incident-field
magnitude (enhancement = norm(E)/norm(E_inc)), updating both occurrences that
assign enhancement so the plotted quantity is an explicit enhancement ratio
independent of Eθ/Eφ amplitudes.

In `@src/common/near_field.jl`:
- Around line 99-123: _field_from_coeffs currently divides by r and x (zn/x,
z/r) and thus produces NaNs when r⃗ == [0,0,0]; add a dedicated small-r branch
at the top of _field_from_coeffs (detect x == 0 or abs(x) < eps(T)) that
computes the regular limiting values instead of performing zn ./ x or similar
divisions. In that branch, avoid computing r̂ from _sph_unit_vectors (or set r̂
to zero) and use the small-x/regular-series results from _vswf_radial (or its
analytic small-x expansion) to build 𝐅 and 𝐆 with znx and dzn replaced by
their finite limits; ensure internal_field overloads that call
_field_from_coeffs (the public sphere-internal paths mentioned) continue to call
this function so they inherit the fixed behavior. Ensure no divides-by-zero
remain and add a small test for internal_field(..., [0,0,0]) to assert finite
values.

In `@src/common/vswf.jl`:
- Around line 82-91: The regular VSWF branch is falling through to the
spherical-coordinate formula and dividing by x (k*r), producing NaNs at the
Cartesian origin; modify vswf to check for kind==:regular and r==0 (or x==0)
immediately after x is computed and before using zn, dzn, or zn_over_x, and
return the analytic finite regular-basis limit there (instead of computing
zn/x). Use the same special-case approach for the other places noted (lines
around 119–125) so vswf(:regular, ..., r==0) and vswf_cartesian(:regular, ...,
[0,0,0]) return the proper finite values; refer to vswf, _vswf_radial, zn, dzn,
zn_over_x, kind, r, and x to locate and implement the branch.

---

Nitpick comments:
In `@examples/near_field.jl`:
- Around line 154-155: Replace the user-facing "TODO" placeholder with a concise
explanatory paragraph describing the internal-field reconstruction: mention that
internal_field is the function that reconstructs the field inside the particle
using the computed internal_coefficients (stored by the solver), briefly state
what internal_coefficients represent (expansion coefficients for the internal
solution), and include a short usage example or pointer to the Tier-2
internal-field reconstruction implementation; remove the literal "TODO" text so
the notebook no longer exposes an unfinished placeholder.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d113e5f0-f2c7-4e37-8e9b-13ef2a9480e9

📥 Commits

Reviewing files that changed from the base of the PR and between 2dd434c and ef48d89.

📒 Files selected for processing (13)
  • benchmark/benchmarks.jl
  • docs/make.jl
  • docs/src/api.md
  • docs/src/examples/index.md
  • docs/src/examples/near_field.md
  • docs/src/usage.md
  • examples/near_field.jl
  • src/EBCM/index.jl
  • src/EBCM/near_field.jl
  • src/TransitionMatrices.jl
  • src/common/index.jl
  • src/common/near_field.jl
  • src/common/vswf.jl

Comment thread examples/near_field.jl Outdated
Comment thread src/common/near_field.jl
Comment thread src/common/vswf.jl
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.
@lucifer1004
lucifer1004 merged commit ab67608 into main Jun 6, 2026
12 checks passed
@lucifer1004
lucifer1004 deleted the near-field branch June 6, 2026 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant