Utility functions
Plotting and reshaping
Cross-sections returned by the high-level functions dispersion_spectrum
and oa_spectrum
can be reshaped into long format with the helper functions dispersion_df
and oa_df
, respectively.
CoupledDipole.dispersion_df
— Functiondispersion_df(x, wavelength)
Long format dataframe for dispersion spectra
x
: CrossSection structure with 3 arrays (extinction, absorption, scattering)wavelength
: vector of wavelengths
CoupledDipole.oa_df
— Functionoa_df(x, wavelength)
Long format dataframe for orientation-averaged spectra
x
: Tuple with 2 CrossSection structures (average and dichroism), each containing 3 arrays (extinction, absorption, scattering)wavelength
: vector of wavelengths
Euler rotations
CoupledDipole.euler_active
— Functioneuler_active(φ::Real, θ::Real, ψ::Real)
3D rotation matrix
φ
: Euler angle (longitude, in [0,2π])θ
: Euler angle (colatitude, in [0,2π])ψ
: Euler angle (rotation around z", in [0,2π])
Examples
julia> round.(euler_active(π/2,0,0), digits=5)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
0.0 -1.0 0.0
1.0 0.0 0.0
-0.0 0.0 1.0
CoupledDipole.euler_passive
— Functioneuler_passive(φ::Real, θ::Real, ψ::Real)
3D rotation matrix
φ
: Euler angle (longitude, in [0,2π])θ
: Euler angle (colatitude, in [0,2π])ψ
: Euler angle (rotation around z", in [0,2π])
Examples
julia> round.(euler_passive(π/2,0,0), digits=5)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
0.0 1.0 -0.0
-1.0 0.0 0.0
0.0 0.0 1.0
CoupledDipole.axis_angle
— Functionaxis_angle(v = SVector(0, 1, 0), θ)
3D rotation matrix from axis-angle representation
v
: SVectorθ
: rotation angle
Examples
julia> axis_angle(SVector(0, 1, 0), π/4)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
0.707107 0.0 0.707107
0.0 1.0 0.0
-0.707107 0.0 0.707107
CoupledDipole.euler_unitvector
— Functioneuler_unitvector(φ::Real, θ::Real)
Unit vector along direction φ, θ
φ
: Euler angle (longitude, in [0,2π])θ
: Euler angle (colatitude, in [0,2π])
Examples
julia> euler_unitvector(π/2, 0)
3-element SVector{3, Float64} with indices SOneTo(3):
0.0
0.0
1.0
Spherical cubature
CoupledDipole.quadrature_lgwt
— Functionquadrature_lgwt(N::Int, a::Real, b::Real)
N-point Gauss-Legendre quadrature over [a,b] interval
N
: number of nodesa,b
: bounds
\[\int_a^b f(x)\,dx=\frac{b-a}{2}\int_{-1}^{1}f\left(\frac{b-a}{2} x + \frac{a+b}{2}\right)\,dx.\]
Examples
julia> quadrature_lgwt(6,0,3)
(nodes = [0.10129572869527204, 0.5081859203006033, 1.1420712208752046, 1.8579287791247954, 2.4918140796993966, 2.898704271304728], weights = [0.25698673856875537, 0.5411423595722078, 0.7018709018590369, 0.7018709018590369, 0.5411423595722078, 0.25698673856875537])
CoupledDipole.cubature_sphere
— Functioncubature_sphere(N::Int, method::String)
N-point cubature on the sphere
N
: number of nodesmethod
: cubature method (only 'gl' currently implemented)
Returns a Cubature object containing 2 arrays (N'x3 nodes and N'x1 weights), N'≈N Note: using array instead of tuple for weights because we'll use them in a scalar product in orientation-averaging For nodes there is less of a reason, but it can be convenient to visualise the nodes.
The cubature is normalised by 4π such that a unit integrand approximates 1.
Examples
julia> cubature_sphere(6)
(nodes = SVector{3, Float64}[[0.43625314334650644, 2.1862760354652844, 0.0], [0.43625314334650644, 0.9553166181245093, 0.0], [2.0735107047038173, 2.1862760354652844, 0.0], [2.0735107047038173, 0.9553166181245093, 0.0], [4.2096746024757685, 2.1862760354652844, 0.0], [4.2096746024757685, 0.9553166181245093, 0.0], [5.846932163833079, 2.1862760354652844, 0.0], [5.846932163833079, 0.9553166181245093, 0.0]], weights = [0.08696371128436346, 0.08696371128436346, 0.16303628871563655, 0.16303628871563655, 0.16303628871563655, 0.16303628871563655, 0.08696371128436346, 0.08696371128436346])