-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## 🚨 Checklist - [x] Read and follow the [Contributing Guidelines](https://github.com/cmichelenstrofer/.github/blob/main/CONTRIBUTING.md). - [x] Provide a more detailed description below, including [referencing or closing the relevant issue(s)](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) 💔 Thanks! ## PR Description - Closes #42. - Adds an equivalence to extend `Periodic` by using a specific, user-supplied, dispersion-relation - This allows converting between temporal and spatial frequencies
- Loading branch information
1 parent
4924035
commit 6d96784
Showing
7 changed files
with
274 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
# equivalences containing angular dimensions | ||
|
||
# periodic equivalence for both temporal and spatial frequency | ||
""" | ||
Periodic() | ||
Equivalence to convert between temporal or spatial period, frequency, | ||
[angular frequency](https://en.wikipedia.org/wiki/Angular_frequency), and angular period. | ||
These quantities are related by ``f = ω/2π = 1/T = 1/(2πT̅)``, where | ||
- ``f`` is the (temporal) frequency, | ||
- ``ω`` is the (temporal) angular frequency, | ||
- ``T`` is the (temporal) period, | ||
- ``T̄`` is the (temporal) angular period, | ||
and ``ν = k/2π = 1/λ = 1/(2πλ̄)``, where | ||
- ``ν`` is the (spatial) frequency (linear wavenumber), | ||
- ``k`` is the (spatial) angular frequency (angular wavenumber), | ||
- ``λ`` is the (spatial) period (linear wavelength), and | ||
- ``λ̄`` is the (spatial) angular period (angular wavelength). | ||
See also [`DimensionfulAngles.Dispersion`](@ref) | ||
# Example | ||
```jldoctest; filter = r"(\\d*).(\\d{1,10})\\d+" => s"\\1.\\2" | ||
julia> using Unitful | ||
julia> using DimensionfulAngles | ||
julia> uconvert(u"s", 10u"Hz", Periodic()) | ||
0.1 s | ||
julia> uconvert(u"radᵃ/s", 1u"Hz", Periodic()) | ||
6.283185307179586 rad s⁻¹ | ||
``` | ||
""" | ||
struct Periodic <: Equivalence end | ||
# temporal | ||
@eqrelation Periodic (AngularVelocity / Frequency = 2π * radᵃ) | ||
@eqrelation Periodic (Frequency * Time = 1) | ||
@eqrelation Periodic (AngularVelocity * Time = 2π * radᵃ) | ||
@eqrelation Periodic (AngularVelocity * AngularPeriod = 1) | ||
@eqrelation Periodic (Time / AngularPeriod = 2π * radᵃ) | ||
@eqrelation Periodic (AngularPeriod * Frequency = 1/(2π * radᵃ)) | ||
# spatial | ||
@eqrelation Periodic (AngularWavenumber / Wavenumber = 2π * radᵃ) | ||
@eqrelation Periodic (Wavenumber * Length = 1) | ||
@eqrelation Periodic (AngularWavenumber * Length = 2π * radᵃ) | ||
@eqrelation Periodic (AngularWavenumber * AngularWavelength = 1) | ||
@eqrelation Periodic (Length / AngularWavelength = 2π * radᵃ) | ||
@eqrelation Periodic (AngularWavelength * Wavenumber = 1/(2π * radᵃ)) | ||
# default to `uconvert` behavior, temporal | ||
@eqrelation Periodic (Frequency / Frequency = 1) | ||
@eqrelation Periodic (Time / Time = 1) | ||
@eqrelation Periodic (AngularVelocity / AngularVelocity = 1) | ||
@eqrelation Periodic (AngularPeriod / AngularPeriod = 1) | ||
# default to `uconvert` behavior, spatial | ||
@eqrelation Periodic (Wavenumber / Wavenumber = 1) | ||
@eqrelation Periodic (Length / Length = 1) | ||
@eqrelation Periodic (AngularWavenumber / AngularWavenumber = 1) | ||
@eqrelation Periodic (AngularWavelength / AngularWavelength = 1) | ||
|
||
|
||
# periodic equivalence with a specific dispersion relation relating temporal and spatial | ||
# frequencies | ||
""" | ||
Dispersion(; dispersion=nothing, dispersion_inverse=nothing) | ||
Equivalence to convert between temporal and spatial frequencies using a specific | ||
[dispersion relation](https://en.wikipedia.org/wiki/Dispersion_relation). | ||
This extends the Periodic() equivalence to convert between spatial and temporal quantities | ||
based on the provided dispersion relation. | ||
See also [`DimensionfulAngles.Periodic`](@ref). | ||
# Example | ||
```jldoctest; filter = r"(\\d*).(\\d{1,10})\\d+" => s"\\1.\\2" | ||
julia> using DimensionfulAngles, Unitful | ||
julia> g = Unitful.gn # gravitational acceleration | ||
9.80665 m s⁻² | ||
julia> deepwater = Dispersion( | ||
dispersion = (k -> √(g*k*θ₀)), dispersion_inverse = (ω -> ω^2/(g*θ₀)) | ||
); | ||
julia> uconvert(u"radᵃ/mm", 1.0u"Hz", deepwater) | ||
0.004025678249387654 rad mm⁻¹ | ||
``` | ||
Some dispersion relations do not have an expressible inverse. | ||
In such cases using `Roots.jl` might be beneficial. | ||
For example, here is how we could use the | ||
linear [water wave dispersion](https://en.wikipedia.org/wiki/Dispersion_(water_waves)) | ||
without deep water approximation: | ||
```jldoctest; filter = r"(\\d*).(\\d{1,10})\\d+" => s"\\1.\\2" | ||
julia> using DimensionfulAngles, Unitful, Roots | ||
julia> g = Unitful.gn # gravitational acceleration | ||
9.80665 m s⁻² | ||
julia> k0 = (2π)u"radᵃ/m" # initial guess: 1m wavelength | ||
6.283185307179586 rad m⁻¹ | ||
julia> h = 0.5u"m" # water depth | ||
0.5 m | ||
julia> waterwaves = Dispersion( | ||
dispersion = (k -> √(k*θ₀*g*tanh(k*h/θ₀))), | ||
dispersion_inverse = (ω -> solve(ZeroProblem(k -> k - ω^2/(g*tanh(k*h/θ₀))/θ₀, k0))) | ||
); | ||
julia> uconvert(u"Hz", 0.004025678249387654u"radᵃ/mm", waterwaves) | ||
0.9823052153509486 Hz | ||
julia> h = (Inf)u"m" # water depth | ||
Inf m | ||
julia> waterwaves = Dispersion( | ||
dispersion = ( k -> √(k*θ₀*g*tanh(k*h/θ₀)) ), | ||
dispersion_inverse = (ω -> solve(ZeroProblem(k -> k - ω^2/(g*tanh(k*h/θ₀))/θ₀, k0))) | ||
); | ||
julia> uconvert(u"Hz", 0.004025678249387654u"radᵃ/mm", waterwaves) ≈ 1u"Hz" | ||
true | ||
``` | ||
""" | ||
struct Dispersion <: Equivalence | ||
dispersion::Union{Function, Nothing} | ||
dispersion_inverse::Union{Function, Nothing} | ||
|
||
function Dispersion(; | ||
dispersion::Union{Function, Nothing}=nothing, | ||
dispersion_inverse::Union{Function, Nothing}=nothing | ||
) | ||
return new(dispersion, dispersion_inverse) | ||
end | ||
end | ||
|
||
const _temporal_frequency_dims = [Time, Frequency, AngularPeriod, AngularVelocity] | ||
const _spatial_frequency_dims = [Length, Wavenumber, AngularWavelength, AngularWavenumber] | ||
const _temporal_frequency_units = Dict( | ||
Time => s, Frequency => Hz, AngularPeriod => s/radᵃ, AngularVelocity => radᵃ/s) | ||
const _spatial_frequency_units = Dict( | ||
Length => m, Wavenumber => 1/m, AngularWavelength => m/radᵃ, AngularWavenumber => radᵃ/m | ||
) | ||
|
||
# use all the equivalences in Periodic | ||
for T1 ∈ _temporal_frequency_dims, T2 ∈ _temporal_frequency_dims | ||
@eval begin | ||
function UnitfulEquivalences.edconvert(d::dimtype($T1), x::$T2, ::Dispersion) | ||
return edconvert(d, x, Periodic()) | ||
end | ||
end | ||
end | ||
|
||
for T1 ∈ _spatial_frequency_dims, T2 ∈ _spatial_frequency_dims | ||
@eval begin | ||
function UnitfulEquivalences.edconvert(d::dimtype($T1), x::$T2, ::Dispersion) | ||
return edconvert(d, x, Periodic()) | ||
end | ||
end | ||
end | ||
|
||
# add new equivalences between temporal <-> spatial frequencies | ||
for D_in ∈ _spatial_frequency_dims, D_out ∈ _temporal_frequency_dims | ||
@eval begin | ||
function UnitfulEquivalences.edconvert( | ||
::dimtype($D_out), x::$D_in, equivalence::Dispersion | ||
) | ||
isnothing(equivalence.dispersion) && throw(ArgumentError( | ||
"`dispersion` function not defined")) | ||
k = uconvert(radᵃ/m, x, Periodic()) | ||
ω = equivalence.dispersion(k) | ||
u = _temporal_frequency_units[$D_out] | ||
return uconvert(u, ω, Periodic()) | ||
end | ||
end | ||
end | ||
|
||
for D_in ∈ _temporal_frequency_dims, D_out ∈ _spatial_frequency_dims | ||
@eval begin | ||
function UnitfulEquivalences.edconvert( | ||
::dimtype($D_out), x::$D_in, equivalence::Dispersion | ||
) | ||
isnothing(equivalence.dispersion_inverse) && throw(ArgumentError( | ||
"`dispersion_inverse` function not defined")) | ||
ω = uconvert(radᵃ/s, x, Periodic()) | ||
k = equivalence.dispersion_inverse(ω) | ||
u = _spatial_frequency_units[$D_out] | ||
return uconvert(u, k, Periodic()) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.