Skip to content

Add super-spheroid / super-ellipsoid shapes (Bi & Lin dust models)#13

Merged
lucifer1004 merged 1 commit into
mainfrom
superellipsoid-shapes
Jun 7, 2026
Merged

Add super-spheroid / super-ellipsoid shapes (Bi & Lin dust models)#13
lucifer1004 merged 1 commit into
mainfrom
superellipsoid-shapes

Conversation

@lucifer1004

@lucifer1004 lucifer1004 commented Jun 7, 2026

Copy link
Copy Markdown
Member

Three new shapes for the Bi Lei group's superquadric dust-aerosol family, with the parameterization verified against Lin & Bi 2018 (JGR, 10.1029/2018JD029464) and Bi et al. 2018 (Opt. Express, 10.1364/OE.26.001726):

  • SuperSpheroid <: AbstractNFoldShape{4} — |x/a|^(2/n)+|y/a|^(2/n)+|z/c|^(2/n)=1, super-circular cross-sections (D4h, 4-fold; NOT axisymmetric), solved via the n-fold IITM. n=1 spheroid, n=2 octahedron, n>2 concave (dust best-fit n∈[2.4,3.0]).
  • SuperEllipsoid <: AbstractNFoldShape{2} — full triaxial super-ellipsoid with the two roundness exponents (e east-west, n north-south), D2h, via the n-fold IITM.
  • SuperSpheroidRevolved <: AbstractAxisymmetricShape — the true surface of revolution (ϱ/a)^(2/n)+(z/c)^(2/n)=1, so it flows into EBCM / Sh-matrix / near-field; n=1 reduces exactly to Spheroid.

Each implements the shape interface (∈, refractive_index, volume/volume_equivalent_radius via the superquadric beta-function formula, rmax, rmin, has_symmetric_plane, and gaussquad for the axisymmetric one), is registered in src/shapes/index.jl, and exported.

The volume's beta function is evaluated in Arb at each value's own precision and converted straight back to the shape's real type (the T(Arblib…(Arb(…); prec)) idiom from special_functions/factorial.jl) — no BigFloat detour — so Float64 / Double64 / Float128 / BigFloat / Arb shapes all keep full precision (Float128 uses the type-level precision(Float128) since the instance method is unimplemented upstream).

Validation: volume formulas confirmed by independent 3D Monte-Carlo (rel ~3e-4) and a per-type precision regression test; degenerate reductions exact (n=1 SuperSpheroidRevolved == Spheroid via EBCM and Sh to ~1e-8; e=n=1 SuperEllipsoid and n=1 SuperSpheroid reduce to the ellipsoid/spheroid IITM); n=2 octahedron volume; full suite 48,229 tests pass.

Summary by CodeRabbit

  • New Features
    • Added three new shapes: SuperSpheroid, SuperEllipsoid, and an axisymmetric SuperSpheroidRevolved.
    • Each shape supports analytic volume, equivalent-radius, geometric bounds, point-membership checks, and refractive-index behavior.
  • Tests
    • Extensive validation covering volumes, geometry predicates, numerical comparisons, and consistency with spheroid cases.

@coderabbitai

coderabbitai Bot commented Jun 7, 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: 8219c09e-e37a-4f51-b634-9cf6d42614b9

📥 Commits

Reviewing files that changed from the base of the PR and between 3edc602 and fba787b.

📒 Files selected for processing (5)
  • src/TransitionMatrices.jl
  • src/shapes/index.jl
  • src/shapes/superellipsoid.jl
  • src/shapes/superspheroid.jl
  • src/shapes/superspheroidrevolved.jl
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/TransitionMatrices.jl
  • src/shapes/superspheroidrevolved.jl
  • src/shapes/index.jl

📝 Walkthrough

Walkthrough

Three new superquadric shape types are added to the library: SuperEllipsoid (3-axis symmetric), SuperSpheroid (4-fold symmetric), and SuperSpheroidRevolved (axisymmetric). Each implements volume calculations, geometric bounds, membership tests, and validates scattering agreement with existing shape implementations.

Changes

Superquadric Shape Implementations

