Mercurial > repos > public > sbplib_julia
diff src/Grids/manifolds.jl @ 1954:b0915f43b122 feature/sbp_operators/laplace_curvilinear
Merge feature/grids/geometry_functions
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Sat, 08 Feb 2025 09:38:58 +0100 |
parents | dd77b45ee1ac |
children | 3fb5b03162ee |
line wrap: on
line diff
--- a/src/Grids/manifolds.jl Sat Feb 08 09:35:13 2025 +0100 +++ b/src/Grids/manifolds.jl Sat Feb 08 09:38:58 2025 +0100 @@ -1,89 +1,3 @@ -""" - ParameterSpace{D} - -A space of parameters of dimension `D`. Used with `Chart` to indicate which -parameters are valid for that chart. - -Common parameter spaces are created using the functions unit sized spaces -* `unitinterval` -* `unitrectangle` -* `unitbox` -* `unittriangle` -* `unittetrahedron` -* `unithyperbox` -* `unitsimplex` - -See also: [`Interval`](@ref), [`Rectangle`](@ref), [`Box`](@ref), -[`Triangle`](@ref), [`Tetrahedron`](@ref), [`HyperBox`](@ref), -[`Simplex`](@ref), -""" -abstract type ParameterSpace{D} end -Base.ndims(::ParameterSpace{D}) where D = D - -struct Interval{T} <: ParameterSpace{1} - a::T - b::T - - function Interval(a,b) - a, b = promote(a, b) - new{typeof(a)}(a,b) - end -end - -limits(i::Interval) = (i.a, i.b) - -unitinterval(T=Float64) = Interval(zero(T), one(T)) - - -struct HyperBox{T,D} <: ParameterSpace{D} - a::SVector{D,T} - b::SVector{D,T} -end - -function HyperBox(a,b) - ET = promote_type(eltype(a),eltype(b)) - T = SVector{length(a),ET} - HyperBox(convert(T,a), convert(T,b)) -end - -Rectangle{T} = HyperBox{T,2} -Box{T} = HyperBox{T,3} - -limits(box::HyperBox, d) = (box.a[d], box.b[d]) -limits(box::HyperBox) = (box.a, box.b) - -unitsquare(T=Float64) = unithyperbox(T,2) -unitcube(T=Float64) = unithyperbox(T,3) -unithyperbox(T, D) = HyperBox((@SVector zeros(T,D)), (@SVector ones(T,D))) -unithyperbox(D) = unithyperbox(Float64,D) - - -struct Simplex{T,D,NV} <: ParameterSpace{D} - verticies::NTuple{NV,SVector{D,T}} -end - -function Simplex(verticies::Vararg{AbstractArray}) - ET = mapreduce(eltype,promote_type,verticies) - T = SVector{length(verticies[1]),ET} - - return Simplex(Tuple(convert(T,v) for v ∈ verticies)) -end - -verticies(s::Simplex) = s.verticies - -Triangle{T} = Simplex{T,2} -Tetrahedron{T} = Simplex{T,3} - -unittriangle(T=Float64) = unitsimplex(T,2) -unittetrahedron(T=Float64) = unitsimplex(T,3) -function unitsimplex(T,D) - z = @SVector zeros(T,D) - unitelement = one(eltype(z)) - verticies = ntuple(i->setindex(z, unitelement, i), D) - return Simplex((z,verticies...)) -end -unitsimplex(D) = unitsimplex(Float64, D) - """ Chart{D} @@ -119,14 +33,14 @@ jacobian(c::Chart, ξ) = jacobian(c.mapping, ξ) # TBD: Can we register a error hint for when jacobian is called with a function that doesn't have a registered jacobian? +boundary_identifiers(c::Chart) = boundary_identifiers(parameterspace(c)) -# TBD: Should Charts, parameterspaces have boundary names? """ Atlas A collection of charts and their connections. -Should implement methods for `charts` and +Should implement methods for `charts` and `connections`. """ abstract type Atlas end @@ -138,90 +52,101 @@ function charts end """ - connections + connections(::Atlas) -TBD: What exactly should this return? +Collection of pairs of multiblock boundary identifiers. +""" +function connections end + """ + CartesianAtlas{D,C<:Chart,AT<:AbstractArray{C,D}} <: Atlas -struct CartesianAtlas <: Atlas - charts::Matrix{Chart} +An atlas where the charts are arranged and connected like an array. +""" +struct CartesianAtlas{D,C<:Chart,AT<:AbstractArray{C,D}} <: Atlas + charts::AT end charts(a::CartesianAtlas) = a.charts -connections(a::CartesianAtlas) = nothing + +function connections(a::CartesianAtlas) + c = Tuple{MultiBlockBoundary, MultiBlockBoundary}[] + + for d ∈ 1:ndims(charts(a)) + Is = eachslice(CartesianIndices(charts(a)); dims=d) + for i ∈ 1:length(Is)-1 # For each interface between slices + for jk ∈ eachindex(Is[i]) # For each block in slice + Iᵢⱼₖ = Tuple(Is[i][jk]) + Iᵢ₊₁ⱼₖ = Tuple(Is[i+1][jk]) + push!(c, + ( + MultiBlockBoundary{Iᵢⱼₖ, CartesianBoundary{d,UpperBoundary}}(), + MultiBlockBoundary{Iᵢ₊₁ⱼₖ, CartesianBoundary{d,LowerBoundary}}(), + ) + ) + end + end + end + + return c +end + +""" + boundary_identifiers(a::CartesianAtlas) -struct UnstructuredAtlas <: Atlas - charts::Vector{Chart} - connections +All non-connected boundaries of the charts of `a`. +""" +function boundary_identifiers(a::CartesianAtlas) + bs = MultiBlockBoundary[] + + for d ∈ 1:ndims(charts(a)) + Is = eachslice(CartesianIndices(charts(a)); dims=d) + + for (i,b) ∈ ((1,LowerBoundary),(length(Is),UpperBoundary)) # For first and last slice + for jk ∈ eachindex(Is[i]) # For each block in slice + Iᵢⱼₖ = Tuple(Is[i][jk]) + push!(bs, + MultiBlockBoundary{Iᵢⱼₖ, CartesianBoundary{d,b}}(), + ) + end + end + end + + return bs +end + + +""" + UnstructuredAtlas{C<:Chart, CN<:Tuple{MultiBlockBoundary,MultiBlockBoundary}, ...} <: Atlas + +An atlas with connections determined by a vector `MultiBlockBoundary` pairs. +""" +struct UnstructuredAtlas{C<:Chart, CN<:Tuple{MultiBlockBoundary,MultiBlockBoundary}, CV<:AbstractVector{C}, CNV<:AbstractVector{CN}} <: Atlas + charts::CV + connections::CNV end charts(a::UnstructuredAtlas) = a.charts -connections(a::UnstructuredAtlas) = nothing - - -### -# Geometry -### +connections(a::UnstructuredAtlas) = a.connections -abstract type Curve end -abstract type Surface end - - -struct Line{PT} <: Curve - p::PT - tangent::PT -end +""" + boundary_identifiers(a::UnstructuredAtlas) -(c::Line)(s) = c.p + s*c.tangent - - -struct LineSegment{PT} <: Curve - a::PT - b::PT -end - -(c::LineSegment)(s) = (1-s)*c.a + s*c.b - - -function linesegments(ps...) - return [LineSegment(ps[i], ps[i+1]) for i ∈ 1:length(ps)-1] -end - +All non-connected boundaries of the charts of `a`. +""" +function boundary_identifiers(a::UnstructuredAtlas) + bs = MultiBlockBoundary[] -function polygon_edges(ps...) - n = length(ps) - return [LineSegment(ps[i], ps[mod1(i+1,n)]) for i ∈ eachindex(Ps)] -end + for (i,c) ∈ enumerate(charts(a)) + for b ∈ boundary_identifiers(c) + mbb = MultiBlockBoundary{i,typeof(b)}() -struct Circle{T,PT} <: Curve - c::PT - r::T -end + if !any(cn->mbb∈cn, connections(a)) + push!(bs, mbb) + end + end + end -(c::Circle)(θ) = c.c + r*@SVector[cos(Θ), sin(Θ)] - -struct TransfiniteInterpolationSurface{T1,T2,T3,T4} <: Surface - c₁::T1 - c₂::T2 - c₃::T3 - c₄::T4 + return bs end - -function (s::TransfiniteInterpolationSurface)(u,v) - c₁, c₂, c₃, c₄ = s.c₁, s.c₂, s.c₃, s.c₄ - P₀₀ = c₁(0) - P₁₀ = c₂(0) - P₁₁ = c₃(0) - P₀₁ = c₄(0) - return (1-v)*c₁(u) + u*c₂(v) + v*c₃(1-u) + (1-u)*c₄(1-v) - ( - (1-u)*(1-v)*P₀₀ + u*(1-v)*P₁₀ + u*v*P₁₁ + (1-u)*v*P₀₁ - ) -end - -function (s::TransfiniteInterpolationSurface)(ξ̄::AbstractArray) - s(ξ̄...) -end - -# TODO: Implement jacobian() for the different mapping helpers -