Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚀 Feature Request: Dispersion relation for Periodic equivalence. #42

Closed
cmichelenstrofer opened this issue Dec 4, 2023 · 2 comments · Fixed by #43
Closed

🚀 Feature Request: Dispersion relation for Periodic equivalence. #42

cmichelenstrofer opened this issue Dec 4, 2023 · 2 comments · Fixed by #43
Labels
enhancement New feature or request

Comments

@cmichelenstrofer
Copy link
Owner

Feature Request

The temporal and spatial properties can be related by a dispersion relation. This relation is different for different types of waves, and so cannot be hardcoded. We could provide a way for users to provide a dispersion relation and we return the expanded equivalence class.

Interested in leading the development of this feature?

  • 🚀 Yes! I can lead the development of this feature.
@cmichelenstrofer cmichelenstrofer added the enhancement New feature or request label Dec 4, 2023
@cmichelenstrofer
Copy link
Owner Author

The code below works! But.. I'm thinking it doesn't belong here. In particular I do not want to add any dependencies outside of Unitful ones and the code below uses Roots (and I like the functionality of using this because many dispersion relations do not have an inverse that can be expressed algebraically). I prefer keeping this package simple: add angles as a dimension.

using Unitful: Length, Wavenumber, Time, Frequency, s, Hz, m, uconvert
using DimensionfulAngles: AngularPeriod, AngularVelocity, AngularWavelength
using DimensionfulAngles: AngularWavenumber, Periodic, radᵃ
using UnitfulEquivalences: UnitfulEquivalences # extend edconvert
using UnitfulEquivalences: dimtype, edconvert, Equivalence
using Roots: solve, ZeroProblem

struct Dispersion <: Equivalence
    dispersion::Function
    dispersion_inverse::Function

    function Dispersion(;
            dispersion::Union{Function, Nothing}=nothing,
            dispersion_inverse::Union{Function, Nothing}=nothing,
        )
        if !isnothing(dispersion) && isnothing(dispersion_inverse)
            k0 = (2π)radᵃ/m # 1m wave
            dispersion_inverse = ω -> solve(ZeroProblem(k -> ω - dispersion(k), k0))
        elseif !isnothing(dispersion_inverse) && isnothing(dispersion)
            ω0 = (2π)radᵃ/s # 1s wave
            dispersion = k -> solve(ZeroProblem-> k - dispersion_inverse(ω), ω0))
        end
        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
            )
            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
            )
            ω = uconvert(radᵃ/s, x, Periodic())
            k = equivalence.dispersion_inverse(ω)
            u = spatial_frequency_units[$D_out]
            return uconvert(u, k, Periodic())
        end
    end
end

e.g.

julia> deepwater = Dispersion(dispersion=k -> (9.81m/s^2 * k * θ₀));

julia> uconvert(u"radᵃ/mm", 1.0u"Hz", deepwater)
0.004024303527457434 rad mm⁻¹

@cmichelenstrofer
Copy link
Owner Author

will add this here but not do the Roots bit... users can do that themselves. Instead I am adding an example of how to do it.

cmichelenstrofer added a commit that referenced this issue Dec 11, 2023
## 🚨 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant