diff --git a/prototyping/coordinate_systems.jl b/prototyping/coordinate_systems.jl new file mode 100644 index 0000000..e10fe76 --- /dev/null +++ b/prototyping/coordinate_systems.jl @@ -0,0 +1,51 @@ + +abstract type Handedness end +struct NotHanded <: Handedness end +abstract type HasHanded end +struct RHand <: HasHanded end +struct LHand <: HasHanded end + +abstract type CoordinateType end + +@kwdef struct Rectangular3D{H <: HasHanded} <: CoordinateType + x::Float64 = 0.0 + y::Float64 = 0.0 + z::Float64 = 0.0 +end + +struct Cylindrical3D{H <: HasHanded} <: CoordinateType + r::Float64 = 0.0 + θ::Float64 = 0.0 + z::Float64 = 0.0 +end + +struct Spherical3D{H <: HasHanded} <: CoordinateType + ρ::Float64 = 0.0 + θ::Float64 = 0.0 + φ::Float64 = 0.0 +end + +struct HorizontalPolar2D{H <: HasHanded} <: CoordinateType + r::Float64 = 0.0 + θ::Float64 = 0.0 +end + +struct VerticalPolar2D{H <: HasHanded} <: CoordinateType + r::Float64 = 0.0 + φ::Float64 = 0.0 +end + +struct Spherical2D{H <: HasHanded} <: CoordinateType + θ::Float64 = 0.0 + φ::Float64 = 0.0 +end + +struct Vertical{H <: HasHanded} <: CoordinateType + z = 0.0 +end + +struct Horizontal{H <: NotHanded} <: CoordinateType + r = 0.0 +end + +CoordinateType(::Function) = Rectangular3D{LHand}() diff --git a/prototyping/environmental_profiles.jl b/prototyping/environmental_profiles.jl new file mode 100644 index 0000000..73b2754 --- /dev/null +++ b/prototyping/environmental_profiles.jl @@ -0,0 +1,85 @@ +## Coordinate Handedness +abstract type Handedness end + +struct UnHanded <: Handedness end + +abstract type IsHanded <: Handedness end + +struct RHand <: IsHanded end +struct LHand <: IsHanded end + +## Coordinate System +abstract type CoordinateSystem end + +struct Rectangular3D{H <: IsHanded} <: CoordinateSystem end +struct Cylindrical3D{H <: IsHanded} <: CoordinateSystem end +struct Spherical3D{H <: IsHanded} <: CoordinateSystem end + +struct HorizontalPolar2D{H <: IsHanded} <: CoordinateSystem end +struct VerticalPolar2D{H <: IsHanded} <: CoordinateSystem end +struct Spherical2D{H <: IsHanded} <: CoordinateSystem end + +struct Vertical{H <: IsHanded} <: CoordinateSystem end +struct Horizontal{H <: UnHanded} <: CoordinateSystem end + +struct Constant{H <: UnHanded} <: CoordinateSystem end + +## Coordinate Transformations + + +## Modelling Abstractions +struct Model{M} end +Model(M::Symbol) = Model{M}() + +abstract type OceanSonarModel <: Function end + +(OSM where {OSM <: OceanSonarModel})(M::Symbol, args...; kw...) = OSM(M |> Model, args...; kw...) + +abstract type ProfileFunction <: OceanSonarModel end + +abstract type ProfileFunctor <: OceanSonarModel end + +function (profile_functor::ProfileFunctor)(M |> Model, centre::Real...; pars::Real...) + profile_functor +end + +## Model Definition +struct SoundSpeedFunctionType <: ProfileFunction end + +const sound_speed = SoundSpeedFunctionType() + +sound_speed(::Model{:Homogeneous}; c::Real) = c + +CoordinateSystem(::SoundSpeedFunctionType, ::Model{:Homogeneous}) = Constant{UnHanded}() + +function sound_speed(::Model{:Munk}, z::Real; ϵ::Real = 7.37e-3) + z̃ = 2(z/1300 - 1) + return 1500( + 1 + ϵ * ( + z̃ - 1 + exp(-z̃) + ) + ) +end + +CoordinateSystem(::SoundSpeedFunctionType, ::Model{:Munk}) = Vertical{LHand}() + +## Model Type +struct SoundSpeed{M, ProfileFunctionType} <: ProfileFunctor + model::Model{M} + profile::ProfileFunctionType + + function SoundSpeed(model::Model{M}, centre) where {M} + profile() + end +end + +function (cel::SoundSpeed)(::Type{<:CoordinateSystem}, args...) + +end + +## Model Instantiation +sound_speed = SoundSpeed(:Munk, centre) + +## Model Usage + +sound_speed() diff --git a/prototyping/sonar_modelling.jl b/prototyping/sonar_modelling.jl new file mode 100644 index 0000000..0cef2bb --- /dev/null +++ b/prototyping/sonar_modelling.jl @@ -0,0 +1,222 @@ +## Symbols +( + c = ("Sound Speed", ) +) + +## Modelling +struct Model{M} end +Model(M::Symbol) = Model{M}() + +abstract type ModellingType <: Function end + +(mt::ModellingType)(M::Symbol, args...; kw...) = mt(M |> Model, args...; kw...) + +abstract type ProfileFunctor <: ModellingType end + +(PF where {PF <: ProfileFunctor})(M::Symbol, args...; kw...) = PF{M |> Model}(args...; kw...) + +## Traits +abstract type Handedness end +struct NotHanded <: Handedness end +abstract type HasHanded end +struct RHand <: HasHanded end +struct LHand <: HasHanded end + +abstract type CoordinateType end + +### 3D +struct Rectangular3D{H <: HasHanded} <: CoordinateType end + +struct Cylindrical3D{H <: HasHanded} <: CoordinateType end + +struct Spherical3D{H <: HasHanded} <: CoordinateType end + +### 2D +struct HorizontalPolar2D{H <: HasHanded} <: CoordinateType end + +struct VerticalPolar2D{H <: HasHanded} <: CoordinateType end + +struct Spherical2D{H <: HasHanded} <: CoordinateType end + +### 1D +struct Vertical{H <: HasHanded} <: CoordinateType end + +struct Horizontal{H <: NotHanded} <: CoordinateType end + +### 0D +struct Constant{H <: NotHanded} <: CoordinateType end + +CoordinateType(::Function) = Rectangular3D{LHand}() + +verticalsignchange(OldHand::H, NewHand::H) where {H <: HasHanded} = 1 +verticalsignchange(OldHand::OH, NewHand::NH) where {OH <: HasHanded, NH <: HasHanded} = -1 + +function convertcoordinates(::VerticalPolar2D{OldHand}, ::Vertical{NewHand}, r::Real, z::Real) where {OldHand <: HasHanded, NewHand <: HasHanded} + return ( + verticalsignchange(OldHand, NewHands) * z, + ) +end + +## Profiles +abstract type ProfileFunction <: ModellingType end + +struct SoundSpeedProfileFunction{M} <: ProfileFunction end + +const sound_speed_profile{M <: Model} = SoundSpeedProfileFunction{M}() + +function sound_speed{Model{:Munk}}(::Vertical{LHand}, z::Real; ϵ::Real = 7.37e-3) + z̃ = 2(z/1300 - 1) + return 1500( + 1 + ϵ * ( + z̃ - 1 + exp(-z̃) + ) + ) +end + +## +struct SoundSpeed{M} <: ProfileFunctor + model::Model{M} + profile::Function + + function SoundSpeed(model::Model{M}; pars...) where {M} + profile + new{M}(model, profile) + end +end + +CoordinateType(::SoundSpeed{:Munk}) = Vertical{LHand}() + +function (c::SoundSpeed{M} where {M})(input_coordinate_type::CoordinateType, coords...; pars...) + c.profile( + CoordinateType(c), + convertcoordinates( + input_coordinate_type, + CoordinateType(c), + coords... + )...; + pars... + ) +end + +function sound_speed(::Model{:Munk}, ::Vertical{LHand}, z::Real; ϵ::Real = 7.37e-3) + z̃ = 2(z/1300 - 1) + return 1500( + 1 + ϵ * ( + z̃ - 1 + exp(-z̃) + ) + ) +end + +struct ReflectionCoefficient{M} <: Function + model::Model{M} +end + +## Containers +mutable struct Medium + c::SoundSpeed +end + +mutable struct Interface + z::Depth + R::ReflectionCoefficient +end + +mutable struct Environment + surface::Interface + bottom::Interface + + atmosphere::Medium + ocean::Medium + seabed::Medium +end + +mutable struct Scenario2D + +end + +mutable struct Scenario3D + +end + +## Computations +abstract type Config end + +struct BeamConfig <: Config + +end + +struct Beam + path + pressure + + Beam(::Model{:Ray}) + Beam(::Model{:Hat}) + Beam(::Model{:Gaussian}) +end + +struct Trace2D <: AbstractVector + beams::Vector{<:Beam} + + Trace2D(::Model{:}) +end + +struct Trace3D <: AbstractArray + beams::Vector{<:Beam} + + Trace3D(::Model{:}) +end + +struct Propagation2D <: AbstractMatrix + positions + pressure + + Propagation2D(::Model{:Trace2D}) = new() + Propagation2D(::Model{:Parabolic}) = new() +end + +struct Propagation3D + r + z + θ + p + + Propagation3D(::Model{:Trace2D}) = new() + Propagation3D(::Model{:Trace3D}) = new() +end + +struct Performance2D + r + z + + SL + PL + TS + NL + AG + RL + SNR + DT + SE + POD + + Performance2D() = new() +end + +struct Performance3D + r + z + θ + + SL + PL + TS + NL + AG + RL + SNR + DT + SE + POD + + Performance3D() = new() +end diff --git a/prototyping/sonar_modelling2.jl b/prototyping/sonar_modelling2.jl new file mode 100644 index 0000000..f7da15d --- /dev/null +++ b/prototyping/sonar_modelling2.jl @@ -0,0 +1,62 @@ +## Modelling Abstractions +abstract type OceanSonarModel <: Function end + +## Computations +struct BeamConfig <: Configuration + +end + +struct Beam + path + pressure + + Beam(::Model{:Ray}) + Beam(::Model{:Hat}) + Beam(::Model{:Gaussian}) +end + +struct Trace <: AbstractArray{<:Beam, 2} + beams::AbstractArray{<:Beam, 2} + + Trace(model::Model{M}) where M = new() # inherits models from `Beam` +end + +struct Propagation + r + z + θ + p + + Propagation(::Model{:Trace}) = new() + Propagation(::Model{:Trace}) = new() +end + +@kwdef struct PerformanceConfiguration <: Configuration end + +struct Performance + model::Model{M} where {M} + configuration::PerformanceConfiguration + + r::Vector{Float64} + z::Vector{Float64} + θ::Vector{Float64} + + SL + PL + TS + NL + AG + RL + SNR + DT + SE + POD + + Performance(::Model{:Multistatic}) = new() + Performance(::Model{:Bistatic}) = new() + Performance(::Model{:Monostatic}) = new() +end + +Configuration(::Type{<:Performance}; opt...) = PerformanceConfiguration(; opt...) + +##