Skip to content

Commit fa3c1f1

Browse files
committed
Add angularmomentum
1 parent 69adcc3 commit fa3c1f1

File tree

3 files changed

+44
-13
lines changed

3 files changed

+44
-13
lines changed

src/HarmonicOrthogonalPolynomials.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import Base: OneTo, oneto, axes, getindex, convert, to_indices, tail, eltype, *,
55
import BlockArrays: block, blockindex, unblock, BlockSlice
66
import DomainSets: indomain, Sphere
77
import LinearAlgebra: norm, factorize
8-
import QuasiArrays: to_quasi_index, SubQuasiArray, *
9-
import ContinuumArrays: TransformFactorization, @simplify, ProjectionFactorization, plan_grid_transform, plan_transform, grid, grid_layout, plotgrid_layout, AbstractBasisLayout, MemoryLayout, abslaplacian, laplacian
8+
import QuasiArrays: to_quasi_index, SubQuasiArray, *, AbstractQuasiVecOrMat
9+
import ContinuumArrays: TransformFactorization, @simplify, ProjectionFactorization, plan_grid_transform, plan_transform, grid, grid_layout, plotgrid_layout,
10+
AbstractBasisLayout, MemoryLayout, abslaplacian, laplacian, AbstractDifferentialQuasiMatrix, operatorcall, similaroperator, SubBasisLayout,
11+
ApplyLayout, arguments, ExpansionLayout
1012
import ClassicalOrthogonalPolynomials: checkpoints, _sum, cardinality, increasingtruncations
1113
import BlockBandedMatrices: BlockRange1, _BandedBlockBandedMatrix
1214
import FastTransforms: Plan, interlace

src/angularmomentum.jl

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,50 @@ Applies the partial derivative with respect to the last angular variable in the
55
For example, in polar coordinates (r, θ) in ℝ² or cylindrical coordinates (r, θ, z) in ℝ³, we apply ∂ / ∂θ = (x ∂ / ∂y - y ∂ / ∂x).
66
In spherical coordinates (ρ, θ, φ) in ℝ³, we apply ∂ / ∂φ = (x ∂ / ∂y - y ∂ / ∂x).
77
"""
8-
struct AngularMomentum{T,Ax<:Inclusion} <: LazyQuasiMatrix{T}
8+
struct AngularMomentum{T,Ax<:Inclusion,Order} <: AbstractDifferentialQuasiMatrix{T}
99
axis::Ax
10+
order::Order
1011
end
1112

12-
AngularMomentum{T}(axis::Inclusion) where T = AngularMomentum{T,typeof(axis)}(axis)
13-
AngularMomentum{T}(domain) where T = AngularMomentum{T}(Inclusion(domain))
14-
AngularMomentum(axis) = AngularMomentum{eltype(eltype(axis))}(axis)
13+
AngularMomentum{T, D}(axis::D, order) where {T,D<:Inclusion} = AngularMomentum{T,D,typeof(order)}(axis, order)
14+
AngularMomentum{T, D}(axis::D) where {T,D<:Inclusion} = AngularMomentum{T,D,Nothing}(axis, nothing)
15+
AngularMomentum{T}(axis::Inclusion, order...) where T = AngularMomentum{T,typeof(axis)}(axis, order...)
16+
AngularMomentum{T}(domain, order...) where T = AngularMomentum{T}(Inclusion(domain), order...)
17+
AngularMomentum(domain, order...) = AngularMomentum(Inclusion(domain), order...)
18+
AngularMomentum(ax::AbstractQuasiVector{T}, order...) where T = AngularMomentum{eltype(eltype(ax))}(ax, order...)
19+
AngularMomentum(L::AbstractQuasiMatrix, order...) = AngularMomentum(axes(L,1), order...)
1520

16-
axes(A::AngularMomentum) = (A.axis, A.axis)
17-
==(a::AngularMomentum, b::AngularMomentum) = a.axis == b.axis
18-
copy(A::AngularMomentum) = AngularMomentum(copy(A.axis))
1921

20-
^(A::AngularMomentum, k::Integer) = ApplyQuasiArray(^, A, k)
22+
operatorcall(::AngularMomentum) = angularmomentum
23+
similaroperator(D::AngularMomentum, ax, ord) = AngularMomentum{eltype(D)}(ax, ord)
2124

22-
@simplify function *(A::AngularMomentum, P::SphericalHarmonic)
25+
simplifiable(::typeof(*), A::AngularMomentum, B::AngularMomentum) = Val(true)
26+
*(D1::AngularMomentum, D2::AngularMomentum) = similaroperator(convert(AbstractQuasiMatrix{promote_type(eltype(D1),eltype(D2))}, D1), D1.axis, operatororder(D1)+operatororder(D2))
27+
28+
angularmomentum(A, order...; dims...) = angularmomentum_layout(MemoryLayout(A), A, order...; dims...)
29+
30+
angularmomentum_layout(::AbstractBasisLayout, Vm, order...; dims...) = error("Overload angularmomentum(::$(typeof(Vm)))")
31+
function angularmomentum_layout(::AbstractBasisLayout, a, order::Int; dims...)
32+
order < 0 && throw(ArgumentError("order must be non-negative"))
33+
order == 0 && return a
34+
isone(order) ? angularmomentum(a) : angularmomentum(angularmomentum(a), order-1)
35+
end
36+
37+
angularmomentum_layout(::ExpansionLayout, A, order...; dims...) = angularmomentum_layout(ApplyLayout{typeof(*)}(), A, order...; dims...)
38+
39+
40+
function angularmomentum_layout(::SubBasisLayout, Vm, order...; dims::Integer=1)
41+
dims == 1 || error("not implemented")
42+
angularmomentum(parent(Vm), order...)[:,parentindices(Vm)[2]]
43+
end
44+
45+
function angularmomentum_layout(LAY::ApplyLayout{typeof(*)}, V::AbstractQuasiVecOrMat, order...; dims=1)
46+
a = arguments(LAY, V)
47+
dims == 1 || throw(ArgumentError("cannot take angularmomentum a vector along dimension $dims"))
48+
*(angularmomentum(a[1], order...), tail(a)...)
49+
end
50+
51+
function angularmomentum(P::SphericalHarmonic)
2352
# Spherical harmonics are the eigenfunctions of the angular momentum operator on the unit sphere
2453
T = real(eltype(P))
2554
k = mortar(Base.OneTo.(1:2:∞))

test/runtests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,9 @@ end
417417
@testset "Angular momentum" begin
418418
S = SphericalHarmonic()
419419
R = RealSphericalHarmonic()
420-
∂θ = AngularMomentum(axes(S, 1))
420+
∂θ = AngularMomentum(S)
421421
@test axes(∂θ) == (axes(S, 1), axes(S, 1))
422-
@test ∂θ == AngularMomentum(axes(R, 1)) == AngularMomentum(axes(S, 1).domain)
422+
@test ∂θ == AngularMomentum(R) == AngularMomentum(axes(S, 1).domain)
423423
@test copy(∂θ) ∂θ
424424
A = S \ (∂θ * S)
425425
A2 = S \ (∂θ^2 * S)

0 commit comments

Comments
 (0)