Layer / File(s) Summary
Module exports and includes
src/TransitionMatrices.jl, src/shapes/index.jl
Export list and module includes updated to register three new shape types and their implementation files.
SuperEllipsoid: 3-axis super-ellipsoid
src/shapes/superellipsoid.jl
Type SuperEllipsoid{T,CT} with (a,b,c,e,n,m), analytic volume via beta functions, volume_equivalent_radius, has_symmetric_plane, rmax/rmin (grid-based rmin), Base.:∈ membership, refractive_index, and tests including analytic checks, Monte-Carlo validation, and IITM/EBCM regression for spheroid reduction.
SuperSpheroid: 4-fold super-spheroid
src/shapes/superspheroid.jl
Type SuperSpheroid{T,CT} with (a,c,n,m), precision-aware _beta_lgamma, analytic volume, volume_equivalent_radius, has_symmetric_plane, rmax/rmin, Base.:∈, refractive_index, and tests covering reductions, precision preservation, Monte-Carlo volume checks, and IITM/EBCM agreement at n=1.
SuperSpheroidRevolved: axisymmetric revolved super-spheroid
src/shapes/superspheroidrevolved.jl
Type SuperSpheroidRevolved{T,CT} with (a,c,n,m), analytic volume, volume_equivalent_radius, has_symmetric_plane, gaussquad computing Gauss–Legendre nodes and r(ϑ)/r'(ϑ) with pole handling, numerical rmax/rmin over ϑ∈[0,π/2], Base.:∈, refractive_index, and tests including analytic vs numeric volume, gaussquad consistency with Spheroid, derivative sign checks, and EBCM regression at n=1.

Sequence Diagram(s)

No sequence diagrams generated.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

"🐰 New shapes spin from beta's bow,
Super curves in code do grow;
Gauss nodes hum and volumes sing,
Tests agree — the T-matrix ring.
Hop, review, and let the rabbits know."

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding three new shape types (super-spheroid and super-ellipsoid) that implement the Bi & Lin dust models.
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 superellipsoid-shapes

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

@codecov

codecov Bot commented Jun 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.00000% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.89%. Comparing base (ab67608) to head (fba787b).

Files with missing lines Patch % Lines
src/shapes/superspheroidrevolved.jl 95.00% 4 Missing ⚠️
src/shapes/superspheroid.jl 96.20% 3 Missing ⚠️
src/shapes/superellipsoid.jl 96.96% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #13      +/-   ##
==========================================
+ Coverage   95.78%   95.89%   +0.11%     
==========================================
  Files          35       38       +3     
  Lines        4726     4951     +225     
==========================================
+ Hits         4527     4748     +221     
- Misses        199      203       +4     
Flag Coverage Δ
julia-1-macos-latest 97.08% <97.19%> (+0.07%) ⬆️
julia-1-ubuntu-latest 97.08% <97.19%> (+0.07%) ⬆️
julia-1-windows-latest 97.08% <97.19%> (+0.07%) ⬆️
julia-1.10-ubuntu-latest 95.83% <95.98%> (+0.11%) ⬆️
julia-nightly-ubuntu-latest 97.02% <97.20%> (+0.07%) ⬆️

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

🤖 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 `@src/shapes/superellipsoid.jl`:
- Around line 130-135: The current rmin(SuperEllipsoid) returns min(a,b,c) which
is not a conservative inner radius for e,n>1; change rmin to compute a
conservative lower bound using the tighter formula mentioned in the comment:
return min(s.a, s.b, s.c) * 2.0^(- (max(s.e, s.n) - 1) / 2), and ensure you
handle edge cases (e or n <= 1) by falling back to min(a,b,c) or clamping the
exponent so the result remains safe; update the function rmin and reference
fields a, b, c, e, n of SuperEllipsoid accordingly.

In `@src/shapes/superspheroid.jl`:
- Around line 158-165: rmin currently only considers the equatorial diagonal and
polar radius; add the true 3D diagonal check by computing the radius along the
(1,1,1) direction and taking the minimum of a_diag, s.c, and that diagonal. In
function rmin(s::SuperSpheroid) (variables n, a_diag, s.c), compute u =
(1,1,1)/√3 and r_diag = ( (abs(u[1])/s.a)^n + (abs(u[2])/s.a)^n +
(abs(u[3])/s.c)^n )^(-1/n ) (use Float64(s.n) for n), then return min(a_diag,
s.c, r_diag).

In `@src/shapes/superspheroidrevolved.jl`:
- Around line 208-222: The current _superspheroidrevolved_rmax_rmin samples r(ϑ)
at 1001 fixed angles and can miss interior extrema; replace the crude sampling
with a robust 1D optimization of the scalar function r(ϑ) = (sin(ϑ)^p/ap +
cos(ϑ)^p/cp)^(-s.n/2) on ϑ ∈ [0, π/2] (where p = 2/s.n, ap = s.a^p, cp = s.c^p)
to find true global maximum and minimum (e.g. use a reliable bracketing/Brent
method or multiple-start golden-section searches) and fall back to endpoint
values only if the optimizer fails; update _superspheroidrevolved_rmax_rmin to
call that optimizer instead of returning maxima/minima of the fixed rvals array.
🪄 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: eb607ce1-d49a-4f78-9977-30ca4ff5f21d

