|
1 | | -######### |
2 | | -# AngularMomentum |
3 | | -# Applies the partial derivative with respect to the last angular variable in the coordinate system. |
4 | | -# For example, in polar coordinates (r, θ) in ℝ² or cylindrical coordinates (r, θ, z) in ℝ³, we apply ∂ / ∂θ = (x ∂ / ∂y - y ∂ / ∂x). |
5 | | -# In spherical coordinates (ρ, θ, φ) in ℝ³, we apply ∂ / ∂φ = (x ∂ / ∂y - y ∂ / ∂x). |
6 | | -######### |
7 | | - |
8 | | -struct AngularMomentum{T,Ax<:Inclusion} <: LazyQuasiMatrix{T} |
| 1 | +""" |
| 2 | + AngularMomentum |
| 3 | + |
| 4 | +Applies the partial derivative with respect to the last angular variable in the coordinate system. |
| 5 | +For example, in polar coordinates (r, θ) in ℝ² or cylindrical coordinates (r, θ, z) in ℝ³, we apply ∂ / ∂θ = (x ∂ / ∂y - y ∂ / ∂x). |
| 6 | +In spherical coordinates (ρ, θ, φ) in ℝ³, we apply ∂ / ∂φ = (x ∂ / ∂y - y ∂ / ∂x). |
| 7 | +""" |
| 8 | +struct AngularMomentum{T,Ax<:Inclusion,Order} <: AbstractDifferentialQuasiMatrix{T} |
9 | 9 | axis::Ax |
| 10 | + order::Order |
10 | 11 | end |
11 | 12 |
|
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...) |
15 | 20 |
|
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)) |
19 | 21 |
|
20 | | -^(A::AngularMomentum, k::Integer) = ApplyQuasiArray(^, A, k) |
| 22 | +operatorcall(::AngularMomentum) = angularmomentum |
| 23 | +similaroperator(D::AngularMomentum, ax, ord) = AngularMomentum{eltype(D)}(ax, ord) |
21 | 24 |
|
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) |
23 | 52 | # Spherical harmonics are the eigenfunctions of the angular momentum operator on the unit sphere |
24 | 53 | T = real(eltype(P)) |
25 | 54 | k = mortar(Base.OneTo.(1:2:∞)) |
|
0 commit comments