📥 Commits

Reviewing files that changed from the base of the PR and between ab67608 and 3edc602.

📒 Files selected for processing (5)
  • src/TransitionMatrices.jl
  • src/shapes/index.jl
  • src/shapes/superellipsoid.jl
  • src/shapes/superspheroid.jl
  • src/shapes/superspheroidrevolved.jl

Comment thread src/shapes/superellipsoid.jl
Comment thread src/shapes/superspheroid.jl
Comment on lines +208 to +222
function _superspheroidrevolved_rmax_rmin(s::SuperSpheroidRevolved)
p = 2 / s.n
ap = s.a^p
cp = s.c^p
# Sample r over ϑ ∈ [0, π/2] (symmetric about equator and pole)
N = 1000
rvals = [begin
ϑ = i * π / 2 / N
sinϑ = sin(ϑ)
cosϑ = cos(ϑ)
g = sinϑ^p / ap + cosϑ^p / cp
g^(-s.n / 2)
end
for i in 0:N]
return maximum(rvals), minimum(rvals)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Sampled extrema do not satisfy the rmax/rmin contract.

This helper only evaluates 1001 angles, so it can return rmax too small or rmin too large by missing an interior extremum. That is exactly the regime this code is trying to handle for concave shapes, so the discretization defeats the special-case logic.

🤖 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 `@src/shapes/superspheroidrevolved.jl` around lines 208 - 222, The current
_superspheroidrevolved_rmax_rmin samples r(ϑ) at 1001 fixed angles and can miss
interior extrema; replace the crude sampling with a robust 1D optimization of
the scalar function r(ϑ) = (sin(ϑ)^p/ap + cos(ϑ)^p/cp)^(-s.n/2) on ϑ ∈ [0, π/2]
(where p = 2/s.n, ap = s.a^p, cp = s.c^p) to find true global maximum and
minimum (e.g. use a reliable bracketing/Brent method or multiple-start
golden-section searches) and fall back to endpoint values only if the optimizer
fails; update _superspheroidrevolved_rmax_rmin to call that optimizer instead of
returning maxima/minima of the fixed rvals array.

Three new shapes for the Bi Lei group's superquadric dust-aerosol family, with the
parameterization verified against Lin & Bi 2018 (JGR, 10.1029/2018JD029464) and
Bi et al. 2018 (Opt. Express, 10.1364/OE.26.001726):

- `SuperSpheroid <: AbstractNFoldShape{4}` — |x/a|^(2/n)+|y/a|^(2/n)+|z/c|^(2/n)=1,
  super-circular cross-sections (D4h, 4-fold; NOT axisymmetric), solved via the n-fold
  IITM. n=1 spheroid, n=2 octahedron, n>2 concave (dust best-fit n∈[2.4,3.0]).
- `SuperEllipsoid <: AbstractNFoldShape{2}` — full triaxial super-ellipsoid with the two
  roundness exponents (e east-west, n north-south), D2h, via the n-fold IITM.
- `SuperSpheroidRevolved <: AbstractAxisymmetricShape` — the true surface of revolution
  (ϱ/a)^(2/n)+(z/c)^(2/n)=1, so it flows into EBCM / Sh-matrix / near-field; n=1 reduces
  exactly to `Spheroid`.

Each implements the shape interface (∈, refractive_index, volume/volume_equivalent_radius
via the superquadric beta-function formula, rmax, rmin, has_symmetric_plane, and gaussquad
for the axisymmetric one), is registered in src/shapes/index.jl, and exported.

The volume's beta function is evaluated in Arb at each value's own precision and converted
straight back to the shape's real type (the `T(Arblib…(Arb(…); prec))` idiom from
special_functions/factorial.jl) — no BigFloat detour — so Float64 / Double64 / Float128 /
BigFloat / Arb shapes all keep full precision (Float128 uses the type-level
`precision(Float128)` since the instance method is unimplemented upstream).

Validation: volume formulas confirmed by independent 3D Monte-Carlo (rel ~3e-4) and a
per-type precision regression test; degenerate reductions exact (n=1 SuperSpheroidRevolved
== Spheroid via EBCM and Sh to ~1e-8; e=n=1 SuperEllipsoid and n=1 SuperSpheroid reduce to
the ellipsoid/spheroid IITM); n=2 octahedron volume; full suite 48,229 tests pass.
@lucifer1004 lucifer1004 force-pushed the superellipsoid-shapes branch from 3edc602 to fba787b Compare June 7, 2026 10:33
@lucifer1004 lucifer1004 merged commit 7e23c0c into main Jun 7, 2026
12 checks passed
@lucifer1004 lucifer1004 deleted the superellipsoid-shapes branch June 7, 2026 11:21
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