From c44c02d03848d7ef561424c6692c82c0c9c69794 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 12 Jul 2023 10:33:11 +0200 Subject: [PATCH 001/145] Introduce FunctionValues and GeometryValues --- src/FEValues/CellValues.jl | 63 +++++++++++++++++++++++++ src/FEValues/FunctionValues.jl | 78 +++++++++++++++++++++++++++++++ src/FEValues/GeometryValues.jl | 84 ++++++++++++++++++++++++++++++++++ src/FEValues/common_values.jl | 15 +----- src/Ferrite.jl | 3 +- src/PointEval/point_values.jl | 12 ++--- test/test_cellvalues.jl | 13 ++++-- 7 files changed, 243 insertions(+), 25 deletions(-) create mode 100644 src/FEValues/CellValues.jl create mode 100644 src/FEValues/FunctionValues.jl create mode 100644 src/FEValues/GeometryValues.jl diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl new file mode 100644 index 0000000000..7cc83fbff3 --- /dev/null +++ b/src/FEValues/CellValues.jl @@ -0,0 +1,63 @@ +include("GeometryValues.jl") +include("FunctionValues.jl") + +function default_geometric_interpolation(::Interpolation{shape}) where {dim, shape <: AbstractRefShape{dim}} + return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) +end + +struct CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCellValues + geo_values::GeometryValues{dMdξ_t, GIP, T} + fun_values::FunctionValues{IP, N_t, dNdx_t, dNdξ_t} + qr::QR +end +function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation) where T + geo_values = GeometryValues(T, ip_geo.ip, qr) + fun_values = FunctionValues(T, ip_fun, qr, ip_geo) + return CellValues(geo_values, fun_values, qr) +end + +CellValues(qr::QuadratureRule, ip::Interpolation, args...) = CellValues(Float64, qr, ip, args...) +function CellValues(::Type{T}, qr, ip::Interpolation, ip_geo::ScalarInterpolation=default_geometric_interpolation(ip)) where T + return CellValues(T, qr, ip, VectorizedInterpolation(ip_geo)) +end + +# Access geometry values +for op = (:getdetJdV, :getngeobasefunctions, :geometric_value) + eval(quote + @propagate_inbounds $op(cv::CellValues, args...) = $op(cv.geo_values, args...) + end) +end + +# Accessors for function values +getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) +for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient, :shape_curl) + eval(quote + @propagate_inbounds $op(cv::CellValues, i::Int, q_point::Int) = $op(cv.fun_values, i, q_point) + end) +end +# Access quadrature rule values +getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) + +function reinit!(cv::CellValues, x::AbstractVector{<:Vec}) + geo_values = cv.geo_values + n_geom_basefuncs = getngeobasefunctions(geo_values) + if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs + throw_incompatible_coord_length(length(x), n_geom_basefuncs) + end + @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) + @inline Jinv = calculate_mapping(geo_values, q_point, w, x) + apply_mapping!(cv.fun_values, q_point, Jinv) + end + return nothing +end + +function Base.show(io::IO, d::MIME"text/plain", cv::CellValues) + rdim = getdim(cv.geo_values.ip) + vdim = isa(shape_value(cv, 1, 1), Vec) ? length(shape_value(cv, 1, 1)) : 0 + sdim = length(shape_gradient(cv, 1, 1)) ÷ length(shape_value(cv, 1, 1)) + vstr = vdim==0 ? "scalar" : "vdim=$vdim" + print(io, "CellValues(", vstr, ", rdim=$rdim, and sdim=$sdim): ") + print(io, getnquadpoints(cv), " quadrature points") + print(io, "\n Function interpolation: "); show(io, d, cv.fun_values.ip) + print(io, "\nGeometric interpolation: "); show(io, d, cv.geo_values.ip^sdim) +end \ No newline at end of file diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl new file mode 100644 index 0000000000..2d2d38c488 --- /dev/null +++ b/src/FEValues/FunctionValues.jl @@ -0,0 +1,78 @@ +# Helpers to get the correct types for FunctionValues for the given function and, if needed, geometric interpolations. +struct SInterpolationDims{rdim,sdim} end +struct VInterpolationDims{rdim,sdim,vdim} end +function InterpolationDims(::ScalarInterpolation, ip_geo::VectorizedInterpolation{sdim}) where sdim + return SInterpolationDims{getdim(ip_geo),sdim}() +end +function InterpolationDims(::VectorInterpolation{vdim}, ip_geo::VectorizedInterpolation{sdim}) where {vdim,sdim} + return VInterpolationDims{getdim(ip_geo),sdim,vdim}() +end + +typeof_N(::Type{T}, ::SInterpolationDims) where T = T +typeof_N(::Type{T}, ::VInterpolationDims{<:Any,dim,dim}) where {T,dim} = Vec{dim,T} +typeof_N(::Type{T}, ::VInterpolationDims{<:Any,<:Any,vdim}) where {T,vdim} = SVector{vdim,T} # Why not ::Vec here? + +typeof_dNdx(::Type{T}, ::SInterpolationDims{dim,dim}) where {T,dim} = Vec{dim,T} +typeof_dNdx(::Type{T}, ::SInterpolationDims{<:Any,sdim}) where {T,sdim} = SVector{sdim,T} # Why not ::Vec here? +typeof_dNdx(::Type{T}, ::VInterpolationDims{dim,dim,dim}) where {T,dim} = Tensor{2,dim,T} +typeof_dNdx(::Type{T}, ::VInterpolationDims{<:Any,sdim,vdim}) where {T,sdim,vdim} = SMatrix{vdim,sdim,T} # If vdim=sdim!=rdim Tensor would be possible... + +typeof_dNdξ(::Type{T}, ::SInterpolationDims{dim,dim}) where {T,dim} = Vec{dim,T} +typeof_dNdξ(::Type{T}, ::SInterpolationDims{rdim}) where {T,rdim} = SVector{rdim,T} # Why not ::Vec here? +typeof_dNdξ(::Type{T}, ::VInterpolationDims{dim,dim,dim}) where {T,dim} = Tensor{2,dim,T} +typeof_dNdξ(::Type{T}, ::VInterpolationDims{rdim,<:Any,vdim}) where {T,rdim,vdim} = SMatrix{vdim,rdim,T} # If vdim=rdim!=sdim Tensor would be possible... + +struct FunctionValues{IP, N_t, dNdx_t, dNdξ_t} + N::Matrix{N_t} + dNdx::Matrix{dNdx_t} + dNdξ::Matrix{dNdξ_t} + ip::IP +end +function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T + ip_dims = InterpolationDims(ip, ip_geo) + N_t = typeof_N(T, ip_dims) + dNdx_t = typeof_dNdx(T, ip_dims) + dNdξ_t = typeof_dNdξ(T, ip_dims) + n_shape = getnbasefunctions(ip) + n_qpoints = getnquadpoints(qr) + + N = zeros(N_t, n_shape, n_qpoints) + dNdξ = zeros(dNdξ_t, n_shape, n_qpoints) + dNdx = fill(zero(dNdx_t) * T(NaN), n_shape, n_qpoints) + fv = FunctionValues(N, dNdx, dNdξ, ip) + precompute_values!(fv, qr) # Precompute N and dNdξ + return fv +end + +function precompute_values!(fv::FunctionValues, qr::QuadratureRule) + n_shape = getnbasefunctions(fv.ip) + for (qp, ξ) in pairs(getpoints(qr)) + for i in 1:n_shape + fv.dNdξ[i, qp], fv.N[i, qp] = shape_gradient_and_value(fv.ip, ξ, i) + end + end +end + +getnbasefunctions(funvals::FunctionValues) = size(funvals.N, 1) +@propagate_inbounds shape_value(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.N[base_func, q_point] +@propagate_inbounds shape_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.dNdx[base_func, q_point] +@propagate_inbounds shape_symmetric_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = symmetric(shape_gradient(funvals, q_point, base_func)) + + +# Hotfix to get the dots right for embedded elements until mixed tensors are merged. +# Scalar/Vector interpolations with sdim == rdim (== vdim) +dothelper(A, B) = A ⋅ B +# Vector interpolations with sdim == rdim != vdim +dothelper(A::SMatrix{vdim, dim}, B::Tensor{2, dim}) where {vdim, dim} = A * SMatrix{dim, dim}(B) +# Scalar interpolations with sdim > rdim +dothelper(A::SVector{rdim}, B::SMatrix{rdim, sdim}) where {rdim, sdim} = B' * A +# Vector interpolations with sdim > rdim +dothelper(B::SMatrix{vdim, rdim}, A::SMatrix{rdim, sdim}) where {vdim, rdim, sdim} = B * A + +function apply_mapping!(funvals::FunctionValues, q_point::Int, Jinv) + @inbounds for j in 1:getnbasefunctions(funvals) + #funvals.dNdx[j, q_point] = funvals.dNdξ[j, q_point] ⋅ Jinv # TODO via Tensors.jl + funvals.dNdx[j, q_point] = dothelper(funvals.dNdξ[j, q_point], Jinv) + end + return nothing +end \ No newline at end of file diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl new file mode 100644 index 0000000000..0464a11eef --- /dev/null +++ b/src/FEValues/GeometryValues.jl @@ -0,0 +1,84 @@ +struct GeometryValues{dMdξ_t, GIP, T} + M::Matrix{T} + dMdξ::Matrix{dMdξ_t} + detJdV::Vector{T} + ip::GIP +end +function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T + n_shape = getnbasefunctions(ip) + n_qpoints = getnquadpoints(qr) + VT = Vec{getdim(ip),T} + M = zeros(T, n_shape, n_qpoints) + dMdξ = zeros(VT, n_shape, n_qpoints) + for (qp, ξ) in pairs(getpoints(qr)) + for i in 1:n_shape + dMdξ[i, qp], M[i, qp] = shape_gradient_and_value(ip, ξ, i) + end + end + detJdV::Vector{T} = fill(T(NaN), n_qpoints) + return GeometryValues(M, dMdξ, detJdV, ip) +end + +getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) +@propagate_inbounds geometric_value(geovals::GeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] +@propagate_inbounds getdetJdV(geovals::GeometryValues, q_point::Int) = geovals.detJdV[q_point] + +function calculate_mapping(geo_values::GeometryValues{<:Vec{dim,T}}, q_point, w, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} + fecv_J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) + @inbounds for j in 1:getngeobasefunctions(geo_values) + fecv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] + end + detJ = det(fecv_J) + detJ > 0.0 || throw_detJ_not_pos(detJ) + @inbounds geo_values.detJdV[q_point] = detJ*w + return inv(fecv_J) +end + + +# Embedded + +""" + embedding_det(J::SMatrix{3, 2}) + +Embedding determinant for surfaces in 3D. + +TLDR: "det(J) =" ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ + +The transformation theorem for some function f on a 2D surface in 3D space leads to + ∫ f ⋅ dS = ∫ f ⋅ (∂x/∂ξ₁ × ∂x/∂ξ₂) dξ₁dξ₂ = ∫ f ⋅ n ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ dξ₁dξ₂ +where ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ is "detJ" and n is the unit normal. +See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation. +For more details see e.g. the doctoral thesis by Mirza Cenanovic **Finite element methods for surface problems* (2017), Ch. 2 **Trangential Calculus**. +""" +embedding_det(J::SMatrix{3,2}) = norm(J[:,1] × J[:,2]) + +""" + embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}}) + +Embedding determinant for curves in 2D and 3D. + +TLDR: "det(J) =" ||∂x/∂ξ||₂ + +The transformation theorem for some function f on a 1D curve in 2D and 3D space leads to + ∫ f ⋅ dE = ∫ f ⋅ ∂x/∂ξ dξ = ∫ f ⋅ t ||∂x/∂ξ||₂ dξ +where ||∂x/∂ξ||₂ is "detJ" and t is "the unit tangent". +See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation. +""" +embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}}) = norm(J) + +function calculate_mapping(geo_values::GeometryValues{<:Vec{rdim,T}}, q_point, w, x::AbstractVector{<:Vec{sdim,T}}) where {rdim,sdim,T} + n_geom_basefuncs = getngeobasefunctions(geo_values) + fecv_J = zero(MMatrix{sdim, rdim, T}) # TODO replace with MixedTensor (see https://github.com/Ferrite-FEM/Tensors.jl/pull/188) + for j in 1:n_geom_basefuncs + #fecv_J += x[j] ⊗ geo_values.dMdξ[j, i] # TODO via Tensors.jl + for k in 1:sdim, l in 1:rdim + fecv_J[k, l] += x[j][k] * geo_values.dMdξ[j, q_point][l] + end + end + fecv_J = SMatrix(fecv_J) + detJ = embedding_det(fecv_J) + detJ > 0.0 || throw_detJ_not_pos(detJ) + @inbounds geo_values.detJdV[q_point] = detJ * w + # Compute "left inverse" of J + return pinv(fecv_J) +end \ No newline at end of file diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index e7d43de843..f11b9a76a0 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -38,13 +38,6 @@ The derivatives of the shape functions, and the new integration weights are comp """ reinit! -""" - getnquadpoints(cv::CellValues) - -Return the number of quadrature points in `cv`'s quadrature rule. -""" -getnquadpoints(fe::CellValues) = getnquadpoints(fe.qr) - """ getnquadpoints(fv::FaceValues) @@ -66,7 +59,6 @@ finite element cell or face as ``\\int\\limits_\\Gamma f(\\mathbf{x}) d \\Gamma \\approx \\sum\\limits_{q = 1}^{n_q} f(\\mathbf{x}_q) \\det(J(\\mathbf{x})) w_q`` """ -@propagate_inbounds getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] @propagate_inbounds getdetJdV(bv::FaceValues, q_point::Int) = bv.detJdV[q_point, bv.current_face[]] """ @@ -75,10 +67,8 @@ finite element cell or face as Return the value of shape function `base_function` evaluated in quadrature point `q_point`. """ -@propagate_inbounds shape_value(cv::CellValues, q_point::Int, base_func::Int) = cv.N[base_func, q_point] @propagate_inbounds shape_value(bv::FaceValues, q_point::Int, base_func::Int) = bv.N[base_func, q_point, bv.current_face[]] -@propagate_inbounds geometric_value(cv::CellValues, q_point::Int, base_func::Int) = cv.M[base_func, q_point] @propagate_inbounds geometric_value(bv::FaceValues, q_point::Int, base_func::Int) = bv.M[base_func, q_point, bv.current_face[]] """ @@ -87,7 +77,6 @@ quadrature point `q_point`. Return the gradient of shape function `base_function` evaluated in quadrature point `q_point`. """ -@propagate_inbounds shape_gradient(cv::CellValues, q_point::Int, base_func::Int) = cv.dNdx[base_func, q_point] @propagate_inbounds shape_gradient(bv::FaceValues, q_point::Int, base_func::Int) = bv.dNdx[base_func, q_point, bv.current_face[]] """ @@ -96,7 +85,7 @@ quadrature point `q_point`. Return the symmetric gradient of shape function `base_function` evaluated in quadrature point `q_point`. """ -@propagate_inbounds shape_symmetric_gradient(cv::CellValues, q_point::Int, base_func::Int) = symmetric(shape_gradient(cv, q_point, base_func)) +function shape_symmetric_gradient end """ shape_divergence(fe_v::AbstractValues, q_point::Int, base_function::Int) @@ -273,7 +262,7 @@ function Base.show(io::IO, ::MIME"text/plain", fe_v::AbstractValues) end # copy -for ValueType in (CellValues, FaceValues) +for ValueType in (GeometryValues, FunctionValues, CellValues, FaceValues) args = [:(copy(cv.$fname)) for fname in fieldnames(ValueType)] @eval begin function Base.copy(cv::$ValueType) diff --git a/src/Ferrite.jl b/src/Ferrite.jl index 533f90f05e..deabdc8406 100644 --- a/src/Ferrite.jl +++ b/src/Ferrite.jl @@ -81,7 +81,8 @@ include("interpolations.jl") include("Quadrature/quadrature.jl") # FEValues -include("FEValues/cell_values.jl") +#include("FEValues/cell_values.jl") +include("FEValues/CellValues.jl") include("FEValues/face_values.jl") include("PointEval/point_values.jl") include("FEValues/common_values.jl") diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 473bd1dda8..2e6eb31860 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -24,7 +24,7 @@ struct PointValues{CV} <: AbstractValues PointValues{CV}(cv::CV) where {CV} = new{CV}(cv) end -PointValues(cv::CellValues) = PointValues(eltype(cv.M), cv.ip, cv.gip) +PointValues(cv::CellValues) = PointValues(eltype(shape_value(cv,1,1)), cv.fun_values.ip, cv.geo_values.ip) function PointValues(ip::Interpolation, ipg::Interpolation = default_geometric_interpolation(ip)) return PointValues(Float64, ip, ipg) end @@ -57,11 +57,11 @@ function_symmetric_gradient(pv::PointValues, u::AbstractVector, args...) = # reinit! on PointValues must first update N and dNdξ for the new "quadrature point" # and then call the regular reinit! for the wrapped CellValues to update dNdx function reinit!(pv::PointValues, x::AbstractVector{<:Vec{D}}, ξ::Vec{D}) where {D} - qp = 1 # PointValues only have a single qp - # TODO: Does M need to be updated too? - for i in 1:getnbasefunctions(pv.cv.ip) - pv.cv.dNdξ[i, qp], pv.cv.N[i, qp] = shape_gradient_and_value(pv.cv.ip, ξ, i) - end + # Update the quadrature point location + qr_points = getpoints(pv.cv.qr) + qr_points[1] = ξ + precompute_values!(pv.cv.fun_values, pv.cv.qr) # See Issue #763, should also update dMdξ!, but separate issue + # Regular reinit reinit!(pv.cv, x) return nothing end diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 73fc0605e0..382d97e9af 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -86,7 +86,8 @@ for (scalar_interpol, quad_rule) in ( @test spatial_coordinate(cv, i, x) ≈ qp_x end - # test copy + # test copy: Disable with new structure. TODO: Re-enable + #= cvc = copy(cv) @test typeof(cv) == typeof(cvc) for fname in fieldnames(typeof(cv)) @@ -97,6 +98,7 @@ for (scalar_interpol, quad_rule) in ( end @test v == vc end + =# end end @@ -279,6 +281,7 @@ end @testset "CellValues constructor entry points" begin qr = QuadratureRule{RefTriangle}(1) + _get_geo_ip(cv::CellValues) = cv.geo_values.ip for fun_ip in (Lagrange{RefTriangle, 1}(), Lagrange{RefTriangle, 2}()^2) value_type(T) = fun_ip isa ScalarInterpolation ? T : Vec{2, T} grad_type(T) = fun_ip isa ScalarInterpolation ? Vec{2, T} : Tensor{2, 2, T, 4} @@ -286,24 +289,24 @@ end cv = CellValues(qr, fun_ip) @test Ferrite.shape_value_type(cv) == value_type(Float64) @test Ferrite.shape_gradient_type(cv) == grad_type(Float64) - @test cv.gip == Lagrange{RefTriangle, 1}() + @test _get_geo_ip(cv) == Lagrange{RefTriangle, 1}() # Numeric type + quadrature + scalar function cv = CellValues(Float32, qr, fun_ip) @test Ferrite.shape_value_type(cv) == value_type(Float32) @test Ferrite.shape_gradient_type(cv) == grad_type(Float32) - @test cv.gip == Lagrange{RefTriangle, 1}() + @test _get_geo_ip(cv) == Lagrange{RefTriangle, 1}() for geo_ip in (Lagrange{RefTriangle, 2}(), Lagrange{RefTriangle, 2}()^2) scalar_ip(ip) = ip isa VectorizedInterpolation ? ip.ip : ip # Quadrature + scalar function + geo cv = CellValues(qr, fun_ip, geo_ip) @test Ferrite.shape_value_type(cv) == value_type(Float64) @test Ferrite.shape_gradient_type(cv) == grad_type(Float64) - @test cv.gip == scalar_ip(geo_ip) + @test _get_geo_ip(cv) == scalar_ip(geo_ip) # Numeric type + quadrature + scalar function + scalar geo cv = CellValues(Float32, qr, fun_ip, geo_ip) @test Ferrite.shape_value_type(cv) == value_type(Float32) @test Ferrite.shape_gradient_type(cv) == grad_type(Float32) - @test cv.gip == scalar_ip(geo_ip) + @test _get_geo_ip(cv) == scalar_ip(geo_ip) end end end From 1d1f7c62c975cead096b15242d8214411f936f5e Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 12 Jul 2023 10:51:55 +0200 Subject: [PATCH 002/145] Add benchmark and temporarily support renamed old types --- cv_benchmark.jl | 65 +++++++++++++++++++++++++ src/FEValues/CellValues.jl | 11 ++++- src/FEValues/FunctionValues.jl | 8 +-- src/FEValues/cell_values.jl | 89 ++++++++++------------------------ 4 files changed, 104 insertions(+), 69 deletions(-) create mode 100644 cv_benchmark.jl diff --git a/cv_benchmark.jl b/cv_benchmark.jl new file mode 100644 index 0000000000..fd8b426a3a --- /dev/null +++ b/cv_benchmark.jl @@ -0,0 +1,65 @@ +using Ferrite, BenchmarkTools, StaticArrays + +function get_values(CellType, ::Val{dim}, q_order=2) where dim + grid = generate_grid(CellType, ntuple(Returns(2), dim)) + ip = Ferrite.default_interpolation(getcelltype(grid)) + RefShape = Ferrite.getrefshape(ip) + qr = QuadratureRule{RefShape}(q_order) + cv_u = CellValues(qr, ip^dim, ip) + cv_p = CellValues(qr, ip, ip) + return cv_u, cv_p, getcoordinates(grid, 1) +end + +function reinit_masterfix!(cv::Ferrite.OldCellValues{<:Any, <:Any, <:Tensor, <:Tensor, T, Vec{dim,T}}, x::AbstractVector{Vec{dim,T}}) where {dim, T} + n_geom_basefuncs = Ferrite.getngeobasefunctions(cv) + n_func_basefuncs = Ferrite.getnbasefunctions(cv) + length(x) == n_geom_basefuncs || Ferrite.throw_incompatible_coord_length(length(x), n_geom_basefuncs) + + @inbounds for (i, w) in pairs(getweights(cv.qr)) + fecv_J = zero(Tensor{2,dim,T}) + for j in 1:n_geom_basefuncs + fecv_J += x[j] ⊗ cv.dMdξ[j, i] + end + detJ = det(fecv_J) + detJ > 0.0 || Ferrite.throw_detJ_not_pos(detJ) + cv.detJdV[i] = detJ * w + Jinv = inv(fecv_J) + for j in 1:n_func_basefuncs + # cv.dNdx[j, i] = cv.dNdξ[j, i] ⋅ Jinv + cv.dNdx[j, i] = Ferrite.dothelper(cv.dNdξ[j, i], Jinv) + end + end +end + +#for (CT, dim) in ((Triangle,2), (QuadraticTriangle,2), (Hexahedron,3), (Tetrahedron,3)) +for (CT, dim) in ((Triangle,2),) + # 2 and 4 fields in 2D + cv_u, cv_p, x = get_values(CT, Val(dim), 2) + ocv_u = Ferrite.OldCellValues(cv_u) + ocv_p = Ferrite.OldCellValues(cv_p) + + print("Scalar : $CT in $(dim)D"); println() + print("1 PR : "); @btime reinit!($cv_p, $x); + print("1 master : "); @btime reinit!($ocv_p, $x); + print("1 master (fix): "); @btime reinit_masterfix!($ocv_p, $x); + + print("Vector : $CT in $(dim)D"); println() + print("1 PR : "); @btime reinit!($cv_u, $x); + print("1 master : "); @btime reinit!($ocv_u, $x); + print("1 master (fix): "); @btime reinit_masterfix!($ocv_u, $x); + # =# + #= + println() + print("2 CellValues : "); @btime reinit2!($cv_u, $cv_p, $x) + print("2 MultiCellValues : "); @btime reinit!($mcv_pu, $x) + print("2 MultiCellValues2 : "); @btime reinit!($mcv2_pu, $x) + println() + # =# + #= + print("4 CellValues : "); @btime reinit4!($cv_u, $cv_p, $cv_u2, $cv_p2, $x) + print("4 MultiValues : "); @btime reinit!($cv4, $x) + print("4 Tuple{CV} : "); @btime reinit_multiple!($x, $cv_u, $cv_p, $cv_u2, $cv_p2) + print("4 ValuesGroup : "); @btime reinit!($cvg4, $x); + println() + # =# +end \ No newline at end of file diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 7cc83fbff3..9215ddd4ed 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -46,7 +46,7 @@ function reinit!(cv::CellValues, x::AbstractVector{<:Vec}) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) @inline Jinv = calculate_mapping(geo_values, q_point, w, x) - apply_mapping!(cv.fun_values, q_point, Jinv) + @inline apply_mapping!(cv.fun_values, q_point, Jinv) end return nothing end @@ -60,4 +60,13 @@ function Base.show(io::IO, d::MIME"text/plain", cv::CellValues) print(io, getnquadpoints(cv), " quadrature points") print(io, "\n Function interpolation: "); show(io, d, cv.fun_values.ip) print(io, "\nGeometric interpolation: "); show(io, d, cv.geo_values.ip^sdim) +end + +# Temporary for benchmark/test +include("cell_values.jl") +function OldCellValues(cv::CellValues) + ip = cv.fun_values.ip + sdim = length(shape_gradient(cv, 1, 1)) ÷ length(shape_value(cv, 1, 1)) + ip_geo = cv.geo_values.ip^sdim + return OldCellValues(cv.qr, ip, ip_geo) end \ No newline at end of file diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 2d2d38c488..3dde38888c 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -61,13 +61,13 @@ getnbasefunctions(funvals::FunctionValues) = size(funvals.N, 1) # Hotfix to get the dots right for embedded elements until mixed tensors are merged. # Scalar/Vector interpolations with sdim == rdim (== vdim) -dothelper(A, B) = A ⋅ B +@inline dothelper(A, B) = A ⋅ B # Vector interpolations with sdim == rdim != vdim -dothelper(A::SMatrix{vdim, dim}, B::Tensor{2, dim}) where {vdim, dim} = A * SMatrix{dim, dim}(B) +@inline dothelper(A::SMatrix{vdim, dim}, B::Tensor{2, dim}) where {vdim, dim} = A * SMatrix{dim, dim}(B) # Scalar interpolations with sdim > rdim -dothelper(A::SVector{rdim}, B::SMatrix{rdim, sdim}) where {rdim, sdim} = B' * A +@inline dothelper(A::SVector{rdim}, B::SMatrix{rdim, sdim}) where {rdim, sdim} = B' * A # Vector interpolations with sdim > rdim -dothelper(B::SMatrix{vdim, rdim}, A::SMatrix{rdim, sdim}) where {vdim, rdim, sdim} = B * A +@inline dothelper(B::SMatrix{vdim, rdim}, A::SMatrix{rdim, sdim}) where {vdim, rdim, sdim} = B * A function apply_mapping!(funvals::FunctionValues, q_point::Int, Jinv) @inbounds for j in 1:getnbasefunctions(funvals) diff --git a/src/FEValues/cell_values.jl b/src/FEValues/cell_values.jl index 953ed36e7b..ebd7fde6f2 100644 --- a/src/FEValues/cell_values.jl +++ b/src/FEValues/cell_values.jl @@ -1,7 +1,7 @@ """ - CellValues([::Type{T},] quad_rule::QuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation]) + OldCellValues([::Type{T},] quad_rule::QuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation]) -A `CellValues` object facilitates the process of evaluating values of shape functions, gradients of shape functions, +A `OldCellValues` object facilitates the process of evaluating values of shape functions, gradients of shape functions, values of nodal functions, gradients and divergences of nodal functions etc. in the finite element cell. **Arguments:** @@ -29,13 +29,13 @@ values of nodal functions, gradients and divergences of nodal functions etc. in * [`function_divergence`](@ref) * [`spatial_coordinate`](@ref) """ -CellValues +OldCellValues function default_geometric_interpolation(::Interpolation{shape}) where {dim, shape <: AbstractRefShape{dim}} return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) end -struct CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCellValues +struct OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCellValues N::Matrix{N_t} dNdx::Matrix{dNdx_t} dNdξ::Matrix{dNdξ_t} @@ -47,8 +47,8 @@ struct CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCell gip::GIP end -# Common initializer code for constructing CellValues after the types have been determined -function CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP}(qr::QR, ip::IP, gip::GIP) where { +# Common initializer code for constructing OldCellValues after the types have been determined +function OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP}(qr::QR, ip::IP, gip::GIP) where { IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP, } @assert isconcretetype(IP) && isconcretetype(N_t) && isconcretetype(dNdx_t) && @@ -78,27 +78,27 @@ function CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP}(qr::QR, ip::I detJdV = fill(T(NaN), n_qpoints) - CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP}(N, dNdx, dNdξ, detJdV, M, dMdξ, qr, ip, gip) + OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP}(N, dNdx, dNdξ, detJdV, M, dMdξ, qr, ip, gip) end # Common entry point that fills in the numeric type and geometric interpolation -function CellValues(qr::QuadratureRule, ip::Interpolation, +function OldCellValues(qr::QuadratureRule, ip::Interpolation, gip::Interpolation = default_geometric_interpolation(ip)) - return CellValues(Float64, qr, ip, gip) + return OldCellValues(Float64, qr, ip, gip) end # Common entry point that fills in the geometric interpolation -function CellValues(::Type{T}, qr::QuadratureRule, ip::Interpolation) where {T} - return CellValues(T, qr, ip, default_geometric_interpolation(ip)) +function OldCellValues(::Type{T}, qr::QuadratureRule, ip::Interpolation) where {T} + return OldCellValues(T, qr, ip, default_geometric_interpolation(ip)) end # Common entry point that vectorizes an input scalar geometric interpolation -function CellValues(::Type{T}, qr::QuadratureRule, ip::Interpolation, sgip::ScalarInterpolation) where {T} - return CellValues(T, qr, ip, VectorizedInterpolation(sgip)) +function OldCellValues(::Type{T}, qr::QuadratureRule, ip::Interpolation, sgip::ScalarInterpolation) where {T} + return OldCellValues(T, qr, ip, VectorizedInterpolation(sgip)) end # Entrypoint for `ScalarInterpolation`s (rdim == sdim) -function CellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { +function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { dim, shape <: AbstractRefShape{dim}, T, QR <: QuadratureRule{shape}, IP <: ScalarInterpolation{shape}, @@ -111,11 +111,11 @@ function CellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { # Geometry interpolation M_t = T dMdξ_t = Vec{dim, T} - return CellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) + return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) end # Entrypoint for `VectorInterpolation`s (vdim == rdim == sdim) -function CellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { +function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { dim, shape <: AbstractRefShape{dim}, T, QR <: QuadratureRule{shape}, IP <: VectorInterpolation{dim, shape}, @@ -128,11 +128,11 @@ function CellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { # Geometry interpolation M_t = T dMdξ_t = Vec{dim, T} - return CellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) + return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) end # Entrypoint for `VectorInterpolation`s (vdim != rdim == sdim) -function CellValues(::Type{T}, qr::QR, ip::IP, vgip::VGIP) where { +function OldCellValues(::Type{T}, qr::QR, ip::IP, vgip::VGIP) where { vdim, dim, shape <: AbstractRefShape{dim}, T, QR <: QuadratureRule{shape}, IP <: VectorInterpolation{vdim, shape}, @@ -145,11 +145,11 @@ function CellValues(::Type{T}, qr::QR, ip::IP, vgip::VGIP) where { # Geometry interpolation M_t = T dMdξ_t = Vec{dim, T} - return CellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, vgip.ip) + return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, vgip.ip) end # reinit! for regular (non-embedded) elements (rdim == sdim) -function reinit!(cv::CellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVector{Vec{dim,T}}) where { +function reinit!(cv::OldCellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVector{Vec{dim,T}}) where { dim, T, vdim, N_t <: Union{Number, Vec{dim}, SVector{vdim} }, dNdx_t <: Union{Vec{dim}, Tensor{2, dim}, SMatrix{vdim, dim}}, @@ -175,18 +175,8 @@ function reinit!(cv::CellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVector{ end end -# Hotfix to get the dots right for embedded elements until mixed tensors are merged. -# Scalar/Vector interpolations with sdim == rdim (== vdim) -@inline dothelper(A, B) = A ⋅ B -# Vector interpolations with sdim == rdim != vdim -@inline dothelper(A::SMatrix{vdim, dim}, B::Tensor{2, dim}) where {vdim, dim} = A * SMatrix{dim, dim}(B) -# Scalar interpolations with sdim > rdim -@inline dothelper(A::SVector{rdim}, B::SMatrix{rdim, sdim}) where {rdim, sdim} = B' * A -# Vector interpolations with sdim > rdim -@inline dothelper(B::SMatrix{vdim, rdim}, A::SMatrix{rdim, sdim}) where {vdim, rdim, sdim} = B * A - # Entrypoint for embedded `ScalarInterpolation`s (rdim < sdim) -function CellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { +function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { sdim, rdim, shape <: AbstractRefShape{rdim}, T, QR <: QuadratureRule{shape}, IP <: ScalarInterpolation{shape}, @@ -201,11 +191,11 @@ function CellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { # Geometry interpolation M_t = T dMdξ_t = Vec{rdim, T} - return CellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) + return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) end # Entrypoint for embedded `VectorInterpolation`s (rdim < sdim) -function CellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { +function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { sdim, vdim, rdim, shape <: AbstractRefShape{rdim}, T, QR <: QuadratureRule{shape}, IP <: VectorInterpolation{vdim, shape}, @@ -220,40 +210,11 @@ function CellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { # Geometry interpolation M_t = T dMdξ_t = Vec{rdim, T} - return CellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) + return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) end -""" - embedding_det(J::SMatrix{3, 2}) - -Embedding determinant for surfaces in 3D. - -TLDR: "det(J) =" ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ - -The transformation theorem for some function f on a 2D surface in 3D space leads to - ∫ f ⋅ dS = ∫ f ⋅ (∂x/∂ξ₁ × ∂x/∂ξ₂) dξ₁dξ₂ = ∫ f ⋅ n ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ dξ₁dξ₂ -where ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ is "detJ" and n is the unit normal. -See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation. -For more details see e.g. the doctoral thesis by Mirza Cenanovic **Finite element methods for surface problems* (2017), Ch. 2 **Trangential Calculus**. -""" -embedding_det(J::SMatrix{3,2}) = norm(J[:,1] × J[:,2]) - -""" - embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}}) - -Embedding determinant for curves in 2D and 3D. - -TLDR: "det(J) =" ||∂x/∂ξ||₂ - -The transformation theorem for some function f on a 1D curve in 2D and 3D space leads to - ∫ f ⋅ dE = ∫ f ⋅ ∂x/∂ξ dξ = ∫ f ⋅ t ||∂x/∂ξ||₂ dξ -where ||∂x/∂ξ||₂ is "detJ" and t is "the unit tangent". -See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation. -""" -embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}}) = norm(J) - # reinit! for embedded elements, rdim < sdim -function reinit!(cv::CellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVector{Vec{sdim,T}}) where { +function reinit!(cv::OldCellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVector{Vec{sdim,T}}) where { rdim, sdim, vdim, T, N_t <: Union{Number, SVector{vdim}}, dNdx_t <: Union{SVector{sdim, T}, SMatrix{vdim, sdim, T}}, From 92b9779dd233e9797aee5c38c89e2901d12eb91e Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 12 Jul 2023 11:12:41 +0200 Subject: [PATCH 003/145] Fix inline annotation for julia 1.6 ? --- src/FEValues/CellValues.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 9215ddd4ed..0ffe18de37 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -45,7 +45,7 @@ function reinit!(cv::CellValues, x::AbstractVector{<:Vec}) throw_incompatible_coord_length(length(x), n_geom_basefuncs) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) - @inline Jinv = calculate_mapping(geo_values, q_point, w, x) + Jinv = @inline calculate_mapping(geo_values, q_point, w, x) @inline apply_mapping!(cv.fun_values, q_point, Jinv) end return nothing From 8fef34dda0eaba9130044a75f76a8ea008449973 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 12 Jul 2023 11:23:31 +0200 Subject: [PATCH 004/145] Move callsite inline to function definitions --- cv_benchmark.jl | 2 +- src/FEValues/CellValues.jl | 4 ++-- src/FEValues/FunctionValues.jl | 2 +- src/FEValues/GeometryValues.jl | 4 ++-- src/FEValues/cell_values.jl | 4 ---- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/cv_benchmark.jl b/cv_benchmark.jl index fd8b426a3a..db5870c996 100644 --- a/cv_benchmark.jl +++ b/cv_benchmark.jl @@ -1,7 +1,7 @@ using Ferrite, BenchmarkTools, StaticArrays function get_values(CellType, ::Val{dim}, q_order=2) where dim - grid = generate_grid(CellType, ntuple(Returns(2), dim)) + grid = generate_grid(CellType, ntuple(_->2, dim)) ip = Ferrite.default_interpolation(getcelltype(grid)) RefShape = Ferrite.getrefshape(ip) qr = QuadratureRule{RefShape}(q_order) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 0ffe18de37..c565e40521 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -45,8 +45,8 @@ function reinit!(cv::CellValues, x::AbstractVector{<:Vec}) throw_incompatible_coord_length(length(x), n_geom_basefuncs) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) - Jinv = @inline calculate_mapping(geo_values, q_point, w, x) - @inline apply_mapping!(cv.fun_values, q_point, Jinv) + Jinv = calculate_mapping(geo_values, q_point, w, x) + apply_mapping!(cv.fun_values, q_point, Jinv) end return nothing end diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 3dde38888c..14a56a0e52 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -69,7 +69,7 @@ getnbasefunctions(funvals::FunctionValues) = size(funvals.N, 1) # Vector interpolations with sdim > rdim @inline dothelper(B::SMatrix{vdim, rdim}, A::SMatrix{rdim, sdim}) where {vdim, rdim, sdim} = B * A -function apply_mapping!(funvals::FunctionValues, q_point::Int, Jinv) +@inline function apply_mapping!(funvals::FunctionValues, q_point::Int, Jinv) @inbounds for j in 1:getnbasefunctions(funvals) #funvals.dNdx[j, q_point] = funvals.dNdξ[j, q_point] ⋅ Jinv # TODO via Tensors.jl funvals.dNdx[j, q_point] = dothelper(funvals.dNdξ[j, q_point], Jinv) diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index 0464a11eef..e9ad79daa2 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -23,7 +23,7 @@ getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) @propagate_inbounds geometric_value(geovals::GeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] @propagate_inbounds getdetJdV(geovals::GeometryValues, q_point::Int) = geovals.detJdV[q_point] -function calculate_mapping(geo_values::GeometryValues{<:Vec{dim,T}}, q_point, w, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} +@inline function calculate_mapping(geo_values::GeometryValues{<:Vec{dim,T}}, q_point, w, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} fecv_J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) @inbounds for j in 1:getngeobasefunctions(geo_values) fecv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] @@ -66,7 +66,7 @@ See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-di """ embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}}) = norm(J) -function calculate_mapping(geo_values::GeometryValues{<:Vec{rdim,T}}, q_point, w, x::AbstractVector{<:Vec{sdim,T}}) where {rdim,sdim,T} +@inline function calculate_mapping(geo_values::GeometryValues{<:Vec{rdim,T}}, q_point, w, x::AbstractVector{<:Vec{sdim,T}}) where {rdim,sdim,T} n_geom_basefuncs = getngeobasefunctions(geo_values) fecv_J = zero(MMatrix{sdim, rdim, T}) # TODO replace with MixedTensor (see https://github.com/Ferrite-FEM/Tensors.jl/pull/188) for j in 1:n_geom_basefuncs diff --git a/src/FEValues/cell_values.jl b/src/FEValues/cell_values.jl index ebd7fde6f2..b50c23193a 100644 --- a/src/FEValues/cell_values.jl +++ b/src/FEValues/cell_values.jl @@ -31,10 +31,6 @@ values of nodal functions, gradients and divergences of nodal functions etc. in """ OldCellValues -function default_geometric_interpolation(::Interpolation{shape}) where {dim, shape <: AbstractRefShape{dim}} - return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) -end - struct OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCellValues N::Matrix{N_t} dNdx::Matrix{dNdx_t} From 506a6f7bdee7d3ffc45142c2acc7ced7849c2766 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 12 Jul 2023 11:42:42 +0200 Subject: [PATCH 005/145] Fix shell example, used internals of cellvalues --- docs/src/literate-tutorials/linear_shell.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/src/literate-tutorials/linear_shell.jl b/docs/src/literate-tutorials/linear_shell.jl index e5927b42e3..637436dbea 100644 --- a/docs/src/literate-tutorials/linear_shell.jl +++ b/docs/src/literate-tutorials/linear_shell.jl @@ -264,6 +264,8 @@ end; # ##### Main element routine # Below is the main routine that calculates the stiffness matrix of the shell element. # Since it is a so called degenerate shell element, the code is similar to that for an standard continuum element. +shape_reference_gradient(cv::CellValues, q_point, i) = cv.fun_values.dNdξ[i, q_point] + function integrate_shell!(ke, cv, qr_ooplane, X, data) nnodes = getnbasefunctions(cv) ndofs = nnodes*5 @@ -281,9 +283,9 @@ function integrate_shell!(ke, cv, qr_ooplane, X, data) ef1, ef2, ef3 = fiber_coordsys(p) for iqp in 1:getnquadpoints(cv) - N = cv.N[:,iqp] - dNdξ = cv.dNdξ[:,iqp] - dNdx = cv.dNdx[:,iqp] + N = [shape_value(cv, iqp, i) for i in 1:nnodes] + dNdξ = [shape_reference_gradient(cv, iqp, i) for i in 1:nnodes] + dNdx = [shape_gradient(cv, iqp, i) for i in 1:nnodes] for oqp in 1:length(qr_ooplane.weights) ζ = qr_ooplane.points[oqp][1] From d2eda0fe4df3c9899f5673bcca5a0c0b951dbc55 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 12 Jul 2023 14:56:44 +0200 Subject: [PATCH 006/145] Use FunctionValues in FaceValues too --- src/FEValues/FaceValues.jl | 174 ++++++++++++++++++++++++++++++++++ src/FEValues/common_values.jl | 10 +- src/FEValues/face_values.jl | 45 ++++----- src/Ferrite.jl | 3 +- 4 files changed, 204 insertions(+), 28 deletions(-) create mode 100644 src/FEValues/FaceValues.jl diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl new file mode 100644 index 0000000000..6b8becfd17 --- /dev/null +++ b/src/FEValues/FaceValues.jl @@ -0,0 +1,174 @@ +struct FaceGeometryValues{dMdξ_t, GIP, T, Normal_t} + M::Matrix{T} + dMdξ::Matrix{dMdξ_t} + detJdV::Vector{T} + normals::Vector{Normal_t} + ip::GIP +end +function FaceGeometryValues(::Type{T}, ip_vec::VectorizedInterpolation{sdim}, qr::QuadratureRule) where {T,sdim} + ip = ip_vec.ip + n_shape = getnbasefunctions(ip) + n_qpoints = getnquadpoints(qr) + M = zeros(T, n_shape, n_qpoints) + dMdξ = zeros(Vec{getdim(ip),T}, n_shape, n_qpoints) + for (qp, ξ) in pairs(getpoints(qr)) + for i in 1:n_shape + dMdξ[i, qp], M[i, qp] = shape_gradient_and_value(ip, ξ, i) + end + end + normals = fill(zero(Vec{sdim,T})*T(NaN), n_qpoints) + detJdV = fill(T(NaN), n_qpoints) + return FaceGeometryValues(M, dMdξ, detJdV, normals, ip) +end + +getngeobasefunctions(geovals::FaceGeometryValues) = size(geovals.M, 1) +@propagate_inbounds geometric_value(geovals::FaceGeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] +@propagate_inbounds getdetJdV(geovals::FaceGeometryValues, q_point::Int) = geovals.detJdV[q_point] +@propagate_inbounds getnormal(geovals::FaceGeometryValues, q_point::Int) = geovals.normals[q_point] + +@inline function calculate_mapping(geo_values::FaceGeometryValues{<:Vec{dim,T}}, face_nr::Int, q_point, w, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} + fefv_J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) + @inbounds for j in 1:getngeobasefunctions(geo_values) + fefv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] + end + weight_norm = weighted_normal(fefv_J, getrefshape(geo_values.ip), face_nr) + detJ = norm(weight_norm) + detJ > 0.0 || throw_detJ_not_pos(detJ) + @inbounds geo_values.detJdV[q_point] = detJ*w + @inbounds geo_values.normals[q_point] = weight_norm / norm(weight_norm) + return inv(fefv_J) +end + +struct FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP} <: AbstractFaceValues + geo_values::Vector{FaceGeometryValues{dMdξ_t, GIP, T, Normal_t}} + fun_values::Vector{FunctionValues{IP, N_t, dNdx_t, dNdξ_t}} + qr::QR # FaceQuadratureRule + current_face::ScalarWrapper{Int} +end + +function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation=default_geometric_interpolation(ip_fun)) where T + geo_values = [FaceGeometryValues(T, ip_geo, qr) for qr in fqr.face_rules] + fun_values = [FunctionValues(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] + return FaceValues(geo_values, fun_values, fqr, ScalarWrapper(1)) +end + +FaceValues(qr::FaceQuadratureRule, ip::Interpolation, args...) = FaceValues(Float64, qr, ip, args...) +function FaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation, ip_geo::ScalarInterpolation) where T + return FaceValues(T, qr, ip, VectorizedInterpolation(ip_geo)) +end + +getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_values(fv)) +getnbasefunctions(fv::FaceValues) = getnbasefunctions(get_fun_values(fv)) +getnquadpoints(fv::FaceValues) = getnquadpoints(fv.qr, getcurrentface(fv)) + +get_geo_values(fv::FaceValues) = @inbounds fv.geo_values[getcurrentface(fv)] +for op = (:getdetJdV, :getngeobasefunctions, :geometric_value) + eval(quote + @propagate_inbounds $op(fv::FaceValues, args...) = $op(get_geo_values(fv), args...) + end) +end + +get_fun_values(fv::FaceValues) = @inbounds fv.fun_values[getcurrentface(fv)] +for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient, :shape_curl) + eval(quote + @propagate_inbounds $op(fv::FaceValues, i::Int, q_point::Int) = $op(get_fun_values(fv), i, q_point) + end) +end + +""" + getcurrentface(fv::FaceValues) + +Return the current active face of the `FaceValues` object (from last `reinit!`). + +""" +getcurrentface(fv::FaceValues) = fv.current_face[] + +""" + getnormal(fv::FaceValues, qp::Int) + +Return the normal at the quadrature point `qp` for the active face of the +`FaceValues` object(from last `reinit!`). +""" +getnormal(fv::FaceValues, qp::Int) = getnormal(fv.geo_values[getcurrentface(fv)], qp) + +nfaces(fv::FaceValues) = length(fv.geo_values) + +function checkface(fv::FaceValues, face::Int) + 0 < face <= nfaces(fv) || error("Face index out of range.") + return nothing +end + +function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int) where {dim, T} + @boundscheck checkface(fv, face_nr) + n_geom_basefuncs = getngeobasefunctions(fv) + length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) + @inbounds geo_values = fv.geo_values[face_nr] + @inbounds fun_values = fv.fun_values[face_nr] + + fv.current_face[] = face_nr + + @inbounds for (q_point, w) in pairs(getweights(fv.qr, face_nr)) + Jinv = calculate_mapping(geo_values, face_nr, q_point, w, x) + apply_mapping!(fun_values, q_point, Jinv) + end +end + +""" + BCValues(func_interpol::Interpolation, geom_interpol::Interpolation, boundary_type::Union{Type{<:BoundaryIndex}}) + +`BCValues` stores the shape values at all faces/edges/vertices (depending on `boundary_type`) for the geomatric interpolation (`geom_interpol`), +for each dof-position determined by the `func_interpol`. Used mainly by the `ConstrainHandler`. +""" +struct BCValues{T} + M::Array{T,3} + nqp::Array{Int} + current_entity::ScalarWrapper{Int} +end + +BCValues(func_interpol::Interpolation, geom_interpol::Interpolation, boundary_type::Type{<:BoundaryIndex} = Ferrite.FaceIndex) = + BCValues(Float64, func_interpol, geom_interpol, boundary_type) + +function BCValues(::Type{T}, func_interpol::Interpolation{refshape}, geom_interpol::Interpolation{refshape}, boundary_type::Type{<:BoundaryIndex} = Ferrite.FaceIndex) where {T,dim,refshape <: AbstractRefShape{dim}} + # set up quadrature rules for each boundary entity with dof-positions + # (determined by func_interpol) as the quadrature points + interpolation_coords = reference_coordinates(func_interpol) + + qrs = QuadratureRule{refshape,T,dim}[] + for boundarydofs in dirichlet_boundarydof_indices(boundary_type)(func_interpol) + dofcoords = Vec{dim,T}[] + for boundarydof in boundarydofs + push!(dofcoords, interpolation_coords[boundarydof]) + end + qrf = QuadratureRule{refshape,T}(fill(T(NaN), length(dofcoords)), dofcoords) # weights will not be used + push!(qrs, qrf) + end + + n_boundary_entities = length(qrs) + n_qpoints = n_boundary_entities == 0 ? 0 : maximum(qr->length(getweights(qr)), qrs) # Bound number of qps correctly. + n_geom_basefuncs = getnbasefunctions(geom_interpol) + M = fill(zero(T) * T(NaN), n_geom_basefuncs, n_qpoints, n_boundary_entities) + nqp = zeros(Int,n_boundary_entities) + + for n_boundary_entity in 1:n_boundary_entities + for (qp, ξ) in enumerate(qrs[n_boundary_entity].points), i in 1:n_geom_basefuncs + M[i, qp, n_boundary_entity] = shape_value(geom_interpol, ξ, i) + end + nqp[n_boundary_entity] = length(qrs[n_boundary_entity].points) + end + + BCValues{T}(M, nqp, ScalarWrapper(0)) +end + +getnquadpoints(bcv::BCValues) = bcv.nqp[bcv.current_entity.x] +function spatial_coordinate(bcv::BCValues, q_point::Int, xh::AbstractVector{Vec{dim,T}}) where {dim,T} + n_base_funcs = size(bcv.M, 1) + length(xh) == n_base_funcs || throw_incompatible_coord_length(length(xh), n_base_funcs) + x = zero(Vec{dim,T}) + face = bcv.current_entity[] + @inbounds for i in 1:n_base_funcs + x += bcv.M[i,q_point,face] * xh[i] # geometric_value(fe_v, q_point, i) * xh[i] + end + return x +end + +include("face_values.jl") \ No newline at end of file diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index f11b9a76a0..eac205a62c 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -44,7 +44,7 @@ reinit! Return the number of quadrature points in `fv`s quadrature for the current (most recently [`reinit!`](@ref)ed) face. """ -getnquadpoints(fe::FaceValues) = getnquadpoints(fe.qr, fe.current_face[]) +function getnquadpoints end """ getdetJdV(fe_v::AbstractValues, q_point::Int) @@ -59,7 +59,7 @@ finite element cell or face as ``\\int\\limits_\\Gamma f(\\mathbf{x}) d \\Gamma \\approx \\sum\\limits_{q = 1}^{n_q} f(\\mathbf{x}_q) \\det(J(\\mathbf{x})) w_q`` """ -@propagate_inbounds getdetJdV(bv::FaceValues, q_point::Int) = bv.detJdV[q_point, bv.current_face[]] +#@propagate_inbounds getdetJdV(bv::FaceValues, q_point::Int) = bv.detJdV[q_point, bv.current_face[]] """ shape_value(fe_v::AbstractValues, q_point::Int, base_function::Int) @@ -67,9 +67,9 @@ finite element cell or face as Return the value of shape function `base_function` evaluated in quadrature point `q_point`. """ -@propagate_inbounds shape_value(bv::FaceValues, q_point::Int, base_func::Int) = bv.N[base_func, q_point, bv.current_face[]] +#@propagate_inbounds shape_value(bv::FaceValues, q_point::Int, base_func::Int) = bv.N[base_func, q_point, bv.current_face[]] -@propagate_inbounds geometric_value(bv::FaceValues, q_point::Int, base_func::Int) = bv.M[base_func, q_point, bv.current_face[]] +#@propagate_inbounds geometric_value(bv::FaceValues, q_point::Int, base_func::Int) = bv.M[base_func, q_point, bv.current_face[]] """ shape_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int) @@ -77,7 +77,7 @@ quadrature point `q_point`. Return the gradient of shape function `base_function` evaluated in quadrature point `q_point`. """ -@propagate_inbounds shape_gradient(bv::FaceValues, q_point::Int, base_func::Int) = bv.dNdx[base_func, q_point, bv.current_face[]] +#@propagate_inbounds shape_gradient(bv::FaceValues, q_point::Int, base_func::Int) = bv.dNdx[base_func, q_point, bv.current_face[]] """ shape_symmetric_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int) diff --git a/src/FEValues/face_values.jl b/src/FEValues/face_values.jl index c0dc14a3f1..342a5161d0 100644 --- a/src/FEValues/face_values.jl +++ b/src/FEValues/face_values.jl @@ -31,7 +31,7 @@ values of nodal functions, gradients and divergences of nodal functions etc. on """ FaceValues -struct FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP} <: AbstractFaceValues +struct OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP} <: AbstractFaceValues N::Array{N_t, 3} dNdx::Array{dNdx_t, 3} dNdξ::Array{dNdξ_t, 3} @@ -45,8 +45,8 @@ struct FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP} <: Ab geo_interp::GIP end -# Common initializer code for constructing FaceValues after the types have been determined -function FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP}(qr::QR, ip::IP, gip::GIP) where { +# Common initializer code for constructing OldFaceValues after the types have been determined +function OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP}(qr::QR, ip::IP, gip::GIP) where { IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP, } @assert isconcretetype(IP) && isconcretetype(N_t) && isconcretetype(dNdx_t) && @@ -81,27 +81,27 @@ function FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP}(qr: detJdV = fill(T(NaN), max_n_qpoints, n_faces) - FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP}(N, dNdx, dNdξ, detJdV, normals, M, dMdξ, qr, ScalarWrapper(0), ip, gip) + OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP}(N, dNdx, dNdξ, detJdV, normals, M, dMdξ, qr, ScalarWrapper(0), ip, gip) end # Common entry point that fills in the numeric type and geometric interpolation -function FaceValues(qr::FaceQuadratureRule, ip::Interpolation, +function OldFaceValues(qr::FaceQuadratureRule, ip::Interpolation, gip::Interpolation = default_geometric_interpolation(ip)) - return FaceValues(Float64, qr, ip, gip) + return OldFaceValues(Float64, qr, ip, gip) end # Common entry point that fills in the geometric interpolation -function FaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation) where {T} - return FaceValues(T, qr, ip, default_geometric_interpolation(ip)) +function OldFaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation) where {T} + return OldFaceValues(T, qr, ip, default_geometric_interpolation(ip)) end # Common entry point that vectorizes an input scalar geometric interpolation -function FaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation, sgip::ScalarInterpolation) where {T} - return FaceValues(T, qr, ip, VectorizedInterpolation(sgip)) +function OldFaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation, sgip::ScalarInterpolation) where {T} + return OldFaceValues(T, qr, ip, VectorizedInterpolation(sgip)) end # Entrypoint for `ScalarInterpolation`s (rdim == sdim) -function FaceValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { +function OldFaceValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { dim, shape <: AbstractRefShape{dim}, T, QR <: FaceQuadratureRule{shape}, IP <: ScalarInterpolation{shape}, @@ -116,11 +116,11 @@ function FaceValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { # Geometry interpolation M_t = T dMdξ_t = Vec{dim, T} - return FaceValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, Normal_t, GIP}(qr, ip, gip.ip) + return OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, Normal_t, GIP}(qr, ip, gip.ip) end # Entrypoint for `VectorInterpolation`s (vdim == rdim == sdim) -function FaceValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { +function OldFaceValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { dim, shape <: AbstractRefShape{dim}, T, QR <: FaceQuadratureRule{shape}, IP <: VectorInterpolation{dim, shape}, @@ -135,10 +135,10 @@ function FaceValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { # Geometry interpolation M_t = T dMdξ_t = Vec{dim, T} - return FaceValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, Normal_t, GIP}(qr, ip, gip.ip) + return OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, Normal_t, GIP}(qr, ip, gip.ip) end -function reinit!(fv::FaceValues{<:Any, N_t, dNdx_t}, x::AbstractVector{Vec{dim,T}}, face::Int) where { +function reinit!(fv::OldFaceValues{<:Any, N_t, dNdx_t}, x::AbstractVector{Vec{dim,T}}, face::Int) where { dim, T, N_t <: Union{Number, Vec{dim}}, dNdx_t <: Union{Vec{dim}, Tensor{2,dim}} @@ -171,21 +171,21 @@ function reinit!(fv::FaceValues{<:Any, N_t, dNdx_t}, x::AbstractVector{Vec{dim,T end """ - getcurrentface(fv::FaceValues) + getcurrentface(fv::OldFaceValues) -Return the current active face of the `FaceValues` object (from last `reinit!`). +Return the current active face of the `OldFaceValues` object (from last `reinit!`). """ -getcurrentface(fv::FaceValues) = fv.current_face[] +getcurrentface(fv::OldFaceValues) = fv.current_face[] """ - getnormal(fv::FaceValues, qp::Int) + getnormal(fv::OldFaceValues, qp::Int) Return the normal at the quadrature point `qp` for the active face of the -`FaceValues` object(from last `reinit!`). +`OldFaceValues` object(from last `reinit!`). """ -getnormal(fv::FaceValues, qp::Int) = fv.normals[qp] - +getnormal(fv::OldFaceValues, qp::Int) = fv.normals[qp] +#= Moved to FaceValues.jl """ BCValues(func_interpol::Interpolation, geom_interpol::Interpolation, boundary_type::Union{Type{<:BoundaryIndex}}) @@ -250,3 +250,4 @@ function checkface(fv::FaceValues, face::Int) 0 < face <= nfaces(fv) || error("Face index out of range.") return nothing end +=# \ No newline at end of file diff --git a/src/Ferrite.jl b/src/Ferrite.jl index deabdc8406..62aad67ef0 100644 --- a/src/Ferrite.jl +++ b/src/Ferrite.jl @@ -83,7 +83,8 @@ include("Quadrature/quadrature.jl") # FEValues #include("FEValues/cell_values.jl") include("FEValues/CellValues.jl") -include("FEValues/face_values.jl") +#include("FEValues/face_values.jl") +include("FEValues/FaceValues.jl") include("PointEval/point_values.jl") include("FEValues/common_values.jl") include("FEValues/face_integrals.jl") From 744ba44896f6dfb20b25f91774351b9dc379f484 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Tue, 18 Jul 2023 15:07:55 +0200 Subject: [PATCH 007/145] Use get_x_values for facevalues --- src/FEValues/FaceValues.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 6b8becfd17..27f33e3de7 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -89,7 +89,7 @@ getcurrentface(fv::FaceValues) = fv.current_face[] Return the normal at the quadrature point `qp` for the active face of the `FaceValues` object(from last `reinit!`). """ -getnormal(fv::FaceValues, qp::Int) = getnormal(fv.geo_values[getcurrentface(fv)], qp) +getnormal(fv::FaceValues, qp::Int) = getnormal(get_geo_values(fv), qp) nfaces(fv::FaceValues) = length(fv.geo_values) @@ -102,11 +102,11 @@ function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int) wh @boundscheck checkface(fv, face_nr) n_geom_basefuncs = getngeobasefunctions(fv) length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) - @inbounds geo_values = fv.geo_values[face_nr] - @inbounds fun_values = fv.fun_values[face_nr] - - fv.current_face[] = face_nr + fv.current_face[] = face_nr + + geo_values = get_geo_values(fv) + fun_values = get_fun_values(fv) @inbounds for (q_point, w) in pairs(getweights(fv.qr, face_nr)) Jinv = calculate_mapping(geo_values, face_nr, q_point, w, x) apply_mapping!(fun_values, q_point, Jinv) From 5cb7052f9c0b6664c5004bd51962d9edbc460cb1 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 11 Aug 2023 19:21:04 +0200 Subject: [PATCH 008/145] Initial work - some ex works, not all tests --- docs/Manifest.toml | 505 +++++++++++++++++++-------------- src/FEValues/CellValues.jl | 15 +- src/FEValues/FaceValues.jl | 66 ++--- src/FEValues/FunctionValues.jl | 39 ++- src/FEValues/GeometryValues.jl | 31 +- test/test_facevalues.jl | 1 + 6 files changed, 372 insertions(+), 285 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index e8cfd843f7..d798928845 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -1,9 +1,14 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.9.1" +julia_version = "1.9.2" manifest_format = "2.0" project_hash = "36aa80ebfd72e2016135d6d7b3122eb6efdc74ea" +[[deps.ADTypes]] +git-tree-sha1 = "f5c25e8a5b29b5e941b7408bc8cc79fea4d9ef9a" +uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" +version = "0.1.6" + [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" @@ -16,9 +21,9 @@ version = "0.4.4" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "cc37d689f599e8df4f464b2fa3870ff7db7492ef" +git-tree-sha1 = "76289dc51920fdc6e0013c872ba9551d54961c24" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.6.1" +version = "3.6.2" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] @@ -35,10 +40,10 @@ uuid = "ec485272-7323-5ecc-a04f-4719b315124d" version = "0.2.0" [[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra", "Requires", "SnoopPrecompile", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "38911c7737e123b28182d89027f4216cfc8a9da7" +deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "f83ec24f76d4c8f525099b2ac475fc098138ec31" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.4.3" +version = "7.4.11" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -64,9 +69,9 @@ version = "0.1.29" [[deps.ArrayLayouts]] deps = ["FillArrays", "LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "4efc22e4c299e49995a38d503d9dbb0544a37838" +git-tree-sha1 = "6189f7819e6345bcc097331c7db571f2f211364f" uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "1.0.4" +version = "1.1.1" [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" @@ -87,9 +92,9 @@ version = "0.1.5" [[deps.BlockArrays]] deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra"] -git-tree-sha1 = "c7d7789c2c6ec98ec78ea5e017485549a95b051e" +git-tree-sha1 = "174b4970af15a500a29e76151f5c53195784b9d4" uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" -version = "0.16.27" +version = "0.16.36" [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -98,10 +103,10 @@ uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" version = "1.0.8+0" [[deps.CPUSummary]] -deps = ["CpuId", "IfElse", "Static"] -git-tree-sha1 = "2c144ddb46b552f72d7eafe7cc2f50746e41ea21" +deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] +git-tree-sha1 = "89e0654ed8c7aebad6d5ad235d6242c2d737a928" uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.2" +version = "0.2.3" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -123,15 +128,15 @@ version = "0.1.12" [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "9c209fb7536406834aa938fb149964b985de6c83" +git-tree-sha1 = "02aa26a4cf76381be7f66e020a3eddeb27b0a092" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.1" +version = "0.7.2" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "be6ab11021cd29f0344d5c4357b163af05a48cba" +git-tree-sha1 = "d9a8f86737b665e15a9641ecbac64deef9ce6724" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.21.0" +version = "3.23.0" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] @@ -140,10 +145,14 @@ uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.11.4" [[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"] -git-tree-sha1 = "600cc5508d66b78aae350f7accdb58763ac18589" +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.9.10" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] @@ -152,9 +161,9 @@ uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.12.10" [[deps.CommonSolve]] -git-tree-sha1 = "9441451ee712d1aec22edad62db1a9af3dc8d852" +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.3" +version = "0.2.4" [[deps.CommonSubexpressions]] deps = ["MacroTools", "Test"] @@ -164,9 +173,9 @@ version = "0.3.0" [[deps.Compat]] deps = ["UUIDs"] -git-tree-sha1 = "7a60c856b9fa189eb34f5f8a6f6b5529b7942957" +git-tree-sha1 = "e460f044ca8b99be31d35fe54fc33a5c33dd8ed7" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.6.1" +version = "4.9.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -175,19 +184,19 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.2+0" +version = "1.0.5+0" [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "b306df2650947e9eb100ec125ff8c65ca2053d30" +git-tree-sha1 = "5372dbbf8f0bdb8c700db5367132925c0771ef7e" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.1.1" +version = "2.2.1" [[deps.ConstructionBase]] deps = ["LinearAlgebra"] -git-tree-sha1 = "738fec4d684a9a6ee9598a8bfee305b26831f28c" +git-tree-sha1 = "fe2838a593b5f776e1597e086dcd47560d94e816" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.2" +version = "1.5.3" [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" @@ -209,15 +218,15 @@ uuid = "adafc99b-e345-5852-983c-f28acb93d879" version = "0.3.1" [[deps.DataAPI]] -git-tree-sha1 = "e8119c1a33d267e16108be441a287a6981ba1630" +git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.14.0" +version = "1.15.0" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "d1fff3a548102f48987a52a2e0d114fa97d730f0" +git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.13" +version = "0.18.15" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -235,10 +244,10 @@ uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" version = "1.9.1" [[deps.DiffEqBase]] -deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "ed1108bd9a68977d5e0cbd8b2882293337c15f1c" +deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] +git-tree-sha1 = "ed586656058844e48660c6d6fdb384e83afc50db" uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "6.124.0" +version = "6.128.0" [deps.DiffEqBase.extensions] DiffEqBaseDistributionsExt = "Distributions" @@ -270,15 +279,19 @@ version = "1.1.0" [[deps.DiffRules]] deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "a4ad7ef19d2cdc2eff57abbbe68032b1cd0bd8f8" +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.13.0" +version = "1.15.1" [[deps.Distances]] -deps = ["LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "49eba9ad9f7ead780bfb7ee319f962c811c6d3b2" +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "b6def76ffad15143924a2199f72a5cd883a2e8a9" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.8" +version = "0.10.9" +weakdeps = ["SparseArrays"] + + [deps.Distances.extensions] + DistancesSparseArraysExt = "SparseArrays" [[deps.Distributed]] deps = ["Random", "Serialization", "Sockets"] @@ -291,8 +304,8 @@ uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" version = "0.9.3" [[deps.Documenter]] -deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "Dates", "DocStringExtensions", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "REPL", "SnoopPrecompile", "Test", "Unicode"] -git-tree-sha1 = "2afe1f1706b90fd4a8593d70b5324d04ddefed69" +deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "Dates", "DocStringExtensions", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "PrecompileTools", "REPL", "Test", "Unicode"] +git-tree-sha1 = "34e4566ad9f151fcc9a9a9c1868b2dc865fa195c" repo-rev = "master" repo-url = "https://github.com/JuliaDocs/Documenter.jl.git" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" @@ -308,11 +321,17 @@ git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" version = "1.0.4" +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "e90caa41f5a86296e014e148ee061bd6c3edec96" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.9" + [[deps.Expat_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "bad72f730e9e91c08d9427d5e8db95478a3c323d" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.4.8+0" +version = "2.5.0+0" [[deps.ExponentialUtilities]] deps = ["Adapt", "ArrayInterface", "GPUArraysCore", "GenericSchur", "LinearAlgebra", "Printf", "SnoopPrecompile", "SparseArrays", "libblastrampoline_jll"] @@ -321,9 +340,9 @@ uuid = "d4d017d3-3776-5f7e-afef-a10c40355c18" version = "1.24.0" [[deps.ExprTools]] -git-tree-sha1 = "c1d06d129da9f55715c6c212866f5b1bddc5fa00" +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.9" +version = "0.1.10" [[deps.FFMPEG]] deps = ["FFMPEG_jll"] @@ -345,9 +364,9 @@ version = "1.3.8+0" [[deps.FastBroadcast]] deps = ["ArrayInterface", "LinearAlgebra", "Polyester", "Static", "StaticArrayInterface", "StrideArraysCore"] -git-tree-sha1 = "d1248fceea0b26493fd33e8e9e8c553270da03bd" +git-tree-sha1 = "aa9925a229d45fe3018715238956766fa21804d1" uuid = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -version = "0.2.5" +version = "0.2.6" [[deps.FastClosures]] git-tree-sha1 = "acebe244d53ee1b461970f8910c235b259e772ef" @@ -356,9 +375,9 @@ version = "0.3.2" [[deps.FastLapackInterface]] deps = ["LinearAlgebra"] -git-tree-sha1 = "c1293a93193f0ae94be7cf338d33e162c39d8788" +git-tree-sha1 = "b12f05108e405dadcc2aff0008db7f831374e051" uuid = "29a986be-02c6-4525-aec4-84b980013641" -version = "1.2.9" +version = "2.0.0" [[deps.Ferrite]] deps = ["EnumX", "LinearAlgebra", "NearestNeighbors", "Preferences", "Reexport", "SparseArrays", "StaticArrays", "Tensors", "WriteVTK"] @@ -376,9 +395,9 @@ version = "0.3.14" [[deps.FerriteGmsh]] deps = ["Ferrite", "Gmsh"] -git-tree-sha1 = "ab52b403356f18bbf0a533a7e8f26c86a8da70f6" +git-tree-sha1 = "702427f9f6b2d3e39da3bfab4eea7d02f459e404" uuid = "4f95f4f8-b27c-4ae5-9a39-ea55e634e36b" -version = "1.0.0" +version = "1.0.1" [[deps.FerriteMeshParser]] deps = ["Ferrite"] @@ -391,15 +410,25 @@ uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FillArrays]] deps = ["LinearAlgebra", "Random", "SparseArrays", "Statistics"] -git-tree-sha1 = "fc86b4fd3eff76c3ce4f5e96e2fdfa6282722885" +git-tree-sha1 = "f372472e8672b1d993e93dada09e23139b509f9e" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.0.0" +version = "1.5.0" [[deps.FiniteDiff]] -deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays", "StaticArrays"] -git-tree-sha1 = "6604e18a0220650dbbea7854938768f15955dd8e" +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "c6e4a1fbe73b31a3dea94b1da449503b8830c306" uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.20.0" +version = "2.21.1" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [[deps.FixedPointNumbers]] deps = ["Statistics"] @@ -421,19 +450,19 @@ version = "0.4.2" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "00e252f4d706b3d55a8863432e742bf5717b498d" +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.35" +version = "0.10.36" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] ForwardDiffStaticArraysExt = "StaticArrays" [[deps.FreeType2_jll]] -deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "87eb71354d8ec1a96d4a7636bd57a7347dde3ef9" +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.10.4+0" +version = "2.13.1+0" [[deps.FriBidi_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -475,21 +504,21 @@ version = "6.2.1+2" [[deps.GPUArraysCore]] deps = ["Adapt"] -git-tree-sha1 = "1cd7f0af1aa58abc02ea1d872953a97359cb87fa" +git-tree-sha1 = "2d6ca471a6c7b536127afccfa7564b5b39227fe0" uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.1.4" +version = "0.1.5" [[deps.GR]] deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Preferences", "Printf", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "UUIDs", "p7zip_jll"] -git-tree-sha1 = "efaac003187ccc71ace6c755b197284cd4811bfe" +git-tree-sha1 = "d73afa4a2bb9de56077242d98cf763074ab9a970" uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" -version = "0.72.4" +version = "0.72.9" [[deps.GR_jll]] -deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt5Base_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "4486ff47de4c18cb511a0da420efebb314556316" +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "1596bab77f4f073a14c62424283e7ebff3072eca" uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" -version = "0.72.4+0" +version = "0.72.9+1" [[deps.GenericSchur]] deps = ["LinearAlgebra", "Printf"] @@ -539,10 +568,10 @@ uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" version = "1.12.2+2" [[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "69182f9a2d6add3736b7a06ab6416aafdeec2196" +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "cb56ccdd481c0dd7f975ad2b3b62d9eda088f7e2" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.8.0" +version = "1.9.14" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -552,15 +581,15 @@ version = "2.8.1+1" [[deps.HostCPUFeatures]] deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] -git-tree-sha1 = "734fd90dd2f920a2f1921d5388dcebe805b262dc" +git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.14" +version = "0.1.16" [[deps.IOCapture]] deps = ["Logging", "Random"] -git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a" +git-tree-sha1 = "d75853a0bdbfb1ac815478bacd89cd27b550ace6" uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.2" +version = "0.2.3" [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" @@ -624,15 +653,9 @@ version = "0.4.0" [[deps.Krylov]] deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "dd90aacbfb622f898a97c2a4411ac49101ebab8a" +git-tree-sha1 = "fbda7c58464204d92f3b158578fb0b3d4224cea5" uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.9.0" - -[[deps.KrylovKit]] -deps = ["ChainRulesCore", "GPUArraysCore", "LinearAlgebra", "Printf"] -git-tree-sha1 = "1a5e1d9941c783b0119897d29f2eb665d876ecf3" -uuid = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" -version = "0.6.0" +version = "0.9.3" [[deps.LAME_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -665,9 +688,9 @@ version = "1.3.0" [[deps.Latexify]] deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Printf", "Requires"] -git-tree-sha1 = "099e356f267354f46ba65087981a77da23a279b7" +git-tree-sha1 = "f428ae552340899a935973270b8d98e5a31c49fe" uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" -version = "0.16.0" +version = "0.16.1" [deps.Latexify.extensions] DataFramesExt = "DataFrames" @@ -748,10 +771,10 @@ uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" version = "2.35.0+0" [[deps.Libtiff_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "3eb79b0ca5764d4799c06699573fd8f533259713" +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "2da088d113af58221c52828a80378e16be7d037a" uuid = "89763e89-9b03-5906-acba-b20f662cd828" -version = "4.4.0+0" +version = "4.5.1+1" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -782,34 +805,44 @@ uuid = "18c40d15-f7cd-5a6d-bc92-87468d86c5db" version = "5.0.0+0" [[deps.LinearSolve]] -deps = ["ArrayInterface", "DocStringExtensions", "EnumX", "FastLapackInterface", "GPUArraysCore", "IterativeSolvers", "KLU", "Krylov", "KrylovKit", "LinearAlgebra", "Preferences", "RecursiveFactorization", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "SnoopPrecompile", "SparseArrays", "Sparspak", "SuiteSparse", "UnPack"] -git-tree-sha1 = "4a4f8cc7a59fadbb02d1852d1e0cef5dca3a9460" +deps = ["ArrayInterface", "DocStringExtensions", "EnumX", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "Libdl", "LinearAlgebra", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "SuiteSparse", "UnPack"] +git-tree-sha1 = "f746a5b9522815bf098049f9cbfbfcae53f29450" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "1.42.0" +version = "2.5.0" [deps.LinearSolve.extensions] - LinearSolveHYPRE = "HYPRE" + LinearSolveCUDAExt = "CUDA" + LinearSolveHYPREExt = "HYPRE" + LinearSolveIterativeSolversExt = "IterativeSolvers" + LinearSolveKrylovKitExt = "KrylovKit" + LinearSolveMKLExt = "MKL_jll" + LinearSolvePardisoExt = "Pardiso" [deps.LinearSolve.weakdeps] + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" HYPRE = "b5ffcf37-a2bd-41ab-a3da-4bd9bc8ad771" + IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" + KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" + MKL_jll = "856f044c-d86e-5d09-b602-aeab76dc8ba7" + Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" [[deps.Literate]] deps = ["Base64", "IOCapture", "JSON", "REPL"] -git-tree-sha1 = "1c4418beaa6664041e0f9b48f0710f57bff2fcbe" +git-tree-sha1 = "a1a0d4ff9f785a2184baca7a5c89e664f144143d" uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -version = "2.14.0" +version = "2.14.1" [[deps.LiveServer]] -deps = ["HTTP", "MIMEs", "Pkg", "Sockets"] -git-tree-sha1 = "494010f12dd98fa0d558cb7679b7c21d3a0a430a" +deps = ["HTTP", "LoggingExtras", "MIMEs", "Pkg", "Sockets", "Test"] +git-tree-sha1 = "24d05efe53436b22a42bf2ae459f47c48b0c2603" uuid = "16fef848-5104-11e9-1b77-fb7a48bbb589" -version = "1.2.0" +version = "1.2.7" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "0a1b7c2863e44523180fdb3146534e265a91870b" +git-tree-sha1 = "c3ce8e7420b3a6e071e0fe4745f5d4300e37b13f" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.23" +version = "0.3.24" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -832,9 +865,9 @@ version = "1.0.0" [[deps.LoopVectorization]] deps = ["ArrayInterface", "ArrayInterfaceCore", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "e7ce3cdc520da8135e73d7cb303e0617a19f582b" +git-tree-sha1 = "c88a4afe1703d731b1c4fdf4e3c7e77e3b176ea2" uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.158" +version = "0.12.165" weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] [deps.LoopVectorization.extensions] @@ -942,10 +975,10 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.NonlinearSolve]] -deps = ["ArrayInterface", "DiffEqBase", "EnumX", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "LinearSolve", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SnoopPrecompile", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "a6000c813371cd3cd9cbbdf8a356fc3a97138d92" +deps = ["ArrayInterface", "DiffEqBase", "EnumX", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "LinearSolve", "PrecompileTools", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "UnPack"] +git-tree-sha1 = "23dabe80f8ebec9a68b0db4cd02f2d2cdbc4f653" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "1.6.0" +version = "1.9.0" [[deps.OCCT_jll]] deps = ["Artifacts", "FreeType2_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll", "Xorg_libXfixes_jll", "Xorg_libXft_jll", "Xorg_libXinerama_jll", "Xorg_libXrender_jll"] @@ -955,9 +988,9 @@ version = "7.6.2+2" [[deps.OffsetArrays]] deps = ["Adapt"] -git-tree-sha1 = "82d7c9e310fe55aa54996e6f7f94674e2a38fcb4" +git-tree-sha1 = "2ac17d29c523ce1cd38e27785a7d23024853a4bb" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.12.9" +version = "1.12.10" [[deps.Ogg_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -982,10 +1015,10 @@ uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" version = "1.4.1" [[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "9ff31d101d987eb9d66bd8b176ac7c277beccd09" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "bbb5c2115d63c2f1451cb70e5ef75e8fe4707019" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "1.1.20+0" +version = "1.1.22+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -995,9 +1028,9 @@ version = "0.5.5+0" [[deps.Optim]] deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "a89b11f0f354f06099e4001c151dffad7ebab015" +git-tree-sha1 = "e3a6546c1577bfd701771b477b794a52949e7594" uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.7.5" +version = "1.7.6" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1006,21 +1039,27 @@ uuid = "91d4177d-7536-5919-b921-800302f37372" version = "1.3.2+0" [[deps.OrderedCollections]] -git-tree-sha1 = "d321bf2de576bf25ec4d3e4360faca399afca282" +git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.0" +version = "1.6.2" [[deps.OrdinaryDiffEq]] -deps = ["Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "IfElse", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "LoopVectorization", "MacroTools", "MuladdMacro", "NLsolve", "NonlinearSolve", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLNLSolve", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "SparseDiffTools", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "47fc5cf4174a7d45fa541669abc5405d9ef6b8df" +deps = ["ADTypes", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "IfElse", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "LoopVectorization", "MacroTools", "MuladdMacro", "NLsolve", "NonlinearSolve", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLNLSolve", "SciMLOperators", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "SparseDiffTools", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] +git-tree-sha1 = "47c560dcb059570bdbd9f887a6b8958190e498a4" uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -version = "6.51.1" +version = "6.53.4" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" version = "10.42.0+0" +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "f9b1e033c2b1205cf30fd119f4e50881316c1923" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.1" +weakdeps = ["Requires", "TOML"] + [[deps.Parameters]] deps = ["OrderedCollections", "UnPack"] git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" @@ -1028,10 +1067,10 @@ uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" version = "0.12.3" [[deps.Parsers]] -deps = ["Dates", "SnoopPrecompile"] -git-tree-sha1 = "478ac6c952fddd4399e71d4779797c538d0ff2bf" +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.5.8" +version = "2.7.2" [[deps.Pipe]] git-tree-sha1 = "6842804e7867b115ca9de748a0cf6b364523c16d" @@ -1039,15 +1078,15 @@ uuid = "b98c9c47-44ae-5843-9183-064241ee97a0" version = "1.3.0" [[deps.Pixman_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "b4f5d02549a10e20780a24fce72bea96b6329e29" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.40.1+0" +version = "0.42.2+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.9.0" +version = "1.9.2" [[deps.PlotThemes]] deps = ["PlotUtils", "Statistics"] @@ -1062,10 +1101,10 @@ uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" version = "1.3.5" [[deps.Plots]] -deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Preferences", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs", "UnicodeFun", "Unzip"] -git-tree-sha1 = "6c7f47fd112001fc95ea1569c2757dffd9e81328" +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Preferences", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "9f8675a55b37a70aa23177ec110f6e3f4dd68466" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -version = "1.38.11" +version = "1.38.17" [deps.Plots.extensions] FileIOExt = "FileIO" @@ -1083,9 +1122,9 @@ version = "1.38.11" [[deps.Polyester]] deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Requires", "Static", "StaticArrayInterface", "StrideArraysCore", "ThreadingUtilities"] -git-tree-sha1 = "0fe4e7c4d8ff4c70bfa507f0dd96fa161b115777" +git-tree-sha1 = "3d811babe092a6e7b130beee84998fe7663348b6" uuid = "f517fe37-dbe3-4b94-8317-1923a5111588" -version = "0.7.3" +version = "0.7.5" [[deps.PolyesterWeave]] deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] @@ -1113,9 +1152,9 @@ version = "0.4.12" [[deps.PrecompileTools]] deps = ["Preferences"] -git-tree-sha1 = "259e206946c293698122f63e2b513a7c99a244e8" +git-tree-sha1 = "9673d39decc5feece56ef3940e5dafba15ba0f81" uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.1.1" +version = "1.1.2" [[deps.Preferences]] deps = ["TOML"] @@ -1133,11 +1172,11 @@ git-tree-sha1 = "d7a7aef8f8f2d537104f170139553b14dfe39fe9" uuid = "92933f4c-e287-5a05-a399-4b506db050ca" version = "1.7.2" -[[deps.Qt5Base_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"] -git-tree-sha1 = "0c03844e2231e12fda4d0086fd7cbe4098ee8dc5" -uuid = "ea2cea3b-5b76-57ae-a6ef-0a8af62496e1" -version = "5.15.3+2" +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"] +git-tree-sha1 = "364898e8f13f7eaaceec55fd3d08680498c0aa6e" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.4.2+3" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] @@ -1161,9 +1200,9 @@ version = "0.6.12" [[deps.RecursiveArrayTools]] deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "Requires", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "68078e9fa9130a6a768815c48002d0921a232c11" +git-tree-sha1 = "7ed35fb5f831aaf09c2d7c8736d44667a1afdcb0" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "2.38.4" +version = "2.38.7" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsMeasurementsExt = "Measurements" @@ -1176,10 +1215,10 @@ version = "2.38.4" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.RecursiveFactorization]] -deps = ["LinearAlgebra", "LoopVectorization", "Polyester", "SnoopPrecompile", "StrideArraysCore", "TriangularSolve"] -git-tree-sha1 = "9088515ad915c99026beb5436d0a09cd8c18163e" +deps = ["LinearAlgebra", "LoopVectorization", "Polyester", "PrecompileTools", "StrideArraysCore", "TriangularSolve"] +git-tree-sha1 = "2b6d4a40339aa02655b1743f4cd7c03109f520c1" uuid = "f2c3362d-daeb-58d1-803e-2bc74f2840b4" -version = "0.2.18" +version = "0.2.20" [[deps.Reexport]] git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" @@ -1200,9 +1239,9 @@ version = "1.3.0" [[deps.RuntimeGeneratedFunctions]] deps = ["ExprTools", "SHA", "Serialization"] -git-tree-sha1 = "d7d9ebe28062161c1e314ed643097b0c6fe657d9" +git-tree-sha1 = "6aacc5eefe8415f47b3e34214c1d79d2674a0ba2" uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47" -version = "0.5.7" +version = "0.5.12" [[deps.SCOTCH_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] @@ -1215,10 +1254,10 @@ uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" [[deps.SIMD]] -deps = ["SnoopPrecompile"] -git-tree-sha1 = "8b20084a97b004588125caebf418d8cab9e393d1" +deps = ["PrecompileTools"] +git-tree-sha1 = "0e270732477b9e551d884e6b07e23bb2ec947790" uuid = "fdea26ae-647d-5447-a871-4b548cad5224" -version = "3.4.4" +version = "3.4.5" [[deps.SIMDTypes]] git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" @@ -1227,27 +1266,27 @@ version = "0.1.0" [[deps.SLEEFPirates]] deps = ["IfElse", "Static", "VectorizationBase"] -git-tree-sha1 = "cda0aece8080e992f6370491b08ef3909d1c04e7" +git-tree-sha1 = "4b8586aece42bee682399c4c4aee95446aa5cd19" uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" -version = "0.6.38" +version = "0.6.39" [[deps.SciMLBase]] -deps = ["ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "Preferences", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SnoopPrecompile", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces"] -git-tree-sha1 = "392d3e28b05984496af37100ded94dc46fa6c8de" +deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces"] +git-tree-sha1 = "04370090604cd399db5bebddb636d80ab9d338e9" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "1.91.7" +version = "1.94.0" [[deps.SciMLNLSolve]] deps = ["DiffEqBase", "LineSearches", "NLsolve", "Reexport", "SciMLBase"] -git-tree-sha1 = "a8eb97c56cac50c21096582afb2a0110784dc36e" +git-tree-sha1 = "9dfc8e9e3d58c0c74f1a821c762b5349da13eccf" uuid = "e9a6253c-8580-4d32-9898-8661bb511710" -version = "0.1.6" +version = "0.1.8" [[deps.SciMLOperators]] deps = ["ArrayInterface", "DocStringExtensions", "Lazy", "LinearAlgebra", "Setfield", "SparseArrays", "StaticArraysCore", "Tricks"] -git-tree-sha1 = "5950ad7bec86ba22e4861db61d031625a26a9ec3" +git-tree-sha1 = "65c2e6ced6f62ea796af251eb292a0e131a3613b" uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "0.2.3" +version = "0.3.6" [[deps.Scratch]] deps = ["Dates"] @@ -1280,13 +1319,13 @@ uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" version = "1.1.0" [[deps.SimpleNonlinearSolve]] -deps = ["ArrayInterface", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "Reexport", "Requires", "SciMLBase", "SnoopPrecompile", "StaticArraysCore"] -git-tree-sha1 = "54c78ac3cc0343a16785adabe5bbf4063c737967" +deps = ["ArrayInterface", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "PackageExtensionCompat", "PrecompileTools", "Reexport", "SciMLBase", "StaticArraysCore"] +git-tree-sha1 = "20aa9831d654bab67ed561e78917047143ecb9bf" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "0.1.14" +version = "0.1.19" [deps.SimpleNonlinearSolve.extensions] - SimpleBatchedNonlinearSolveExt = "NNlib" + SimpleNonlinearSolveNNlibExt = "NNlib" [deps.SimpleNonlinearSolve.weakdeps] NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" @@ -1313,19 +1352,25 @@ uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "a4ada03f999bd01b3a25dcaa30b2d929fe537e00" +git-tree-sha1 = "c60ec5c62180f27efea3ba2908480f8055e17cee" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.1.0" +version = "1.1.1" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [[deps.SparseDiffTools]] -deps = ["Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "Requires", "SparseArrays", "StaticArrays", "VertexSafeGraphs"] -git-tree-sha1 = "e19ac47477c9a8fcca06dab5e5471417d5d9d723" +deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "Reexport", "Requires", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "VertexSafeGraphs"] +git-tree-sha1 = "4c1a57bcbc0b795fbfdc2009e70f9c2fd2815bfe" uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804" -version = "1.31.0" +version = "2.4.1" + + [deps.SparseDiffTools.extensions] + SparseDiffToolsZygoteExt = "Zygote" + + [deps.SparseDiffTools.weakdeps] + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.Sparspak]] deps = ["Libdl", "LinearAlgebra", "Logging", "OffsetArrays", "Printf", "SparseArrays", "Test"] @@ -1335,9 +1380,9 @@ version = "0.3.9" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "ef28127915f4229c971eb43f3fc075dd3fe91880" +git-tree-sha1 = "7beb031cf8145577fbccacd94b8a8f4ce78428d3" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.2.0" +version = "2.3.0" weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] @@ -1345,9 +1390,9 @@ weakdeps = ["ChainRulesCore"] [[deps.Static]] deps = ["IfElse"] -git-tree-sha1 = "08be5ee09a7632c32695d954a602df96a877bf0d" +git-tree-sha1 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "0.8.6" +version = "0.8.8" [[deps.StaticArrayInterface]] deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "Requires", "SnoopPrecompile", "SparseArrays", "Static", "SuiteSparse"] @@ -1361,15 +1406,19 @@ weakdeps = ["OffsetArrays", "StaticArrays"] StaticArrayInterfaceStaticArraysExt = "StaticArrays" [[deps.StaticArrays]] -deps = ["LinearAlgebra", "Random", "StaticArraysCore", "Statistics"] -git-tree-sha1 = "c262c8e978048c2b095be1672c9bee55b4619521" +deps = ["LinearAlgebra", "Random", "StaticArraysCore"] +git-tree-sha1 = "9cabadf6e7cd2349b6cf49f1915ad2028d65e881" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.5.24" +version = "1.6.2" +weakdeps = ["Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysStatisticsExt = "Statistics" [[deps.StaticArraysCore]] -git-tree-sha1 = "6b7ba252635a5eff6a0b0664a41ee140a1c9e72a" +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.0" +version = "1.4.2" [[deps.Statistics]] deps = ["LinearAlgebra", "SparseArrays"] @@ -1384,15 +1433,15 @@ version = "1.6.0" [[deps.StatsBase]] deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "d1bf48bfcc554a3761a133fe3a9bb01488e06916" +git-tree-sha1 = "75ebe04c5bed70b91614d684259b661c9e6274a4" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.33.21" +version = "0.34.0" [[deps.StrideArraysCore]] deps = ["ArrayInterface", "CloseOpenIntervals", "IfElse", "LayoutPointers", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface", "ThreadingUtilities"] -git-tree-sha1 = "b3e9c174a9df77ed7b66fc0aa605def3351a0653" +git-tree-sha1 = "f02eb61eb5c97b48c153861c72fbbfdddc607e06" uuid = "7792a7ef-975c-4747-a70f-980b88e8d1da" -version = "0.4.13" +version = "0.4.17" [[deps.SuiteSparse]] deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] @@ -1438,10 +1487,10 @@ uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" version = "0.1.1" [[deps.Tensors]] -deps = ["ForwardDiff", "LinearAlgebra", "SIMD", "SnoopPrecompile", "StaticArrays", "Statistics"] -git-tree-sha1 = "71f054343e85ab1eab12bf8336004309002ff82d" +deps = ["ForwardDiff", "LinearAlgebra", "PrecompileTools", "SIMD", "StaticArrays", "Statistics"] +git-tree-sha1 = "bcbb366323add300742c9e4a5447e584640aeff2" uuid = "48a634ad-e948-5137-8d70-aa71f2a747f4" -version = "1.13.1" +version = "1.15.0" [[deps.Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] @@ -1449,9 +1498,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.ThreadingUtilities]] deps = ["ManualMemory"] -git-tree-sha1 = "c97f60dd4f2331e1a495527f80d242501d2f9865" +git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" -version = "0.5.1" +version = "0.5.2" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] @@ -1478,14 +1527,14 @@ version = "0.1.7" [[deps.TruncatedStacktraces]] deps = ["InteractiveUtils", "MacroTools", "Preferences"] -git-tree-sha1 = "7bc1632a4eafbe9bd94cf1a784a9a4eb5e040a91" +git-tree-sha1 = "ea3e54c2bdde39062abf5a9758a23735558705e1" uuid = "781d530d-4396-4725-bb49-402e4bee1e77" -version = "1.3.0" +version = "1.4.0" [[deps.URIs]] -git-tree-sha1 = "074f993b0ca030848b897beff716d93aca60f06a" +git-tree-sha1 = "b7a5e99f24892b6824a954199a45e9ffcc1c70f0" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.4.2" +version = "1.5.0" [[deps.UUIDs]] deps = ["Random", "SHA"] @@ -1505,6 +1554,26 @@ git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" version = "0.4.1" +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "64eb17acef1d9734cf09967539818f38093d9b35" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.16.2" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + InverseFunctionsUnitfulExt = "InverseFunctions" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "e2d817cc500e960fdbafcf988ac8436ba3208bfd" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.6.3" + [[deps.Unzip]] git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" @@ -1557,17 +1626,23 @@ git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" uuid = "aed1982a-8fda-507f-9586-7b0439959a61" version = "1.1.34+0" +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "cf2c7de82431ca6f39250d2fc4aacd0daa1675c0" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.4.4+0" + [[deps.Xorg_libX11_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] -git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" -version = "1.6.9+4" +version = "1.8.6+0" [[deps.Xorg_libXau_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" -version = "1.0.9+4" +version = "1.0.11+0" [[deps.Xorg_libXcursor_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] @@ -1576,10 +1651,10 @@ uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" version = "1.2.0+4" [[deps.Xorg_libXdmcp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" -version = "1.1.3+4" +version = "1.1.4+0" [[deps.Xorg_libXext_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] @@ -1624,22 +1699,22 @@ uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" version = "0.9.10+4" [[deps.Xorg_libpthread_stubs_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" -version = "0.1.0+3" +version = "0.1.1+0" [[deps.Xorg_libxcb_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] -git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6" +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.13.0+3" +version = "1.15.0+0" [[deps.Xorg_libxkbfile_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "730eeca102434283c50ccf7d1ecdadf521a765a4" uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" -version = "1.1.0+4" +version = "1.1.2+0" [[deps.Xorg_xcb_util_image_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] @@ -1672,22 +1747,22 @@ uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" version = "0.4.1+1" [[deps.Xorg_xkbcomp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"] -git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "330f955bc41bb8f5270a369c473fc4a5a4e4d3cb" uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" -version = "1.4.2+4" +version = "1.4.6+0" [[deps.Xorg_xkeyboard_config_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"] -git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "691634e5453ad362044e2ad653e79f3ee3bb98c3" uuid = "33bec58e-1273-512f-9401-5d533626f822" -version = "2.27.0+4" +version = "2.39.0+0" [[deps.Xorg_xtrans_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" -version = "1.4.0+3" +version = "1.5.0+0" [[deps.Zlib_jll]] deps = ["Libdl"] diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index c565e40521..bdb6c5bdad 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -1,3 +1,4 @@ + include("GeometryValues.jl") include("FunctionValues.jl") @@ -7,13 +8,15 @@ end struct CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCellValues geo_values::GeometryValues{dMdξ_t, GIP, T} + detJdV::Vector{T} fun_values::FunctionValues{IP, N_t, dNdx_t, dNdξ_t} qr::QR end function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation) where T geo_values = GeometryValues(T, ip_geo.ip, qr) fun_values = FunctionValues(T, ip_fun, qr, ip_geo) - return CellValues(geo_values, fun_values, qr) + detJdV = fill(T(NaN), length(getweights(qr))) + return CellValues(geo_values, detJdV, fun_values, qr) end CellValues(qr::QuadratureRule, ip::Interpolation, args...) = CellValues(Float64, qr, ip, args...) @@ -22,11 +25,12 @@ function CellValues(::Type{T}, qr, ip::Interpolation, ip_geo::ScalarInterpolatio end # Access geometry values -for op = (:getdetJdV, :getngeobasefunctions, :geometric_value) +for op = (:getngeobasefunctions, :geometric_value) eval(quote @propagate_inbounds $op(cv::CellValues, args...) = $op(cv.geo_values, args...) end) end +getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] # Accessors for function values getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) @@ -45,8 +49,11 @@ function reinit!(cv::CellValues, x::AbstractVector{<:Vec}) throw_incompatible_coord_length(length(x), n_geom_basefuncs) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) - Jinv = calculate_mapping(geo_values, q_point, w, x) - apply_mapping!(cv.fun_values, q_point, Jinv) + mapping = calculate_mapping(geo_values, q_point, x) + detJ = calculate_detJ(getjacobian(mapping)) + detJ > 0.0 || throw_detJ_not_pos(detJ) + @inbounds cv.detJdV[q_point] = detJ*w + apply_mapping!(cv.fun_values, q_point, mapping) end return nothing end diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 27f33e3de7..9514f471ea 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -1,55 +1,18 @@ -struct FaceGeometryValues{dMdξ_t, GIP, T, Normal_t} - M::Matrix{T} - dMdξ::Matrix{dMdξ_t} +struct FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP} <: AbstractFaceValues + geo_values::Vector{GeometryValues{dMdξ_t, GIP, T}} detJdV::Vector{T} normals::Vector{Normal_t} - ip::GIP -end -function FaceGeometryValues(::Type{T}, ip_vec::VectorizedInterpolation{sdim}, qr::QuadratureRule) where {T,sdim} - ip = ip_vec.ip - n_shape = getnbasefunctions(ip) - n_qpoints = getnquadpoints(qr) - M = zeros(T, n_shape, n_qpoints) - dMdξ = zeros(Vec{getdim(ip),T}, n_shape, n_qpoints) - for (qp, ξ) in pairs(getpoints(qr)) - for i in 1:n_shape - dMdξ[i, qp], M[i, qp] = shape_gradient_and_value(ip, ξ, i) - end - end - normals = fill(zero(Vec{sdim,T})*T(NaN), n_qpoints) - detJdV = fill(T(NaN), n_qpoints) - return FaceGeometryValues(M, dMdξ, detJdV, normals, ip) -end - -getngeobasefunctions(geovals::FaceGeometryValues) = size(geovals.M, 1) -@propagate_inbounds geometric_value(geovals::FaceGeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] -@propagate_inbounds getdetJdV(geovals::FaceGeometryValues, q_point::Int) = geovals.detJdV[q_point] -@propagate_inbounds getnormal(geovals::FaceGeometryValues, q_point::Int) = geovals.normals[q_point] - -@inline function calculate_mapping(geo_values::FaceGeometryValues{<:Vec{dim,T}}, face_nr::Int, q_point, w, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} - fefv_J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) - @inbounds for j in 1:getngeobasefunctions(geo_values) - fefv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] - end - weight_norm = weighted_normal(fefv_J, getrefshape(geo_values.ip), face_nr) - detJ = norm(weight_norm) - detJ > 0.0 || throw_detJ_not_pos(detJ) - @inbounds geo_values.detJdV[q_point] = detJ*w - @inbounds geo_values.normals[q_point] = weight_norm / norm(weight_norm) - return inv(fefv_J) -end - -struct FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP} <: AbstractFaceValues - geo_values::Vector{FaceGeometryValues{dMdξ_t, GIP, T, Normal_t}} fun_values::Vector{FunctionValues{IP, N_t, dNdx_t, dNdξ_t}} qr::QR # FaceQuadratureRule current_face::ScalarWrapper{Int} end -function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation=default_geometric_interpolation(ip_fun)) where T - geo_values = [FaceGeometryValues(T, ip_geo, qr) for qr in fqr.face_rules] +function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun)) where {T,sdim} + geo_values = [GeometryValues(T, ip_geo.ip, qr) for qr in fqr.face_rules] fun_values = [FunctionValues(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] - return FaceValues(geo_values, fun_values, fqr, ScalarWrapper(1)) + detJdV = fill(T(NaN), maximum(qr->length(getweights(qr)), fqr.face_rules)) + normals = fill(zero(Vec{sdim,T})*T(NaN), length(geo_values)) + return FaceValues(geo_values, detJdV, normals, fun_values, fqr, ScalarWrapper(1)) end FaceValues(qr::FaceQuadratureRule, ip::Interpolation, args...) = FaceValues(Float64, qr, ip, args...) @@ -60,9 +23,10 @@ end getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_values(fv)) getnbasefunctions(fv::FaceValues) = getnbasefunctions(get_fun_values(fv)) getnquadpoints(fv::FaceValues) = getnquadpoints(fv.qr, getcurrentface(fv)) +getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] get_geo_values(fv::FaceValues) = @inbounds fv.geo_values[getcurrentface(fv)] -for op = (:getdetJdV, :getngeobasefunctions, :geometric_value) +for op = (:getngeobasefunctions, :geometric_value) eval(quote @propagate_inbounds $op(fv::FaceValues, args...) = $op(get_geo_values(fv), args...) end) @@ -89,7 +53,7 @@ getcurrentface(fv::FaceValues) = fv.current_face[] Return the normal at the quadrature point `qp` for the active face of the `FaceValues` object(from last `reinit!`). """ -getnormal(fv::FaceValues, qp::Int) = getnormal(get_geo_values(fv), qp) +getnormal(fv::FaceValues, qp::Int) = fv.normals[qp] nfaces(fv::FaceValues) = length(fv.geo_values) @@ -108,8 +72,14 @@ function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int) wh geo_values = get_geo_values(fv) fun_values = get_fun_values(fv) @inbounds for (q_point, w) in pairs(getweights(fv.qr, face_nr)) - Jinv = calculate_mapping(geo_values, face_nr, q_point, w, x) - apply_mapping!(fun_values, q_point, Jinv) + mapping = calculate_mapping(geo_values, q_point, x) + J = getjacobian(mapping) + weight_norm = weighted_normal(J, getrefshape(geo_values.ip), face_nr) + detJ = norm(weight_norm) + detJ > 0.0 || throw_detJ_not_pos(detJ) + @inbounds fv.detJdV[q_point] = detJ*w + @inbounds fv.normals[q_point] = weight_norm / norm(weight_norm) + apply_mapping!(fun_values, q_point, mapping) end end diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 14a56a0e52..95245cb494 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -58,6 +58,26 @@ getnbasefunctions(funvals::FunctionValues) = size(funvals.N, 1) @propagate_inbounds shape_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.dNdx[base_func, q_point] @propagate_inbounds shape_symmetric_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = symmetric(shape_gradient(funvals, q_point, base_func)) +# Mapping types +struct IdentityMapping end +struct CovariantPiolaMapping end +struct ContravariantPiolaMapping end +# Not yet implemented: +# struct DoubleCovariantPiolaMapping end +# struct DoubleContravariantPiolaMapping end + +get_mapping_type(::FunctionValues{<:ScalarInterpolation}) = IdentityMapping() +get_mapping_type(::FunctionValues{<:VectorizedInterpolation}) = IdentityMapping() +#get_mapping_type(::FunctionValues{<:HdivIP}) = ContravariantPiolaMapping() +#get_mapping_type(::FunctionValues{<:HcurlIP}) = CovariantPiolaMapping() + +requires_hessian(::IdentityMapping) = false +requires_hessian(::ContravariantPiolaMapping) = true +requires_hessian(::CovariantPiolaMapping) = true + + +calculate_Jinv(J::Tensor{2}) = inv(J) +calculate_Jinv(J::SMatrix) = pinv(J) # Hotfix to get the dots right for embedded elements until mixed tensors are merged. # Scalar/Vector interpolations with sdim == rdim (== vdim) @@ -69,10 +89,25 @@ getnbasefunctions(funvals::FunctionValues) = size(funvals.N, 1) # Vector interpolations with sdim > rdim @inline dothelper(B::SMatrix{vdim, rdim}, A::SMatrix{rdim, sdim}) where {vdim, rdim, sdim} = B * A -@inline function apply_mapping!(funvals::FunctionValues, q_point::Int, Jinv) +@inline function apply_mapping!(funvals::FunctionValues, args...) + return apply_mapping!(funvals, get_mapping_type(funvals), args...) +end + +@inline function apply_mapping!(funvals::FunctionValues, ::IdentityMapping, q_point::Int, mapping_values) + Jinv = calculate_Jinv(getjacobian(mapping_values)) @inbounds for j in 1:getnbasefunctions(funvals) #funvals.dNdx[j, q_point] = funvals.dNdξ[j, q_point] ⋅ Jinv # TODO via Tensors.jl funvals.dNdx[j, q_point] = dothelper(funvals.dNdξ[j, q_point], Jinv) end return nothing -end \ No newline at end of file +end +#= +@inline function apply_mapping!(funvals::FunctionValues, ::IdentityMapping, q_point::Int, mapping_values) + Jinv = inv(getjacobian(mapping_values)) + @inbounds for j in 1:getnbasefunctions(funvals) + #funvals.dNdx[j, q_point] = funvals.dNdξ[j, q_point] ⋅ Jinv # TODO via Tensors.jl + funvals.dNdx[j, q_point] = dothelper(funvals.dNdξ[j, q_point], Jinv) + end + return nothing +end +=# \ No newline at end of file diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index e9ad79daa2..e36855b3e0 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -1,7 +1,14 @@ +struct MappingValues{JT, HT<:Union{Nothing,AbstractTensor{3}}} + J::JT # dx/dξ # Jacobian + H::HT # dJ/dξ # Hessian +end +@inline getjacobian(mv::MappingValues) = mv.J +@inline gethessian(mv::MappingValues) = mv.H + + struct GeometryValues{dMdξ_t, GIP, T} M::Matrix{T} dMdξ::Matrix{dMdξ_t} - detJdV::Vector{T} ip::GIP end function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T @@ -15,25 +22,22 @@ function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) dMdξ[i, qp], M[i, qp] = shape_gradient_and_value(ip, ξ, i) end end - detJdV::Vector{T} = fill(T(NaN), n_qpoints) - return GeometryValues(M, dMdξ, detJdV, ip) + return GeometryValues(M, dMdξ, ip) end getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) @propagate_inbounds geometric_value(geovals::GeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] -@propagate_inbounds getdetJdV(geovals::GeometryValues, q_point::Int) = geovals.detJdV[q_point] -@inline function calculate_mapping(geo_values::GeometryValues{<:Vec{dim,T}}, q_point, w, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} +@inline function calculate_mapping(geo_values::GeometryValues{<:Vec{dim,T}}, q_point, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} fecv_J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) @inbounds for j in 1:getngeobasefunctions(geo_values) fecv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] end - detJ = det(fecv_J) - detJ > 0.0 || throw_detJ_not_pos(detJ) - @inbounds geo_values.detJdV[q_point] = detJ*w - return inv(fecv_J) + return MappingValues(fecv_J, nothing) end +calculate_detJ(J::Tensor{2}) = det(J) +calculate_detJ(J::SMatrix) = embedding_det(J) # Embedded @@ -66,7 +70,7 @@ See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-di """ embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}}) = norm(J) -@inline function calculate_mapping(geo_values::GeometryValues{<:Vec{rdim,T}}, q_point, w, x::AbstractVector{<:Vec{sdim,T}}) where {rdim,sdim,T} +@inline function calculate_mapping(geo_values::GeometryValues{<:Vec{rdim,T}}, q_point, x::AbstractVector{<:Vec{sdim,T}}) where {rdim,sdim,T} n_geom_basefuncs = getngeobasefunctions(geo_values) fecv_J = zero(MMatrix{sdim, rdim, T}) # TODO replace with MixedTensor (see https://github.com/Ferrite-FEM/Tensors.jl/pull/188) for j in 1:n_geom_basefuncs @@ -75,10 +79,5 @@ embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}}) = norm(J) fecv_J[k, l] += x[j][k] * geo_values.dMdξ[j, q_point][l] end end - fecv_J = SMatrix(fecv_J) - detJ = embedding_det(fecv_J) - detJ > 0.0 || throw_detJ_not_pos(detJ) - @inbounds geo_values.detJdV[q_point] = detJ * w - # Compute "left inverse" of J - return pinv(fecv_J) + return MappingValues(SMatrix(fecv_J), nothing) end \ No newline at end of file diff --git a/test/test_facevalues.jl b/test/test_facevalues.jl index 1ab9ef9594..7e68c46314 100644 --- a/test/test_facevalues.jl +++ b/test/test_facevalues.jl @@ -102,6 +102,7 @@ for (scalar_interpol, quad_rule) in ( if hasmethod(pointer, Tuple{typeof(v)}) @test pointer(v) != pointer(vc) end + v != vc && println(typeof(fv)) @test v == vc end end From bb47cdb6fec5c4a8e571c52d68dca3de808b8d3f Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 12 Aug 2023 11:46:54 +0200 Subject: [PATCH 009/145] Fix construction of FaceValues --- src/FEValues/FaceValues.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 9514f471ea..6ad5db4ef0 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -10,8 +10,9 @@ end function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun)) where {T,sdim} geo_values = [GeometryValues(T, ip_geo.ip, qr) for qr in fqr.face_rules] fun_values = [FunctionValues(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] - detJdV = fill(T(NaN), maximum(qr->length(getweights(qr)), fqr.face_rules)) - normals = fill(zero(Vec{sdim,T})*T(NaN), length(geo_values)) + max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) + detJdV = fill(T(NaN), max_nquadpoints) + normals = fill(zero(Vec{sdim,T})*T(NaN), max_nquadpoints) return FaceValues(geo_values, detJdV, normals, fun_values, fqr, ScalarWrapper(1)) end From 7ae714e410f2e5a403c0e68f945f2f0dccc7aafe Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 28 Aug 2023 15:25:22 +0200 Subject: [PATCH 010/145] Trying out to get RT working --- src/FEValues/FunctionValues.jl | 5 +++-- src/interpolations.jl | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 95245cb494..30ed0ebfe8 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -66,8 +66,9 @@ struct ContravariantPiolaMapping end # struct DoubleCovariantPiolaMapping end # struct DoubleContravariantPiolaMapping end -get_mapping_type(::FunctionValues{<:ScalarInterpolation}) = IdentityMapping() -get_mapping_type(::FunctionValues{<:VectorizedInterpolation}) = IdentityMapping() +get_mapping_type(fv::FunctionValues) = get_mapping_type(fv.ip) +#get_mapping_type(::FunctionValues{<:ScalarInterpolation}) = IdentityMapping() +#get_mapping_type(::FunctionValues{<:VectorizedInterpolation}) = IdentityMapping() #get_mapping_type(::FunctionValues{<:HdivIP}) = ContravariantPiolaMapping() #get_mapping_type(::FunctionValues{<:HcurlIP}) = CovariantPiolaMapping() diff --git a/src/interpolations.jl b/src/interpolations.jl index 46e4a2576a..2803e82eac 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1374,3 +1374,25 @@ function shape_gradient_and_value(ipv::VectorizedInterpolation{vdim, shape}, ξ: end reference_coordinates(ip::VectorizedInterpolation) = reference_coordinates(ip.ip) + + +get_mapping_type(::Interpolation) = IdentityMapping() + +# https://defelement.com/elements/raviart-thomas.html +# https://defelement.com/elements/qdiv.html +struct RaviartThomas{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end + +facedof_interior_indices(ip::RaviartThomas) = facedof_indices(ip) + +getnbasefunctions(::RaviartThomas{2,RefTriangle,1}) = 3 +facedof_indices(::RaviartThomas{2,RefTriangle,1}) = ((1,), (2,), (3,)) +adjust_dofs_during_distribution(::RaviartThomas) = false # Not sure how this works, but should be done for higher orders +# https://defelement.com/elements/examples/triangle-N1div-1.html +function shape_value(ip::RaviartThomas{2,RefTriangle,1}, ξ::Vec{2}, i::Int) + ξ_x, ξ_y = ξ + i == 1 && return -ξ + i == 2 && return Vec(ξ_x-1, ξ_y) + i == 3 && return Vec(-ξ_x, 1 - ξ_y) + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + From 7f484ebc28fa17875a931d6ed556c13ef2acf734 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 28 Aug 2023 21:05:35 +0200 Subject: [PATCH 011/145] Add definition of positive faces and edges --- src/Grid/grid.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Grid/grid.jl b/src/Grid/grid.jl index d21e0962b5..2fe1f78422 100644 --- a/src/Grid/grid.jl +++ b/src/Grid/grid.jl @@ -732,6 +732,22 @@ end ################################# #### Orientation of Entities #### ################################# +function face_sign(::AbstractCell{<:AbstractRefShape{1}}, facenr) + error("Not defined") +end +function face_sign(cell::AbstractCell{<:AbstractRefShape{2}}, facenr) + vertices = faces(cell)[facenr] + return vertices[1] < vertices[2] ? 1 : -1 +end +function face_sign(::AbstractCell{<:AbstractRefShape{3}}, facenr) + error("Implement me") +end + +function edge_sign(cell::AbstractCell, edgenr) + vertices = edges(cell)[edgenr] + return vertices[1] < vertices[2] ? 1 : -1 +end + # @TODO merge this code with into the logic in `ConstraintHandler`. """ From 6daaf656815a3e7bd94ff701b0ed7633777f8b88 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 17 Sep 2023 00:40:13 +0200 Subject: [PATCH 012/145] Fix show to old values --- src/FEValues/cell_values.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FEValues/cell_values.jl b/src/FEValues/cell_values.jl index d6393c5e39..d7480df1d8 100644 --- a/src/FEValues/cell_values.jl +++ b/src/FEValues/cell_values.jl @@ -243,7 +243,7 @@ function reinit!(cv::OldCellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVect return nothing end -function Base.show(io::IO, m::MIME"text/plain", cv::CellValues) +function Base.show(io::IO, m::MIME"text/plain", cv::OldCellValues) println(io, "CellValues with") println(io, "- Quadrature rule with ", getnquadpoints(cv), " points") print(io, "- Function interpolation: "); show(io, m, cv.ip) From 2a6aee03430b78d924fbe10e06f11e13a994f4ff Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 18 Sep 2023 23:33:32 +0200 Subject: [PATCH 013/145] Seemingly working triangle and nedelec --- docs/Manifest.toml | 645 ++++++++++++++++++- docs/Project.toml | 1 + docs/generate.jl | 2 +- docs/make.jl | 15 +- docs/src/literate-tutorials/maxwell.jl | 64 ++ docs/src/literate-tutorials/maxwell_refel.jl | 60 ++ src/FEValues/CellValues.jl | 11 +- src/FEValues/FunctionValues.jl | 34 +- src/FEValues/GeometryValues.jl | 41 +- src/interpolations.jl | 34 +- 10 files changed, 852 insertions(+), 55 deletions(-) create mode 100644 docs/src/literate-tutorials/maxwell.jl create mode 100644 docs/src/literate-tutorials/maxwell_refel.jl diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 5943cd517a..d1f841f815 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -2,18 +2,34 @@ julia_version = "1.9.2" manifest_format = "2.0" -project_hash = "a0caf5d07899f1863658c7736f8530d20d28db07" +project_hash = "0444e709e1c6f42386a9ac2b8c455eb5004d33dc" [[deps.ADTypes]] -git-tree-sha1 = "f2b16fe1a3491b295105cae080c2a5f77a842718" +git-tree-sha1 = "5d2e21d7b0d8c22f67483ef95ebdc39c0e6b6003" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "0.2.3" +version = "0.2.4" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" version = "0.0.1" +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "f35684b7349da49fcc8a9e520e30e45dbb077166" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.2.1" + [[deps.AbstractTrees]] git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" @@ -29,6 +45,12 @@ weakdeps = ["StaticArrays"] [deps.Adapt.extensions] AdaptStaticArraysExt = "StaticArrays" +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" version = "1.1.1" @@ -80,6 +102,24 @@ weakdeps = ["SparseArrays"] [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +[[deps.Automa]] +deps = ["TranscodingStreams"] +git-tree-sha1 = "ef9997b3d5547c48b41c7bd8899e812a917b409d" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "0.8.4" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.0.1" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" @@ -123,18 +163,56 @@ git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" version = "1.0.8+0" +[[deps.CEnum]] +git-tree-sha1 = "eb4cb44a499229b3b8426dcfb5dd85333951ff90" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.4.2" + [[deps.CPUSummary]] deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" version = "0.2.4" +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm]] +deps = ["CRlibm_jll"] +git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "1.0.1" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.Cairo]] +deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] +git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b" +uuid = "159f3aea-2a34-519c-b102-8c37f9878175" +version = "1.0.5" + +[[deps.CairoMakie]] +deps = ["Base64", "Cairo", "Colors", "FFTW", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools", "SHA"] +git-tree-sha1 = "696e7931bd6f5c773418452cbe5fd241cb85ac2a" +uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +version = "0.10.9" + [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" version = "1.16.1+1" +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra", "SparseArrays"] git-tree-sha1 = "e30f2f4e20f7f186dc36529910beaedc60cfa644" @@ -153,6 +231,12 @@ git-tree-sha1 = "02aa26a4cf76381be7f66e020a3eddeb27b0a092" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" version = "0.7.2" +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] git-tree-sha1 = "d9a8f86737b665e15a9641ecbac64deef9ce6724" @@ -166,14 +250,10 @@ uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.11.4" [[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"] +git-tree-sha1 = "600cc5508d66b78aae350f7accdb58763ac18589" uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.10.0" -weakdeps = ["SpecialFunctions"] - - [deps.ColorVectorSpace.extensions] - SpecialFunctionsExt = "SpecialFunctions" +version = "0.9.10" [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] @@ -181,6 +261,11 @@ git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.12.10" +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + [[deps.CommonSolve]] git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" @@ -218,15 +303,12 @@ deps = ["LinearAlgebra"] git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" version = "1.5.4" +weakdeps = ["IntervalSets", "StaticArrays"] [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" ConstructionBaseStaticArraysExt = "StaticArrays" - [deps.ConstructionBase.weakdeps] - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - [[deps.Contour]] git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" @@ -258,6 +340,12 @@ version = "1.0.0" deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "bea7984f7e09aeb28a3b071c420a0186cb4fabad" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.8" + [[deps.DelimitedFiles]] deps = ["Mmap"] git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" @@ -318,6 +406,20 @@ weakdeps = ["SparseArrays"] deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "Test"] +git-tree-sha1 = "938fe2981db009f531b6332e31c58e9584a2f9bd" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.100" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + [[deps.DocStringExtensions]] deps = ["LibGit2"] git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" @@ -332,22 +434,43 @@ version = "1.0.0" [[deps.DocumenterCitations]] deps = ["AbstractTrees", "Bibliography", "Documenter", "Markdown", "MarkdownAST", "OrderedCollections", "Unicode"] -git-tree-sha1 = "5f815482eac14b068725bc1fa8752876ae850ee8" -repo-rev = "fe/Documenter-v1" -repo-url = "https://github.com/JuliaDocs/DocumenterCitations.jl" +git-tree-sha1 = "375b49c31c2c3676f3ddb65efea31c7dbea42af1" uuid = "daee34ce-89f3-4625-b898-19384cb65244" -version = "1.1.0-dev" +version = "1.2.0" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + [[deps.EnumX]] git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" version = "1.0.4" +[[deps.ErrorfreeArithmetic]] +git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.5.2" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] +git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.5" + [[deps.ExceptionUnwrapping]] deps = ["Test"] git-tree-sha1 = "e90caa41f5a86296e014e148ee061bd6c3edec96" @@ -371,6 +494,11 @@ git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" version = "0.1.10" +[[deps.Extents]] +git-tree-sha1 = "5e1e4c53fa39afe63a7d356e30452249365fba99" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.1" + [[deps.FFMPEG]] deps = ["FFMPEG_jll"] git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8" @@ -383,6 +511,18 @@ git-tree-sha1 = "74faea50c1d007c85837327f6775bea60b5492dd" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" version = "4.4.2+2" +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "b4fbdd20c889804969571cc589900803edda16b7" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.7.1" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + [[deps.FLTK_jll]] deps = ["Artifacts", "Fontconfig_jll", "FreeType2_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll", "Xorg_libXfixes_jll", "Xorg_libXft_jll", "Xorg_libXinerama_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] git-tree-sha1 = "72a4842f93e734f378cf381dae2ca4542f019d23" @@ -406,6 +546,12 @@ git-tree-sha1 = "b12f05108e405dadcc2aff0008db7f831374e051" uuid = "29a986be-02c6-4525-aec4-84b980013641" version = "2.0.0" +[[deps.FastRounding]] +deps = ["ErrorfreeArithmetic", "LinearAlgebra"] +git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.3.1" + [[deps.Ferrite]] deps = ["EnumX", "LinearAlgebra", "NearestNeighbors", "Preferences", "Reexport", "SparseArrays", "StaticArrays", "Tensors", "WriteVTK"] path = ".." @@ -496,12 +642,24 @@ weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] ForwardDiffStaticArraysExt = "StaticArrays" +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "50351f83f95282cf903e968d7c6e8d44a5f83d0b" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.0" + [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" version = "2.13.1+0" +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "38a92e40157100e796690421e34a11c107205c86" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.0" + [[deps.FriBidi_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" @@ -564,6 +722,18 @@ git-tree-sha1 = "fb69b2a645fa69ba5f474af09221b9308b160ce6" uuid = "c145ed77-6b09-5dd9-b285-bf645a82121e" version = "0.5.3" +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "bb198ff907228523f3dee1070ceee63b9359b6ab" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.1" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "424a5a6ce7c5d97cca7bcc4eac551b97294c54af" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.9" + [[deps.Gettext_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" @@ -582,6 +752,12 @@ git-tree-sha1 = "4d4dedef84147934837c683538467cea54c44d44" uuid = "705231aa-382f-11e9-3f0c-b7cb4346fdeb" version = "0.2.2" +[[deps.Graphics]] +deps = ["Colors", "LinearAlgebra", "NaNMath"] +git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "1.1.2" + [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" @@ -594,6 +770,12 @@ git-tree-sha1 = "1cf1d7dcb4bc32d7b4a5add4232db3750c27ecb4" uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" version = "1.8.0" +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.9.2" + [[deps.Grisu]] git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" @@ -623,6 +805,12 @@ git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" version = "0.1.16" +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + [[deps.IOCapture]] deps = ["Logging", "Random"] git-tree-sha1 = "d75853a0bdbfb1ac815478bacd89cd27b550ace6" @@ -634,20 +822,105 @@ git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" version = "0.1.1" +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "b51bb8cae22c66d0f6357e3bcb6363145ef20835" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.5" + +[[deps.ImageCore]] +deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"] +git-tree-sha1 = "acf614720ef026d38400b3817614c45882d75500" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.9.4" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + [[deps.Inflate]] git-tree-sha1 = "5cd07aab533df5170988219191dfad0519391428" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" version = "0.1.3" +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ad37c091f7d7daf900963171600d7c1c5c3ede32" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2023.2.0+0" + [[deps.InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "721ec2cf720536ad005cb38f50dbba7b02419a15" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.14.7" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] +git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.20.9" + +[[deps.IntervalSets]] +deps = ["Dates", "Random"] +git-tree-sha1 = "8e59ea773deee525c99a8018409f64f19fb719e6" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.7" +weakdeps = ["Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsStatisticsExt = "Statistics" + [[deps.IrrationalConstants]] git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" version = "0.2.2" +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "4ced6667f9974fc5c5943fa5e2ef1ca43ea9e450" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.8.0" + [[deps.IterativeSolvers]] deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] git-tree-sha1 = "1169632f425f79429f245113b775a0e3d121457c" @@ -689,6 +962,12 @@ git-tree-sha1 = "5f0bd0cd69df978fa64ccdcb5c152fbc705455a1" uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692" version = "1.3.0" +[[deps.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "327713faef2a3e5c80f96bf38d1fa26f7a6ae29e" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.3" + [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "6f2675ef130a300a112286de91973805fcc5ffbc" @@ -701,6 +980,12 @@ git-tree-sha1 = "884c2968c2e8e7e6bf5956af88cb46aa745c854b" uuid = "ef3ab10e-7fda-4108-b977-705223b18434" version = "0.4.1" +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "90442c50e202a5cdf21a7899c66b240fdef14035" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.7" + [[deps.Krylov]] deps = ["LinearAlgebra", "Printf", "SparseArrays"] git-tree-sha1 = "17e462054b42dcdda73e9a9ba0c67754170c88ae" @@ -767,6 +1052,15 @@ git-tree-sha1 = "1370f8202dac30758f3c345f9909b97f53d87d3f" uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" version = "0.15.1" +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" @@ -853,6 +1147,12 @@ version = "7.2.0" deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Permutations", "Primes", "SimplePolynomials"] +git-tree-sha1 = "558a338f1eeabe933f9c2d4052aa7c2c707c3d52" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.1.12" + [[deps.LinearElasticity_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "71e8ee0f9fe0e86a8f8c7f28361e5118eab2f93f" @@ -942,6 +1242,12 @@ git-tree-sha1 = "65f28ad4b594aebe22157d6fac869786a255b7eb" uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" version = "0.1.4" +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "eb006abbd7041c28e0d16260e50a24f8f9104913" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2023.2.0+0" + [[deps.MMG_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "LinearElasticity_jll", "Pkg", "SCOTCH_jll"] git-tree-sha1 = "70a59df96945782bb0d43b56d0fbfdf1ce2e4729" @@ -954,11 +1260,28 @@ git-tree-sha1 = "9ee1618cbf5240e6d4e0371d6f24065083f60c48" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.11" +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "ecc334efc4a8a68800776b0d85ab7bb2fff63f7a" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.19.9" + +[[deps.MakieCore]] +deps = ["Observables"] +git-tree-sha1 = "1efb1166dd9398f2ccf6d728f896658c9c84733e" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.6.6" + [[deps.ManualMemory]] git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" version = "0.1.8" +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" @@ -969,6 +1292,17 @@ git-tree-sha1 = "e8513266815200c0c8f522d6d44ffb5e9b366ae4" uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" version = "0.1.1" +[[deps.Match]] +git-tree-sha1 = "1d9bc5c1a6e7ee24effb93f175c9342f9154d97f" +uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf" +version = "1.2.0" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "Test", "UnicodeFun"] +git-tree-sha1 = "8f52dbaa1351ce4cb847d95568cb29e62a307d93" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.6" + [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "Random", "Sockets"] git-tree-sha1 = "03a9b9718f5682ecb107ac9f7308991db4ce395b" @@ -994,6 +1328,17 @@ version = "1.1.0" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" +[[deps.Mods]] +git-tree-sha1 = "61be59e4daffff43a8cec04b5e0dc773cbb5db3a" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "1.3.3" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2022.10.11" @@ -1003,6 +1348,11 @@ git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" version = "0.2.4" +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + [[deps.NLSolversBase]] deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" @@ -1027,6 +1377,12 @@ git-tree-sha1 = "2c3726ceb3388917602169bed973dbc97f1b51a8" uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" version = "0.4.13" +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" @@ -1043,6 +1399,11 @@ git-tree-sha1 = "acc8099ae8ed10226dc8424fb256ec9fe367a1f0" uuid = "baad4e97-8daa-5946-aac2-2edac59d34e1" version = "7.6.2+2" +[[deps.Observables]] +git-tree-sha1 = "6862738f9796b3edc1c09d0890afce4eca9e7e93" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.4" + [[deps.OffsetArrays]] deps = ["Adapt"] git-tree-sha1 = "2ac17d29c523ce1cd38e27785a7d23024853a4bb" @@ -1060,6 +1421,18 @@ deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" version = "0.3.21+4" +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" @@ -1111,12 +1484,42 @@ deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" version = "10.42.0+0" +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "67eae2738d63117a196f497d7db789821bce61d1" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.17" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "9b02b27ac477cad98114584ff964e3052f656a0f" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.0" + [[deps.PackageExtensionCompat]] git-tree-sha1 = "f9b1e033c2b1205cf30fd119f4e50881316c1923" uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" version = "1.0.1" weakdeps = ["Requires", "TOML"] +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4745216e94f71cb768d58330b059c9b76f32cb66" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.50.14+0" + [[deps.Parameters]] deps = ["OrderedCollections", "UnPack"] git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" @@ -1129,6 +1532,12 @@ git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.7.2" +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "25e2bb0973689836bf164ecb960762f1bb8794dd" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.17" + [[deps.Pipe]] git-tree-sha1 = "6842804e7867b115ca9de748a0cf6b364523c16d" uuid = "b98c9c47-44ae-5843-9183-064241ee97a0" @@ -1145,6 +1554,12 @@ deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", " uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" version = "1.9.2" +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + [[deps.PlotThemes]] deps = ["PlotUtils", "Statistics"] git-tree-sha1 = "1f03a2d339f42dca4a4da149c7e15e9b896ad899" @@ -1189,6 +1604,29 @@ git-tree-sha1 = "240d7170f5ffdb285f9427b92333c3463bf65bf6" uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" version = "0.2.1" +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "ea78a2764f31715093de7ab495e12c0187f231d1" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.4" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + [[deps.PositiveFactorizations]] deps = ["LinearAlgebra"] git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" @@ -1219,6 +1657,12 @@ git-tree-sha1 = "7eb1686b4f04b82f96ed7a4ea5890a4f0c7a09f1" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.0" +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "4c9f306e5d6603ae203c2000dd460d81a5251489" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.4" + [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" @@ -1229,12 +1673,24 @@ git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" uuid = "92933f4c-e287-5a05-a399-4b506db050ca" version = "1.9.0" +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + [[deps.Qt6Base_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"] git-tree-sha1 = "364898e8f13f7eaaceec55fd3d08680498c0aa6e" uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" version = "6.4.2+3" +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "6ec7ac8412e83d57e313393220879ede1740f9ee" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.8.2" + [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" @@ -1243,6 +1699,21 @@ uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" deps = ["SHA", "Serialization"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + [[deps.RecipesBase]] deps = ["PrecompileTools"] git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" @@ -1302,6 +1773,29 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + [[deps.RuntimeGeneratedFunctions]] deps = ["ExprTools", "SHA", "Serialization"] git-tree-sha1 = "6aacc5eefe8415f47b3e34214c1d79d2674a0ba2" @@ -1368,12 +1862,23 @@ version = "1.2.0" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +[[deps.SetRounding]] +git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.1" + [[deps.Setfield]] deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" version = "1.1.1" +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "0d15c3e7b2003f4451714f08ffec2b77badc2dc4" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.3.0" + [[deps.SharedArrays]] deps = ["Distributed", "Mmap", "Random", "Serialization"] uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" @@ -1384,11 +1889,23 @@ git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" version = "1.0.3" +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + [[deps.SimpleBufferStream]] git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" version = "1.1.0" +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "b608903049d11cc557c45e03b3a53e9260579c19" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.4" + [[deps.SimpleNonlinearSolve]] deps = ["ArrayInterface", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "PackageExtensionCompat", "PrecompileTools", "Reexport", "SciMLBase", "StaticArraysCore"] git-tree-sha1 = "20aa9831d654bab67ed561e78917047143ecb9bf" @@ -1401,6 +1918,24 @@ version = "0.1.19" [deps.SimpleNonlinearSolve.weakdeps] NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "dcc02923a53f316ab97da8ef3136e80b4543dbf1" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.0" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "d537c31cf9995236166e3e9afc424a5a1c59ff9d" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.14" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + [[deps.SimpleTraits]] deps = ["InteractiveUtils", "MacroTools"] git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" @@ -1412,6 +1947,12 @@ git-tree-sha1 = "58e6353e72cde29b90a69527e56df1b5c3d8c437" uuid = "ce78b400-467f-4804-87d8-8f486da07d0a" version = "1.1.0" +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + [[deps.SnoopPrecompile]] deps = ["Preferences"] git-tree-sha1 = "e760a70afdcd461cf01a575947738d359234665c" @@ -1463,6 +2004,18 @@ weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" +[[deps.StableHashTraits]] +deps = ["Compat", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "19df33ca14f24a3ad2df9e89124bd5f5cc8467a2" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.0.1" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + [[deps.Static]] deps = ["IfElse"] git-tree-sha1 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" @@ -1512,6 +2065,20 @@ git-tree-sha1 = "75ebe04c5bed70b91614d684259b661c9e6274a4" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" version = "0.34.0" +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + [[deps.StrideArraysCore]] deps = ["ArrayInterface", "CloseOpenIntervals", "IfElse", "LayoutPointers", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface", "ThreadingUtilities"] git-tree-sha1 = "f02eb61eb5c97b48c153861c72fbbfdddc607e06" @@ -1524,6 +2091,12 @@ git-tree-sha1 = "b765e46ba27ecf6b44faf70df40c57aa3a547dcb" uuid = "69024149-9ee7-55f6-a4c4-859efe599b68" version = "0.3.7" +[[deps.StructArrays]] +deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] +git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.16" + [[deps.StructTypes]] deps = ["Dates", "UUIDs"] git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" @@ -1575,7 +2148,7 @@ version = "0.1.1" [[deps.Tensors]] deps = ["ForwardDiff", "LinearAlgebra", "PrecompileTools", "SIMD", "StaticArrays", "Statistics"] -git-tree-sha1 = "bcbb366323add300742c9e4a5447e584640aeff2" +path = "C:\\Users\\meyer\\.julia\\dev\\Tensors" uuid = "48a634ad-e948-5137-8d70-aa71f2a747f4" version = "1.15.0" @@ -1589,6 +2162,12 @@ git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" version = "0.5.2" +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "8621f5c499a8aa4aa970b1ae381aae0ef1576966" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.4" + [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" @@ -1612,12 +2191,22 @@ git-tree-sha1 = "aadb748be58b492045b4f56166b5188aa63ce549" uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" version = "0.1.7" +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + [[deps.TruncatedStacktraces]] deps = ["InteractiveUtils", "MacroTools", "Preferences"] git-tree-sha1 = "ea3e54c2bdde39062abf5a9758a23735558705e1" uuid = "781d530d-4396-4725-bb49-402e4bee1e77" version = "1.4.0" +[[deps.TupleTools]] +git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.4.3" + [[deps.URIs]] git-tree-sha1 = "b7a5e99f24892b6824a954199a45e9ffcc1c70f0" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" @@ -1695,6 +2284,12 @@ git-tree-sha1 = "4528479aa01ee1b3b4cd0e6faef0e04cf16466da" uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91" version = "1.25.0+0" +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.5.5" + [[deps.WriteVTK]] deps = ["Base64", "CodecZlib", "FillArrays", "LightXML", "TranscodingStreams", "VTKBase"] git-tree-sha1 = "7b46936613e41cfe1c6a5897d243ddcab8feabec" @@ -1886,6 +2481,12 @@ git-tree-sha1 = "d4cf3bb87fa0669f569e51f6f06cd083771bab65" uuid = "630162c2-fc9b-58b3-9910-8442a8a132e6" version = "4.10.2+1" +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + [[deps.libaom_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" @@ -1915,6 +2516,12 @@ git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" version = "1.6.38+0" +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" diff --git a/docs/Project.toml b/docs/Project.toml index 2d83ab8a20..01eb9b476d 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,6 @@ [deps] BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" +CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244" Ferrite = "c061ca5d-56c9-439f-9c0e-210fe06d3992" diff --git a/docs/generate.jl b/docs/generate.jl index 8bcb08dc78..e06d3a14e9 100644 --- a/docs/generate.jl +++ b/docs/generate.jl @@ -22,7 +22,7 @@ include("download_resources.jl") # Run Literate on all examples @timeit dto "Literate." for (IN, OUT) in [(TUTORIALS_IN, TUTORIALS_OUT), (HOWTO_IN, HOWTO_OUT), (GALLERY_IN, GALLERY_OUT)], program in readdir(IN; join=true) name = basename(program) - if endswith(program, ".jl") + if endswith(program, "maxwell.jl") if !liveserver script = @timeit dto "script()" @timeit dto name Literate.script(program, OUT) code = strip(read(script, String)) diff --git a/docs/make.jl b/docs/make.jl index d7a082af71..e1eefa6a17 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -45,8 +45,9 @@ bibtex_plugin = CitationBibliography( "Home" => "index.md", # hide("Changelog" => "changelog.md"), "Tutorials" => [ - "Tutorials overview" => "tutorials/index.md", - "tutorials/heat_equation.md", + # "Tutorials overview" => "tutorials/index.md", + "tutorials/maxwell.md", + #= "tutorials/heat_equation.md", "tutorials/linear_elasticity.md", "tutorials/incompressible_elasticity.md", "tutorials/hyperelasticity.md", @@ -55,9 +56,9 @@ bibtex_plugin = CitationBibliography( "tutorials/computational_homogenization.md", "tutorials/stokes-flow.md", "tutorials/ns_vs_diffeq.md", - "tutorials/linear_shell.md", + "tutorials/linear_shell.md",=# ], - "Topic guides" => [ +#= "Topic guides" => [ "Topic guide overview" => "topics/index.md", "topics/fe_intro.md", "topics/degrees_of_freedom.md", @@ -66,7 +67,7 @@ bibtex_plugin = CitationBibliography( "topics/constraints.md", "topics/grid.md", "topics/export.md" - ], + ],=# "Reference" => [ "Reference overview" => "reference/index.md", "reference/quadrature.md", @@ -79,11 +80,11 @@ bibtex_plugin = CitationBibliography( "reference/export.md", "reference/utils.md", ], - "How-to guides" => [ + #= "How-to guides" => [ "How-to guide overview" => "howto/index.md", "howto/postprocessing.md", "howto/threaded_assembly.md", - ], + ],=# "gallery/index.md", # "Code gallery" => [ # "Code gallery overview" => "gallery/index.md", diff --git a/docs/src/literate-tutorials/maxwell.jl b/docs/src/literate-tutorials/maxwell.jl new file mode 100644 index 0000000000..3a8a224f91 --- /dev/null +++ b/docs/src/literate-tutorials/maxwell.jl @@ -0,0 +1,64 @@ +# Maxwell's equations +# For simplicity, we start with the very basic example from +# https://www.math.colostate.edu/~bangerth/videos.676.33.html +# Specifically, +# ```math +# \int_\Omega \left[\mathrm{curl}(\boldsymbol{\delta u}) \cdot \mathrm{curl}(\boldsymbol{u}) +# + \mathrm{div}(\boldsymbol{\delta u}) \mathrm{div}(\boldsymbol{u})\right] \mathrm{d}\Omega = 0 +# ``` +# As noted in the lecture, standard Lagrange elements are not sufficient to solve this problem accurately, +# and we therefore use the Nedelec interpolation. +using Ferrite +import Ferrite: Nedelec +import CairoMakie as M +ip = Nedelec{2,RefTriangle,1}() +grid = generate_grid(Triangle, (2,2)) +dh = DofHandler(grid) +add!(dh, :B, ip) +close!(dh) + +ip_geo = Ferrite.default_interpolation(Triangle) +qr = QuadratureRule{RefTriangle}(10) +cv = CellValues(qr, ip, ip_geo) + +n_qp = getncells(grid)*getnquadpoints(cv) +coords = (zeros(n_qp), zeros(n_qp)) +vectors = (zeros(n_qp), zeros(n_qp)) + +for nr in 1:(ndofs(dh)) + u = zeros(ndofs(dh)) + u[nr] = 1.0 + + for cell_nr in 1:getncells(grid) + x = getcoordinates(grid, cell_nr) + reinit!(cv, x, getcells(grid, cell_nr)) + ue = u[celldofs(dh, cell_nr)] + for q_point in 1:getnquadpoints(cv) + i = getnquadpoints(cv)*(cell_nr-1) + q_point + qp_x = spatial_coordinate(cv, q_point, x) + v = function_value(cv, q_point, ue) + sfac = norm(v) ≈ 0 ? NaN : 1.0 # Skip plotting zero-vector points + coords[1][i] = sfac*qp_x[1] + coords[2][i] = sfac*qp_x[2] + vectors[1][i] = v[1] + vectors[2][i] = v[2] + end + end + + fig = M.Figure() + ax = M.Axis(fig[1,1]; aspect=M.DataAspect()) + for cellnr in 1:getncells(grid) + x = getcoordinates(grid, cellnr) + push!(x, x[1]) + M.lines!(ax, first.(x), last.(x), color=:black) + end + M.arrows!(ax, coords..., vectors...; lengthscale=0.1) + display(fig) +end +#= +mutable struct NewCellCache{T,dim,CT} + const x::Vector{Vec{dim,T}} + const dofs::Vector{Int} + cell::CT +end +=# \ No newline at end of file diff --git a/docs/src/literate-tutorials/maxwell_refel.jl b/docs/src/literate-tutorials/maxwell_refel.jl new file mode 100644 index 0000000000..d3fdb10c88 --- /dev/null +++ b/docs/src/literate-tutorials/maxwell_refel.jl @@ -0,0 +1,60 @@ +# Maxwell's equations +# For simplicity, we start with the very basic example from +# https://www.math.colostate.edu/~bangerth/videos.676.33.html +# Specifically, +# ```math +# \int_\Omega \left[\mathrm{curl}(\boldsymbol{\delta u}) \cdot \mathrm{curl}(\boldsymbol{u}) +# + \mathrm{div}(\boldsymbol{\delta u}) \mathrm{div}(\boldsymbol{u})\right] \mathrm{d}\Omega = 0 +# ``` +# As noted in the lecture, standard Lagrange elements are not sufficient to solve this problem accurately, +# and we therefore use the Nedelec interpolation. +import CairoMakie as M +using Ferrite +import Ferrite: Nedelec +import Ferrite: reference_coordinates +ip = Nedelec{2,RefTriangle,1}() +ip_geo = Lagrange{RefTriangle,1}() +ref_x = reference_coordinates(ip_geo) + +x_vertices = [ref_x..., ref_x[1]] + +function create_testpoints(npts) + inside(x) = (1 - x[1]) > x[2] + x = Vec{2,Float64}[] + for i in 0:(npts-1) + for j in i:(npts-1) + push!(x, Vec((i/(npts-1)), 1 - j/(npts-1))) + end + end + return x +end +x = create_testpoints(10) + +w = ones(length(x))*0.5/length(x) +qr = QuadratureRule{RefTriangle}(w, x) + +fig = M.Figure(resolution=(1000,1000)); +for i in 1:3 + ax=M.Axis(fig[i,1]; aspect=M.DataAspect()); + M.lines!(ax, first.(x_vertices), last.(x_vertices)) + v = shape_value.((ip,), x, i) + M.scatter!(ax, first.(x), last.(x)) + M.arrows!(ax, first.(x), last.(x), first.(v), last.(v); lengthscale=0.25) +end +display(fig) + +fig2 = M.Figure(resolution=(1000,1000)) +cv = CellValues(qr, ip, ip_geo) +ref_x[1] = Vec(4.0,0.0) +reinit!(cv, ref_x) +x_vertices = [ref_x..., ref_x[1]] +for i in 1:3 + ax=M.Axis(fig2[i,1]; aspect=M.DataAspect()); + M.lines!(ax, first.(x_vertices), last.(x_vertices)) + x_qp = spatial_coordinate.((cv,), 1:length(x), (ref_x,)) + @show x_qp ≈ x + v = shape_value.((cv,), 1:length(x), i) + M.scatter!(ax, first.(x_qp), last.(x_qp)) + M.arrows!(ax, first.(x_qp), last.(x_qp), first.(v), last.(v); lengthscale=0.25) +end +fig2 \ No newline at end of file diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index bdb6c5bdad..5eed0c56f2 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -13,7 +13,8 @@ struct CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCell qr::QR end function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation) where T - geo_values = GeometryValues(T, ip_geo.ip, qr) + mapping_type = get_mapping_type(ip_fun) + geo_values = GeometryValues(T, ip_geo.ip, qr, RequiresHessian(requires_hessian(mapping_type))) fun_values = FunctionValues(T, ip_fun, qr, ip_geo) detJdV = fill(T(NaN), length(getweights(qr))) return CellValues(geo_values, detJdV, fun_values, qr) @@ -42,18 +43,20 @@ end # Access quadrature rule values getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) -function reinit!(cv::CellValues, x::AbstractVector{<:Vec}) +function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) geo_values = cv.geo_values + mapping_type = get_mapping_type(cv.fun_values) + map_req = RequiresHessian(requires_hessian(mapping_type)) n_geom_basefuncs = getngeobasefunctions(geo_values) if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs throw_incompatible_coord_length(length(x), n_geom_basefuncs) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) - mapping = calculate_mapping(geo_values, q_point, x) + mapping = calculate_mapping(map_req, geo_values, q_point, x) detJ = calculate_detJ(getjacobian(mapping)) detJ > 0.0 || throw_detJ_not_pos(detJ) @inbounds cv.detJdV[q_point] = detJ*w - apply_mapping!(cv.fun_values, q_point, mapping) + apply_mapping!(cv.fun_values, q_point, mapping, geo_values, cell) end return nothing end diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 30ed0ebfe8..ef71dbaf31 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -23,7 +23,8 @@ typeof_dNdξ(::Type{T}, ::VInterpolationDims{dim,dim,dim}) where {T,dim} = Tenso typeof_dNdξ(::Type{T}, ::VInterpolationDims{rdim,<:Any,vdim}) where {T,rdim,vdim} = SMatrix{vdim,rdim,T} # If vdim=rdim!=sdim Tensor would be possible... struct FunctionValues{IP, N_t, dNdx_t, dNdξ_t} - N::Matrix{N_t} + N_x::Matrix{N_t} + N_ξ::Matrix{N_t} dNdx::Matrix{dNdx_t} dNdξ::Matrix{dNdξ_t} ip::IP @@ -36,10 +37,15 @@ function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) - N = zeros(N_t, n_shape, n_qpoints) + N_ξ = zeros(N_t, n_shape, n_qpoints) + if isa(get_mapping_type(ip), IdentityMapping) + N_x = N_ξ + else + N_x = zeros(N_t, n_shape, n_qpoints) + end dNdξ = zeros(dNdξ_t, n_shape, n_qpoints) dNdx = fill(zero(dNdx_t) * T(NaN), n_shape, n_qpoints) - fv = FunctionValues(N, dNdx, dNdξ, ip) + fv = FunctionValues(N_x, N_ξ, dNdx, dNdξ, ip) precompute_values!(fv, qr) # Precompute N and dNdξ return fv end @@ -48,13 +54,13 @@ function precompute_values!(fv::FunctionValues, qr::QuadratureRule) n_shape = getnbasefunctions(fv.ip) for (qp, ξ) in pairs(getpoints(qr)) for i in 1:n_shape - fv.dNdξ[i, qp], fv.N[i, qp] = shape_gradient_and_value(fv.ip, ξ, i) + fv.dNdξ[i, qp], fv.N_ξ[i, qp] = shape_gradient_and_value(fv.ip, ξ, i) end end end -getnbasefunctions(funvals::FunctionValues) = size(funvals.N, 1) -@propagate_inbounds shape_value(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.N[base_func, q_point] +getnbasefunctions(funvals::FunctionValues) = size(funvals.N_x, 1) +@propagate_inbounds shape_value(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.N_x[base_func, q_point] @propagate_inbounds shape_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.dNdx[base_func, q_point] @propagate_inbounds shape_symmetric_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = symmetric(shape_gradient(funvals, q_point, base_func)) @@ -94,7 +100,7 @@ calculate_Jinv(J::SMatrix) = pinv(J) return apply_mapping!(funvals, get_mapping_type(funvals), args...) end -@inline function apply_mapping!(funvals::FunctionValues, ::IdentityMapping, q_point::Int, mapping_values) +@inline function apply_mapping!(funvals::FunctionValues, ::IdentityMapping, q_point::Int, mapping_values, args...) Jinv = calculate_Jinv(getjacobian(mapping_values)) @inbounds for j in 1:getnbasefunctions(funvals) #funvals.dNdx[j, q_point] = funvals.dNdξ[j, q_point] ⋅ Jinv # TODO via Tensors.jl @@ -102,13 +108,19 @@ end end return nothing end -#= -@inline function apply_mapping!(funvals::FunctionValues, ::IdentityMapping, q_point::Int, mapping_values) + +@inline function apply_mapping!(funvals::FunctionValues, ::CovariantPiolaMapping, q_point::Int, mapping_values, geovals::GeometryValues, cell) + H = gethessian(mapping_values) Jinv = inv(getjacobian(mapping_values)) @inbounds for j in 1:getnbasefunctions(funvals) + face_vertices = faces(cell)[j] + d = face_vertices[2] > face_vertices[1] ? 1 : -1 + #d = 1 #funvals.dNdx[j, q_point] = funvals.dNdξ[j, q_point] ⋅ Jinv # TODO via Tensors.jl - funvals.dNdx[j, q_point] = dothelper(funvals.dNdξ[j, q_point], Jinv) + dNdξ = funvals.dNdξ[j, q_point] + N_ξ = funvals.N_ξ[j, q_point] + funvals.N_x[j, q_point] = d*(N_ξ ⋅ Jinv) + funvals.dNdx[j, q_point] = d*(Jinv' ⋅ dNdξ ⋅ Jinv - Jinv' ⋅ (N_ξ ⋅ Jinv ⋅ H ⋅ Jinv)) end return nothing end -=# \ No newline at end of file diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index e36855b3e0..3ef7971a36 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -5,30 +5,43 @@ end @inline getjacobian(mv::MappingValues) = mv.J @inline gethessian(mv::MappingValues) = mv.H +struct RequiresHessian{B} end +RequiresHessian(B) = RequiresHessian{B}() -struct GeometryValues{dMdξ_t, GIP, T} - M::Matrix{T} - dMdξ::Matrix{dMdξ_t} - ip::GIP +struct GeometryValues{dMdξ_t, GIP, T, d2Mdξ2_t} + M::Matrix{T} # value of geometric shape function + dMdξ::Matrix{dMdξ_t} # gradient of geometric shape function in ref-domain + d2Mdξ2::Matrix{d2Mdξ2_t} # hessian of geometric shape function in ref-domain + ip::GIP # geometric interpolation end -function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T +function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, ::RequiresHessian{RH}) where {T,RH} n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) - VT = Vec{getdim(ip),T} + VT = Vec{getdim(ip),T} M = zeros(T, n_shape, n_qpoints) dMdξ = zeros(VT, n_shape, n_qpoints) + if RH + HT = Tensor{2,getdim(ip),T} + dM2dξ2 = zeros(HT, n_shape, n_qpoints) + else + dM2dξ2 = Matrix{Nothing}(undef,0,0) + end for (qp, ξ) in pairs(getpoints(qr)) for i in 1:n_shape - dMdξ[i, qp], M[i, qp] = shape_gradient_and_value(ip, ξ, i) + if RH + dM2dξ2[i, qp], dMdξ[i, qp], M[i, qp] = shape_hessian_gradient_and_value(ip, ξ, i) + else + dMdξ[i, qp], M[i, qp] = shape_gradient_and_value(ip, ξ, i) + end end end - return GeometryValues(M, dMdξ, ip) + return GeometryValues(M, dMdξ, dM2dξ2, ip) end getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) @propagate_inbounds geometric_value(geovals::GeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] -@inline function calculate_mapping(geo_values::GeometryValues{<:Vec{dim,T}}, q_point, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} +@inline function calculate_mapping(::RequiresHessian{false}, geo_values::GeometryValues{<:Vec{dim,T}}, q_point, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} fecv_J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) @inbounds for j in 1:getngeobasefunctions(geo_values) fecv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] @@ -36,6 +49,16 @@ getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) return MappingValues(fecv_J, nothing) end +@inline function calculate_mapping(::RequiresHessian{true}, geo_values::GeometryValues{<:Vec{dim,T}}, q_point, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} + J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) + H = zero(Tensor{3,dim,T}) + @inbounds for j in 1:getngeobasefunctions(geo_values) + J += x[j] ⊗ geo_values.dMdξ[j, q_point] + H += x[j] ⊗ geo_values.d2Mdξ2[j, q_point] + end + return MappingValues(J, H) +end + calculate_detJ(J::Tensor{2}) = det(J) calculate_detJ(J::SMatrix) = embedding_det(J) diff --git a/src/interpolations.jl b/src/interpolations.jl index 6e6ededefa..a235e7bb9c 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -237,6 +237,16 @@ function shape_gradient_and_value(ip::Interpolation, ξ::Vec, i::Int) return gradient(x -> shape_value(ip, x, i), ξ, :all) end +""" + shape_hessian_gradient_and_value(ip::Interpolation, ξ::Vec, i::Int) + +Optimized version combining the evaluation [`Ferrite.shape_value(::Interpolation)`](@ref), +[`Ferrite.shape_gradient(::Interpolation)`](@ref), and the gradient of the latter. +""" +function shape_hessian_gradient_and_value(ip::Interpolation, ξ::Vec, i::Int) + return hessian(x -> shape_value(ip, x, i), ξ, :all) +end + """ reference_coordinates(ip::Interpolation) @@ -1504,8 +1514,7 @@ function shape_gradient_and_value(ipv::VectorizedInterpolation{vdim, shape}, ξ: end reference_coordinates(ip::VectorizedInterpolation) = reference_coordinates(ip.ip) - - +is_discontinuous(::Type{<:VectorizedInterpolation{<:Any, <:Any, <:Any, ip}}) where {ip} = is_discontinuous(ip) get_mapping_type(::Interpolation) = IdentityMapping() # https://defelement.com/elements/raviart-thomas.html @@ -1517,7 +1526,7 @@ facedof_interior_indices(ip::RaviartThomas) = facedof_indices(ip) getnbasefunctions(::RaviartThomas{2,RefTriangle,1}) = 3 facedof_indices(::RaviartThomas{2,RefTriangle,1}) = ((1,), (2,), (3,)) adjust_dofs_during_distribution(::RaviartThomas) = false # Not sure how this works, but should be done for higher orders -# https://defelement.com/elements/examples/triangle-N1div-1.html +# https://defelement.com/elements/examples/triangle-raviart-thomas-lagrange-1.html function shape_value(ip::RaviartThomas{2,RefTriangle,1}, ξ::Vec{2}, i::Int) ξ_x, ξ_y = ξ i == 1 && return -ξ @@ -1526,4 +1535,21 @@ function shape_value(ip::RaviartThomas{2,RefTriangle,1}, ξ::Vec{2}, i::Int) throw(ArgumentError("no shape function $i for interpolation $ip")) end -is_discontinuous(::Type{<:VectorizedInterpolation{<:Any, <:Any, <:Any, ip}}) where {ip} = is_discontinuous(ip) + +struct Nedelec{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end +# https://defelement.com/elements/examples/triangle-nedelec1-lagrange-1.html +function shape_value(ip::Nedelec{2,RefTriangle,1}, ξ::Vec{2}, i::Int) + ξ_x, ξ_y = ξ + i == 1 && return Vec( - ξ_y, ξ_x) + i == 2 && return Vec( - ξ_y, ξ_x - 1) + i == 3 && return Vec(1 - ξ_y, ξ_x) + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +get_mapping_type(::Nedelec) = CovariantPiolaMapping() +#facedof_interior_indices(ip::Nedelec) = facedof_indices(ip) + +getnbasefunctions(::Nedelec{2,RefTriangle,1}) = 3 +facedof_indices(::Nedelec{2,RefTriangle,1}) = ((), (), ()) +facedof_interior_indices(::Nedelec{2,RefTriangle,1}) = ((1,), (2,), (3,)) +adjust_dofs_during_distribution(::Nedelec) = false # Not sure how this works, but should be done for higher orders From ac047245983e7a57900c0e8e861bc88b533995f3 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Tue, 19 Sep 2023 21:43:40 +0200 Subject: [PATCH 014/145] Add notes for new iterator --- docs/src/literate-tutorials/maxwell.jl | 1 + src/iterators.jl | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/docs/src/literate-tutorials/maxwell.jl b/docs/src/literate-tutorials/maxwell.jl index 3a8a224f91..159190c0cb 100644 --- a/docs/src/literate-tutorials/maxwell.jl +++ b/docs/src/literate-tutorials/maxwell.jl @@ -55,6 +55,7 @@ for nr in 1:(ndofs(dh)) M.arrows!(ax, coords..., vectors...; lengthscale=0.1) display(fig) end + #= mutable struct NewCellCache{T,dim,CT} const x::Vector{Vec{dim,T}} diff --git a/src/iterators.jl b/src/iterators.jl index dbbc504376..e623ab0d82 100644 --- a/src/iterators.jl +++ b/src/iterators.jl @@ -406,3 +406,16 @@ function _check_same_celltype(grid::AbstractGrid, faceset::Set{FaceIndex}) error("The cells in the faceset are not all of the same celltype.") end end + + +mutable struct CellIterator2{CC,DH,IC} + cache::CC # const + dh::SDH # const + cells::IC # const + current_cell::Int +end +mutable struct CellCache2{T,dim,CT} + const x::Vector{Vec{dim,T}} + const dofs::Vector{Int} + cell::CT +end From 4994e6e08b5955361b9fddf37e91eb7d03fd64e3 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 20 Sep 2023 21:48:42 +0200 Subject: [PATCH 015/145] Generalize and support 2nd order Nedelec on triangle --- docs/src/literate-tutorials/maxwell.jl | 19 ++-- docs/src/literate-tutorials/maxwell_refel.jl | 2 +- src/FEValues/CellValues.jl | 6 +- src/FEValues/FunctionValues.jl | 7 +- src/FEValues/GeometryValues.jl | 8 +- src/interpolations.jl | 103 +++++++++++++++++-- src/iterators.jl | 19 ++-- 7 files changed, 127 insertions(+), 37 deletions(-) diff --git a/docs/src/literate-tutorials/maxwell.jl b/docs/src/literate-tutorials/maxwell.jl index 159190c0cb..7c295e4068 100644 --- a/docs/src/literate-tutorials/maxwell.jl +++ b/docs/src/literate-tutorials/maxwell.jl @@ -11,14 +11,20 @@ using Ferrite import Ferrite: Nedelec import CairoMakie as M -ip = Nedelec{2,RefTriangle,1}() -grid = generate_grid(Triangle, (2,2)) +ip = Nedelec{2,RefTriangle,2}() +grid = generate_grid(Triangle, (1,2)) dh = DofHandler(grid) add!(dh, :B, ip) close!(dh) ip_geo = Ferrite.default_interpolation(Triangle) qr = QuadratureRule{RefTriangle}(10) + +qr_points = Vec{2,Float64}[]; n=6 +append!(qr_points, [Vec((0.0, i/(n+1))) for i in 1:n]) +append!(qr_points, [Vec((i/(n+1), 0.0)) for i in 1:n]) +append!(qr_points, [Vec((i/(n+1), 1 - i/(n+1))) for i in 1:n]) +qr = QuadratureRule{RefTriangle}(zeros(length(qr_points)), qr_points) cv = CellValues(qr, ip, ip_geo) n_qp = getncells(grid)*getnquadpoints(cv) @@ -56,10 +62,9 @@ for nr in 1:(ndofs(dh)) display(fig) end + +# Remaining tasks #= -mutable struct NewCellCache{T,dim,CT} - const x::Vector{Vec{dim,T}} - const dofs::Vector{Int} - cell::CT -end +✓ 2nd order Nedelec +* =# \ No newline at end of file diff --git a/docs/src/literate-tutorials/maxwell_refel.jl b/docs/src/literate-tutorials/maxwell_refel.jl index d3fdb10c88..c61849f88b 100644 --- a/docs/src/literate-tutorials/maxwell_refel.jl +++ b/docs/src/literate-tutorials/maxwell_refel.jl @@ -46,7 +46,7 @@ display(fig) fig2 = M.Figure(resolution=(1000,1000)) cv = CellValues(qr, ip, ip_geo) ref_x[1] = Vec(4.0,0.0) -reinit!(cv, ref_x) +reinit!(cv, ref_x, Triangle((1,2,3))) x_vertices = [ref_x..., ref_x[1]] for i in 1:3 ax=M.Axis(fig2[i,1]; aspect=M.DataAspect()); diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 5eed0c56f2..beaf76ce82 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -45,8 +45,8 @@ getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) geo_values = cv.geo_values - mapping_type = get_mapping_type(cv.fun_values) - map_req = RequiresHessian(requires_hessian(mapping_type)) + fun_values = cv.fun_values + map_req = RequiresHessian(fun_values.ip, geo_values.ip) n_geom_basefuncs = getngeobasefunctions(geo_values) if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs throw_incompatible_coord_length(length(x), n_geom_basefuncs) @@ -56,7 +56,7 @@ function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) detJ = calculate_detJ(getjacobian(mapping)) detJ > 0.0 || throw_detJ_not_pos(detJ) @inbounds cv.detJdV[q_point] = detJ*w - apply_mapping!(cv.fun_values, q_point, mapping, geo_values, cell) + apply_mapping!(fun_values, q_point, mapping, cell) end return nothing end diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index ef71dbaf31..1e91d13279 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -109,14 +109,11 @@ end return nothing end -@inline function apply_mapping!(funvals::FunctionValues, ::CovariantPiolaMapping, q_point::Int, mapping_values, geovals::GeometryValues, cell) +@inline function apply_mapping!(funvals::FunctionValues, ::CovariantPiolaMapping, q_point::Int, mapping_values, cell) H = gethessian(mapping_values) Jinv = inv(getjacobian(mapping_values)) @inbounds for j in 1:getnbasefunctions(funvals) - face_vertices = faces(cell)[j] - d = face_vertices[2] > face_vertices[1] ? 1 : -1 - #d = 1 - #funvals.dNdx[j, q_point] = funvals.dNdξ[j, q_point] ⋅ Jinv # TODO via Tensors.jl + d = get_direction(funvals.ip, j, cell) dNdξ = funvals.dNdξ[j, q_point] N_ξ = funvals.N_ξ[j, q_point] funvals.N_x[j, q_point] = d*(N_ξ ⋅ Jinv) diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index 3ef7971a36..1bcbacd3b8 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -6,7 +6,13 @@ end @inline gethessian(mv::MappingValues) = mv.H struct RequiresHessian{B} end -RequiresHessian(B) = RequiresHessian{B}() +RequiresHessian(B::Bool) = RequiresHessian{B}() +function RequiresHessian(ip_fun::Interpolation, ip_geo::Interpolation) + # Leave ip_geo as input, because for later the hessian can also be avoided + # for fully linear geometric elements (e.g. triangle and tetrahedron) + # This optimization is left out for now. + RequiresHessian(requires_hessian(get_mapping_type(ip_fun))) +end struct GeometryValues{dMdξ_t, GIP, T, d2Mdξ2_t} M::Matrix{T} # value of geometric shape function diff --git a/src/interpolations.jl b/src/interpolations.jl index a235e7bb9c..2aa7f31e73 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1515,7 +1515,10 @@ end reference_coordinates(ip::VectorizedInterpolation) = reference_coordinates(ip.ip) is_discontinuous(::Type{<:VectorizedInterpolation{<:Any, <:Any, <:Any, ip}}) where {ip} = is_discontinuous(ip) -get_mapping_type(::Interpolation) = IdentityMapping() +get_mapping_type(::ScalarInterpolation) = IdentityMapping() +get_mapping_type(::VectorizedInterpolation) = IdentityMapping() + +#= Just notes for now for RaviartThomas. Nedelec below tbd first # https://defelement.com/elements/raviart-thomas.html # https://defelement.com/elements/qdiv.html @@ -1534,22 +1537,108 @@ function shape_value(ip::RaviartThomas{2,RefTriangle,1}, ξ::Vec{2}, i::Int) i == 3 && return Vec(-ξ_x, 1 - ξ_y) throw(ArgumentError("no shape function $i for interpolation $ip")) end +=# +##################################### +# Nedelec (1st kind), H(curl) # +##################################### struct Nedelec{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end +get_mapping_type(::Nedelec) = CovariantPiolaMapping() + +# RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-1.html function shape_value(ip::Nedelec{2,RefTriangle,1}, ξ::Vec{2}, i::Int) ξ_x, ξ_y = ξ i == 1 && return Vec( - ξ_y, ξ_x) - i == 2 && return Vec( - ξ_y, ξ_x - 1) + i == 2 && return Vec( - ξ_y, ξ_x - 1) # Changed signed, follow Ferrite's sign convention i == 3 && return Vec(1 - ξ_y, ξ_x) throw(ArgumentError("no shape function $i for interpolation $ip")) end -get_mapping_type(::Nedelec) = CovariantPiolaMapping() -#facedof_interior_indices(ip::Nedelec) = facedof_indices(ip) - getnbasefunctions(::Nedelec{2,RefTriangle,1}) = 3 -facedof_indices(::Nedelec{2,RefTriangle,1}) = ((), (), ()) facedof_interior_indices(::Nedelec{2,RefTriangle,1}) = ((1,), (2,), (3,)) -adjust_dofs_during_distribution(::Nedelec) = false # Not sure how this works, but should be done for higher orders +adjust_dofs_during_distribution(::Nedelec{2,RefTriangle,1}) = false + +function get_direction(::Nedelec{2,RefTriangle,1}, j, cell) + face_vertices = faces(cell)[j] + return face_vertices[2] > face_vertices[1] ? 1 : -1 +end + +# RefTriangle, 2nd order Lagrange +# https://defelement.com/elements/examples/triangle-nedelec1-lagrange-2.html +function shape_value(ip::Nedelec{2,RefTriangle,2}, ξ::Vec{2}, i::Int) + ξ_x, ξ_y = ξ + # Face 1 + i == 1 && return Vec( 2*ξ_y*(1 - 4*ξ_x), + 4*ξ_x*(2*ξ_x - 1)) + i == 2 && return Vec( 4*ξ_y*(1 - 2*ξ_y), + 2*ξ_x*(4*ξ_y - 1)) + # Face 2 (flip order and sign compared to defelement) + i == 3 && return Vec( 4*ξ_y*(1 - 2*ξ_y), + 8*ξ_x*ξ_y - 2*ξ_x - 6*ξ_y + 2) + i == 4 && return Vec( 2*ξ_y*(4*ξ_x + 4*ξ_y - 3), + -8*ξ_x^2 - 8*ξ_x*ξ_y + 12*ξ_x + 6*ξ_y - 4) + # Face 3 + i == 5 && return Vec( 8*ξ_x*ξ_y - 6*ξ_x + 8*ξ_y^2 - 12*ξ_y + 4, + 2*ξ_x*(-4*ξ_x - 4*ξ_y + 3)) + i == 6 && return Vec(-8*ξ_x*ξ_y + 6*ξ_x + 2*ξ_y - 2, + 4*ξ_x*(2*ξ_x - 1)) + # Cell + i == 7 && return Vec( 8*ξ_y*(-ξ_x - 2*ξ_y + 2), + 8*ξ_x*( ξ_x + 2*ξ_y - 1)) + i == 8 && return Vec( 8*ξ_y*( 2*ξ_x + ξ_y - 1), + 8*ξ_x*(-2*ξ_x - ξ_y + 2)) + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::Nedelec{2,RefTriangle,2}) = 8 +facedof_interior_indices(::Nedelec{2,RefTriangle,2}) = ((1,2), (3,4), (5,6)) +celldof_interior_indices(::Nedelec{2,RefTriangle,2}) = (7,8) +adjust_dofs_during_distribution(::Nedelec{2,RefTriangle,2}) = true + +function get_direction(::Nedelec{2,RefTriangle,2}, j, cell) + j>6 && return 1 + facenr = (j+1)÷2 + face_vertices = faces(cell)[facenr] + return face_vertices[2] > face_vertices[1] ? 1 : -1 +end + +# RefTetrahedron, 1st order Lagrange - 𝐍𝐎𝐓 𝐓𝐄𝐒𝐓𝐄𝐃 +# https://defelement.com/elements/examples/tetrahedron-nedelec1-lagrange-1.html +function shape_value(ip::Nedelec{2,RefTetrahedron,1}, ξ::Vec{3,T}, i::Int) where T + x, y, z = ξ + # Edge 1 (defelement 5, positive) + i == 1 && return Vec(- y - z + 1, x, x) + # Edge 2 (defelement 2, positive) + i == 2 && return Vec(-y, x, zero(T)) + # Edge 3 (defelement 4, negative) + i == 3 && return Vec(-y, x + z - 1, -y) + # Edge 4 (defelement 3, positive) + i == 4 && return Vec(z, z, -x - y + 1) + # Edge 5 (defelement 1, positive) + i == 5 && return Vec(-z, zero(T), x) + # Edge 6 (defelement 0, positive) + i == 6 && return Vec(zero(T), -z, y) + + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::Nedelec{2,RefTetrahedron,1}) = 6 +facedof_interior_indices(::Nedelec{2,RefTetrahedron,1}) = ntuple(i->(i,), 6) +adjust_dofs_during_distribution(::Nedelec{2,RefTetrahedron,1}) = false + +function get_direction(::Nedelec{2,RefTetrahedron,1}, j, cell) + edge_vertices = edges(cell)[j] + return edge_vertices[2] > edge_vertices[1] ? 1 : -1 +end + +# RefTetrahedron, 2nd order Lagrange +# https://defelement.com/elements/examples/tetrahedron-nedelec1-lagrange-2.html +#= Notes +The dofs belong to faces seem to require extra consideration, but not sure. +Basically, we need to make sure they are aligned with the same edges that they refer to. +It might be that this works automatically, following `adjust_dofs_during_distribution`, +but test cases need to be developed first to make sure. +No point in implementing guesses that cannot be verified... +=# \ No newline at end of file diff --git a/src/iterators.jl b/src/iterators.jl index e623ab0d82..258230623b 100644 --- a/src/iterators.jl +++ b/src/iterators.jl @@ -374,7 +374,6 @@ function Base.iterate(ii::InterfaceIterator, state...) end end - # Iterator interface for CellIterator/FaceIterator const GridIterators{C} = Union{CellIterator{C}, FaceIterator{C}, InterfaceIterator{C}} @@ -407,15 +406,9 @@ function _check_same_celltype(grid::AbstractGrid, faceset::Set{FaceIndex}) end end - -mutable struct CellIterator2{CC,DH,IC} - cache::CC # const - dh::SDH # const - cells::IC # const - current_cell::Int -end -mutable struct CellCache2{T,dim,CT} - const x::Vector{Vec{dim,T}} - const dofs::Vector{Int} - cell::CT -end +#= Remaining tasks +1) Test on quadrilateral +2) Generalize to 2nd order case +3) Generalize to 3d-face +4) Consider RaviartThomas elements for 0-3 as well. +=# \ No newline at end of file From f62961c12b869834630ad68c036496fe40325aa6 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 20 Sep 2023 21:53:22 +0200 Subject: [PATCH 016/145] Add citation from master --- src/FEValues/GeometryValues.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index 1bcbacd3b8..d1a6300d04 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -81,7 +81,7 @@ The transformation theorem for some function f on a 2D surface in 3D space leads ∫ f ⋅ dS = ∫ f ⋅ (∂x/∂ξ₁ × ∂x/∂ξ₂) dξ₁dξ₂ = ∫ f ⋅ n ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ dξ₁dξ₂ where ||∂x/∂ξ₁ × ∂x/∂ξ₂||₂ is "detJ" and n is the unit normal. See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation. -For more details see e.g. the doctoral thesis by Mirza Cenanovic **Finite element methods for surface problems* (2017), Ch. 2 **Trangential Calculus**. +For more details see e.g. the doctoral thesis by Mirza Cenanovic **Tangential Calculus** [Cenanovic2017](@cite). """ embedding_det(J::SMatrix{3,2}) = norm(J[:,1] × J[:,2]) From eeb1245fbca2cb85afded775047635dc0d5c386e Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 20 Sep 2023 21:53:40 +0200 Subject: [PATCH 017/145] Empty cell_values.jl --- src/FEValues/cell_values.jl | 252 ------------------------------------ 1 file changed, 252 deletions(-) diff --git a/src/FEValues/cell_values.jl b/src/FEValues/cell_values.jl index d7480df1d8..e69de29bb2 100644 --- a/src/FEValues/cell_values.jl +++ b/src/FEValues/cell_values.jl @@ -1,252 +0,0 @@ -""" - OldCellValues([::Type{T},] quad_rule::QuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation]) - -A `OldCellValues` object facilitates the process of evaluating values of shape functions, gradients of shape functions, -values of nodal functions, gradients and divergences of nodal functions etc. in the finite element cell. - -**Arguments:** -* `T`: an optional argument (default to `Float64`) to determine the type the internal data is stored as. -* `quad_rule`: an instance of a [`QuadratureRule`](@ref) -* `func_interpol`: an instance of an [`Interpolation`](@ref) used to interpolate the approximated function -* `geom_interpol`: an optional instance of a [`Interpolation`](@ref) which is used to interpolate the geometry. - By default linear Lagrange interpolation is used. For embedded elements the geometric interpolations should - be vectorized to the spatial dimension. - -**Common methods:** - -* [`reinit!`](@ref) -* [`getnquadpoints`](@ref) -* [`getdetJdV`](@ref) - -* [`shape_value`](@ref) -* [`shape_gradient`](@ref) -* [`shape_symmetric_gradient`](@ref) -* [`shape_divergence`](@ref) - -* [`function_value`](@ref) -* [`function_gradient`](@ref) -* [`function_symmetric_gradient`](@ref) -* [`function_divergence`](@ref) -* [`spatial_coordinate`](@ref) -""" -OldCellValues - -struct OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCellValues - N::Matrix{N_t} - dNdx::Matrix{dNdx_t} - dNdξ::Matrix{dNdξ_t} - detJdV::Vector{T} - M::Matrix{T} - dMdξ::Matrix{dMdξ_t} - qr::QR - ip::IP - gip::GIP -end - -# Common initializer code for constructing OldCellValues after the types have been determined -function OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP}(qr::QR, ip::IP, gip::GIP) where { - IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP, -} - @assert isconcretetype(IP) && isconcretetype(N_t) && isconcretetype(dNdx_t) && - isconcretetype(dNdξ_t) && isconcretetype(T) && isconcretetype(dMdξ_t) && - isconcretetype(QR) && isconcretetype(GIP) - n_qpoints = getnquadpoints(qr) - - # Field interpolation - n_func_basefuncs = getnbasefunctions(ip) - N = fill(zero(N_t) * T(NaN), n_func_basefuncs, n_qpoints) - dNdx = fill(zero(dNdx_t) * T(NaN), n_func_basefuncs, n_qpoints) - dNdξ = fill(zero(dNdξ_t) * T(NaN), n_func_basefuncs, n_qpoints) - - # Geometry interpolation - n_geom_basefuncs = getnbasefunctions(gip) - M = fill(zero(T) * T(NaN), n_geom_basefuncs, n_qpoints) - dMdξ = fill(zero(dMdξ_t) * T(NaN), n_geom_basefuncs, n_qpoints) - - for (qp, ξ) in pairs(getpoints(qr)) - for basefunc in 1:n_func_basefuncs - dNdξ[basefunc, qp], N[basefunc, qp] = shape_gradient_and_value(ip, ξ, basefunc) - end - for basefunc in 1:n_geom_basefuncs - dMdξ[basefunc, qp], M[basefunc, qp] = shape_gradient_and_value(gip, ξ, basefunc) - end - end - - detJdV = fill(T(NaN), n_qpoints) - - OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP}(N, dNdx, dNdξ, detJdV, M, dMdξ, qr, ip, gip) -end - -# Common entry point that fills in the numeric type and geometric interpolation -function OldCellValues(qr::QuadratureRule, ip::Interpolation, - gip::Interpolation = default_geometric_interpolation(ip)) - return OldCellValues(Float64, qr, ip, gip) -end - -# Common entry point that fills in the geometric interpolation -function OldCellValues(::Type{T}, qr::QuadratureRule, ip::Interpolation) where {T} - return OldCellValues(T, qr, ip, default_geometric_interpolation(ip)) -end - -# Common entry point that vectorizes an input scalar geometric interpolation -function OldCellValues(::Type{T}, qr::QuadratureRule, ip::Interpolation, sgip::ScalarInterpolation) where {T} - return OldCellValues(T, qr, ip, VectorizedInterpolation(sgip)) -end - -# Entrypoint for `ScalarInterpolation`s (rdim == sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - dim, shape <: AbstractRefShape{dim}, T, - QR <: QuadratureRule{shape}, - IP <: ScalarInterpolation{shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{dim, shape, <:Any, GIP}, -} - # Function interpolation - N_t = T - dNdx_t = dNdξ_t = Vec{dim, T} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{dim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) -end - -# Entrypoint for `VectorInterpolation`s (vdim == rdim == sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - dim, shape <: AbstractRefShape{dim}, T, - QR <: QuadratureRule{shape}, - IP <: VectorInterpolation{dim, shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{dim, shape, <:Any, GIP}, -} - # Field interpolation - N_t = Vec{dim, T} - dNdx_t = dNdξ_t = Tensor{2, dim, T, Tensors.n_components(Tensor{2,dim})} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{dim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) -end - -# Entrypoint for `VectorInterpolation`s (vdim != rdim == sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, vgip::VGIP) where { - vdim, dim, shape <: AbstractRefShape{dim}, T, - QR <: QuadratureRule{shape}, - IP <: VectorInterpolation{vdim, shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{dim, shape, <:Any, GIP}, -} - # Field interpolation - N_t = SVector{vdim, T} - dNdx_t = dNdξ_t = SMatrix{vdim, dim, T, vdim*dim} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{dim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, vgip.ip) -end - -# reinit! for regular (non-embedded) elements (rdim == sdim) -function reinit!(cv::OldCellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVector{Vec{dim,T}}) where { - dim, T, vdim, - N_t <: Union{Number, Vec{dim}, SVector{vdim} }, - dNdx_t <: Union{Vec{dim}, Tensor{2, dim}, SMatrix{vdim, dim}}, - dNdξ_t <: Union{Vec{dim}, Tensor{2, dim}, SMatrix{vdim, dim}}, -} - n_geom_basefuncs = getngeobasefunctions(cv) - n_func_basefuncs = getnbasefunctions(cv) - length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) - - @inbounds for (i, w) in pairs(getweights(cv.qr)) - fecv_J = zero(Tensor{2,dim,T}) - for j in 1:n_geom_basefuncs - fecv_J += x[j] ⊗ cv.dMdξ[j, i] - end - detJ = det(fecv_J) - detJ > 0.0 || throw_detJ_not_pos(detJ) - cv.detJdV[i] = detJ * w - Jinv = inv(fecv_J) - for j in 1:n_func_basefuncs - # cv.dNdx[j, i] = cv.dNdξ[j, i] ⋅ Jinv - cv.dNdx[j, i] = dothelper(cv.dNdξ[j, i], Jinv) - end - end -end - -# Entrypoint for embedded `ScalarInterpolation`s (rdim < sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - sdim, rdim, shape <: AbstractRefShape{rdim}, T, - QR <: QuadratureRule{shape}, - IP <: ScalarInterpolation{shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{sdim, shape, <:Any, GIP}, -} - @assert sdim > rdim - # Function interpolation - N_t = T - dNdx_t = SVector{sdim, T} - dNdξ_t = SVector{rdim, T} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{rdim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) -end - -# Entrypoint for embedded `VectorInterpolation`s (rdim < sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - sdim, vdim, rdim, shape <: AbstractRefShape{rdim}, T, - QR <: QuadratureRule{shape}, - IP <: VectorInterpolation{vdim, shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{sdim, shape, <:Any, GIP}, -} - @assert sdim > rdim - # Function interpolation - N_t = SVector{vdim, T} - dNdx_t = SMatrix{vdim, sdim, T, vdim*sdim} - dNdξ_t = SMatrix{vdim, rdim, T, vdim*rdim} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{rdim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) -end - -# reinit! for embedded elements, rdim < sdim -function reinit!(cv::OldCellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVector{Vec{sdim,T}}) where { - rdim, sdim, vdim, T, - N_t <: Union{Number, SVector{vdim}}, - dNdx_t <: Union{SVector{sdim, T}, SMatrix{vdim, sdim, T}}, - dNdξ_t <: Union{SVector{rdim, T}, SMatrix{vdim, rdim, T}}, -} - @assert sdim > rdim "This reinit only works for embedded elements. Maybe you swapped the reference and spatial dimensions?" - n_geom_basefuncs = getngeobasefunctions(cv) - n_func_basefuncs = getnbasefunctions(cv) - length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) - - @inbounds for (i, w) in pairs(getweights(cv.qr)) - fecv_J = zero(MMatrix{sdim, rdim, T}) # TODO replace with MixedTensor (see https://github.com/Ferrite-FEM/Tensors.jl/pull/188) - for j in 1:n_geom_basefuncs - #fecv_J += x[j] ⊗ cv.dMdξ[j, i] # TODO via Tensors.jl - for k in 1:sdim, l in 1:rdim - fecv_J[k, l] += x[j][k] * cv.dMdξ[j, i][l] - end - end - fecv_J = SMatrix(fecv_J) - detJ = embedding_det(fecv_J) - detJ > 0.0 || throw_detJ_not_pos(detJ) - cv.detJdV[i] = detJ * w - # Compute "left inverse" of J - Jinv = pinv(fecv_J) - for j in 1:n_func_basefuncs - #cv.dNdx[j, i] = cv.dNdξ[j, i] ⋅ Jinv # TODO via Tensors.jl - cv.dNdx[j, i] = dothelper(cv.dNdξ[j, i], Jinv) - end - end - return nothing -end - -function Base.show(io::IO, m::MIME"text/plain", cv::OldCellValues) - println(io, "CellValues with") - println(io, "- Quadrature rule with ", getnquadpoints(cv), " points") - print(io, "- Function interpolation: "); show(io, m, cv.ip) - println(io) - print(io, "- Geometric interpolation: "); show(io, m, cv.gip) -end \ No newline at end of file From 6f7f98813e128006d3ba135e15f3170aee727bea Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 20 Sep 2023 22:27:06 +0200 Subject: [PATCH 018/145] Use mapping requirement info in GeometryValues --- src/FEValues/CellValues.jl | 7 +++---- src/FEValues/FaceValues.jl | 10 +++++----- src/FEValues/GeometryValues.jl | 6 +++++- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index beaf76ce82..8cdf9b1ba0 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -6,8 +6,8 @@ function default_geometric_interpolation(::Interpolation{shape}) where {dim, sha return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) end -struct CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCellValues - geo_values::GeometryValues{dMdξ_t, GIP, T} +struct CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP, d2Mdξ2_t} <: AbstractCellValues + geo_values::GeometryValues{dMdξ_t, GIP, T, d2Mdξ2_t} detJdV::Vector{T} fun_values::FunctionValues{IP, N_t, dNdx_t, dNdξ_t} qr::QR @@ -46,13 +46,12 @@ getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) geo_values = cv.geo_values fun_values = cv.fun_values - map_req = RequiresHessian(fun_values.ip, geo_values.ip) n_geom_basefuncs = getngeobasefunctions(geo_values) if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs throw_incompatible_coord_length(length(x), n_geom_basefuncs) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) - mapping = calculate_mapping(map_req, geo_values, q_point, x) + mapping = calculate_mapping(geo_values, q_point, x) detJ = calculate_detJ(getjacobian(mapping)) detJ > 0.0 || throw_detJ_not_pos(detJ) @inbounds cv.detJdV[q_point] = detJ*w diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 6ad5db4ef0..9d8ebec0c3 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -1,5 +1,5 @@ -struct FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP} <: AbstractFaceValues - geo_values::Vector{GeometryValues{dMdξ_t, GIP, T}} +struct FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP, d2Mdξ2_t} <: AbstractFaceValues + geo_values::Vector{GeometryValues{dMdξ_t, GIP, T, d2Mdξ2_t}} detJdV::Vector{T} normals::Vector{Normal_t} fun_values::Vector{FunctionValues{IP, N_t, dNdx_t, dNdξ_t}} @@ -8,7 +8,7 @@ struct FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP} <: Ab end function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun)) where {T,sdim} - geo_values = [GeometryValues(T, ip_geo.ip, qr) for qr in fqr.face_rules] + geo_values = [GeometryValues(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) for qr in fqr.face_rules] fun_values = [FunctionValues(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) detJdV = fill(T(NaN), max_nquadpoints) @@ -63,7 +63,7 @@ function checkface(fv::FaceValues, face::Int) return nothing end -function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int) where {dim, T} +function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, cell=nothing) where {dim, T} @boundscheck checkface(fv, face_nr) n_geom_basefuncs = getngeobasefunctions(fv) length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) @@ -80,7 +80,7 @@ function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int) wh detJ > 0.0 || throw_detJ_not_pos(detJ) @inbounds fv.detJdV[q_point] = detJ*w @inbounds fv.normals[q_point] = weight_norm / norm(weight_norm) - apply_mapping!(fun_values, q_point, mapping) + apply_mapping!(fun_values, q_point, mapping, cell) end end diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index d1a6300d04..349c1bbc9c 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -43,10 +43,14 @@ function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, end return GeometryValues(M, dMdξ, dM2dξ2, ip) end +RequiresHessian(::GeometryValues{<:Any,<:Any,<:Any,Nothing}) = RequiresHessian(false) +RequiresHessian(::GeometryValues) = RequiresHessian(true) getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) @propagate_inbounds geometric_value(geovals::GeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] +@propagate_inbounds calculate_mapping(geovals::GeometryValues, args...) = calculate_mapping(RequiresHessian(geovals), geovals, args...) + @inline function calculate_mapping(::RequiresHessian{false}, geo_values::GeometryValues{<:Vec{dim,T}}, q_point, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} fecv_J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) @inbounds for j in 1:getngeobasefunctions(geo_values) @@ -99,7 +103,7 @@ See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-di """ embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}}) = norm(J) -@inline function calculate_mapping(geo_values::GeometryValues{<:Vec{rdim,T}}, q_point, x::AbstractVector{<:Vec{sdim,T}}) where {rdim,sdim,T} +@inline function calculate_mapping(::RequiresHessian{false}, geo_values::GeometryValues{<:Vec{rdim,T}}, q_point, x::AbstractVector{<:Vec{sdim,T}}) where {rdim,sdim,T} n_geom_basefuncs = getngeobasefunctions(geo_values) fecv_J = zero(MMatrix{sdim, rdim, T}) # TODO replace with MixedTensor (see https://github.com/Ferrite-FEM/Tensors.jl/pull/188) for j in 1:n_geom_basefuncs From f1020f3da5a9dafef8a57772f5bf5e759d900775 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Thu, 21 Sep 2023 18:20:44 +0200 Subject: [PATCH 019/145] Add test for gradient and continuity of Nedelec --- docs/Manifest.toml | 20 ++--- docs/Project.toml | 1 + docs/src/literate-tutorials/maxwell.jl | 73 +++++++++------- src/interpolations.jl | 10 +-- test/InterpolationTestUtils.jl | 116 +++++++++++++++++++++++++ test/test_interpolations.jl | 35 ++++++++ 6 files changed, 210 insertions(+), 45 deletions(-) create mode 100644 test/InterpolationTestUtils.jl diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 97f82d95b6..00a9f3dfcf 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.9.2" manifest_format = "2.0" -project_hash = "0444e709e1c6f42386a9ac2b8c455eb5004d33dc" +project_hash = "f4ba79c26c9d5fa21c707a95d5a76911eedc0ccf" [[deps.ADTypes]] git-tree-sha1 = "5d2e21d7b0d8c22f67483ef95ebdc39c0e6b6003" @@ -460,6 +460,12 @@ git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" version = "1.0.4" +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8e9441ee83492030ace98f9789a654a6d0b1f643" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+0" + [[deps.ErrorfreeArithmetic]] git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" @@ -1680,8 +1686,8 @@ uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" version = "1.0.0" [[deps.Qt6Base_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"] -git-tree-sha1 = "ea513c73c8f657985e8fb9b8067dd7cf306adc35" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"] +git-tree-sha1 = "364898e8f13f7eaaceec55fd3d08680498c0aa6e" uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" version = "6.4.2+3" @@ -2272,14 +2278,8 @@ git-tree-sha1 = "8351f8d73d7e880bfc042a8b6922684ebeafb35c" uuid = "19fa3120-7c27-5ec5-8db8-b0b0aa330d6f" version = "0.2.0" -[[deps.Vulkan_Loader_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] -git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" -uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" -version = "1.3.243+0" - [[deps.Wayland_jll]] -deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"] git-tree-sha1 = "ed8d92d9774b077c53e1da50fd81a36af3744c1c" uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" version = "1.21.0+0" diff --git a/docs/Project.toml b/docs/Project.toml index 01eb9b476d..92114eb028 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -17,6 +17,7 @@ Optim = "429524aa-4258-5aef-a3af-852621145aeb" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Tensors = "48a634ad-e948-5137-8d70-aa71f2a747f4" TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" UnPack = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" diff --git a/docs/src/literate-tutorials/maxwell.jl b/docs/src/literate-tutorials/maxwell.jl index 7c295e4068..a09a5631e2 100644 --- a/docs/src/literate-tutorials/maxwell.jl +++ b/docs/src/literate-tutorials/maxwell.jl @@ -8,6 +8,9 @@ # ``` # As noted in the lecture, standard Lagrange elements are not sufficient to solve this problem accurately, # and we therefore use the Nedelec interpolation. +import LinearAlgebra: normalize +using StaticArrays +using Test using Ferrite import Ferrite: Nedelec import CairoMakie as M @@ -27,44 +30,54 @@ append!(qr_points, [Vec((i/(n+1), 1 - i/(n+1))) for i in 1:n]) qr = QuadratureRule{RefTriangle}(zeros(length(qr_points)), qr_points) cv = CellValues(qr, ip, ip_geo) -n_qp = getncells(grid)*getnquadpoints(cv) -coords = (zeros(n_qp), zeros(n_qp)) -vectors = (zeros(n_qp), zeros(n_qp)) +function plot_shapes(dh, cv) + grid = dh.grid + n_qp = getncells(grid)*getnquadpoints(cv) + coords = (zeros(n_qp), zeros(n_qp)) + vectors = (zeros(n_qp), zeros(n_qp)) -for nr in 1:(ndofs(dh)) - u = zeros(ndofs(dh)) - u[nr] = 1.0 + for nr in 1:(ndofs(dh)) + u = zeros(ndofs(dh)) + u[nr] = 1.0 - for cell_nr in 1:getncells(grid) - x = getcoordinates(grid, cell_nr) - reinit!(cv, x, getcells(grid, cell_nr)) - ue = u[celldofs(dh, cell_nr)] - for q_point in 1:getnquadpoints(cv) - i = getnquadpoints(cv)*(cell_nr-1) + q_point - qp_x = spatial_coordinate(cv, q_point, x) - v = function_value(cv, q_point, ue) - sfac = norm(v) ≈ 0 ? NaN : 1.0 # Skip plotting zero-vector points - coords[1][i] = sfac*qp_x[1] - coords[2][i] = sfac*qp_x[2] - vectors[1][i] = v[1] - vectors[2][i] = v[2] + for cell_nr in 1:getncells(grid) + x = getcoordinates(grid, cell_nr) + reinit!(cv, x, getcells(grid, cell_nr)) + ue = u[celldofs(dh, cell_nr)] + for q_point in 1:getnquadpoints(cv) + i = getnquadpoints(cv)*(cell_nr-1) + q_point + qp_x = spatial_coordinate(cv, q_point, x) + v = function_value(cv, q_point, ue) + sfac = norm(v) ≈ 0 ? NaN : 1.0 # Skip plotting zero-vector points + coords[1][i] = sfac*qp_x[1] + coords[2][i] = sfac*qp_x[2] + vectors[1][i] = v[1] + vectors[2][i] = v[2] + end end - end - fig = M.Figure() - ax = M.Axis(fig[1,1]; aspect=M.DataAspect()) - for cellnr in 1:getncells(grid) - x = getcoordinates(grid, cellnr) - push!(x, x[1]) - M.lines!(ax, first.(x), last.(x), color=:black) + fig = M.Figure() + ax = M.Axis(fig[1,1]; aspect=M.DataAspect()) + for cellnr in 1:getncells(grid) + x = getcoordinates(grid, cellnr) + push!(x, x[1]) + M.lines!(ax, first.(x), last.(x), color=:black) + end + M.arrows!(ax, coords..., vectors...; lengthscale=0.1) + display(fig) end - M.arrows!(ax, coords..., vectors...; lengthscale=0.1) - display(fig) + return nothing end +# plot_shapes(dh, cv) # Remaining tasks #= ✓ 2nd order Nedelec -* -=# \ No newline at end of file +* Develop test cases for + a) Continuity + b) Gradient check +=# + + +test_gradient(dh, 1) diff --git a/src/interpolations.jl b/src/interpolations.jl index 2aa7f31e73..285c19dca5 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1606,7 +1606,7 @@ end # RefTetrahedron, 1st order Lagrange - 𝐍𝐎𝐓 𝐓𝐄𝐒𝐓𝐄𝐃 # https://defelement.com/elements/examples/tetrahedron-nedelec1-lagrange-1.html -function shape_value(ip::Nedelec{2,RefTetrahedron,1}, ξ::Vec{3,T}, i::Int) where T +function shape_value(ip::Nedelec{3,RefTetrahedron,1}, ξ::Vec{3,T}, i::Int) where T x, y, z = ξ # Edge 1 (defelement 5, positive) i == 1 && return Vec(- y - z + 1, x, x) @@ -1624,11 +1624,11 @@ function shape_value(ip::Nedelec{2,RefTetrahedron,1}, ξ::Vec{3,T}, i::Int) wher throw(ArgumentError("no shape function $i for interpolation $ip")) end -getnbasefunctions(::Nedelec{2,RefTetrahedron,1}) = 6 -facedof_interior_indices(::Nedelec{2,RefTetrahedron,1}) = ntuple(i->(i,), 6) -adjust_dofs_during_distribution(::Nedelec{2,RefTetrahedron,1}) = false +getnbasefunctions(::Nedelec{3,RefTetrahedron,1}) = 6 +edgedof_interior_indices(::Nedelec{3,RefTetrahedron,1}) = ntuple(i->(i,), 6) +adjust_dofs_during_distribution(::Nedelec{3,RefTetrahedron,1}) = false -function get_direction(::Nedelec{2,RefTetrahedron,1}, j, cell) +function get_direction(::Nedelec{3,RefTetrahedron,1}, j, cell) edge_vertices = edges(cell)[j] return edge_vertices[2] > edge_vertices[1] ? 1 : -1 end diff --git a/test/InterpolationTestUtils.jl b/test/InterpolationTestUtils.jl new file mode 100644 index 0000000000..612be6df5b --- /dev/null +++ b/test/InterpolationTestUtils.jl @@ -0,0 +1,116 @@ +module InterpolationTestUtils + using Ferrite + using Test + import LinearAlgebra: normalize + import Random: randperm + + function find_matching_face(grid, face::FaceIndex) + cell, facenr = face + face_vertices = Set(Ferrite.faces(getcells(grid, cell))[facenr]) + for cnr in 1:getncells(grid) + cnr == cell && continue + for (i, f_vert) in enumerate(Ferrite.faces(getcells(grid, cnr))) + face_vertices == Set(f_vert) && return FaceIndex(cnr, i) + end + end + return nothing + end + + function test_continuity(dh::DofHandler, face::FaceIndex; + transformation_function::Function=identity, + value_function::Function=function_value) + # transformation_function: (v,n) -> z + # Examples + # * Tangential continuity: fun(v, n) = v - (v ⋅ n)*n + # * Normal continuity: fun(v, n) = v ⋅ n + # value_function: (fe_v, q_point, ue) -> z + + # Check validity of input + @assert length(dh.subdofhandlers) == 1 + @assert Ferrite.nfields(dh) == 1 + + # Find the matching FaceIndex + cellnr, facenr = face + face2 = find_matching_face(dh.grid, face) + face2 === nothing && return false + + # Pick "random" points on the face + cell = getcells(dh.grid, cellnr) + RefShape = Ferrite.getrefshape(getcells(dh.grid, cellnr)) + ip_geo = Ferrite.default_interpolation(typeof(cell)) + ip_fun = Ferrite.getfieldinterpolation(dh, (1,1)) + fqr = FaceQuadratureRule{RefShape}(10) + fv = FaceValues(fqr, ip_fun, ip_geo) + cell_coords = getcoordinates(dh.grid, cellnr) + inds = randperm(getnquadpoints(fv))[1:min(4, getnquadpoints(fv))] + + # Random dof vector to test continuity + u = rand(ndofs(dh)) + + # Calculate coordinates and function values for these + point_coords = zeros(eltype(cell_coords), length(inds)) + point_normal = similar(point_coords) + fun_vals = zeros(typeof(shape_value(fv, 1, 1)), length(inds)) + reinit!(fv, cell_coords, facenr, cell) + ue = u[celldofs(dh, cellnr)] + for (i, q_point) in enumerate(inds) + point_coords[i] = spatial_coordinate(fv, q_point, cell_coords) + point_normal[i] = getnormal(fv, q_point) + fun_vals[i] = value_function(fv, q_point, ue) + end + + # Calculate function values on the other cell + cell2 = getcells(dh.grid, face2[1]) + cell_coords2 = getcoordinates(dh.grid, face2[1]) + local_coords = map(x->Ferrite.find_local_coordinate(ip_geo, cell_coords2, x), point_coords) + @assert all(first.(local_coords)) # check that find_local_coordinate converged + ξs = collect(last.(local_coords)) # Extract the local coordinates + qr = QuadratureRule{RefShape}(zeros(length(ξs)), ξs) + cv = CellValues(qr, ip_fun, ip_geo) + reinit!(cv, cell_coords2, cell2) + fun_vals2 = similar(fun_vals) + ue2 = u[celldofs(dh, face2[1])] + for q_point in 1:getnquadpoints(cv) + @assert spatial_coordinate(cv, q_point, cell_coords2) ≈ point_coords[q_point] + fun_vals2[q_point] = value_function(cv, q_point, ue2) + end + + d1 = map((v,n)->transformation_function(v,n), fun_vals, point_normal) + d2 = map((v,n)->transformation_function(v,n), fun_vals2, point_normal) + @test d1 ≈ d2 + return true + end + + function create_gradcheck_qr(ip_geo::Interpolation{RefShape}, ΔL) where RefShape + dim = Ferrite.getdim(ip_geo) + xref = Ferrite.reference_coordinates(ip_geo) + xc = sum(xref)/length(xref) + ws = rand(length(xref))*((1-ΔL)/length(xref)) + xp = xc + sum(map((x,w) -> w*(x - xc), xref, ws)) + v = normalize(rand(Vec{dim}) - ones(Vec{dim})/2) + x1 = xp + ΔL*v + qr_w = [NaN, NaN] + qr_x = [xp, x1] + return QuadratureRule{RefShape}(qr_w, qr_x) + end + + function test_gradient(dh, cellnr; ΔL=1e-6) + ue = rand(ndofs_per_cell(dh, cellnr)) + x = getcoordinates(dh.grid, cellnr) + cell = getcells(dh.grid, cellnr) + ip_geo = Ferrite.default_interpolation(typeof(cell)) + ip_fun = Ferrite.getfieldinterpolation(dh, (1,1)) + qr = create_gradcheck_qr(ip_geo, ΔL) + cv = CellValues(qr, ip_fun, ip_geo) + reinit!(cv, x, cell) + Δu_num = function_value(cv, 2, ue) - function_value(cv, 1, ue) + Δx = spatial_coordinate(cv, 2, x) - spatial_coordinate(cv, 1, x) + ∇u1 = function_gradient(cv, 1, ue) + ∇u2 = function_gradient(cv, 2, ue) + Δu_ana = 0.5*(∇u1+∇u2) ⋅ Δx + # Δu_ana_var = 0.5*(∇u2-∇u1) ⋅ Δx # Relevant to compare magnitude if test fails + @test Δu_num ≈ Δu_ana + return nothing + end + +end \ No newline at end of file diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index b6653b4491..ed8f20f225 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -1,3 +1,4 @@ + @testset "interpolations" begin @testset "$interpolation" for interpolation in ( @@ -178,4 +179,38 @@ end @test Ferrite.is_discontinuous(ip_t) == false @test Ferrite.is_discontinuous(d_ip) == true @test Ferrite.is_discontinuous(d_ip_t) == true + +@testset "Nedelec" begin + include(joinpath(@__DIR__, "InterpolationTestUtils.jl")) + import .InterpolationTestUtils as ITU + nel = 3 + for CT in (Triangle, QuadraticTriangle, Tetrahedron) + dim = Ferrite.getdim(CT) + p1, p2 = (rand(Vec{dim}), ones(Vec{dim})+rand(Vec{dim})) + grid = generate_grid(CT, ntuple(_->nel, dim), p1, p2) + # Distort grid, important to properly test geometry mapping + # for 2nd order elements. Make sure distortion is less than + # a 10th of the element size. + transform_coordinates!(grid, x->(x + rand(x)/(10*nel))) + RefShape = Ferrite.getrefshape(getcells(grid, 1)) + for order in (1, 2) + dim == 3 && order > 1 && continue + ip = Nedelec{dim,RefShape,order}() + @testset "$CT, $ip" begin + dh = DofHandler(grid) + add!(dh, :u, ip) + close!(dh) + cellnr = getncells(grid)÷2 # Should be a cell in the center + for facenr in 1:nfaces(RefShape) + fi = FaceIndex(cellnr, facenr) + # Check continuity of tangential function value + ITU.test_continuity(dh, fi; transformation_function=(v,n)-> v - n*(v⋅n)) + end + # Check gradient calculation + ITU.test_gradient(dh, cellnr) + end + end + end end +end + From 02051eebe1518656d8fba1245000cf174180c33c Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Thu, 21 Sep 2023 20:13:53 +0200 Subject: [PATCH 020/145] Basic RaviartThomas implementation, gradient mapping seems to have an error though (test fails) --- docs/src/literate-tutorials/maxwell.jl | 17 +---- docs/src/literate-tutorials/maxwell_refel.jl | 5 +- src/FEValues/FunctionValues.jl | 24 +++++-- src/FEValues/GeometryValues.jl | 5 +- src/exports.jl | 2 + src/interpolations.jl | 72 +++++++++++--------- test/runtests.jl | 3 +- test/test_interpolations.jl | 39 ++++++----- 8 files changed, 96 insertions(+), 71 deletions(-) diff --git a/docs/src/literate-tutorials/maxwell.jl b/docs/src/literate-tutorials/maxwell.jl index a09a5631e2..20d5498b79 100644 --- a/docs/src/literate-tutorials/maxwell.jl +++ b/docs/src/literate-tutorials/maxwell.jl @@ -12,9 +12,10 @@ import LinearAlgebra: normalize using StaticArrays using Test using Ferrite -import Ferrite: Nedelec +import Ferrite: Nedelec, RaviartThomas import CairoMakie as M ip = Nedelec{2,RefTriangle,2}() +ip = RaviartThomas{2,RefTriangle,1}() grid = generate_grid(Triangle, (1,2)) dh = DofHandler(grid) add!(dh, :B, ip) @@ -68,16 +69,4 @@ function plot_shapes(dh, cv) end return nothing end - -# plot_shapes(dh, cv) - -# Remaining tasks -#= -✓ 2nd order Nedelec -* Develop test cases for - a) Continuity - b) Gradient check -=# - - -test_gradient(dh, 1) +plot_shapes(dh, cv) diff --git a/docs/src/literate-tutorials/maxwell_refel.jl b/docs/src/literate-tutorials/maxwell_refel.jl index c61849f88b..7bbc56c73a 100644 --- a/docs/src/literate-tutorials/maxwell_refel.jl +++ b/docs/src/literate-tutorials/maxwell_refel.jl @@ -10,9 +10,10 @@ # and we therefore use the Nedelec interpolation. import CairoMakie as M using Ferrite -import Ferrite: Nedelec +import Ferrite: Nedelec, RaviartThomas import Ferrite: reference_coordinates ip = Nedelec{2,RefTriangle,1}() +ip = RaviartThomas{2,RefTriangle,1}() ip_geo = Lagrange{RefTriangle,1}() ref_x = reference_coordinates(ip_geo) @@ -52,7 +53,7 @@ for i in 1:3 ax=M.Axis(fig2[i,1]; aspect=M.DataAspect()); M.lines!(ax, first.(x_vertices), last.(x_vertices)) x_qp = spatial_coordinate.((cv,), 1:length(x), (ref_x,)) - @show x_qp ≈ x + @show x_qp ≈ x # should be false v = shape_value.((cv,), 1:length(x), i) M.scatter!(ax, first.(x_qp), last.(x_qp)) M.arrows!(ax, first.(x_qp), last.(x_qp), first.(v), last.(v); lengthscale=0.25) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 1e91d13279..99daa6d168 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -73,16 +73,11 @@ struct ContravariantPiolaMapping end # struct DoubleContravariantPiolaMapping end get_mapping_type(fv::FunctionValues) = get_mapping_type(fv.ip) -#get_mapping_type(::FunctionValues{<:ScalarInterpolation}) = IdentityMapping() -#get_mapping_type(::FunctionValues{<:VectorizedInterpolation}) = IdentityMapping() -#get_mapping_type(::FunctionValues{<:HdivIP}) = ContravariantPiolaMapping() -#get_mapping_type(::FunctionValues{<:HcurlIP}) = CovariantPiolaMapping() requires_hessian(::IdentityMapping) = false requires_hessian(::ContravariantPiolaMapping) = true requires_hessian(::CovariantPiolaMapping) = true - calculate_Jinv(J::Tensor{2}) = inv(J) calculate_Jinv(J::SMatrix) = pinv(J) @@ -121,3 +116,22 @@ end end return nothing end + +@inline function apply_mapping!(funvals::FunctionValues, ::ContravariantPiolaMapping, q_point::Int, mapping_values, cell) + H = gethessian(mapping_values) + J = getjacobian(mapping_values) + Jinv = inv(J) + detJ = det(J) + I2 = one(J) + H_Jinv = H⋅Jinv + A1 = (H_Jinv ⊡ (otimesl(I2,I2))) / detJ + A2 = (Jinv' ⊡ H_Jinv) / detJ + @inbounds for j in 1:getnbasefunctions(funvals) + d = get_direction(funvals.ip, j, cell) + dNdξ = funvals.dNdξ[j, q_point] + N_ξ = funvals.N_ξ[j, q_point] + funvals.N_x[j, q_point] = d*(J ⋅ N_ξ)/detJ + funvals.dNdx[j, q_point] = d*(Jinv ⋅ dNdξ ⋅ Jinv/detJ + A1 ⋅ N_ξ - (J ⋅ N_ξ) ⊗ A2) + end + return nothing +end diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index 349c1bbc9c..71b73d45f3 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -3,7 +3,10 @@ struct MappingValues{JT, HT<:Union{Nothing,AbstractTensor{3}}} H::HT # dJ/dξ # Hessian end @inline getjacobian(mv::MappingValues) = mv.J -@inline gethessian(mv::MappingValues) = mv.H +@inline gethessian(mv::MappingValues{<:Any,<:AbstractTensor}) = mv.H + +@inline gethessian(::MappingValues{JT,Nothing}) where JT = _make_hessian(JT) +@inline _make_hessian(::Type{Tensor{2,dim,T}}) where {dim,T} = zero(Tensor{3,dim,T}) struct RequiresHessian{B} end RequiresHessian(B::Bool) = RequiresHessian{B}() diff --git a/src/exports.jl b/src/exports.jl index 09a0ab1e5e..a25d7e8420 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -16,6 +16,8 @@ export Lagrange, DiscontinuousLagrange, Serendipity, + Nedelec, + RaviartThomas, getnbasefunctions, # Quadrature diff --git a/src/interpolations.jl b/src/interpolations.jl index 285c19dca5..224118b2dc 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1518,26 +1518,34 @@ is_discontinuous(::Type{<:VectorizedInterpolation{<:Any, <:Any, <:Any, ip}}) whe get_mapping_type(::ScalarInterpolation) = IdentityMapping() get_mapping_type(::VectorizedInterpolation) = IdentityMapping() -#= Just notes for now for RaviartThomas. Nedelec below tbd first +##################################### +# RaviartThomas (1st kind), H(div) # +##################################### # https://defelement.com/elements/raviart-thomas.html # https://defelement.com/elements/qdiv.html struct RaviartThomas{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end +get_mapping_type(::RaviartThomas) = ContravariantPiolaMapping() -facedof_interior_indices(ip::RaviartThomas) = facedof_indices(ip) - -getnbasefunctions(::RaviartThomas{2,RefTriangle,1}) = 3 -facedof_indices(::RaviartThomas{2,RefTriangle,1}) = ((1,), (2,), (3,)) -adjust_dofs_during_distribution(::RaviartThomas) = false # Not sure how this works, but should be done for higher orders +# RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-raviart-thomas-lagrange-1.html +# Signs changed when needed to make positive direction outwards function shape_value(ip::RaviartThomas{2,RefTriangle,1}, ξ::Vec{2}, i::Int) - ξ_x, ξ_y = ξ - i == 1 && return -ξ - i == 2 && return Vec(ξ_x-1, ξ_y) - i == 3 && return Vec(-ξ_x, 1 - ξ_y) + x, y = ξ + i == 1 && return ξ # Flip sign + i == 2 && return Vec(x-1, y) # Keep sign + i == 3 && return Vec(x, y - 1) # Flip sign throw(ArgumentError("no shape function $i for interpolation $ip")) end -=# + +getnbasefunctions(::RaviartThomas{2,RefTriangle,1}) = 3 +facedof_interior_indices(::RaviartThomas{2,RefTriangle,1}) = ((1,), (2,), (3,)) +adjust_dofs_during_distribution(::RaviartThomas) = false + +function get_direction(::RaviartThomas{2,RefTriangle,1}, j, cell) + face_vertices = faces(cell)[j] + return face_vertices[2] > face_vertices[1] ? 1 : -1 +end ##################################### @@ -1549,10 +1557,10 @@ get_mapping_type(::Nedelec) = CovariantPiolaMapping() # RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-1.html function shape_value(ip::Nedelec{2,RefTriangle,1}, ξ::Vec{2}, i::Int) - ξ_x, ξ_y = ξ - i == 1 && return Vec( - ξ_y, ξ_x) - i == 2 && return Vec( - ξ_y, ξ_x - 1) # Changed signed, follow Ferrite's sign convention - i == 3 && return Vec(1 - ξ_y, ξ_x) + x, y = ξ + i == 1 && return Vec( - y, x) + i == 2 && return Vec( - y, x - 1) # Changed signed, follow Ferrite's sign convention + i == 3 && return Vec(1 - y, x) throw(ArgumentError("no shape function $i for interpolation $ip")) end @@ -1568,27 +1576,27 @@ end # RefTriangle, 2nd order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-2.html function shape_value(ip::Nedelec{2,RefTriangle,2}, ξ::Vec{2}, i::Int) - ξ_x, ξ_y = ξ + x, y = ξ # Face 1 - i == 1 && return Vec( 2*ξ_y*(1 - 4*ξ_x), - 4*ξ_x*(2*ξ_x - 1)) - i == 2 && return Vec( 4*ξ_y*(1 - 2*ξ_y), - 2*ξ_x*(4*ξ_y - 1)) + i == 1 && return Vec( 2*y*(1 - 4*x), + 4*x*(2*x - 1)) + i == 2 && return Vec( 4*y*(1 - 2*y), + 2*x*(4*y - 1)) # Face 2 (flip order and sign compared to defelement) - i == 3 && return Vec( 4*ξ_y*(1 - 2*ξ_y), - 8*ξ_x*ξ_y - 2*ξ_x - 6*ξ_y + 2) - i == 4 && return Vec( 2*ξ_y*(4*ξ_x + 4*ξ_y - 3), - -8*ξ_x^2 - 8*ξ_x*ξ_y + 12*ξ_x + 6*ξ_y - 4) + i == 3 && return Vec( 4*y*(1 - 2*y), + 8*x*y - 2*x - 6*y + 2) + i == 4 && return Vec( 2*y*(4*x + 4*y - 3), + -8*x^2 - 8*x*y + 12*x + 6*y - 4) # Face 3 - i == 5 && return Vec( 8*ξ_x*ξ_y - 6*ξ_x + 8*ξ_y^2 - 12*ξ_y + 4, - 2*ξ_x*(-4*ξ_x - 4*ξ_y + 3)) - i == 6 && return Vec(-8*ξ_x*ξ_y + 6*ξ_x + 2*ξ_y - 2, - 4*ξ_x*(2*ξ_x - 1)) + i == 5 && return Vec( 8*x*y - 6*x + 8*y^2 - 12*y + 4, + 2*x*(-4*x - 4*y + 3)) + i == 6 && return Vec(-8*x*y + 6*x + 2*y - 2, + 4*x*(2*x - 1)) # Cell - i == 7 && return Vec( 8*ξ_y*(-ξ_x - 2*ξ_y + 2), - 8*ξ_x*( ξ_x + 2*ξ_y - 1)) - i == 8 && return Vec( 8*ξ_y*( 2*ξ_x + ξ_y - 1), - 8*ξ_x*(-2*ξ_x - ξ_y + 2)) + i == 7 && return Vec( 8*y*(-x - 2*y + 2), + 8*x*( x + 2*y - 1)) + i == 8 && return Vec( 8*y*( 2*x + y - 1), + 8*x*(-2*x - y + 2)) throw(ArgumentError("no shape function $i for interpolation $ip")) end diff --git a/test/runtests.jl b/test/runtests.jl index d11ed6d582..e98ca2daa4 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -19,7 +19,7 @@ end include("test_utils.jl") include("test_interpolations.jl") -include("test_cellvalues.jl") +#=include("test_cellvalues.jl") include("test_facevalues.jl") include("test_quadrules.jl") include("test_assemble.jl") @@ -38,3 +38,4 @@ include("test_deprecations.jl") HAS_EXTENSIONS && include("blockarrays.jl") include("test_examples.jl") @test all(x -> isdefined(Ferrite, x), names(Ferrite)) # Test that all exported symbols are defined +=# \ No newline at end of file diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index ed8f20f225..fe22eff22c 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -1,6 +1,6 @@ @testset "interpolations" begin - +#= @testset "$interpolation" for interpolation in ( Lagrange{RefLine, 1}(), Lagrange{RefLine, 2}(), @@ -179,11 +179,14 @@ end @test Ferrite.is_discontinuous(ip_t) == false @test Ferrite.is_discontinuous(d_ip) == true @test Ferrite.is_discontinuous(d_ip_t) == true - -@testset "Nedelec" begin +=# +@testset "Hcurl and Hdiv" begin include(joinpath(@__DIR__, "InterpolationTestUtils.jl")) import .InterpolationTestUtils as ITU nel = 3 + transformation_functions = Dict( + Nedelec=>(v,n)-> v - n*(v⋅n), # Hcurl (tangent continuity) + RaviartThomas=>(v,n) -> v ⋅ n) # Hdiv (normal continuity) for CT in (Triangle, QuadraticTriangle, Tetrahedron) dim = Ferrite.getdim(CT) p1, p2 = (rand(Vec{dim}), ones(Vec{dim})+rand(Vec{dim})) @@ -194,20 +197,24 @@ end transform_coordinates!(grid, x->(x + rand(x)/(10*nel))) RefShape = Ferrite.getrefshape(getcells(grid, 1)) for order in (1, 2) - dim == 3 && order > 1 && continue - ip = Nedelec{dim,RefShape,order}() - @testset "$CT, $ip" begin - dh = DofHandler(grid) - add!(dh, :u, ip) - close!(dh) - cellnr = getncells(grid)÷2 # Should be a cell in the center - for facenr in 1:nfaces(RefShape) - fi = FaceIndex(cellnr, facenr) - # Check continuity of tangential function value - ITU.test_continuity(dh, fi; transformation_function=(v,n)-> v - n*(v⋅n)) + for IPT in (Nedelec, RaviartThomas) + dim == 3 && order > 1 && continue + IPT == RaviartThomas && (dim == 3 || order > 1) && continue + transformation_function=transformation_functions[IPT] + ip = IPT{dim,RefShape,order}() + @testset "$CT, $ip" begin + dh = DofHandler(grid) + add!(dh, :u, ip) + close!(dh) + cellnr = getncells(grid)÷2 # Should be a cell in the center + for facenr in 1:nfaces(RefShape) + fi = FaceIndex(cellnr, facenr) + # Check continuity of tangential function value + ITU.test_continuity(dh, fi; transformation_function) + end + # Check gradient calculation + ITU.test_gradient(dh, cellnr) end - # Check gradient calculation - ITU.test_gradient(dh, cellnr) end end end From df83ae84579d81ce3403446ec4e973e0d24d9c99 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 22 Sep 2023 23:29:24 +0200 Subject: [PATCH 021/145] Fix error in ContravariantPiolaMapping gradient calculation --- src/FEValues/FunctionValues.jl | 2 +- test/InterpolationTestUtils.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 99daa6d168..2290e310d4 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -131,7 +131,7 @@ end dNdξ = funvals.dNdξ[j, q_point] N_ξ = funvals.N_ξ[j, q_point] funvals.N_x[j, q_point] = d*(J ⋅ N_ξ)/detJ - funvals.dNdx[j, q_point] = d*(Jinv ⋅ dNdξ ⋅ Jinv/detJ + A1 ⋅ N_ξ - (J ⋅ N_ξ) ⊗ A2) + funvals.dNdx[j, q_point] = d*(J ⋅ dNdξ ⋅ Jinv/detJ + A1 ⋅ N_ξ - (J ⋅ N_ξ) ⊗ A2) end return nothing end diff --git a/test/InterpolationTestUtils.jl b/test/InterpolationTestUtils.jl index 612be6df5b..6cace40b44 100644 --- a/test/InterpolationTestUtils.jl +++ b/test/InterpolationTestUtils.jl @@ -27,7 +27,7 @@ module InterpolationTestUtils # Check validity of input @assert length(dh.subdofhandlers) == 1 - @assert Ferrite.nfields(dh) == 1 + @assert length(Ferrite.getfieldnames(dh)) == 1 # Find the matching FaceIndex cellnr, facenr = face From c4e1d63d299a7e7bd55105c6c17e1311018948c0 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 23 Sep 2023 10:58:20 +0200 Subject: [PATCH 022/145] Reenable tests, setup tmp ci, add mapping desc to devdocs --- .github/workflows/ci.yml | 8 +- docs/Manifest.toml | 4 +- docs/src/assets/fe_mapping.svg | 3089 ++++++++++++++++++++++++++++++++ docs/src/devdocs/index.md | 2 +- docs/src/devdocs/mapping.md | 103 ++ test/runtests.jl | 3 +- test/test_interpolations.jl | 4 +- 7 files changed, 3206 insertions(+), 7 deletions(-) create mode 100644 docs/src/assets/fe_mapping.svg create mode 100644 docs/src/devdocs/mapping.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2401b36ad..99e406eb71 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,13 @@ jobs: - uses: julia-actions/setup-julia@v1 with: version: ${{ matrix.julia-version }} - - uses: julia-actions/julia-buildpkg@v1 + #- uses: julia-actions/julia-buildpkg@v1 + - run: | + julia --color=yes --project=. -e ' + using Pkg + Pkg.add(url="https://github.com/KnutAM/Tensors.jl.git", rev="kam/3rd_order") + Pkg.instantiate()' + shell: bash - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 with: diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 00a9f3dfcf..073d66c467 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -2154,7 +2154,9 @@ version = "0.1.1" [[deps.Tensors]] deps = ["ForwardDiff", "LinearAlgebra", "PrecompileTools", "SIMD", "StaticArrays", "Statistics"] -path = "C:\\Users\\meyer\\.julia\\dev\\Tensors" +git-tree-sha1 = "09650779b3c5124b8742986904d6e69f854be0bd" +repo-rev = "kam/3rd_order" +repo-url = "https://github.com/KnutAM/Tensors.jl.git" uuid = "48a634ad-e948-5137-8d70-aa71f2a747f4" version = "1.15.0" diff --git a/docs/src/assets/fe_mapping.svg b/docs/src/assets/fe_mapping.svg new file mode 100644 index 0000000000..39fd0e70fb --- /dev/null +++ b/docs/src/assets/fe_mapping.svg @@ -0,0 +1,3089 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/devdocs/index.md b/docs/src/devdocs/index.md index 3560eff4a1..75b50844c6 100644 --- a/docs/src/devdocs/index.md +++ b/docs/src/devdocs/index.md @@ -5,5 +5,5 @@ developing the library. ```@contents Depth = 1 -Pages = ["reference_cells.md", "interpolations.md", "elements.md", "dofhandler.md", "performance.md"] +Pages = ["reference_cells.md", "interpolations.md", "elements.md", "mapping.md", "dofhandler.md", "performance.md"] ``` diff --git a/docs/src/devdocs/mapping.md b/docs/src/devdocs/mapping.md new file mode 100644 index 0000000000..9d741fb839 --- /dev/null +++ b/docs/src/devdocs/mapping.md @@ -0,0 +1,103 @@ +# Mapping of finite elements +The shape functions and gradients stored in an `FEValues` object, is reinitialized for each cell by calling the `reinit!` function. The main part of this calculation, considers how to map the functions described on the reference cell, to the actual cell. + +The geometric mapping of a finite element from the reference coordinates to the real coordinates is shown in the following illustration. + +![mapping_figure](../assets/fe_mapping.svg) + +This mapping is given by the geometric shape functions, $\hat{N}_i^g(\boldsymbol{\xi})$, such that +```math +\begin{align*} + \boldsymbol{x}(\boldsymbol{\xi}) =& \sum_{i}^N \hat{\boldsymbol{x}}_i \hat{N}_i^g(\boldsymbol{\xi}) \\ + \boldsymbol{J} :=& \frac{\mathrm{d}\boldsymbol{x}}{\mathrm{d}\boldsymbol{\xi}} = \sum_{i}^N \hat{\boldsymbol{x}}_i \otimes \frac{\mathrm{d} \hat{N}_i^g}{\mathrm{d}\boldsymbol{\xi}}\\ + \boldsymbol{\mathcal{H}} :=& + \frac{\mathrm{d} \boldsymbol{J}}{\mathrm{d} \boldsymbol{\xi}} = \sum_{\alpha=1}^N \hat{\boldsymbol{x}}_\alpha \otimes \frac{\mathrm{d}^2 \hat{N}^g_\alpha}{\mathrm{d} \boldsymbol{\xi}^2} +\end{align*} +``` +where the defined $\boldsymbol{J}$ is the jacobian of the mapping, and in some cases we will also need the corresponding hessian, $\boldsymbol{\mathcal{H}}$ (3rd order tensor). + +We require that the mapping from reference coordinates to real coordinates is bijective, meaning that we can express $\boldsymbol{x} = \boldsymbol{x}(\boldsymbol{\xi}(\boldsymbol{x}))$, such that +```math +\begin{align*} + \frac{\mathrm{d}\boldsymbol{x}}{\mathrm{d}\boldsymbol{x}} = \boldsymbol{I} &= \frac{\mathrm{d}\boldsymbol{x}}{\mathrm{d}\boldsymbol{\xi}} \cdot \frac{\mathrm{d}\boldsymbol{\xi}}{\mathrm{d}\boldsymbol{x}} + \quad\Rightarrow\quad + \frac{\mathrm{d}\boldsymbol{\xi}}{\mathrm{d}\boldsymbol{x}} = \left[\frac{\mathrm{d}\boldsymbol{x}}{\mathrm{d}\boldsymbol{\xi}}\right]^{-1} = \boldsymbol{J}^{-1} +\end{align*} +``` +Depending on the function interpolation, we may want different types of mappings to conserve certain properties of the fields. This results in the different mapping types described below. + +## Identity mapping +`Ferrite.IdentityMapping` + +For scalar fields, we always use scalar base functions. For tensorial fields (non-scalar, e.g. vector-fields), the base functions can be constructed from scalar base functions, by using e.g. `VectorizedInterpolation`. From the perspective of the mapping, however, each component is mapped as an individual scalar base function. And for scalar base functions, we only require that the value of the base function is invariant to the element shape (real coordinate), and only depends on the reference coordinate, i.e. +```math +\begin{align*} + N(\boldsymbol{x}) &= \hat{N}(\boldsymbol{\xi}(\boldsymbol{x}))\nonumber \\ + \mathrm{grad}(N(\boldsymbol{x})) &= \frac{\mathrm{d}\hat{N}}{\mathrm{d}\boldsymbol{\xi}} \cdot \boldsymbol{J}^{-1} +\end{align*} +``` + +## Covariant Piola mapping, H(curl) +`Ferrite.CovariantPiolaMapping` + +The covariant Piola mapping of a vectorial base function preserves the tangential components. For the value, the mapping is defined as +```math +\begin{align*} + \boldsymbol{N}(\boldsymbol{x}) = \boldsymbol{J}^{-\mathrm{T}} \cdot \hat{\boldsymbol{N}}(\boldsymbol{\xi}(\boldsymbol{x})) +\end{align*} +``` +which yields the gradient, +```math +\begin{align*} + \mathrm{grad}(\boldsymbol{N}(\boldsymbol{x})) &= \boldsymbol{J}^{-T} \cdot \frac{\mathrm{d} \hat{\boldsymbol{N}}}{\mathrm{d} \boldsymbol{\xi}} \cdot \boldsymbol{J}^{-1} - \boldsymbol{J}^{-T} \cdot \left[\hat{\boldsymbol{N}}(\boldsymbol{\xi}(\boldsymbol{x}))\cdot \boldsymbol{J}^{-1} \cdot \boldsymbol{\mathcal{H}}\cdot \boldsymbol{J}^{-1}\right] +\end{align*} +``` + +!!! details "Derivation" + Expressing the gradient, $\mathrm{grad}(\boldsymbol{N})$, in index notation, + ```math + \begin{align*} + \frac{\mathrm{d} N_i}{\mathrm{d} x_j} &= \frac{\mathrm{d}}{\mathrm{d} x_j} \left[J^{-\mathrm{T}}_{ik} \hat{N}_k\right] = \frac{\mathrm{d} J^{-\mathrm{T}}_{ik}}{\mathrm{d} x_j} \hat{N}_k + J^{-\mathrm{T}}_{ik} \frac{\mathrm{d} \hat{N}_k}{\mathrm{d} \xi_l} J_{lj}^{-1} + \end{align*} + ``` + + Except for a few elements, $\boldsymbol{J}$ varies as a function of $\boldsymbol{x}$. The derivative can be calculated as + ```math + \begin{align*} + \frac{\mathrm{d} J^{-\mathrm{T}}_{ik}}{\mathrm{d} x_j} &= \frac{\mathrm{d} J^{-\mathrm{T}}_{ik}}{\mathrm{d} J_{mn}} \frac{\mathrm{d} J_{mn}}{\mathrm{d} x_j} = - J_{km}^{-1} J_{in}^{-T} \frac{\mathrm{d} J_{mn}}{\mathrm{d} x_j} \nonumber \\ + \frac{\mathrm{d} J_{mn}}{\mathrm{d} x_j} &= \mathcal{H}_{mno} J_{oj}^{-1} + \end{align*} + ``` + +## Contravariant Piola mapping, H(div) +`Ferrite.ContravariantPiolaMapping` + +The covariant Piola mapping of a vectorial base function preserves the normal components. For the value, the mapping is defined as +```math +\begin{align*} + \boldsymbol{N}(\boldsymbol{x}) = \frac{\boldsymbol{J}}{\det(\boldsymbol{J})} \cdot \hat{\boldsymbol{N}}(\boldsymbol{\xi}(\boldsymbol{x})) +\end{align*} +``` +This gives the gradient +```math +\begin{align*} + \mathrm{grad}(\boldsymbol{N}(\boldsymbol{x})) = [\boldsymbol{\mathcal{H}}\cdot\boldsymbol{J}^{-1}] : \frac{[\boldsymbol{I} \underline{\otimes} \boldsymbol{I}] \cdot \hat{\boldsymbol{N}}}{\det(\boldsymbol{J})} + - \left[\frac{\boldsymbol{J} \cdot \hat{\boldsymbol{N}}}{\det(\boldsymbol{J})}\right] \otimes \left[\boldsymbol{J}^{-T} : \boldsymbol{\mathcal{H}} \cdot \boldsymbol{J}^{-1}\right] + + \boldsymbol{J} \cdot \frac{\mathrm{d} \hat{\boldsymbol{N}}}{\mathrm{d} \boldsymbol{\xi}} \cdot \frac{\boldsymbol{J}^{-1}}{\det(\boldsymbol{J})} +\end{align*} +``` + +!!! details "Derivation" + Expressing the gradient, $\mathrm{grad}(\boldsymbol{N})$, in index notation, + ```math + \begin{align*} + \frac{\mathrm{d} N_i}{\mathrm{d} x_j} &= \frac{\mathrm{d}}{\mathrm{d} x_j} \left[\frac{J_{ik}}{\det(\boldsymbol{J})} \hat{N}_k\right] =\nonumber\\ + &= \frac{\mathrm{d} J_{ik}}{\mathrm{d} x_j} \frac{\hat{N}_k}{\det(\boldsymbol{J})} + - \frac{\mathrm{d} \det(\boldsymbol{J})}{\mathrm{d} x_j} \frac{J_{ik} \hat{N}_k}{\det(\boldsymbol{J})^2} + + \frac{J_{ik}}{\det(\boldsymbol{J})} \frac{\mathrm{d} \hat{N}_k}{\mathrm{d} \xi_l} J_{lj}^{-1} \\ + &= \mathcal{H}_{ikl} J^{-1}_{lj} \frac{\hat{N}_k}{\det(\boldsymbol{J})} + - J^{-T}_{mn} \mathcal{H}_{mnl} J^{-1}_{lj} \frac{J_{ik} \hat{N}_k}{\det(\boldsymbol{J})} + + \frac{J_{ik}}{\det(\boldsymbol{J})} \frac{\mathrm{d} \hat{N}_k}{\mathrm{d} \xi_l} J_{lj}^{-1} + \end{align*} + ``` + diff --git a/test/runtests.jl b/test/runtests.jl index e98ca2daa4..d11ed6d582 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -19,7 +19,7 @@ end include("test_utils.jl") include("test_interpolations.jl") -#=include("test_cellvalues.jl") +include("test_cellvalues.jl") include("test_facevalues.jl") include("test_quadrules.jl") include("test_assemble.jl") @@ -38,4 +38,3 @@ include("test_deprecations.jl") HAS_EXTENSIONS && include("blockarrays.jl") include("test_examples.jl") @test all(x -> isdefined(Ferrite, x), names(Ferrite)) # Test that all exported symbols are defined -=# \ No newline at end of file diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index fe22eff22c..da462b27f9 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -1,6 +1,6 @@ @testset "interpolations" begin -#= + @testset "$interpolation" for interpolation in ( Lagrange{RefLine, 1}(), Lagrange{RefLine, 2}(), @@ -179,7 +179,7 @@ end @test Ferrite.is_discontinuous(ip_t) == false @test Ferrite.is_discontinuous(d_ip) == true @test Ferrite.is_discontinuous(d_ip_t) == true -=# + @testset "Hcurl and Hdiv" begin include(joinpath(@__DIR__, "InterpolationTestUtils.jl")) import .InterpolationTestUtils as ITU From 562041a275ffd3a256d281cf0b09fb382a21b4c2 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 25 Sep 2023 18:28:40 +0200 Subject: [PATCH 023/145] bijective to diffeomorphic in theory section --- docs/src/devdocs/mapping.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/devdocs/mapping.md b/docs/src/devdocs/mapping.md index 9d741fb839..0d9dca4302 100644 --- a/docs/src/devdocs/mapping.md +++ b/docs/src/devdocs/mapping.md @@ -16,7 +16,7 @@ This mapping is given by the geometric shape functions, $\hat{N}_i^g(\boldsymbol ``` where the defined $\boldsymbol{J}$ is the jacobian of the mapping, and in some cases we will also need the corresponding hessian, $\boldsymbol{\mathcal{H}}$ (3rd order tensor). -We require that the mapping from reference coordinates to real coordinates is bijective, meaning that we can express $\boldsymbol{x} = \boldsymbol{x}(\boldsymbol{\xi}(\boldsymbol{x}))$, such that +We require that the mapping from reference coordinates to real coordinates is [diffeomorphic](https://en.wikipedia.org/wiki/Diffeomorphism), meaning that we can express $\boldsymbol{x} = \boldsymbol{x}(\boldsymbol{\xi}(\boldsymbol{x}))$, such that ```math \begin{align*} \frac{\mathrm{d}\boldsymbol{x}}{\mathrm{d}\boldsymbol{x}} = \boldsymbol{I} &= \frac{\mathrm{d}\boldsymbol{x}}{\mathrm{d}\boldsymbol{\xi}} \cdot \frac{\mathrm{d}\boldsymbol{\xi}}{\mathrm{d}\boldsymbol{x}} From cf44f6c9a8ea0da87a55091b129f9cc8d01d967e Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 27 Sep 2023 12:08:36 +0200 Subject: [PATCH 024/145] Work on maxwell eigenproblem, but doesn't give correct results --- docs/generate.jl | 2 +- docs/make.jl | 2 +- .../literate-tutorials/maxwell_eigenvalue.jl | 103 ++++++++++++++++++ ...ll.jl => nedelec_raviartthomas_testing.jl} | 0 ...=> nedelec_raviartthomas_testing_refel.jl} | 0 src/FEValues/CellValues.jl | 2 +- src/FEValues/common_values.jl | 1 + src/interpolations.jl | 6 +- 8 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 docs/src/literate-tutorials/maxwell_eigenvalue.jl rename docs/src/literate-tutorials/{maxwell.jl => nedelec_raviartthomas_testing.jl} (100%) rename docs/src/literate-tutorials/{maxwell_refel.jl => nedelec_raviartthomas_testing_refel.jl} (100%) diff --git a/docs/generate.jl b/docs/generate.jl index e06d3a14e9..fabe1410b5 100644 --- a/docs/generate.jl +++ b/docs/generate.jl @@ -22,7 +22,7 @@ include("download_resources.jl") # Run Literate on all examples @timeit dto "Literate." for (IN, OUT) in [(TUTORIALS_IN, TUTORIALS_OUT), (HOWTO_IN, HOWTO_OUT), (GALLERY_IN, GALLERY_OUT)], program in readdir(IN; join=true) name = basename(program) - if endswith(program, "maxwell.jl") + if endswith(program, "maxwell_eigenvalue.jl") if !liveserver script = @timeit dto "script()" @timeit dto name Literate.script(program, OUT) code = strip(read(script, String)) diff --git a/docs/make.jl b/docs/make.jl index dc12933932..a737ad81e8 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -46,7 +46,7 @@ bibtex_plugin = CitationBibliography( # hide("Changelog" => "changelog.md"), "Tutorials" => [ # "Tutorials overview" => "tutorials/index.md", - "tutorials/maxwell.md", + "tutorials/maxwell_eigenvalue.md", #= "tutorials/heat_equation.md", "tutorials/linear_elasticity.md", "tutorials/incompressible_elasticity.md", diff --git a/docs/src/literate-tutorials/maxwell_eigenvalue.jl b/docs/src/literate-tutorials/maxwell_eigenvalue.jl new file mode 100644 index 0000000000..782937ae01 --- /dev/null +++ b/docs/src/literate-tutorials/maxwell_eigenvalue.jl @@ -0,0 +1,103 @@ +# The Maxwell eigenvalue problem +# Following the Fenics tutorial, +# [*Stable and unstable finite elements for the Maxwell eigenvalue problem*](https://fenicsproject.org/olddocs/dolfin/2019.1.0/python/demos/maxwell-eigenvalues/demo_maxwell-eigenvalues.py.html), +# we show how Nedelec elements can be used +# with Ferrite.jl +# ## Problem description +# ### Strong form +# +# ### Weak form +# ```math +# \int_\Omega \mathrm{curl}(\boldsymbol{\delta u}) \cdot \mathrm{curl}(\boldsymbol{u})\, \mathrm{d}\Omega = \lambda \int_\Omega \boldsymbol{\delta u}\cdot \boldsymbol{u}\ \mathrm{d}\Omega +# ``` +# ### FE form +# ```math +# \begin{align*} +# \int_\Omega \mathrm{curl}(\boldsymbol{\delta N}_i) \cdot \mathrm{curl}(\boldsymbol{N}_j)\, \mathrm{d}\Omega a_j &= \lambda \int_\Omega \boldsymbol{\delta N}_i\cdot \boldsymbol{N}_j\ \mathrm{d}\Omega a_j \\ +# A_{ij} a_j &= \lambda B_{ij} a_j +# \end{align*} +# ``` + +# https://iterativesolvers.julialinearalgebra.org/dev/eigenproblems/lobpcg/ +using Ferrite +import Ferrite: Nedelec, RaviartThomas +import IterativeSolvers: lobpcg +using LinearAlgebra + +function assemble_cell!(Ae, Be, cv) + n = getnbasefunctions(cv) + for q_point in 1:getnquadpoints(cv) + dΩ = getdetJdV(cv, q_point) + for i in 1:n + δNi = shape_value(cv, q_point, i) + curl_δNi = shape_curl(cv, q_point, i) + for j in 1:n + Nj = shape_value(cv, q_point, j) + curl_Nj = shape_curl(cv, q_point, j) + Ae[i,j] += (curl_δNi ⋅ curl_Nj)*dΩ + Be[i,j] += (δNi ⋅ Nj)*dΩ + end + end + end + return Ae, Be +end + +function doassemble(dh::DofHandler, cv::CellValues) + grid = dh.grid + A, B = create_sparsity_pattern.((dh, dh)) + assemA, assemB = start_assemble.((A, B)) + x = getcoordinates(grid, 1) + n_el_dofs = ndofs_per_cell(dh, 1) + dofs = zeros(Int, n_el_dofs) + Ae, Be = [zeros(n_el_dofs, n_el_dofs) for _ in 1:2] + + for (ic, cell) in pairs(getcells(grid)) + getcoordinates!(x, grid, cell) + celldofs!(dofs, dh, ic) + reinit!(cv, x, cell) + fill!.((Ae, Be), 0) + assemble_cell!(Ae, Be, cv) + assemble!(assemA, dofs, Ae) + assemble!(assemB, dofs, Be) + end + return A, B +end + +function get_matrices(ip::Interpolation; CT=Quadrilateral, nel=40, usebc=true) + RefShape = Ferrite.getrefshape(ip) + grid = generate_grid(CT, (nel,nel), zero(Vec{2}), π*ones(Vec{2})) + dh = DofHandler(grid) + add!(dh, :u, ip) + close!(dh) + ip_geo = Ferrite.default_interpolation(CT) + cv = CellValues(QuadratureRule{RefShape}(2), ip, ip_geo) + A, B = doassemble(dh, cv) + if usebc + ch = ConstraintHandler(dh) + dΩh = union(getfaceset(grid, "left"), getfaceset(grid, "right")) + dΩv = union(getfaceset(grid, "top"), getfaceset(grid, "bottom")) + if ip isa VectorizedInterpolation + add!(ch, Dirichlet(:u, dΩh, Returns(0.0), 2)) # y-component on left-right + add!(ch, Dirichlet(:u, dΩv, Returns(0.0), 1)) # x-component on top-bottom + else + add!(ch, Dirichlet(:u, union!(dΩh,dΩv), Returns(0.0))) + end + close!(ch) + update!(ch, 0.0) + apply!(A, ch) + apply!(B, ch) + end + return A, B +end + +function solve(ip; num_values, kwargs...) + A, B = get_matrices(ip; kwargs...) + n = size(A,1) + r = lobpcg(Symmetric(A), Symmetric(B), false, zeros(n,num_values)) + return r.λ +end + +ip = Nedelec{2,RefTriangle,1}() +#ip = Lagrange{RefTriangle,1}()^2 + +λ = solve(ip; CT=Triangle, num_values=10) \ No newline at end of file diff --git a/docs/src/literate-tutorials/maxwell.jl b/docs/src/literate-tutorials/nedelec_raviartthomas_testing.jl similarity index 100% rename from docs/src/literate-tutorials/maxwell.jl rename to docs/src/literate-tutorials/nedelec_raviartthomas_testing.jl diff --git a/docs/src/literate-tutorials/maxwell_refel.jl b/docs/src/literate-tutorials/nedelec_raviartthomas_testing_refel.jl similarity index 100% rename from docs/src/literate-tutorials/maxwell_refel.jl rename to docs/src/literate-tutorials/nedelec_raviartthomas_testing_refel.jl diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 8cdf9b1ba0..2c09019414 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -35,7 +35,7 @@ getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] # Accessors for function values getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) -for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient, :shape_curl) +for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient) eval(quote @propagate_inbounds $op(cv::CellValues, i::Int, q_point::Int) = $op(cv.fun_values, i, q_point) end) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index eac205a62c..683cc36511 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -103,6 +103,7 @@ function shape_curl(cv::AbstractValues, q_point::Int, base_func::Int) return curl_from_gradient(shape_gradient(cv, q_point, base_func)) end curl_from_gradient(∇v::SecondOrderTensor{3}) = Vec{3}((∇v[3,2] - ∇v[2,3], ∇v[1,3] - ∇v[3,1], ∇v[2,1] - ∇v[1,2])) +curl_from_gradient(∇v::SecondOrderTensor{2}) = Vec{1}((∇v[2,1] - ∇v[1,2],)) # Alternatively define as Vec{3}((0,0,v)) """ function_value(fe_v::AbstractValues, q_point::Int, u::AbstractVector) diff --git a/src/interpolations.jl b/src/interpolations.jl index 224118b2dc..f8235f2bb0 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -53,7 +53,6 @@ n_components(::ScalarInterpolation) = 1 n_components(::VectorInterpolation{vdim}) where {vdim} = vdim # Number of components that are allowed to prescribe in e.g. Dirichlet BC n_dbc_components(ip::Interpolation) = n_components(ip) -# n_dbc_components(::Union{RaviartThomas,Nedelec}) = 1 # TODO: Remove: this is a hotfix to apply constraints to embedded elements. edges(ip::InterpolationByDim{2}) = faces(ip) @@ -1526,6 +1525,7 @@ get_mapping_type(::VectorizedInterpolation) = IdentityMapping() # https://defelement.com/elements/qdiv.html struct RaviartThomas{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end get_mapping_type(::RaviartThomas) = ContravariantPiolaMapping() +n_dbc_components(::RaviartThomas) = 1 # RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-raviart-thomas-lagrange-1.html @@ -1553,7 +1553,9 @@ end ##################################### struct Nedelec{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end get_mapping_type(::Nedelec) = CovariantPiolaMapping() - +reference_coordinates(ip::Nedelec{vdim}) where vdim = fill(NaN*zero(Vec{vdim}), getnbasefunctions(ip)) +dirichlet_facedof_indices(ip::Nedelec) = facedof_interior_indices(ip) +n_dbc_components(::Nedelec) = 1 # RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-1.html function shape_value(ip::Nedelec{2,RefTriangle,1}, ξ::Vec{2}, i::Int) From bafd9cefddbf64bd219806c74798a5bfe4a8ee40 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Tue, 3 Oct 2023 12:04:55 +0200 Subject: [PATCH 025/145] Remove unintended comments --- src/iterators.jl | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/iterators.jl b/src/iterators.jl index 5e31f934c8..5915dcd02e 100644 --- a/src/iterators.jl +++ b/src/iterators.jl @@ -405,11 +405,4 @@ function _check_same_celltype(grid::AbstractGrid, faceset::Set{FaceIndex}) if !all(getcelltype(grid, face[1]) == celltype for face in faceset) error("The cells in the faceset are not all of the same celltype.") end -end - -#= Remaining tasks -1) Test on quadrilateral -2) Generalize to 2nd order case -3) Generalize to 3d-face -4) Consider RaviartThomas elements for 0-3 as well. -=# \ No newline at end of file +end \ No newline at end of file From eed2740544586e9d8c0c3929659f049da2658c2f Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 7 Oct 2023 16:40:57 +0200 Subject: [PATCH 026/145] Create mixed formulation, RaviartThomas example --- docs/generate.jl | 2 +- docs/make.jl | 17 +- .../literate-tutorials/heat_equation_rt.jl | 268 ++++++++++++++++++ .../heat_equation_triangle.jl | 229 +++++++++++++++ notes/heat_equation_rt_theory.md | 34 +++ .../maxwell_eigenvalue.jl | 62 +++- .../nedelec_raviartthomas_testing.jl | 0 .../nedelec_raviartthomas_testing_refel.jl | 0 8 files changed, 601 insertions(+), 11 deletions(-) create mode 100644 docs/src/literate-tutorials/heat_equation_rt.jl create mode 100644 docs/src/literate-tutorials/heat_equation_triangle.jl create mode 100644 notes/heat_equation_rt_theory.md rename {docs/src/literate-tutorials => notes}/maxwell_eigenvalue.jl (64%) rename {docs/src/literate-tutorials => notes}/nedelec_raviartthomas_testing.jl (100%) rename {docs/src/literate-tutorials => notes}/nedelec_raviartthomas_testing_refel.jl (100%) diff --git a/docs/generate.jl b/docs/generate.jl index fabe1410b5..8bcb08dc78 100644 --- a/docs/generate.jl +++ b/docs/generate.jl @@ -22,7 +22,7 @@ include("download_resources.jl") # Run Literate on all examples @timeit dto "Literate." for (IN, OUT) in [(TUTORIALS_IN, TUTORIALS_OUT), (HOWTO_IN, HOWTO_OUT), (GALLERY_IN, GALLERY_OUT)], program in readdir(IN; join=true) name = basename(program) - if endswith(program, "maxwell_eigenvalue.jl") + if endswith(program, ".jl") if !liveserver script = @timeit dto "script()" @timeit dto name Literate.script(program, OUT) code = strip(read(script, String)) diff --git a/docs/make.jl b/docs/make.jl index a737ad81e8..5f949e897a 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -45,9 +45,10 @@ bibtex_plugin = CitationBibliography( "Home" => "index.md", # hide("Changelog" => "changelog.md"), "Tutorials" => [ - # "Tutorials overview" => "tutorials/index.md", - "tutorials/maxwell_eigenvalue.md", - #= "tutorials/heat_equation.md", + "Tutorials overview" => "tutorials/index.md", + "tutorials/heat_equation.md", + "tutorials/heat_equation_rt.md", + "tutorials/heat_equation_triangle.md", "tutorials/linear_elasticity.md", "tutorials/incompressible_elasticity.md", "tutorials/hyperelasticity.md", @@ -56,9 +57,9 @@ bibtex_plugin = CitationBibliography( "tutorials/computational_homogenization.md", "tutorials/stokes-flow.md", "tutorials/ns_vs_diffeq.md", - "tutorials/linear_shell.md",=# + "tutorials/linear_shell.md", ], -#= "Topic guides" => [ + "Topic guides" => [ "Topic guide overview" => "topics/index.md", "topics/fe_intro.md", "topics/degrees_of_freedom.md", @@ -67,7 +68,7 @@ bibtex_plugin = CitationBibliography( "topics/constraints.md", "topics/grid.md", "topics/export.md" - ],=# + ], "Reference" => [ "Reference overview" => "reference/index.md", "reference/quadrature.md", @@ -80,11 +81,11 @@ bibtex_plugin = CitationBibliography( "reference/export.md", "reference/utils.md", ], - #= "How-to guides" => [ + "How-to guides" => [ "How-to guide overview" => "howto/index.md", "howto/postprocessing.md", "howto/threaded_assembly.md", - ],=# + ], "gallery/index.md", # "Code gallery" => [ # "Code gallery overview" => "gallery/index.md", diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl new file mode 100644 index 0000000000..8d000047bf --- /dev/null +++ b/docs/src/literate-tutorials/heat_equation_rt.jl @@ -0,0 +1,268 @@ +# # [Heat equation](@id tutorial-heat-equation) +# +# ![](heat_square.png) +# +# *Figure 1*: Temperature field on the unit square with an internal uniform heat source +# solved with homogeneous Dirichlet boundary conditions on the boundary. +# +#- +#md # !!! tip +#md # This example is also available as a Jupyter notebook: +#md # [`heat_equation.ipynb`](@__NBVIEWER_ROOT_URL__/examples/heat_equation.ipynb). +#- +# +# ## Introduction +# +# ## Strong form +# ```math +# \nabla \cdot \boldsymbol{q} = h \in \Omega \\ +# \boldsymbol{q} = - k\ \nabla u \in \Omega \\ +# \boldsymbol{q}\cdot \boldsymbol{n} = q_n \in \Gamma_\mathrm{N}\\ +# u = u_\mathrm{D} \in \Gamma_\mathrm{D} +# ``` +# +# ## Weak form +# ### Part 1 +# ```math +# \int_{\Omega} \delta u \nabla \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ +# \int_{\Gamma} \delta u \boldsymbol{n} \cdot \boldsymbol{q}\ \mathrm{d}\Gamma - +# \int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ +# ``` +# +# ### Part 2 +# ```math +# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega = - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega +# ``` +# where no Green-Gauss theorem is applied. +# +# ### Summary +# The weak form becomes, find $u\in H^1$ and $\boldsymbol{q} \in H\mathrm{(div)}$, such that +# ```math +# \begin{align*} +# -\int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega - +# \int_{\Gamma} \delta u\ q_\mathrm{n}\ \mathrm{d}\Gamma +# \quad +# \forall\ \delta u \in \delta H^1 \\ +# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega +# \quad \forall\ \boldsymbol{\delta q} \in \delta H\mathrm{(div)} +# \end{align*} +# ``` +# +# ## Commented Program +# +# Now we solve the problem in Ferrite. What follows is a program spliced with comments. +#md # The full program, without comments, can be found in the next [section](@ref heat_equation-plain-program). +# +# First we load Ferrite, and some other packages we need +using Ferrite, SparseArrays +# We start by generating a simple grid with 20x20 quadrilateral elements +# using `generate_grid`. The generator defaults to the unit square, +# so we don't need to specify the corners of the domain. +grid = generate_grid(Triangle, (100, 100)); + +# ### Trial and test functions +# A `CellValues` facilitates the process of evaluating values and gradients of +# test and trial functions (among other things). To define +# this we need to specify an interpolation space for the shape functions. +# We use Lagrange functions +# based on the two-dimensional reference quadrilateral. We also define a quadrature rule based on +# the same reference element. We combine the interpolation and the quadrature rule +# to a `CellValues` object. +ip_geo = Lagrange{RefTriangle, 1}() +ipu = Lagrange{RefTriangle, 1}() +ipq = RaviartThomas{2,RefTriangle,1}() +qr = QuadratureRule{RefTriangle}(2) +cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) + +# ### Degrees of freedom +# Next we need to define a `DofHandler`, which will take care of numbering +# and distribution of degrees of freedom for our approximated fields. +# We create the `DofHandler` and then add a single scalar field called `:u` based on +# our interpolation `ip` defined above. +# Lastly we `close!` the `DofHandler`, it is now that the dofs are distributed +# for all the elements. +dh = DofHandler(grid) +add!(dh, :u, ipu) +add!(dh, :q, ipq) +close!(dh); + +# Now that we have distributed all our dofs we can create our tangent matrix, +# using `create_sparsity_pattern`. This function returns a sparse matrix +# with the correct entries stored. +K = create_sparsity_pattern(dh) + +# ### Boundary conditions +# In Ferrite constraints like Dirichlet boundary conditions +# are handled by a `ConstraintHandler`. +ch = ConstraintHandler(dh); + +# Next we need to add constraints to `ch`. For this problem we define +# homogeneous Dirichlet boundary conditions on the whole boundary, i.e. +# the `union` of all the face sets on the boundary. +∂Ω = union( + getfaceset(grid, "left"), + getfaceset(grid, "right"), + getfaceset(grid, "top"), + getfaceset(grid, "bottom"), +); + +# Now we are set up to define our constraint. We specify which field +# the condition is for, and our combined face set `∂Ω`. The last +# argument is a function of the form $f(\textbf{x})$ or $f(\textbf{x}, t)$, +# where $\textbf{x}$ is the spatial coordinate and +# $t$ the current time, and returns the prescribed value. Since the boundary condition in +# this case do not depend on time we define our function as $f(\textbf{x}) = 0$, i.e. +# no matter what $\textbf{x}$ we return $0$. When we have +# specified our constraint we `add!` it to `ch`. +dbc = Dirichlet(:u, ∂Ω, (x, t) -> 0) +add!(ch, dbc); + +# Finally we also need to `close!` our constraint handler. When we call `close!` +# the dofs corresponding to our constraints are calculated and stored +# in our `ch` object. +close!(ch) + +# Note that if one or more of the constraints are time dependent we would use +# [`update!`](@ref) to recompute prescribed values in each new timestep. + +# ### Assembling the linear system +# +# Now we have all the pieces needed to assemble the linear system, $K u = f$. +# Assembling of the global system is done by looping over all the elements in order to +# compute the element contributions ``K_e`` and ``f_e``, which are then assembled to the +# appropriate place in the global ``K`` and ``f``. +# +# #### Element assembly +# We define the function `assemble_element!` (see below) which computes the contribution for +# an element. The function takes pre-allocated `ke` and `fe` (they are allocated once and +# then reused for all elements) so we first need to make sure that they are all zeroes at +# the start of the function by using `fill!`. Then we loop over all the quadrature points, +# and for each quadrature point we loop over all the (local) shape functions. We need the +# value and gradient of the test function, `δu` and also the gradient of the trial function +# `u`. We get all of these from `cellvalues`. +# +# !!! note "Notation" +# Comparing with the brief finite element introduction in [Introduction to FEM](@ref), +# the variables `δu`, `∇δu` and `∇u` are actually $\phi_i(\textbf{x}_q)$, $\nabla +# \phi_i(\textbf{x}_q)$ and $\nabla \phi_j(\textbf{x}_q)$, i.e. the evaluation of the +# trial and test functions in the quadrature point ``\textbf{x}_q``. However, to +# underline the strong parallel between the weak form and the implementation, this +# example uses the symbols appearing in the weak form. + +function assemble_element!(Ke::Matrix, fe::Vector, cv::NamedTuple, dr::NamedTuple) + cvu = cv[:u] + cvq = cv[:q] + dru = dr[:u] + drq = dr[:q] + n_basefuncs = getnbasefunctions(cvu) + ## Loop over quadrature points + for q_point in 1:getnquadpoints(cvu) + ## Get the quadrature weight + dΩ = getdetJdV(cvu, q_point) + ## Loop over test shape functions + for (iu, Iu) in pairs(dru) + δu = shape_value(cvu, q_point, iu) + ∇δu = shape_gradient(cvu, q_point, iu) + ## Add contribution to fe + fe[Iu] += δu * dΩ + ## Loop over trial shape functions + for (jq, Jq) in pairs(drq) + q = shape_value(cvq, q_point, jq) + ## Add contribution to Ke + Ke[Iu, Jq] -= (∇δu ⋅ q) * dΩ + end + end + for (iq, Iq) in pairs(drq) + δq = shape_value(cvq, q_point, iq) + for (ju, Ju) in pairs(dru) + ∇u = shape_gradient(cvu, q_point, ju) + Ke[Iq, Ju] += (δq ⋅ ∇u) * dΩ + end + for (jq, Jq) in pairs(drq) + q = shape_value(cvq, q_point, jq) + Ke[Iq, Jq] += (δq ⋅ q) * dΩ + end + end + end + return Ke, fe +end +#md nothing # hide + +# #### Global assembly +# We define the function `assemble_global` to loop over the elements and do the global +# assembly. The function takes our `cellvalues`, the sparse matrix `K`, and our DofHandler +# as input arguments and returns the assembled global stiffness matrix, and the assembled +# global force vector. We start by allocating `Ke`, `fe`, and the global force vector `f`. +# We also create an assembler by using `start_assemble`. The assembler lets us assemble into +# `K` and `f` efficiently. We then start the loop over all the elements. In each loop +# iteration we reinitialize `cellvalues` (to update derivatives of shape functions etc.), +# compute the element contribution with `assemble_element!`, and then assemble into the +# global `K` and `f` with `assemble!`. +# +# !!! note "Notation" +# Comparing again with [Introduction to FEM](@ref), `f` and `u` correspond to +# $\underline{\hat{f}}$ and $\underline{\hat{u}}$, since they represent the discretized +# versions. However, through the code we use `f` and `u` instead to reflect the strong +# connection between the weak form and the Ferrite implementation. + +function assemble_global(cellvalues, K::SparseMatrixCSC, dh::DofHandler) + ## Allocate the element stiffness matrix and element force vector + dofranges = (u = dof_range(dh, :u), q = dof_range(dh, :q)) + ncelldofs = ndofs_per_cell(dh) + Ke = zeros(ncelldofs, ncelldofs) + fe = zeros(ncelldofs) + ## Allocate global force vector f + f = zeros(ndofs(dh)) + ## Create an assembler + assembler = start_assemble(K, f) + x = copy(getcoordinates(dh.grid, 1)) + dofs = copy(celldofs(dh, 1)) + ## Loop over all cels + for cellnr in 1:getncells(dh.grid) + ## Reinitialize cellvalues for this cell + cell = getcells(dh.grid, cellnr) + getcoordinates!(x, grid, cell) + celldofs!(dofs, dh, cellnr) + reinit!(cellvalues[:u], x, cell) + reinit!(cellvalues[:q], x, cell) + ## Reset to 0 + fill!(Ke, 0) + fill!(fe, 0) + ## Compute element contribution + assemble_element!(Ke, fe, cellvalues, dofranges) + ## Assemble Ke and fe into K and f + assemble!(assembler, dofs, Ke, fe) + end + return K, f +end +#md nothing # hide + +# ### Solution of the system +# The last step is to solve the system. First we call `assemble_global` +# to obtain the global stiffness matrix `K` and force vector `f`. +K, f = assemble_global(cellvalues, K, dh); + +# To account for the boundary conditions we use the `apply!` function. +# This modifies elements in `K` and `f` respectively, such that +# we can get the correct solution vector `u` by using `\`. +apply!(K, f, ch) +u = K \ f; + +# ### Exporting to VTK +# To visualize the result we export the grid and our field `u` +# to a VTK-file, which can be viewed in e.g. [ParaView](https://www.paraview.org/). +u_nodes = evaluate_at_grid_nodes(dh, u, :u) +vtk_grid("heat_equation_rt", dh) do vtk + vtk_point_data(vtk, u_nodes, "u") +end + +@show norm(u_nodes)/length(u_nodes) + +#md # ## [Plain program](@id heat_equation-plain-program) +#md # +#md # Here follows a version of the program without any comments. +#md # The file is also available here: [`heat_equation.jl`](heat_equation.jl). +#md # +#md # ```julia +#md # @__CODE__ +#md # ``` diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl new file mode 100644 index 0000000000..d5ea45e4df --- /dev/null +++ b/docs/src/literate-tutorials/heat_equation_triangle.jl @@ -0,0 +1,229 @@ +# # [Heat equation](@id tutorial-heat-equation) +# +# ![](heat_square.png) +# +# *Figure 1*: Temperature field on the unit square with an internal uniform heat source +# solved with homogeneous Dirichlet boundary conditions on the boundary. +# +#- +#md # !!! tip +#md # This example is also available as a Jupyter notebook: +#md # [`heat_equation.ipynb`](@__NBVIEWER_ROOT_URL__/examples/heat_equation.ipynb). +#- +# +# ## Introduction +# +# The heat equation is the "Hello, world!" equation of finite elements. +# Here we solve the equation on a unit square, with a uniform internal source. +# The strong form of the (linear) heat equation is given by +# +# ```math +# -\nabla \cdot (k \nabla u) = f \quad \textbf{x} \in \Omega, +# ``` +# +# where $u$ is the unknown temperature field, $k$ the heat conductivity, +# $f$ the heat source and $\Omega$ the domain. For simplicity we set $f = 1$ +# and $k = 1$. We will consider homogeneous Dirichlet boundary conditions such that +# ```math +# u(\textbf{x}) = 0 \quad \textbf{x} \in \partial \Omega, +# ``` +# where $\partial \Omega$ denotes the boundary of $\Omega$. +# The resulting weak form is given given as follows: Find ``u \in \mathbb{U}`` such that +# ```math +# \int_{\Omega} \nabla \delta u \cdot \nabla u \ d\Omega = \int_{\Omega} \delta u \ d\Omega \quad \forall \delta u \in \mathbb{T}, +# ``` +# where $\delta u$ is a test function, and where $\mathbb{U}$ and $\mathbb{T}$ are suitable +# trial and test function sets, respectively. +#- +# ## Commented Program +# +# Now we solve the problem in Ferrite. What follows is a program spliced with comments. +#md # The full program, without comments, can be found in the next [section](@ref heat_equation-plain-program). +# +# First we load Ferrite, and some other packages we need +using Ferrite, SparseArrays +# We start by generating a simple grid with 20x20 quadrilateral elements +# using `generate_grid`. The generator defaults to the unit square, +# so we don't need to specify the corners of the domain. +grid = generate_grid(Triangle, (100, 100)); + +# ### Trial and test functions +# A `CellValues` facilitates the process of evaluating values and gradients of +# test and trial functions (among other things). To define +# this we need to specify an interpolation space for the shape functions. +# We use Lagrange functions +# based on the two-dimensional reference quadrilateral. We also define a quadrature rule based on +# the same reference element. We combine the interpolation and the quadrature rule +# to a `CellValues` object. +ip = Lagrange{RefTriangle, 1}() +qr = QuadratureRule{RefTriangle}(2) +cellvalues = CellValues(qr, ip); + +# ### Degrees of freedom +# Next we need to define a `DofHandler`, which will take care of numbering +# and distribution of degrees of freedom for our approximated fields. +# We create the `DofHandler` and then add a single scalar field called `:u` based on +# our interpolation `ip` defined above. +# Lastly we `close!` the `DofHandler`, it is now that the dofs are distributed +# for all the elements. +dh = DofHandler(grid) +add!(dh, :u, ip) +close!(dh); + +# Now that we have distributed all our dofs we can create our tangent matrix, +# using `create_sparsity_pattern`. This function returns a sparse matrix +# with the correct entries stored. +K = create_sparsity_pattern(dh) + +# ### Boundary conditions +# In Ferrite constraints like Dirichlet boundary conditions +# are handled by a `ConstraintHandler`. +ch = ConstraintHandler(dh); + +# Next we need to add constraints to `ch`. For this problem we define +# homogeneous Dirichlet boundary conditions on the whole boundary, i.e. +# the `union` of all the face sets on the boundary. +∂Ω = union( + getfaceset(grid, "left"), + getfaceset(grid, "right"), + getfaceset(grid, "top"), + getfaceset(grid, "bottom"), +); + +# Now we are set up to define our constraint. We specify which field +# the condition is for, and our combined face set `∂Ω`. The last +# argument is a function of the form $f(\textbf{x})$ or $f(\textbf{x}, t)$, +# where $\textbf{x}$ is the spatial coordinate and +# $t$ the current time, and returns the prescribed value. Since the boundary condition in +# this case do not depend on time we define our function as $f(\textbf{x}) = 0$, i.e. +# no matter what $\textbf{x}$ we return $0$. When we have +# specified our constraint we `add!` it to `ch`. +dbc = Dirichlet(:u, ∂Ω, (x, t) -> 0) +add!(ch, dbc); + +# Finally we also need to `close!` our constraint handler. When we call `close!` +# the dofs corresponding to our constraints are calculated and stored +# in our `ch` object. +close!(ch) + +# Note that if one or more of the constraints are time dependent we would use +# [`update!`](@ref) to recompute prescribed values in each new timestep. + +# ### Assembling the linear system +# +# Now we have all the pieces needed to assemble the linear system, $K u = f$. +# Assembling of the global system is done by looping over all the elements in order to +# compute the element contributions ``K_e`` and ``f_e``, which are then assembled to the +# appropriate place in the global ``K`` and ``f``. +# +# #### Element assembly +# We define the function `assemble_element!` (see below) which computes the contribution for +# an element. The function takes pre-allocated `ke` and `fe` (they are allocated once and +# then reused for all elements) so we first need to make sure that they are all zeroes at +# the start of the function by using `fill!`. Then we loop over all the quadrature points, +# and for each quadrature point we loop over all the (local) shape functions. We need the +# value and gradient of the test function, `δu` and also the gradient of the trial function +# `u`. We get all of these from `cellvalues`. +# +# !!! note "Notation" +# Comparing with the brief finite element introduction in [Introduction to FEM](@ref), +# the variables `δu`, `∇δu` and `∇u` are actually $\phi_i(\textbf{x}_q)$, $\nabla +# \phi_i(\textbf{x}_q)$ and $\nabla \phi_j(\textbf{x}_q)$, i.e. the evaluation of the +# trial and test functions in the quadrature point ``\textbf{x}_q``. However, to +# underline the strong parallel between the weak form and the implementation, this +# example uses the symbols appearing in the weak form. + +function assemble_element!(Ke::Matrix, fe::Vector, cellvalues::CellValues) + n_basefuncs = getnbasefunctions(cellvalues) + ## Reset to 0 + fill!(Ke, 0) + fill!(fe, 0) + ## Loop over quadrature points + for q_point in 1:getnquadpoints(cellvalues) + ## Get the quadrature weight + dΩ = getdetJdV(cellvalues, q_point) + ## Loop over test shape functions + for i in 1:n_basefuncs + δu = shape_value(cellvalues, q_point, i) + ∇δu = shape_gradient(cellvalues, q_point, i) + ## Add contribution to fe + fe[i] += δu * dΩ + ## Loop over trial shape functions + for j in 1:n_basefuncs + ∇u = shape_gradient(cellvalues, q_point, j) + ## Add contribution to Ke + Ke[i, j] += (∇δu ⋅ ∇u) * dΩ + end + end + end + return Ke, fe +end +#md nothing # hide + +# #### Global assembly +# We define the function `assemble_global` to loop over the elements and do the global +# assembly. The function takes our `cellvalues`, the sparse matrix `K`, and our DofHandler +# as input arguments and returns the assembled global stiffness matrix, and the assembled +# global force vector. We start by allocating `Ke`, `fe`, and the global force vector `f`. +# We also create an assembler by using `start_assemble`. The assembler lets us assemble into +# `K` and `f` efficiently. We then start the loop over all the elements. In each loop +# iteration we reinitialize `cellvalues` (to update derivatives of shape functions etc.), +# compute the element contribution with `assemble_element!`, and then assemble into the +# global `K` and `f` with `assemble!`. +# +# !!! note "Notation" +# Comparing again with [Introduction to FEM](@ref), `f` and `u` correspond to +# $\underline{\hat{f}}$ and $\underline{\hat{u}}$, since they represent the discretized +# versions. However, through the code we use `f` and `u` instead to reflect the strong +# connection between the weak form and the Ferrite implementation. + +function assemble_global(cellvalues::CellValues, K::SparseMatrixCSC, dh::DofHandler) + ## Allocate the element stiffness matrix and element force vector + n_basefuncs = getnbasefunctions(cellvalues) + Ke = zeros(n_basefuncs, n_basefuncs) + fe = zeros(n_basefuncs) + ## Allocate global force vector f + f = zeros(ndofs(dh)) + ## Create an assembler + assembler = start_assemble(K, f) + ## Loop over all cels + for cell in CellIterator(dh) + ## Reinitialize cellvalues for this cell + reinit!(cellvalues, cell) + ## Compute element contribution + assemble_element!(Ke, fe, cellvalues) + ## Assemble Ke and fe into K and f + assemble!(assembler, celldofs(cell), Ke, fe) + end + return K, f +end +#md nothing # hide + +# ### Solution of the system +# The last step is to solve the system. First we call `assemble_global` +# to obtain the global stiffness matrix `K` and force vector `f`. +K, f = assemble_global(cellvalues, K, dh); + +# To account for the boundary conditions we use the `apply!` function. +# This modifies elements in `K` and `f` respectively, such that +# we can get the correct solution vector `u` by using `\`. +apply!(K, f, ch) +u = K \ f; + +# ### Exporting to VTK +# To visualize the result we export the grid and our field `u` +# to a VTK-file, which can be viewed in e.g. [ParaView](https://www.paraview.org/). +vtk_grid("heat_equation", dh) do vtk + vtk_point_data(vtk, dh, u) +end + +@show norm(u)/length(u) + +#md # ## [Plain program](@id heat_equation-plain-program) +#md # +#md # Here follows a version of the program without any comments. +#md # The file is also available here: [`heat_equation.jl`](heat_equation.jl). +#md # +#md # ```julia +#md # @__CODE__ +#md # ``` diff --git a/notes/heat_equation_rt_theory.md b/notes/heat_equation_rt_theory.md new file mode 100644 index 0000000000..28088bbd3c --- /dev/null +++ b/notes/heat_equation_rt_theory.md @@ -0,0 +1,34 @@ +## Strong form +$$ +\nabla \cdot \boldsymbol{q} = h \in \Omega \\ +\boldsymbol{q} = - k\ \nabla u \in \Omega \\ +\boldsymbol{q}\cdot \boldsymbol{n} = q_n \in \Gamma_\mathrm{N}\\ +u = u_\mathrm{D} \in \Gamma_\mathrm{D} +$$ + +## Weak form +### Part 1 +$$ +\int_{\Omega} \delta u \nabla \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ +\int_{\Gamma} \delta u \boldsymbol{n} \cdot \boldsymbol{q}\ \mathrm{d}\Gamma - +\int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ +$$ + +### Part 2 +$$ +\int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega = - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega +$$ +where no Green-Gauss theorem is applied. + +### Summary +The weak form becomes, find $u\in H^1$ and $\boldsymbol{q} \in H\mathrm{(div)}$, such that +$$ +\begin{align*} +-\int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega - +\int_{\Gamma} \delta u\ q_\mathrm{n}\ \mathrm{d}\Gamma +\quad +\forall\ \delta u \in \delta H^1 \\ +\int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega + \quad \forall\ \boldsymbol{\delta q} \in \delta H\mathrm{(div)} +\end{align*} +$$ diff --git a/docs/src/literate-tutorials/maxwell_eigenvalue.jl b/notes/maxwell_eigenvalue.jl similarity index 64% rename from docs/src/literate-tutorials/maxwell_eigenvalue.jl rename to notes/maxwell_eigenvalue.jl index 782937ae01..2c64dfa140 100644 --- a/docs/src/literate-tutorials/maxwell_eigenvalue.jl +++ b/notes/maxwell_eigenvalue.jl @@ -23,6 +23,7 @@ using Ferrite import Ferrite: Nedelec, RaviartThomas import IterativeSolvers: lobpcg using LinearAlgebra +import CairoMakie as M function assemble_cell!(Ae, Be, cv) n = getnbasefunctions(cv) @@ -42,6 +43,49 @@ function assemble_cell!(Ae, Be, cv) return Ae, Be end +function plot_shapes(dh, ip, a) + cv = CellValues(QuadratureRule{RefTriangle}(1), ip, Lagrange{RefTriangle,1}()) + grid = dh.grid + n_cells = getncells(grid) + coords = (zeros(n_cells), zeros(n_cells)) + vectors = (zeros(n_cells), zeros(n_cells)) + + for cell_nr in 1:getncells(grid) + x = getcoordinates(grid, cell_nr) + reinit!(cv, x, getcells(grid, cell_nr)) + ue = a[celldofs(dh, cell_nr)] + for q_point in 1:getnquadpoints(cv) + #i = getnquadpoints(cv)*(cell_nr-1) + q_point + i = cell_nr + qp_x = spatial_coordinate(cv, q_point, x) + v = function_value(cv, q_point, ue) + sfac = norm(v) ≈ 0 ? NaN : 1.0 # Skip plotting zero-vector points + coords[1][i] = sfac*qp_x[1] + coords[2][i] = sfac*qp_x[2] + vectors[1][i] = v[1] + vectors[2][i] = v[2] + end + end + vtk_grid("tmp", dh.grid) do vtk + vtk_cell_data(vtk, vectors[1], "u1") + vtk_cell_data(vtk, vectors[2], "u2") + end + nothing, nothing + #= + fig = M.Figure() + for i in 1:2 + ax = M.Axis(fig[i,1]; aspect=M.DataAspect()) + #=for cellnr in 1:getncells(grid) + x = getcoordinates(grid, cellnr) + push!(x, x[1]) + M.lines!(ax, first.(x), last.(x), color=:black) + end=# + M.scatter!(ax, coords..., vectors[i]; lengthscale=0.1) + end + return fig + =# +end + function doassemble(dh::DofHandler, cv::CellValues) grid = dh.grid A, B = create_sparsity_pattern.((dh, dh)) @@ -87,7 +131,7 @@ function get_matrices(ip::Interpolation; CT=Quadrilateral, nel=40, usebc=true) apply!(A, ch) apply!(B, ch) end - return A, B + return A, B, dh end function solve(ip; num_values, kwargs...) @@ -97,7 +141,21 @@ function solve(ip; num_values, kwargs...) return r.λ end +function solve_single(ip, λ=2; kwargs...) + A, B, dh = get_matrices(ip; kwargs...) + a = (A-λ*B)\zeros(size(A,1)) + return dh, a +end + ip = Nedelec{2,RefTriangle,1}() #ip = Lagrange{RefTriangle,1}()^2 +dh, a = solve_single(ip, CT=Triangle) +cv = CellValues(QuadratureRule{RefTriangle}(2), ip, Lagrange{RefTriangle,1}()) +fig = plot_shapes(dh, ip, a) +#λ = solve(ip; CT=Triangle, num_values=10) -λ = solve(ip; CT=Triangle, num_values=10) \ No newline at end of file +m, n = (1,1) +λ=m^2+n^2 +u(x,y)=Vec((sin(m*x),sin(n*y))) +a = zeros(ndofs) +apply_analytical!() \ No newline at end of file diff --git a/docs/src/literate-tutorials/nedelec_raviartthomas_testing.jl b/notes/nedelec_raviartthomas_testing.jl similarity index 100% rename from docs/src/literate-tutorials/nedelec_raviartthomas_testing.jl rename to notes/nedelec_raviartthomas_testing.jl diff --git a/docs/src/literate-tutorials/nedelec_raviartthomas_testing_refel.jl b/notes/nedelec_raviartthomas_testing_refel.jl similarity index 100% rename from docs/src/literate-tutorials/nedelec_raviartthomas_testing_refel.jl rename to notes/nedelec_raviartthomas_testing_refel.jl From 026c753aa02bc9e4ee38841cb925aa3c9d642876 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 7 Oct 2023 17:11:17 +0200 Subject: [PATCH 027/145] Update docs manifest --- docs/Manifest.toml | 264 +++++++++++++++++++++++++++++---------------- 1 file changed, 171 insertions(+), 93 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 073d66c467..52fe3bffa6 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -91,9 +91,9 @@ version = "0.1.29" [[deps.ArrayLayouts]] deps = ["FillArrays", "LinearAlgebra"] -git-tree-sha1 = "0d61921af2799487b80453a44abb57db7a0c1381" +git-tree-sha1 = "9a731850434825d183af39c6e6cd0a1c32dd7e20" uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "1.4.1" +version = "1.4.2" weakdeps = ["SparseArrays"] [deps.ArrayLayouts.extensions] @@ -197,9 +197,9 @@ version = "1.0.5" [[deps.CairoMakie]] deps = ["Base64", "Cairo", "Colors", "FFTW", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools", "SHA"] -git-tree-sha1 = "696e7931bd6f5c773418452cbe5fd241cb85ac2a" +git-tree-sha1 = "74384dc4aba2b377e22703e849154252930c434d" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.10.9" +version = "0.10.11" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -239,9 +239,9 @@ version = "0.4.0" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "d9a8f86737b665e15a9641ecbac64deef9ce6724" +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.23.0" +version = "3.24.0" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] @@ -279,9 +279,9 @@ version = "0.3.0" [[deps.Compat]] deps = ["UUIDs"] -git-tree-sha1 = "e460f044ca8b99be31d35fe54fc33a5c33dd8ed7" +git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.9.0" +version = "4.10.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -292,6 +292,11 @@ deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.0.5+0" +[[deps.ConcreteStructs]] +git-tree-sha1 = "f749037478283d372048690eb3b5f92a79432b34" +uuid = "2569d6c7-a4a2-43d3-a901-331e8e4be471" +version = "0.2.3" + [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] git-tree-sha1 = "5372dbbf8f0bdb8c700db5367132925c0771ef7e" @@ -353,13 +358,14 @@ uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" version = "1.9.1" [[deps.DiffEqBase]] -deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "dee066b8dce741815729f5973b6db757416948b7" +deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] +git-tree-sha1 = "766ab4574433d22ff75ab28e9081114e73cef5d5" uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "6.128.4" +version = "6.132.0" [deps.DiffEqBase.extensions] DiffEqBaseDistributionsExt = "Distributions" + DiffEqBaseEnzymeExt = "Enzyme" DiffEqBaseGeneralizedGeneratedExt = "GeneralizedGenerated" DiffEqBaseMPIExt = "MPI" DiffEqBaseMeasurementsExt = "Measurements" @@ -371,6 +377,7 @@ version = "6.128.4" [deps.DiffEqBase.weakdeps] Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" GeneralizedGenerated = "6b9d7cbe-bcb9-11e9-073f-15a7a543e2eb" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" @@ -394,12 +401,13 @@ version = "1.15.1" [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "b6def76ffad15143924a2199f72a5cd883a2e8a9" +git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.9" -weakdeps = ["SparseArrays"] +version = "0.10.10" +weakdeps = ["ChainRulesCore", "SparseArrays"] [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" DistancesSparseArraysExt = "SparseArrays" [[deps.Distributed]] @@ -408,9 +416,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.Distributions]] deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "938fe2981db009f531b6332e31c58e9584a2f9bd" +git-tree-sha1 = "3d5873f811f582873bb9871fc9c451784d5dc8c7" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.100" +version = "0.25.102" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" @@ -428,15 +436,15 @@ version = "0.9.3" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "Dates", "DocStringExtensions", "Downloads", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "Test", "Unicode"] -git-tree-sha1 = "43a76dfac223a3a0d7d33443f7c9154fe75bb264" +git-tree-sha1 = "f667b805e90d643aeb1ca70189827f991a7cc115" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.0.0" +version = "1.1.0" [[deps.DocumenterCitations]] deps = ["AbstractTrees", "Bibliography", "Documenter", "Markdown", "MarkdownAST", "OrderedCollections", "Unicode"] -git-tree-sha1 = "375b49c31c2c3676f3ddb65efea31c7dbea42af1" +git-tree-sha1 = "0c5c141a66807796d580ef4fe592647132832f39" uuid = "daee34ce-89f3-4625-b898-19384cb65244" -version = "1.2.0" +version = "1.2.1" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] @@ -460,6 +468,12 @@ git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" version = "1.0.4" +[[deps.EnzymeCore]] +deps = ["Adapt"] +git-tree-sha1 = "1091d4bbc2f2f7840a65fc0496c782b955dd82fb" +uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" +version = "0.6.0" + [[deps.EpollShim_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "8e9441ee83492030ace98f9789a654a6d0b1f643" @@ -580,9 +594,9 @@ version = "1.0.1" [[deps.FerriteMeshParser]] deps = ["Ferrite"] -git-tree-sha1 = "34366b4cc58c6513dff733f5c2dfd3a4f07e5d40" +git-tree-sha1 = "8b948577bc4066e9c8693438fd511309c7383761" uuid = "0f8c756f-80dd-4a75-85c6-b0a5ab9d4620" -version = "0.1.6" +version = "0.1.7" [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] @@ -712,15 +726,15 @@ version = "0.1.5" [[deps.GR]] deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Preferences", "Printf", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "UUIDs", "p7zip_jll"] -git-tree-sha1 = "d73afa4a2bb9de56077242d98cf763074ab9a970" +git-tree-sha1 = "27442171f28c952804dede8ff72828a96f2bfc1f" uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" -version = "0.72.9" +version = "0.72.10" [[deps.GR_jll]] deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "1596bab77f4f073a14c62424283e7ebff3072eca" +git-tree-sha1 = "025d171a2847f616becc0f84c8dc62fe18f0f6dd" uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" -version = "0.72.9+1" +version = "0.72.10+0" [[deps.GenericSchur]] deps = ["LinearAlgebra", "Printf"] @@ -730,9 +744,9 @@ version = "0.5.3" [[deps.GeoInterface]] deps = ["Extents"] -git-tree-sha1 = "bb198ff907228523f3dee1070ceee63b9359b6ab" +git-tree-sha1 = "d53480c0793b13341c40199190f92c611aa2e93c" uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.1" +version = "1.3.2" [[deps.GeometryBasics]] deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] @@ -772,9 +786,9 @@ version = "1.3.14+0" [[deps.Graphs]] deps = ["ArnoldiMethod", "Compat", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "1cf1d7dcb4bc32d7b4a5add4232db3750c27ecb4" +git-tree-sha1 = "899050ace26649433ef1af25bc17a815b3db52b7" uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" -version = "1.8.0" +version = "1.9.0" [[deps.GridLayoutBase]] deps = ["GeometryBasics", "InteractiveUtils", "Observables"] @@ -795,9 +809,9 @@ version = "1.12.2+2" [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "19e974eced1768fb46fd6020171f2cec06b1edb5" +git-tree-sha1 = "5eab648309e2e060198b45820af1a37182de3cce" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.9.15" +version = "1.10.0" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -970,9 +984,9 @@ version = "1.3.0" [[deps.JpegTurbo]] deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] -git-tree-sha1 = "327713faef2a3e5c80f96bf38d1fa26f7a6ae29e" +git-tree-sha1 = "d65930fa2bc96b07d7691c652d701dcbe7d9cf0b" uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" -version = "0.1.3" +version = "0.1.4" [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1166,26 +1180,30 @@ uuid = "18c40d15-f7cd-5a6d-bc92-87468d86c5db" version = "5.0.0+0" [[deps.LinearSolve]] -deps = ["ArrayInterface", "DocStringExtensions", "EnumX", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "Libdl", "LinearAlgebra", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "SuiteSparse", "UnPack"] -git-tree-sha1 = "69cbd612e6e67ba2f8121bc8725bc9d04d803599" +deps = ["ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnumX", "EnzymeCore", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "Libdl", "LinearAlgebra", "MKL_jll", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "SuiteSparse", "UnPack"] +git-tree-sha1 = "435ab14ca589757a0feae6e3e347bc37addda42d" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "2.5.1" +version = "2.9.2" [deps.LinearSolve.extensions] + LinearSolveBlockDiagonalsExt = "BlockDiagonals" LinearSolveCUDAExt = "CUDA" + LinearSolveEnzymeExt = "Enzyme" LinearSolveHYPREExt = "HYPRE" LinearSolveIterativeSolversExt = "IterativeSolvers" + LinearSolveKernelAbstractionsExt = "KernelAbstractions" LinearSolveKrylovKitExt = "KrylovKit" - LinearSolveMKLExt = "MKL_jll" LinearSolveMetalExt = "Metal" LinearSolvePardisoExt = "Pardiso" [deps.LinearSolve.weakdeps] + BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" HYPRE = "b5ffcf37-a2bd-41ab-a3da-4bd9bc8ad771" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" + KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" - MKL_jll = "856f044c-d86e-5d09-b602-aeab76dc8ba7" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" @@ -1222,9 +1240,9 @@ uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" [[deps.LoggingExtras]] deps = ["Dates", "Logging"] -git-tree-sha1 = "0d097476b6c381ab7906460ef1ef1638fbce1d91" +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.0.2" +version = "1.0.3" [[deps.LoopVectorization]] deps = ["ArrayInterface", "ArrayInterfaceCore", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] @@ -1268,15 +1286,15 @@ version = "0.5.11" [[deps.Makie]] deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "ecc334efc4a8a68800776b0d85ab7bb2fff63f7a" +git-tree-sha1 = "1d16d20279a145119899b4205258332f0fbeaa94" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.19.9" +version = "0.19.11" [[deps.MakieCore]] -deps = ["Observables"] -git-tree-sha1 = "1efb1166dd9398f2ccf6d728f896658c9c84733e" +deps = ["Observables", "REPL"] +git-tree-sha1 = "a94bf3fef9c690a2a4ac1d09d86a59ab89c7f8e4" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.6.6" +version = "0.6.8" [[deps.ManualMemory]] git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" @@ -1294,9 +1312,9 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[deps.MarkdownAST]] deps = ["AbstractTrees", "Markdown"] -git-tree-sha1 = "e8513266815200c0c8f522d6d44ffb5e9b366ae4" +git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" -version = "0.1.1" +version = "0.1.2" [[deps.Match]] git-tree-sha1 = "1d9bc5c1a6e7ee24effb93f175c9342f9154d97f" @@ -1394,10 +1412,10 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.NonlinearSolve]] -deps = ["ArrayInterface", "DiffEqBase", "EnumX", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "LinearSolve", "PrecompileTools", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "ee53089df81a6bdf3c06c17cf674e90931b10a73" +deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "EnumX", "FiniteDiff", "ForwardDiff", "LineSearches", "LinearAlgebra", "LinearSolve", "PrecompileTools", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "UnPack"] +git-tree-sha1 = "445a7ba86794e1f8ee9da3b3b7becf284e2625fd" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "1.10.0" +version = "2.1.0" [[deps.OCCT_jll]] deps = ["Artifacts", "FreeType2_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll", "Xorg_libXfixes_jll", "Xorg_libXft_jll", "Xorg_libXinerama_jll", "Xorg_libXrender_jll"] @@ -1481,9 +1499,9 @@ version = "1.6.2" [[deps.OrdinaryDiffEq]] deps = ["ADTypes", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "IfElse", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "LoopVectorization", "MacroTools", "MuladdMacro", "NLsolve", "NonlinearSolve", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLNLSolve", "SciMLOperators", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "SparseDiffTools", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "ba3ed480f991b846cf9a8118d3370d9752e7166d" +git-tree-sha1 = "def999a7447854f0e9ca9fdda235e04a65916b76" uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -version = "6.55.0" +version = "6.58.0" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] @@ -1492,9 +1510,9 @@ version = "10.42.0+0" [[deps.PDMats]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "67eae2738d63117a196f497d7db789821bce61d1" +git-tree-sha1 = "fcf8fd477bd7f33cb8dbb1243653fb0d415c256c" uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.17" +version = "0.11.25" [[deps.PNGFiles]] deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] @@ -1503,9 +1521,9 @@ uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" version = "0.4.0" [[deps.PackageExtensionCompat]] -git-tree-sha1 = "f9b1e033c2b1205cf30fd119f4e50881316c1923" +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" -version = "1.0.1" +version = "1.0.2" weakdeps = ["Requires", "TOML"] [[deps.Packing]] @@ -1600,9 +1618,9 @@ version = "1.39.0" [[deps.Polyester]] deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Requires", "Static", "StaticArrayInterface", "StrideArraysCore", "ThreadingUtilities"] -git-tree-sha1 = "3d811babe092a6e7b130beee84998fe7663348b6" +git-tree-sha1 = "c7dc9720390fcc296bf757b3f833f9e41c68a086" uuid = "f517fe37-dbe3-4b94-8317-1923a5111588" -version = "0.7.5" +version = "0.7.7" [[deps.PolyesterWeave]] deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] @@ -1659,9 +1677,9 @@ version = "1.2.0" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "7eb1686b4f04b82f96ed7a4ea5890a4f0c7a09f1" +git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.0" +version = "1.4.1" [[deps.Primes]] deps = ["IntegerMathUtils"] @@ -1686,16 +1704,16 @@ uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" version = "1.0.0" [[deps.Qt6Base_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"] -git-tree-sha1 = "364898e8f13f7eaaceec55fd3d08680498c0aa6e" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "7c29f0e8c575428bd84dc3c72ece5178caa67336" uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" -version = "6.4.2+3" +version = "6.5.2+2" [[deps.QuadGK]] deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "6ec7ac8412e83d57e313393220879ede1740f9ee" +git-tree-sha1 = "9ebcd48c498668c7fa0e97a9cae873fbee7bfee1" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.8.2" +version = "2.9.1" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] @@ -1837,21 +1855,27 @@ version = "0.6.39" [[deps.SciMLBase]] deps = ["ADTypes", "ArrayInterface", "ChainRulesCore", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FillArrays", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "6de099dba3c80e23bde1d19011161ea91a23ed6b" +git-tree-sha1 = "1e09c5c89f5502eb4e3657730b0fb6817a1bca8d" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "1.98.0" +version = "2.3.0" [deps.SciMLBase.extensions] - ZygoteExt = "Zygote" + SciMLBasePyCallExt = "PyCall" + SciMLBasePythonCallExt = "PythonCall" + SciMLBaseRCallExt = "RCall" + SciMLBaseZygoteExt = "Zygote" [deps.SciMLBase.weakdeps] + PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" + PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" + RCall = "6f49c342-dc21-5d91-9882-a32aef131414" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.SciMLNLSolve]] deps = ["DiffEqBase", "LineSearches", "NLsolve", "Reexport", "SciMLBase"] -git-tree-sha1 = "9dfc8e9e3d58c0c74f1a821c762b5349da13eccf" +git-tree-sha1 = "765b788339abd7d983618c09cfc0192e2b6b15fd" uuid = "e9a6253c-8580-4d32-9898-8661bb511710" -version = "0.1.8" +version = "0.1.9" [[deps.SciMLOperators]] deps = ["ArrayInterface", "DocStringExtensions", "Lazy", "LinearAlgebra", "Setfield", "SparseArrays", "StaticArraysCore", "Tricks"] @@ -1881,9 +1905,9 @@ version = "1.1.1" [[deps.ShaderAbstractions]] deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "0d15c3e7b2003f4451714f08ffec2b77badc2dc4" +git-tree-sha1 = "db0219befe4507878b1a90e07820fed3e62c289d" uuid = "65257c39-d410-5151-9873-9b3e5be5013e" -version = "0.3.0" +version = "0.4.0" [[deps.SharedArrays]] deps = ["Distributed", "Mmap", "Random", "Serialization"] @@ -1914,9 +1938,9 @@ version = "0.8.4" [[deps.SimpleNonlinearSolve]] deps = ["ArrayInterface", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "PackageExtensionCompat", "PrecompileTools", "Reexport", "SciMLBase", "StaticArraysCore"] -git-tree-sha1 = "20aa9831d654bab67ed561e78917047143ecb9bf" +git-tree-sha1 = "4d53b83af904049c493daaf2a225bcae994a3c59" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "0.1.19" +version = "0.1.20" [deps.SimpleNonlinearSolve.extensions] SimpleNonlinearSolveNNlibExt = "NNlib" @@ -1979,10 +2003,10 @@ deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [[deps.SparseDiffTools]] -deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] -git-tree-sha1 = "42d131931906bf4f0af97a7113c8456d0a8aff9d" +deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Random", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] +git-tree-sha1 = "0a4538040f6eeae9016043104056dc6c13e1d8c1" uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804" -version = "2.6.0" +version = "2.7.0" [deps.SparseDiffTools.extensions] SparseDiffToolsEnzymeExt = "Enzyme" @@ -2041,9 +2065,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "Random", "StaticArraysCore"] -git-tree-sha1 = "51621cca8651d9e334a659443a74ce50a3b6dfab" +git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.6.3" +version = "1.6.5" weakdeps = ["Statistics"] [deps.StaticArrays.extensions] @@ -2067,9 +2091,9 @@ version = "1.7.0" [[deps.StatsBase]] deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "75ebe04c5bed70b91614d684259b661c9e6274a4" +git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.0" +version = "0.34.2" [[deps.StatsFuns]] deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] @@ -2136,10 +2160,10 @@ uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" version = "1.0.1" [[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"] -git-tree-sha1 = "1544b926975372da01227b382066ab70e574a3ec" +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.10.1" +version = "1.11.0" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -2172,9 +2196,9 @@ version = "0.5.2" [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] -git-tree-sha1 = "8621f5c499a8aa4aa970b1ae381aae0ef1576966" +git-tree-sha1 = "7fd97bd1c5b1ff53a291cbd351d1d3d6ff4da5a5" uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.6.4" +version = "0.6.7" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] @@ -2280,11 +2304,17 @@ git-tree-sha1 = "8351f8d73d7e880bfc042a8b6922684ebeafb35c" uuid = "19fa3120-7c27-5ec5-8db8-b0b0aa330d6f" version = "0.2.0" +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + [[deps.Wayland_jll]] deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"] -git-tree-sha1 = "ed8d92d9774b077c53e1da50fd81a36af3744c1c" +git-tree-sha1 = "7558e29847e99bc3f04d6569e82d0f5c54460703" uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" -version = "1.21.0+0" +version = "1.21.0+1" [[deps.Wayland_protocols_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -2306,9 +2336,9 @@ version = "1.18.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "04a51d15436a572301b5abbb9d099713327e9fc4" +git-tree-sha1 = "24b81b59bd35b3c42ab84fa589086e19be919916" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.10.4+0" +version = "2.11.5+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] @@ -2322,6 +2352,18 @@ git-tree-sha1 = "cf2c7de82431ca6f39250d2fc4aacd0daa1675c0" uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" version = "5.4.4+0" +[[deps.Xorg_libICE_jll]] +deps = ["Libdl", "Pkg"] +git-tree-sha1 = "e5becd4411063bdcac16be8b66fc2f9f6f1e8fe5" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.0.10+1" + +[[deps.Xorg_libSM_jll]] +deps = ["Libdl", "Pkg", "Xorg_libICE_jll"] +git-tree-sha1 = "4a9d9e4c180e1e8119b5ffc224a7b59d3a7f7e18" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.3+0" + [[deps.Xorg_libX11_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" @@ -2406,6 +2448,12 @@ git-tree-sha1 = "730eeca102434283c50ccf7d1ecdadf521a765a4" uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" version = "1.1.2+0" +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "04341cb870f29dcd5e39055f895c39d016e18ccd" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.4+0" + [[deps.Xorg_xcb_util_image_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97" @@ -2477,6 +2525,12 @@ git-tree-sha1 = "977aed5d006b840e2e40c0b48984f7463109046d" uuid = "700de1a5-db45-46bc-99cf-38207098b444" version = "0.2.3" +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "gperf_jll"] +git-tree-sha1 = "431b678a28ebb559d224c0b6b6d01afce87c51ba" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.9+0" + [[deps.fzf_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "868e669ccb12ba16eaf50cb2957ee2ff61261c56" @@ -2489,6 +2543,12 @@ git-tree-sha1 = "d4cf3bb87fa0669f569e51f6f06cd083771bab65" uuid = "630162c2-fc9b-58b3-9910-8442a8a132e6" version = "4.10.2+1" +[[deps.gperf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3516a5630f741c9eecb3720b1ec9d8edc3ecc033" +uuid = "1a1c6b14-54f6-533d-8383-74cd7377aa70" +version = "3.1.1+0" + [[deps.isoband_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" @@ -2512,12 +2572,24 @@ deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" version = "5.8.0+0" +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "141fe65dc3efabb0b1d5ba74e91f6ad26f84cc22" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.11.0+0" + [[deps.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" version = "2.0.2+0" +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "ad50e5b90f222cfe78aa3d5183a20a12de1322ce" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.18.0+0" + [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c" @@ -2536,6 +2608,12 @@ git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" version = "1.3.7+1" +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "814e154bdb7be91d78b6802843f76b6ece642f11" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.6+0" + [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" @@ -2560,6 +2638,6 @@ version = "3.5.0+0" [[deps.xkbcommon_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] -git-tree-sha1 = "9ebfc140cc56e8c2156a15ceac2f0302e327ac0a" +git-tree-sha1 = "9c304562909ab2bab0262639bd4f444d7bc2be37" uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" -version = "1.4.1+0" +version = "1.4.1+1" From 4df280ea4c8477484eebc3003b7ad2b2221f3d4d Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 7 Oct 2023 17:16:47 +0200 Subject: [PATCH 028/145] Instantiate new Manifest --- docs/Manifest.toml | 137 +-------------------------------------------- 1 file changed, 3 insertions(+), 134 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 36b5ba92b4..476cdcfa74 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -92,10 +92,8 @@ version = "0.1.29" [[deps.ArrayLayouts]] deps = ["FillArrays", "LinearAlgebra"] git-tree-sha1 = "9a731850434825d183af39c6e6cd0a1c32dd7e20" -git-tree-sha1 = "9a731850434825d183af39c6e6cd0a1c32dd7e20" uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" version = "1.4.2" -version = "1.4.2" weakdeps = ["SparseArrays"] [deps.ArrayLayouts.extensions] @@ -242,10 +240,8 @@ version = "0.4.0" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" -git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" version = "3.24.0" -version = "3.24.0" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] @@ -284,10 +280,8 @@ version = "0.3.0" [[deps.Compat]] deps = ["UUIDs"] git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" -git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" version = "4.10.0" -version = "4.10.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -366,16 +360,12 @@ version = "1.9.1" [[deps.DiffEqBase]] deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] git-tree-sha1 = "766ab4574433d22ff75ab28e9081114e73cef5d5" -deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "766ab4574433d22ff75ab28e9081114e73cef5d5" uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "6.132.0" version = "6.132.0" [deps.DiffEqBase.extensions] DiffEqBaseDistributionsExt = "Distributions" DiffEqBaseEnzymeExt = "Enzyme" - DiffEqBaseEnzymeExt = "Enzyme" DiffEqBaseGeneralizedGeneratedExt = "GeneralizedGenerated" DiffEqBaseMPIExt = "MPI" DiffEqBaseMeasurementsExt = "Measurements" @@ -388,7 +378,6 @@ version = "6.132.0" [deps.DiffEqBase.weakdeps] Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" GeneralizedGenerated = "6b9d7cbe-bcb9-11e9-073f-15a7a543e2eb" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" @@ -413,16 +402,12 @@ version = "1.15.1" [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" -git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" version = "0.10.10" -weakdeps = ["ChainRulesCore", "SparseArrays"] -version = "0.10.10" weakdeps = ["ChainRulesCore", "SparseArrays"] [deps.Distances.extensions] DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesChainRulesCoreExt = "ChainRulesCore" DistancesSparseArraysExt = "SparseArrays" [[deps.Distributed]] @@ -452,18 +437,14 @@ version = "0.9.3" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "Dates", "DocStringExtensions", "Downloads", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "Test", "Unicode"] git-tree-sha1 = "f667b805e90d643aeb1ca70189827f991a7cc115" -git-tree-sha1 = "f667b805e90d643aeb1ca70189827f991a7cc115" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" version = "1.1.0" -version = "1.1.0" [[deps.DocumenterCitations]] deps = ["AbstractTrees", "Bibliography", "Documenter", "Markdown", "MarkdownAST", "OrderedCollections", "Unicode"] git-tree-sha1 = "0c5c141a66807796d580ef4fe592647132832f39" -git-tree-sha1 = "0c5c141a66807796d580ef4fe592647132832f39" uuid = "daee34ce-89f3-4625-b898-19384cb65244" version = "1.2.1" -version = "1.2.1" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] @@ -592,8 +573,8 @@ uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" version = "0.3.1" [[deps.Ferrite]] -deps = ["EnumX", "LinearAlgebra", "NearestNeighbors", "Preferences", "Reexport", "SparseArrays", "StaticArrays", "Tensors", "WriteVTK"] -path = ".." +deps = ["EnumX", "LinearAlgebra", "NearestNeighbors", "Preferences", "Reexport", "SparseArrays", "Tensors", "WriteVTK"] +git-tree-sha1 = "a31b9d4dd58e00686e5da175dab11667af3108b6" uuid = "c061ca5d-56c9-439f-9c0e-210fe06d3992" version = "0.3.14" @@ -614,10 +595,8 @@ version = "1.0.1" [[deps.FerriteMeshParser]] deps = ["Ferrite"] git-tree-sha1 = "8b948577bc4066e9c8693438fd511309c7383761" -git-tree-sha1 = "8b948577bc4066e9c8693438fd511309c7383761" uuid = "0f8c756f-80dd-4a75-85c6-b0a5ab9d4620" version = "0.1.7" -version = "0.1.7" [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] @@ -748,18 +727,14 @@ version = "0.1.5" [[deps.GR]] deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Preferences", "Printf", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "UUIDs", "p7zip_jll"] git-tree-sha1 = "27442171f28c952804dede8ff72828a96f2bfc1f" -git-tree-sha1 = "27442171f28c952804dede8ff72828a96f2bfc1f" uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" version = "0.72.10" -version = "0.72.10" [[deps.GR_jll]] deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] git-tree-sha1 = "025d171a2847f616becc0f84c8dc62fe18f0f6dd" -git-tree-sha1 = "025d171a2847f616becc0f84c8dc62fe18f0f6dd" uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" version = "0.72.10+0" -version = "0.72.10+0" [[deps.GenericSchur]] deps = ["LinearAlgebra", "Printf"] @@ -812,7 +787,6 @@ version = "1.3.14+0" [[deps.Graphs]] deps = ["ArnoldiMethod", "Compat", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] git-tree-sha1 = "899050ace26649433ef1af25bc17a815b3db52b7" -git-tree-sha1 = "899050ace26649433ef1af25bc17a815b3db52b7" uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" version = "1.9.0" @@ -836,10 +810,8 @@ version = "1.12.2+2" [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] git-tree-sha1 = "5eab648309e2e060198b45820af1a37182de3cce" -git-tree-sha1 = "5eab648309e2e060198b45820af1a37182de3cce" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" version = "1.10.0" -version = "1.10.0" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -1210,36 +1182,27 @@ version = "5.0.0+0" [[deps.LinearSolve]] deps = ["ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnumX", "EnzymeCore", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "Libdl", "LinearAlgebra", "MKL_jll", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "SuiteSparse", "UnPack"] git-tree-sha1 = "435ab14ca589757a0feae6e3e347bc37addda42d" -deps = ["ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnumX", "EnzymeCore", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "Libdl", "LinearAlgebra", "MKL_jll", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "SuiteSparse", "UnPack"] -git-tree-sha1 = "435ab14ca589757a0feae6e3e347bc37addda42d" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "2.9.2" version = "2.9.2" [deps.LinearSolve.extensions] LinearSolveBlockDiagonalsExt = "BlockDiagonals" - LinearSolveBlockDiagonalsExt = "BlockDiagonals" LinearSolveCUDAExt = "CUDA" LinearSolveEnzymeExt = "Enzyme" - LinearSolveEnzymeExt = "Enzyme" LinearSolveHYPREExt = "HYPRE" LinearSolveIterativeSolversExt = "IterativeSolvers" LinearSolveKernelAbstractionsExt = "KernelAbstractions" - LinearSolveKernelAbstractionsExt = "KernelAbstractions" LinearSolveKrylovKitExt = "KrylovKit" LinearSolveMetalExt = "Metal" LinearSolvePardisoExt = "Pardiso" [deps.LinearSolve.weakdeps] BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0" - BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" HYPRE = "b5ffcf37-a2bd-41ab-a3da-4bd9bc8ad771" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" - KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" @@ -1278,10 +1241,8 @@ uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" [[deps.LoggingExtras]] deps = ["Dates", "Logging"] git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" -git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" version = "1.0.3" -version = "1.0.3" [[deps.LoopVectorization]] deps = ["ArrayInterface", "ArrayInterfaceCore", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] @@ -1311,12 +1272,6 @@ git-tree-sha1 = "eb006abbd7041c28e0d16260e50a24f8f9104913" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" version = "2023.2.0+0" -[[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "eb006abbd7041c28e0d16260e50a24f8f9104913" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2023.2.0+0" - [[deps.MMG_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "LinearElasticity_jll", "Pkg", "SCOTCH_jll"] git-tree-sha1 = "70a59df96945782bb0d43b56d0fbfdf1ce2e4729" @@ -1358,7 +1313,6 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[deps.MarkdownAST]] deps = ["AbstractTrees", "Markdown"] git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" -git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" version = "0.1.2" @@ -1460,11 +1414,8 @@ version = "1.2.0" [[deps.NonlinearSolve]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "EnumX", "FiniteDiff", "ForwardDiff", "LineSearches", "LinearAlgebra", "LinearSolve", "PrecompileTools", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "UnPack"] git-tree-sha1 = "445a7ba86794e1f8ee9da3b3b7becf284e2625fd" -deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "EnumX", "FiniteDiff", "ForwardDiff", "LineSearches", "LinearAlgebra", "LinearSolve", "PrecompileTools", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "445a7ba86794e1f8ee9da3b3b7becf284e2625fd" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" version = "2.1.0" -version = "2.1.0" [[deps.OCCT_jll]] deps = ["Artifacts", "FreeType2_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll", "Xorg_libXfixes_jll", "Xorg_libXft_jll", "Xorg_libXinerama_jll", "Xorg_libXrender_jll"] @@ -1549,10 +1500,8 @@ version = "1.6.2" [[deps.OrdinaryDiffEq]] deps = ["ADTypes", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "IfElse", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "LoopVectorization", "MacroTools", "MuladdMacro", "NLsolve", "NonlinearSolve", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLNLSolve", "SciMLOperators", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "SparseDiffTools", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] git-tree-sha1 = "def999a7447854f0e9ca9fdda235e04a65916b76" -git-tree-sha1 = "def999a7447854f0e9ca9fdda235e04a65916b76" uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" version = "6.58.0" -version = "6.58.0" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] @@ -1573,10 +1522,8 @@ version = "0.4.0" [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" -git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" version = "1.0.2" -version = "1.0.2" weakdeps = ["Requires", "TOML"] [[deps.Packing]] @@ -1672,10 +1619,8 @@ version = "1.39.0" [[deps.Polyester]] deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Requires", "Static", "StaticArrayInterface", "StrideArraysCore", "ThreadingUtilities"] git-tree-sha1 = "c7dc9720390fcc296bf757b3f833f9e41c68a086" -git-tree-sha1 = "c7dc9720390fcc296bf757b3f833f9e41c68a086" uuid = "f517fe37-dbe3-4b94-8317-1923a5111588" version = "0.7.7" -version = "0.7.7" [[deps.PolyesterWeave]] deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] @@ -1733,7 +1678,6 @@ version = "1.2.0" [[deps.Preferences]] deps = ["TOML"] git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" -git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.1" @@ -1762,8 +1706,6 @@ version = "1.0.0" [[deps.Qt6Base_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] git-tree-sha1 = "7c29f0e8c575428bd84dc3c72ece5178caa67336" -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] -git-tree-sha1 = "7c29f0e8c575428bd84dc3c72ece5178caa67336" uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" version = "6.5.2+2" @@ -1914,9 +1856,7 @@ version = "0.6.39" [[deps.SciMLBase]] deps = ["ADTypes", "ArrayInterface", "ChainRulesCore", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FillArrays", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces", "ZygoteRules"] git-tree-sha1 = "1e09c5c89f5502eb4e3657730b0fb6817a1bca8d" -git-tree-sha1 = "1e09c5c89f5502eb4e3657730b0fb6817a1bca8d" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.3.0" version = "2.3.0" [deps.SciMLBase.extensions] @@ -1924,27 +1864,18 @@ version = "2.3.0" SciMLBasePythonCallExt = "PythonCall" SciMLBaseRCallExt = "RCall" SciMLBaseZygoteExt = "Zygote" - SciMLBasePyCallExt = "PyCall" - SciMLBasePythonCallExt = "PythonCall" - SciMLBaseRCallExt = "RCall" - SciMLBaseZygoteExt = "Zygote" [deps.SciMLBase.weakdeps] PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" RCall = "6f49c342-dc21-5d91-9882-a32aef131414" - PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" - PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" - RCall = "6f49c342-dc21-5d91-9882-a32aef131414" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.SciMLNLSolve]] deps = ["DiffEqBase", "LineSearches", "NLsolve", "Reexport", "SciMLBase"] git-tree-sha1 = "765b788339abd7d983618c09cfc0192e2b6b15fd" -git-tree-sha1 = "765b788339abd7d983618c09cfc0192e2b6b15fd" uuid = "e9a6253c-8580-4d32-9898-8661bb511710" version = "0.1.9" -version = "0.1.9" [[deps.SciMLOperators]] deps = ["ArrayInterface", "DocStringExtensions", "Lazy", "LinearAlgebra", "Setfield", "SparseArrays", "StaticArraysCore", "Tricks"] @@ -2008,9 +1939,7 @@ version = "0.8.4" [[deps.SimpleNonlinearSolve]] deps = ["ArrayInterface", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "PackageExtensionCompat", "PrecompileTools", "Reexport", "SciMLBase", "StaticArraysCore"] git-tree-sha1 = "4d53b83af904049c493daaf2a225bcae994a3c59" -git-tree-sha1 = "4d53b83af904049c493daaf2a225bcae994a3c59" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "0.1.20" version = "0.1.20" [deps.SimpleNonlinearSolve.extensions] @@ -2076,10 +2005,7 @@ uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [[deps.SparseDiffTools]] deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Random", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] git-tree-sha1 = "0a4538040f6eeae9016043104056dc6c13e1d8c1" -deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Random", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] -git-tree-sha1 = "0a4538040f6eeae9016043104056dc6c13e1d8c1" uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804" -version = "2.7.0" version = "2.7.0" [deps.SparseDiffTools.extensions] @@ -2140,10 +2066,8 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "Random", "StaticArraysCore"] git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" -git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" uuid = "90137ffa-7385-5640-81b9-e52037218182" version = "1.6.5" -version = "1.6.5" weakdeps = ["Statistics"] [deps.StaticArrays.extensions] @@ -2168,7 +2092,6 @@ version = "1.7.0" [[deps.StatsBase]] deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" -git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" version = "0.34.2" @@ -2239,11 +2162,8 @@ version = "1.0.1" [[deps.Tables]] deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] git-tree-sha1 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" version = "1.11.0" -version = "1.11.0" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -2258,9 +2178,7 @@ version = "0.1.1" [[deps.Tensors]] deps = ["ForwardDiff", "LinearAlgebra", "PrecompileTools", "SIMD", "StaticArrays", "Statistics"] -git-tree-sha1 = "09650779b3c5124b8742986904d6e69f854be0bd" -repo-rev = "kam/3rd_order" -repo-url = "https://github.com/KnutAM/Tensors.jl.git" +git-tree-sha1 = "bcbb366323add300742c9e4a5447e584640aeff2" uuid = "48a634ad-e948-5137-8d70-aa71f2a747f4" version = "1.15.0" @@ -2393,11 +2311,8 @@ version = "1.3.243+0" [[deps.Wayland_jll]] deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"] git-tree-sha1 = "7558e29847e99bc3f04d6569e82d0f5c54460703" -deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"] -git-tree-sha1 = "7558e29847e99bc3f04d6569e82d0f5c54460703" uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" version = "1.21.0+1" -version = "1.21.0+1" [[deps.Wayland_protocols_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -2420,10 +2335,8 @@ version = "1.18.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] git-tree-sha1 = "24b81b59bd35b3c42ab84fa589086e19be919916" -git-tree-sha1 = "24b81b59bd35b3c42ab84fa589086e19be919916" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" version = "2.11.5+0" -version = "2.11.5+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] @@ -2449,18 +2362,6 @@ git-tree-sha1 = "4a9d9e4c180e1e8119b5ffc224a7b59d3a7f7e18" uuid = "c834827a-8449-5923-a945-d239c165b7dd" version = "1.2.3+0" -[[deps.Xorg_libICE_jll]] -deps = ["Libdl", "Pkg"] -git-tree-sha1 = "e5becd4411063bdcac16be8b66fc2f9f6f1e8fe5" -uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" -version = "1.0.10+1" - -[[deps.Xorg_libSM_jll]] -deps = ["Libdl", "Pkg", "Xorg_libICE_jll"] -git-tree-sha1 = "4a9d9e4c180e1e8119b5ffc224a7b59d3a7f7e18" -uuid = "c834827a-8449-5923-a945-d239c165b7dd" -version = "1.2.3+0" - [[deps.Xorg_libX11_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" @@ -2551,12 +2452,6 @@ git-tree-sha1 = "04341cb870f29dcd5e39055f895c39d016e18ccd" uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" version = "0.1.4+0" -[[deps.Xorg_xcb_util_cursor_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] -git-tree-sha1 = "04341cb870f29dcd5e39055f895c39d016e18ccd" -uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" -version = "0.1.4+0" - [[deps.Xorg_xcb_util_image_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97" @@ -2634,12 +2529,6 @@ git-tree-sha1 = "431b678a28ebb559d224c0b6b6d01afce87c51ba" uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" version = "3.2.9+0" -[[deps.eudev_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "gperf_jll"] -git-tree-sha1 = "431b678a28ebb559d224c0b6b6d01afce87c51ba" -uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" -version = "3.2.9+0" - [[deps.fzf_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "868e669ccb12ba16eaf50cb2957ee2ff61261c56" @@ -2687,12 +2576,6 @@ git-tree-sha1 = "141fe65dc3efabb0b1d5ba74e91f6ad26f84cc22" uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" version = "1.11.0+0" -[[deps.libevdev_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "141fe65dc3efabb0b1d5ba74e91f6ad26f84cc22" -uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" -version = "1.11.0+0" - [[deps.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" @@ -2705,12 +2588,6 @@ git-tree-sha1 = "ad50e5b90f222cfe78aa3d5183a20a12de1322ce" uuid = "36db933b-70db-51c0-b978-0f229ee0e533" version = "1.18.0+0" -[[deps.libinput_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "eudev_jll", "libevdev_jll", "mtdev_jll"] -git-tree-sha1 = "ad50e5b90f222cfe78aa3d5183a20a12de1322ce" -uuid = "36db933b-70db-51c0-b978-0f229ee0e533" -version = "1.18.0+0" - [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c" @@ -2735,12 +2612,6 @@ git-tree-sha1 = "814e154bdb7be91d78b6802843f76b6ece642f11" uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" version = "1.1.6+0" -[[deps.mtdev_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "814e154bdb7be91d78b6802843f76b6ece642f11" -uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" -version = "1.1.6+0" - [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" @@ -2766,7 +2637,5 @@ version = "3.5.0+0" [[deps.xkbcommon_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] git-tree-sha1 = "9c304562909ab2bab0262639bd4f444d7bc2be37" -git-tree-sha1 = "9c304562909ab2bab0262639bd4f444d7bc2be37" uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" version = "1.4.1+1" -version = "1.4.1+1" From 2557b3e3974fa7083fe0b245d5b84069517398f6 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 7 Oct 2023 19:52:05 +0200 Subject: [PATCH 029/145] Correct Manifest update oopsi --- docs/Manifest.toml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 476cdcfa74..52fe3bffa6 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -573,8 +573,8 @@ uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" version = "0.3.1" [[deps.Ferrite]] -deps = ["EnumX", "LinearAlgebra", "NearestNeighbors", "Preferences", "Reexport", "SparseArrays", "Tensors", "WriteVTK"] -git-tree-sha1 = "a31b9d4dd58e00686e5da175dab11667af3108b6" +deps = ["EnumX", "LinearAlgebra", "NearestNeighbors", "Preferences", "Reexport", "SparseArrays", "StaticArrays", "Tensors", "WriteVTK"] +path = ".." uuid = "c061ca5d-56c9-439f-9c0e-210fe06d3992" version = "0.3.14" @@ -2178,7 +2178,9 @@ version = "0.1.1" [[deps.Tensors]] deps = ["ForwardDiff", "LinearAlgebra", "PrecompileTools", "SIMD", "StaticArrays", "Statistics"] -git-tree-sha1 = "bcbb366323add300742c9e4a5447e584640aeff2" +git-tree-sha1 = "09650779b3c5124b8742986904d6e69f854be0bd" +repo-rev = "kam/3rd_order" +repo-url = "https://github.com/KnutAM/Tensors.jl.git" uuid = "48a634ad-e948-5137-8d70-aa71f2a747f4" version = "1.15.0" From 27a22ccdcba2c4cff46df77c7d16f55c5cc489b6 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 7 Oct 2023 21:02:47 +0200 Subject: [PATCH 030/145] Update examples to calculate flux --- .../literate-tutorials/heat_equation_rt.jl | 62 ++++++++++++++++++- .../heat_equation_triangle.jl | 30 ++++++++- 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl index 8d000047bf..6070db81f7 100644 --- a/docs/src/literate-tutorials/heat_equation_rt.jl +++ b/docs/src/literate-tutorials/heat_equation_rt.jl @@ -58,7 +58,7 @@ using Ferrite, SparseArrays # We start by generating a simple grid with 20x20 quadrilateral elements # using `generate_grid`. The generator defaults to the unit square, # so we don't need to specify the corners of the domain. -grid = generate_grid(Triangle, (100, 100)); +grid = generate_grid(Triangle, (20, 20)); # ### Trial and test functions # A `CellValues` facilitates the process of evaluating values and gradients of @@ -154,7 +154,6 @@ function assemble_element!(Ke::Matrix, fe::Vector, cv::NamedTuple, dr::NamedTupl cvq = cv[:q] dru = dr[:u] drq = dr[:q] - n_basefuncs = getnbasefunctions(cvu) ## Loop over quadrature points for q_point in 1:getnquadpoints(cvu) ## Get the quadrature weight @@ -252,12 +251,71 @@ u = K \ f; # To visualize the result we export the grid and our field `u` # to a VTK-file, which can be viewed in e.g. [ParaView](https://www.paraview.org/). u_nodes = evaluate_at_grid_nodes(dh, u, :u) +∂Ω_cells = zeros(Int, getncells(grid)) +for (cellnr, facenr) in ∂Ω + ∂Ω_cells[cellnr] = 1 +end vtk_grid("heat_equation_rt", dh) do vtk vtk_point_data(vtk, u_nodes, "u") + vtk_cell_data(vtk, ∂Ω_cells, "dO") end @show norm(u_nodes)/length(u_nodes) +# ## Postprocess the total flux +function calculate_flux(dh, dΩ, ip, a) + qr = FaceQuadratureRule{RefTriangle}(4) + fv = FaceValues(qr, ip, Lagrange{RefTriangle,1}()) + grid = dh.grid + dofrange = dof_range(dh, :q) + flux = 0.0 + dofs = celldofs(dh, 1) + ae = zeros(length(dofs)) + x = getcoordinates(grid, 1) + for (cellnr, facenr) in dΩ + getcoordinates!(x, grid, cellnr) + cell = getcells(grid, cellnr) + celldofs!(dofs, dh, cellnr) + map!(i->a[i], ae, dofs) + reinit!(fv, x, facenr, cell) + for q_point in 1:getnquadpoints(fv) + dΓ = getdetJdV(fv, q_point) + n = getnormal(fv, q_point) + q = function_value(fv, q_point, ae, dofrange) + flux += (q ⋅ n)*dΓ + end + end + return flux +end + +function calculate_flux_lag(dh, dΩ, ip, a) + qr = FaceQuadratureRule{RefTriangle}(4) + fv = FaceValues(qr, ip, Lagrange{RefTriangle,1}()) + grid = dh.grid + dofrange = dof_range(dh, :u) + flux = 0.0 + dofs = celldofs(dh, 1) + ae = zeros(length(dofs)) + x = getcoordinates(grid, 1) + for (cellnr, facenr) in dΩ + getcoordinates!(x, grid, cellnr) + cell = getcells(grid, cellnr) + celldofs!(dofs, dh, cellnr) + map!(i->a[i], ae, dofs) + reinit!(fv, x, facenr, cell) + for q_point in 1:getnquadpoints(fv) + dΓ = getdetJdV(fv, q_point) + n = getnormal(fv, q_point) + q = function_gradient(fv, q_point, ae, dofrange) + flux -= (q ⋅ n)*dΓ + end + end + return flux +end + +flux = calculate_flux(dh, ∂Ω, ipq, u) +flux_lag = calculate_flux_lag(dh, ∂Ω, ipu, u) +@show flux, flux_lag #md # ## [Plain program](@id heat_equation-plain-program) #md # #md # Here follows a version of the program without any comments. diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl index d5ea45e4df..e2ec7c3ed0 100644 --- a/docs/src/literate-tutorials/heat_equation_triangle.jl +++ b/docs/src/literate-tutorials/heat_equation_triangle.jl @@ -45,7 +45,7 @@ using Ferrite, SparseArrays # We start by generating a simple grid with 20x20 quadrilateral elements # using `generate_grid`. The generator defaults to the unit square, # so we don't need to specify the corners of the domain. -grid = generate_grid(Triangle, (100, 100)); +grid = generate_grid(Triangle, (20, 20)); # ### Trial and test functions # A `CellValues` facilitates the process of evaluating values and gradients of @@ -219,6 +219,34 @@ end @show norm(u)/length(u) +function calculate_flux_lag(dh, dΩ, ip, a) + qr = FaceQuadratureRule{RefTriangle}(2) + fv = FaceValues(qr, ip, Lagrange{RefTriangle,1}()) + grid = dh.grid + dofrange = dof_range(dh, :u) + flux = 0.0 + dofs = celldofs(dh, 1) + ae = zeros(length(dofs)) + x = getcoordinates(grid, 1) + for (cellnr, facenr) in dΩ + getcoordinates!(x, grid, cellnr) + cell = getcells(grid, cellnr) + celldofs!(dofs, dh, cellnr) + map!(i->a[i], ae, dofs) + reinit!(fv, x, facenr, cell) + for q_point in 1:getnquadpoints(fv) + dΓ = getdetJdV(fv, q_point) + n = getnormal(fv, q_point) + q = function_gradient(fv, q_point, ae, dofrange) + flux -= (q ⋅ n)*dΓ + end + end + return flux +end + +flux = calculate_flux_lag(dh, ∂Ω, ip, u) +@show flux + #md # ## [Plain program](@id heat_equation-plain-program) #md # #md # Here follows a version of the program without any comments. From 3facc077eb1032f8e3f0d506247d5a9562dc7a74 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 7 Oct 2023 23:07:00 +0200 Subject: [PATCH 031/145] Change parameterization and fix test tolerances --- benchmark/helper.jl | 6 ++--- docs/src/literate-howto/postprocessing.jl | 2 +- .../incompressible_elasticity.jl | 6 ++--- src/Dofs/DofHandler.jl | 2 +- src/FEValues/CellValues.jl | 17 +++++++----- src/FEValues/FaceValues.jl | 22 ++++++++------- src/FEValues/FunctionValues.jl | 5 ++++ src/FEValues/GeometryValues.jl | 1 + src/FEValues/common_values.jl | 27 ++++++++++++++++--- src/deprecations.jl | 3 ++- test/InterpolationTestUtils.jl | 2 +- test/runtests.jl | 2 +- 12 files changed, 65 insertions(+), 30 deletions(-) diff --git a/benchmark/helper.jl b/benchmark/helper.jl index 5a8b44c4b2..faba95f1c4 100644 --- a/benchmark/helper.jl +++ b/benchmark/helper.jl @@ -66,17 +66,17 @@ function _generalized_ritz_galerkin_assemble_local_matrix(grid::Ferrite.Abstract end # Minimal Petrov-Galerkin type local assembly loop. We assume that both function spaces share the same integration rule. Test is applied from the left. -function _generalized_petrov_galerkin_assemble_local_matrix(grid::Ferrite.AbstractGrid, cellvalues_shape::CellValues{<: Ferrite.InterpolationByDim{dim}}, f_shape, cellvalues_test::CellValues{<: Ferrite.InterpolationByDim{dim}}, f_test, op) where {dim} +function _generalized_petrov_galerkin_assemble_local_matrix(grid::Ferrite.AbstractGrid, cellvalues_shape::CellValues, f_shape, cellvalues_test::CellValues, f_test, op) n_basefuncs_shape = getnbasefunctions(cellvalues_shape) n_basefuncs_test = getnbasefunctions(cellvalues_test) Ke = zeros(n_basefuncs_test, n_basefuncs_shape) #implicit assumption: Same geometry! - X_shape = zeros(Vec{dim,Float64}, Ferrite.getngeobasefunctions(cellvalues_shape)) + X_shape = zeros(get_coordinate_type(grid), Ferrite.getngeobasefunctions(cellvalues_shape)) getcoordinates!(X_shape, grid, 1) reinit!(cellvalues_shape, X_shape) - X_test = zeros(Vec{dim,Float64}, Ferrite.getngeobasefunctions(cellvalues_test)) + X_test = zeros(get_coordinate_type(grid), Ferrite.getngeobasefunctions(cellvalues_test)) getcoordinates!(X_test, grid, 1) reinit!(cellvalues_test, X_test) diff --git a/docs/src/literate-howto/postprocessing.jl b/docs/src/literate-howto/postprocessing.jl index 57c524a47f..79586f0640 100644 --- a/docs/src/literate-howto/postprocessing.jl +++ b/docs/src/literate-howto/postprocessing.jl @@ -46,7 +46,7 @@ include("../tutorials/heat_equation.jl"); # Next we define a function that computes the heat flux for each integration point in the domain. # Fourier's law is adopted, where the conductivity tensor is assumed to be isotropic with unit # conductivity ``\lambda = 1 ⇒ q = - \nabla u``, where ``u`` is the temperature. -function compute_heat_fluxes(cellvalues::CellValues{<:ScalarInterpolation}, dh::DofHandler, a::AbstractVector{T}) where T +function compute_heat_fluxes(cellvalues::CellValues, dh::DofHandler, a::AbstractVector{T}) where T n = getnbasefunctions(cellvalues) cell_dofs = zeros(Int, n) diff --git a/docs/src/literate-tutorials/incompressible_elasticity.jl b/docs/src/literate-tutorials/incompressible_elasticity.jl index 53154f6c52..e69b8a6577 100644 --- a/docs/src/literate-tutorials/incompressible_elasticity.jl +++ b/docs/src/literate-tutorials/incompressible_elasticity.jl @@ -85,9 +85,9 @@ end # use a `PseudoBlockArray` from `BlockArrays.jl`. function doassemble( - cellvalues_u::CellValues{<:VectorInterpolation}, - cellvalues_p::CellValues{<:ScalarInterpolation}, - facevalues_u::FaceValues{<:VectorInterpolation}, + cellvalues_u::CellValues, + cellvalues_p::CellValues, + facevalues_u::FaceValues, K::SparseMatrixCSC, grid::Grid, dh::DofHandler, mp::LinearElasticity ) f = zeros(ndofs(dh)) diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index a653c8a563..ec17ef13e1 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -915,7 +915,7 @@ function _evaluate_at_grid_nodes!(data::Union{Vector,Matrix}, sdh::SubDofHandler u::Vector{T}, cv::CellValues, drange::UnitRange, ::Type{RT}) where {T, RT} ue = zeros(T, length(drange)) # TODO: Remove this hack when embedding works... - if RT <: Vec && cv isa CellValues{<:ScalarInterpolation} + if RT <: Vec && get_function_interpolation(cv) isa ScalarInterpolation uer = reinterpret(RT, ue) else uer = ue diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 2c09019414..929a13ca6a 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -6,18 +6,18 @@ function default_geometric_interpolation(::Interpolation{shape}) where {dim, sha return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) end -struct CellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP, d2Mdξ2_t} <: AbstractCellValues - geo_values::GeometryValues{dMdξ_t, GIP, T, d2Mdξ2_t} - detJdV::Vector{T} - fun_values::FunctionValues{IP, N_t, dNdx_t, dNdξ_t} - qr::QR +struct CellValues{FV, GV, QR, detT<:AbstractVector} <: AbstractCellValues + fun_values::FV # FunctionValues + geo_values::GV # GeometryValues + qr::QR # QuadratureRule + detJdV::detT # AbstractVector{<:Number} end function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation) where T mapping_type = get_mapping_type(ip_fun) geo_values = GeometryValues(T, ip_geo.ip, qr, RequiresHessian(requires_hessian(mapping_type))) fun_values = FunctionValues(T, ip_fun, qr, ip_geo) detJdV = fill(T(NaN), length(getweights(qr))) - return CellValues(geo_values, detJdV, fun_values, qr) + return CellValues(fun_values, geo_values, qr, detJdV) end CellValues(qr::QuadratureRule, ip::Interpolation, args...) = CellValues(Float64, qr, ip, args...) @@ -35,6 +35,11 @@ getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] # Accessors for function values getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) +get_function_interpolation(cv::CellValues) = get_function_interpolation(cv.fun_values) +get_geometric_interpolation(cv::CellValues) = get_geometric_interpolation(cv.geo_values) +shape_value_type(cv::CellValues) = shape_value_type(cv.fun_values) +shape_gradient_type(cv::CellValues) = shape_gradient_type(cv.fun_values) + for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient) eval(quote @propagate_inbounds $op(cv::CellValues, i::Int, q_point::Int) = $op(cv.fun_values, i, q_point) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 9d8ebec0c3..0316ef729d 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -1,9 +1,9 @@ -struct FaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP, d2Mdξ2_t} <: AbstractFaceValues - geo_values::Vector{GeometryValues{dMdξ_t, GIP, T, d2Mdξ2_t}} - detJdV::Vector{T} - normals::Vector{Normal_t} - fun_values::Vector{FunctionValues{IP, N_t, dNdx_t, dNdξ_t}} - qr::QR # FaceQuadratureRule +struct FaceValues{FV, GV, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GV<:AbstractVector{GV}} <: AbstractFaceValues + fun_values::V_FV # AbstractVector{FunctionValues} + geo_values::V_GV # AbstractVector{GeometryValues} + qr::QR # FaceQuadratureRule + detJdV::detT # AbstractVector{<:Number} + normals::nT # AbstractVector{<:Vec} current_face::ScalarWrapper{Int} end @@ -13,18 +13,22 @@ function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, i max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) detJdV = fill(T(NaN), max_nquadpoints) normals = fill(zero(Vec{sdim,T})*T(NaN), max_nquadpoints) - return FaceValues(geo_values, detJdV, normals, fun_values, fqr, ScalarWrapper(1)) + return FaceValues(fun_values, geo_values, fqr, detJdV, normals, ScalarWrapper(1)) end FaceValues(qr::FaceQuadratureRule, ip::Interpolation, args...) = FaceValues(Float64, qr, ip, args...) function FaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation, ip_geo::ScalarInterpolation) where T return FaceValues(T, qr, ip, VectorizedInterpolation(ip_geo)) end - getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_values(fv)) getnbasefunctions(fv::FaceValues) = getnbasefunctions(get_fun_values(fv)) getnquadpoints(fv::FaceValues) = getnquadpoints(fv.qr, getcurrentface(fv)) -getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] +getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] + +shape_value_type(fv::FaceValues) = shape_value_type(get_fun_values(fv)) +shape_gradient_type(fv::FaceValues) = shape_gradient_type(get_fun_values(fv)) +get_function_interpolation(fv::FaceValues) = get_function_interpolation(get_fun_values(fv)) +get_geometric_interpolation(fv::FaceValues) = get_geometric_interpolation(get_geo_values(fv)) get_geo_values(fv::FaceValues) = @inbounds fv.geo_values[getcurrentface(fv)] for op = (:getngeobasefunctions, :geometric_value) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 2290e310d4..47fa2702b5 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -64,6 +64,11 @@ getnbasefunctions(funvals::FunctionValues) = size(funvals.N_x, 1) @propagate_inbounds shape_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.dNdx[base_func, q_point] @propagate_inbounds shape_symmetric_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = symmetric(shape_gradient(funvals, q_point, base_func)) +get_function_interpolation(funvals::FunctionValues) = funvals.ip + +shape_value_type(funvals::FunctionValues) = eltype(funvals.N_x) +shape_gradient_type(funvals::FunctionValues) = eltype(funvals.dNdx) + # Mapping types struct IdentityMapping end struct CovariantPiolaMapping end diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index 71b73d45f3..65719d6cc1 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -51,6 +51,7 @@ RequiresHessian(::GeometryValues) = RequiresHessian(true) getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) @propagate_inbounds geometric_value(geovals::GeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] +get_geometric_interpolation(geovals::GeometryValues) = geovals.ip @propagate_inbounds calculate_mapping(geovals::GeometryValues, args...) = calculate_mapping(RequiresHessian(geovals), geovals, args...) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 683cc36511..6c0a42f0ea 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -67,9 +67,16 @@ finite element cell or face as Return the value of shape function `base_function` evaluated in quadrature point `q_point`. """ +function shape_value end #@propagate_inbounds shape_value(bv::FaceValues, q_point::Int, base_func::Int) = bv.N[base_func, q_point, bv.current_face[]] -#@propagate_inbounds geometric_value(bv::FaceValues, q_point::Int, base_func::Int) = bv.M[base_func, q_point, bv.current_face[]] +""" + geometric_value(fe_v::AbstractValues, q_point, base_function::Int) + +Return the value of the geometric shape function `base_function` evaluated in +quadrature point `q_point`. +""" +function geometric_value end """ shape_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int) @@ -77,7 +84,7 @@ quadrature point `q_point`. Return the gradient of shape function `base_function` evaluated in quadrature point `q_point`. """ -#@propagate_inbounds shape_gradient(bv::FaceValues, q_point::Int, base_func::Int) = bv.dNdx[base_func, q_point, bv.current_face[]] +function shape_gradient end """ shape_symmetric_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int) @@ -132,7 +139,13 @@ end # TODO: Implement fallback or require this to be defined? # Alt: shape_value_type(cv) = typeof(shape_value(cv, qp=1, i=1)) -shape_value_type(::Union{CellValues{<:Any, N_t}, FaceValues{<:Any, N_t}}) where N_t = N_t +""" + shape_value_type(fe_v::AbstractValues) + +Return the type of `shape_value(fe_v, q_point, base_function)` +""" +function shape_value_type end + function_value_init(cv::AbstractValues, ::AbstractVector{T}) where {T} = zero(shape_value_type(cv)) * zero(T) """ @@ -177,7 +190,13 @@ end # TODO: Implement fallback or require this to be defined? # Alt: shape_gradient_type(cv) = typeof(shape_gradient(cv, qp=1, i=1)) -shape_gradient_type(::Union{CellValues{<:Any, <:Any, dNdx_t}, FaceValues{<:Any, <:Any, dNdx_t}}) where dNdx_t = dNdx_t +""" + shape_gradient_type(fe_v::AbstractValues) + +Return the type of `shape_gradient(fe_v, q_point, base_function)` +""" +function shape_gradient_type end + function function_gradient_init(cv::AbstractValues, ::AbstractVector{T}) where {T} return zero(shape_gradient_type(cv)) * zero(T) end diff --git a/src/deprecations.jl b/src/deprecations.jl index 9c8d832644..cb0c2f3cd8 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -154,8 +154,9 @@ for VT in ( end end +# TODO: Are these needed to be deprecated - harder? with the new parameterization # (Cell|Face)Values with vector dofs -const _VectorValues = Union{CellValues{<:VectorInterpolation}, FaceValues{<:VectorInterpolation}} +const _VectorValues = Union{CellValues{<:FV}, FaceValues{<:FV}} where {FV <: FunctionValues{<:VectorInterpolation}} @deprecate function_value(fe_v::_VectorValues, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T} function_value(fe_v, q_point, reinterpret(T, u)) @deprecate function_gradient(fe_v::_VectorValues, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T} function_gradient(fe_v, q_point, reinterpret(T, u)) @deprecate function_divergence(fe_v::_VectorValues, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T} function_divergence(fe_v, q_point, reinterpret(T, u)) diff --git a/test/InterpolationTestUtils.jl b/test/InterpolationTestUtils.jl index 6cace40b44..9d98ceaa19 100644 --- a/test/InterpolationTestUtils.jl +++ b/test/InterpolationTestUtils.jl @@ -77,7 +77,7 @@ module InterpolationTestUtils d1 = map((v,n)->transformation_function(v,n), fun_vals, point_normal) d2 = map((v,n)->transformation_function(v,n), fun_vals2, point_normal) - @test d1 ≈ d2 + @test isapprox(d1, d2; rtol=1e-6) # Approximate points can contribute to the inexactness return true end diff --git a/test/runtests.jl b/test/runtests.jl index d11ed6d582..832afced7d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -19,7 +19,7 @@ end include("test_utils.jl") include("test_interpolations.jl") -include("test_cellvalues.jl") +include("test_cellvalues.jl") include("test_facevalues.jl") include("test_quadrules.jl") include("test_assemble.jl") From a6e450511e5fa1ebb4a692c54f8f6ea7bd3b6b73 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 11:07:33 +0200 Subject: [PATCH 032/145] Relax type-constraints in GeometryValues and FunctionValues --- src/FEValues/FunctionValues.jl | 13 +++---- src/FEValues/GeometryValues.jl | 63 +++++++++++++++++++--------------- test/test_interpolations.jl | 9 ++--- 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 47fa2702b5..c9b3a671c4 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -23,11 +23,11 @@ typeof_dNdξ(::Type{T}, ::VInterpolationDims{dim,dim,dim}) where {T,dim} = Tenso typeof_dNdξ(::Type{T}, ::VInterpolationDims{rdim,<:Any,vdim}) where {T,rdim,vdim} = SMatrix{vdim,rdim,T} # If vdim=rdim!=sdim Tensor would be possible... struct FunctionValues{IP, N_t, dNdx_t, dNdξ_t} - N_x::Matrix{N_t} - N_ξ::Matrix{N_t} - dNdx::Matrix{dNdx_t} - dNdξ::Matrix{dNdξ_t} - ip::IP + ip::IP # ::Interpolation + N_x::N_t # ::AbstractMatrix{Union{<:Tensor,<:Number}} + N_ξ::N_t # ::AbstractMatrix{Union{<:Tensor,<:Number}} + dNdx::dNdx_t # ::AbstractMatrix{Union{<:Tensor,<:StaticArray}} + dNdξ::dNdξ_t # ::AbstractMatrix{Union{<:Tensor,<:StaticArray}} end function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T ip_dims = InterpolationDims(ip, ip_geo) @@ -45,7 +45,7 @@ function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo end dNdξ = zeros(dNdξ_t, n_shape, n_qpoints) dNdx = fill(zero(dNdx_t) * T(NaN), n_shape, n_qpoints) - fv = FunctionValues(N_x, N_ξ, dNdx, dNdξ, ip) + fv = FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) precompute_values!(fv, qr) # Precompute N and dNdξ return fv end @@ -83,6 +83,7 @@ requires_hessian(::IdentityMapping) = false requires_hessian(::ContravariantPiolaMapping) = true requires_hessian(::CovariantPiolaMapping) = true +# Support for embedded elements calculate_Jinv(J::Tensor{2}) = inv(J) calculate_Jinv(J::SMatrix) = pinv(J) diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index 65719d6cc1..4ed3b0fc12 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -17,11 +17,11 @@ function RequiresHessian(ip_fun::Interpolation, ip_geo::Interpolation) RequiresHessian(requires_hessian(get_mapping_type(ip_fun))) end -struct GeometryValues{dMdξ_t, GIP, T, d2Mdξ2_t} - M::Matrix{T} # value of geometric shape function - dMdξ::Matrix{dMdξ_t} # gradient of geometric shape function in ref-domain - d2Mdξ2::Matrix{d2Mdξ2_t} # hessian of geometric shape function in ref-domain - ip::GIP # geometric interpolation +struct GeometryValues{IP, M_t, dMdξ_t, d2Mdξ2_t} + ip::IP # ::Interpolation Geometric interpolation + M::M_t # ::AbstractVector{<:Number} Values of geometric shape functions + dMdξ::dMdξ_t # ::AbstractVector{<:Vec} Gradients of geometric shape functions in ref-domain + d2Mdξ2::d2Mdξ2_t # ::AbstractVector{<:Tensor{2}} Hessians of geometric shape functions in ref-domain end function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, ::RequiresHessian{RH}) where {T,RH} n_shape = getnbasefunctions(ip) @@ -33,7 +33,7 @@ function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, HT = Tensor{2,getdim(ip),T} dM2dξ2 = zeros(HT, n_shape, n_qpoints) else - dM2dξ2 = Matrix{Nothing}(undef,0,0) + dM2dξ2 = nothing end for (qp, ξ) in pairs(getpoints(qr)) for i in 1:n_shape @@ -44,28 +44,49 @@ function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, end end end - return GeometryValues(M, dMdξ, dM2dξ2, ip) + return GeometryValues(ip, M, dMdξ, dM2dξ2) end -RequiresHessian(::GeometryValues{<:Any,<:Any,<:Any,Nothing}) = RequiresHessian(false) -RequiresHessian(::GeometryValues) = RequiresHessian(true) getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) @propagate_inbounds geometric_value(geovals::GeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] get_geometric_interpolation(geovals::GeometryValues) = geovals.ip +RequiresHessian(geovals::GeometryValues) = RequiresHessian(geovals.d2Mdξ2 !== nothing) + +# Hot-fixes to support embedded elements before MixedTensors are available +# See https://github.com/Ferrite-FEM/Tensors.jl/pull/188 +@inline otimes_helper(x::Vec{dim}, dMdξ::Vec{dim}) where dim = x ⊗ dMdξ +@inline function otimes_helper(x::Vec{sdim}, dMdξ::Vec{rdim}) where {sdim, rdim} + SMatrix{sdim,rdim}((x[i]*dMdξ[j] for i in 1:sdim, j in 1:rdim)...) +end +# End of embedded hot-fixes + +# For creating initial value +function otimes_returntype(#=typeof(x)=#::Type{<:Vec{sdim,Tx}}, #=typeof(dMdξ)=#::Type{<:Vec{rdim,TM}}) where {sdim,rdim,Tx,TM} + return SMatrix{sdim,rdim,promote_type(Tx,TM)} +end +function otimes_returntype(#=typeof(x)=#::Type{<:Vec{dim,Tx}}, #=typeof(dMdξ)=#::Type{<:Vec{dim,TM}}) where {dim, Tx, TM} + return Tensor{2,dim,promote_type(Tx,TM)} +end +function otimes_returntype(#=typeof(x)=#::Type{<:Vec{dim,Tx}}, #=typeof(d2Mdξ2)=#::Type{<:Tensor{2,dim,TM}}) where {dim, Tx, TM} + return Tensor{3,dim,promote_type(Tx,TM)} +end + @propagate_inbounds calculate_mapping(geovals::GeometryValues, args...) = calculate_mapping(RequiresHessian(geovals), geovals, args...) -@inline function calculate_mapping(::RequiresHessian{false}, geo_values::GeometryValues{<:Vec{dim,T}}, q_point, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} - fecv_J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) +@inline function calculate_mapping(::RequiresHessian{false}, geo_values::GeometryValues, q_point, x) + #fecv_J = zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) + fecv_J = zero(otimes_returntype(eltype(x), eltype(geo_values.dMdξ))) @inbounds for j in 1:getngeobasefunctions(geo_values) - fecv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] + #fecv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] + fecv_J += otimes_helper(x[j], geo_values.dMdξ[j, q_point]) end return MappingValues(fecv_J, nothing) end -@inline function calculate_mapping(::RequiresHessian{true}, geo_values::GeometryValues{<:Vec{dim,T}}, q_point, x::AbstractVector{<:Vec{dim,T}}) where {dim,T} - J = zero(Tensor{2,dim,T}) # zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) - H = zero(Tensor{3,dim,T}) +@inline function calculate_mapping(::RequiresHessian{true}, geo_values::GeometryValues, q_point, x) + J = zero(otimes_returntype(eltype(x), eltype(geo_values.dMdξ))) + H = zero(otimes_returntype(eltype(x), eltype(geo_values.d2Mdξ2))) @inbounds for j in 1:getngeobasefunctions(geo_values) J += x[j] ⊗ geo_values.dMdξ[j, q_point] H += x[j] ⊗ geo_values.d2Mdξ2[j, q_point] @@ -106,15 +127,3 @@ where ||∂x/∂ξ||₂ is "detJ" and t is "the unit tangent". See e.g. https://scicomp.stackexchange.com/questions/41741/integration-of-d-1-dimensional-functions-on-finite-element-surfaces for simple explanation. """ embedding_det(J::Union{SMatrix{2, 1}, SMatrix{3, 1}}) = norm(J) - -@inline function calculate_mapping(::RequiresHessian{false}, geo_values::GeometryValues{<:Vec{rdim,T}}, q_point, x::AbstractVector{<:Vec{sdim,T}}) where {rdim,sdim,T} - n_geom_basefuncs = getngeobasefunctions(geo_values) - fecv_J = zero(MMatrix{sdim, rdim, T}) # TODO replace with MixedTensor (see https://github.com/Ferrite-FEM/Tensors.jl/pull/188) - for j in 1:n_geom_basefuncs - #fecv_J += x[j] ⊗ geo_values.dMdξ[j, i] # TODO via Tensors.jl - for k in 1:sdim, l in 1:rdim - fecv_J[k, l] += x[j][k] * geo_values.dMdξ[j, q_point][l] - end - end - return MappingValues(SMatrix(fecv_J), nothing) -end \ No newline at end of file diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index da462b27f9..5e7dccca4a 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -191,10 +191,11 @@ end dim = Ferrite.getdim(CT) p1, p2 = (rand(Vec{dim}), ones(Vec{dim})+rand(Vec{dim})) grid = generate_grid(CT, ntuple(_->nel, dim), p1, p2) - # Distort grid, important to properly test geometry mapping - # for 2nd order elements. Make sure distortion is less than - # a 10th of the element size. - transform_coordinates!(grid, x->(x + rand(x)/(10*nel))) + # Smoothly distort grid (to avoid spuriously badly deformed elements). + # A distorted grid is important to properly test the geometry mapping + # for 2nd order elements. + transfun(x) = typeof(x)(i->sinpi(x[mod(i, length(x))+1]+i/3))/10 + transform_coordinates!(grid, x->(x + transfun(x))) RefShape = Ferrite.getrefshape(getcells(grid, 1)) for order in (1, 2) for IPT in (Nedelec, RaviartThomas) From 85bf3f7564ea75082c3298b6ddaf4437844d36f7 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 11:09:45 +0200 Subject: [PATCH 033/145] Create extra titles for heat eq modifications --- docs/src/literate-tutorials/heat_equation_rt.jl | 15 +-------------- .../literate-tutorials/heat_equation_triangle.jl | 8 +------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl index 6070db81f7..8ff5f2d75c 100644 --- a/docs/src/literate-tutorials/heat_equation_rt.jl +++ b/docs/src/literate-tutorials/heat_equation_rt.jl @@ -1,17 +1,4 @@ -# # [Heat equation](@id tutorial-heat-equation) -# -# ![](heat_square.png) -# -# *Figure 1*: Temperature field on the unit square with an internal uniform heat source -# solved with homogeneous Dirichlet boundary conditions on the boundary. -# -#- -#md # !!! tip -#md # This example is also available as a Jupyter notebook: -#md # [`heat_equation.ipynb`](@__NBVIEWER_ROOT_URL__/examples/heat_equation.ipynb). -#- -# -# ## Introduction +# # [Heat equation (Mixed, RaviartThomas)](@id tutorial-heat-equation-rt) # # ## Strong form # ```math diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl index e2ec7c3ed0..fee7ac52b6 100644 --- a/docs/src/literate-tutorials/heat_equation_triangle.jl +++ b/docs/src/literate-tutorials/heat_equation_triangle.jl @@ -1,16 +1,10 @@ -# # [Heat equation](@id tutorial-heat-equation) +# # [Heat equation (Triangle)](@id tutorial-heat-equation-triangle) # # ![](heat_square.png) # # *Figure 1*: Temperature field on the unit square with an internal uniform heat source # solved with homogeneous Dirichlet boundary conditions on the boundary. # -#- -#md # !!! tip -#md # This example is also available as a Jupyter notebook: -#md # [`heat_equation.ipynb`](@__NBVIEWER_ROOT_URL__/examples/heat_equation.ipynb). -#- -# # ## Introduction # # The heat equation is the "Hello, world!" equation of finite elements. From 06a097dbcdc5368aed6c0d95bb4fb47675bdb44d Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 11:26:53 +0200 Subject: [PATCH 034/145] Use RequiresHessian in CellValues, and comment out unused future functions --- src/FEValues/CellValues.jl | 3 +-- src/FEValues/GeometryValues.jl | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 929a13ca6a..5e2a9c4986 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -13,8 +13,7 @@ struct CellValues{FV, GV, QR, detT<:AbstractVector} <: AbstractCellValues detJdV::detT # AbstractVector{<:Number} end function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation) where T - mapping_type = get_mapping_type(ip_fun) - geo_values = GeometryValues(T, ip_geo.ip, qr, RequiresHessian(requires_hessian(mapping_type))) + geo_values = GeometryValues(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) fun_values = FunctionValues(T, ip_fun, qr, ip_geo) detJdV = fill(T(NaN), length(getweights(qr))) return CellValues(fun_values, geo_values, qr, detJdV) diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index 4ed3b0fc12..7dcc74a23a 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -5,8 +5,10 @@ end @inline getjacobian(mv::MappingValues) = mv.J @inline gethessian(mv::MappingValues{<:Any,<:AbstractTensor}) = mv.H -@inline gethessian(::MappingValues{JT,Nothing}) where JT = _make_hessian(JT) -@inline _make_hessian(::Type{Tensor{2,dim,T}}) where {dim,T} = zero(Tensor{3,dim,T}) +# This will be needed for optimizing away the hessian calculation/updates +# for cases when this is known to be zero (due to the geometric interpolation) +#@inline gethessian(::MappingValues{JT,Nothing}) where JT = _make_hessian(JT) +#@inline _make_hessian(::Type{Tensor{2,dim,T}}) where {dim,T} = zero(Tensor{3,dim,T}) struct RequiresHessian{B} end RequiresHessian(B::Bool) = RequiresHessian{B}() @@ -22,6 +24,7 @@ struct GeometryValues{IP, M_t, dMdξ_t, d2Mdξ2_t} M::M_t # ::AbstractVector{<:Number} Values of geometric shape functions dMdξ::dMdξ_t # ::AbstractVector{<:Vec} Gradients of geometric shape functions in ref-domain d2Mdξ2::d2Mdξ2_t # ::AbstractVector{<:Tensor{2}} Hessians of geometric shape functions in ref-domain + # ::Nothing When hessians are not required end function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, ::RequiresHessian{RH}) where {T,RH} n_shape = getnbasefunctions(ip) From bcb25d33fb58c029554e951535ca8e887e236097 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 12:57:02 +0200 Subject: [PATCH 035/145] Fix copy for CellValues and FaceValues --- src/FEValues/CellValues.jl | 4 ++++ src/FEValues/FaceValues.jl | 7 ++++++ src/FEValues/FunctionValues.jl | 6 ++++++ src/FEValues/GeometryValues.jl | 5 +++++ src/FEValues/common_values.jl | 10 --------- test/test_cellvalues.jl | 33 ++++++++++++++++++---------- test/test_facevalues.jl | 39 +++++++++++++++++++++++++--------- 7 files changed, 73 insertions(+), 31 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 5e2a9c4986..7327b581d0 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -24,6 +24,10 @@ function CellValues(::Type{T}, qr, ip::Interpolation, ip_geo::ScalarInterpolatio return CellValues(T, qr, ip, VectorizedInterpolation(ip_geo)) end +function Base.copy(cv::CellValues) + return CellValues(copy(cv.fun_values), copy(cv.geo_values), copy(cv.qr), copy(cv.detJdV)) +end + # Access geometry values for op = (:getngeobasefunctions, :geometric_value) eval(quote diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 0316ef729d..5202e596e3 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -20,6 +20,13 @@ FaceValues(qr::FaceQuadratureRule, ip::Interpolation, args...) = FaceValues(Floa function FaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation, ip_geo::ScalarInterpolation) where T return FaceValues(T, qr, ip, VectorizedInterpolation(ip_geo)) end + +function Base.copy(fv::FaceValues) + fun_values = map(copy, fv.fun_values) + geo_values = map(copy, fv.geo_values) + return FaceValues(fun_values, geo_values, copy(fv.qr), copy(fv.detJdV), copy(fv.normals), copy(fv.current_face)) +end + getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_values(fv)) getnbasefunctions(fv::FaceValues) = getnbasefunctions(get_fun_values(fv)) getnquadpoints(fv::FaceValues) = getnquadpoints(fv.qr, getcurrentface(fv)) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index c9b3a671c4..993751cee5 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -49,6 +49,12 @@ function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo precompute_values!(fv, qr) # Precompute N and dNdξ return fv end +function Base.copy(funvals::FunctionValues) + (;ip, N_ξ, N_x, dNdξ, dNdx) = funvals + N_ξ_copy = copy(N_ξ) + N_x_copy = N_ξ === N_x ? N_ξ_copy : copy(N_x) # Preserve aliasing + return FunctionValues(copy(ip), N_x_copy, N_ξ_copy, copy(dNdx), copy(dNdξ)) +end function precompute_values!(fv::FunctionValues, qr::QuadratureRule) n_shape = getnbasefunctions(fv.ip) diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index 7dcc74a23a..6c33fa4bfe 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -49,6 +49,11 @@ function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, end return GeometryValues(ip, M, dMdξ, dM2dξ2) end +function Base.copy(geovals::GeometryValues) + (;ip, M, dMdξ, d2Mdξ2) = geovals + d2Mdξ2_copy = d2Mdξ2 === nothing ? nothing : copy(d2Mdξ2) + return GeometryValues(copy(ip), copy(M), copy(dMdξ), d2Mdξ2_copy) +end getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) @propagate_inbounds geometric_value(geovals::GeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 6c0a42f0ea..2e5c2f565f 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -280,13 +280,3 @@ end function Base.show(io::IO, ::MIME"text/plain", fe_v::AbstractValues) print(io, "$(typeof(fe_v)) with $(getnbasefunctions(fe_v)) shape functions and $(getnquadpoints(fe_v)) quadrature points") end - -# copy -for ValueType in (GeometryValues, FunctionValues, CellValues, FaceValues) - args = [:(copy(cv.$fname)) for fname in fieldnames(ValueType)] - @eval begin - function Base.copy(cv::$ValueType) - return typeof(cv)($(args...)) - end - end -end diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 9e10fa2fff..9428684f9b 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -88,19 +88,30 @@ for (scalar_interpol, quad_rule) in ( @test spatial_coordinate(cv, i, x) ≈ qp_x end - # test copy: Disable with new structure. TODO: Re-enable - #= - cvc = copy(cv) - @test typeof(cv) == typeof(cvc) - for fname in fieldnames(typeof(cv)) - v = getfield(cv, fname) - vc = getfield(cvc, fname) - if hasmethod(pointer, Tuple{typeof(v)}) - @test pointer(getfield(cv, fname)) != pointer(getfield(cvc, fname)) + @testset "copy(::CellValues)" begin + cvc = copy(cv) + @test typeof(cv) == typeof(cvc) + + # Test that all mutable types in FunctionValues and GeometryValues have been copied + for key in (:fun_values, :geo_values) + val = getfield(cv, key) + valc = getfield(cvc, key) + for fname in fieldnames(typeof(val)) + v = getfield(val, fname) + vc = getfield(valc, fname) + isbits(v) || @test v !== vc + @test v == vc + end + end + # Test that qr and detJdV is copied as expected. + # Note that qr remain aliased, as defined by `copy(qr)=qr`, see quadrature.jl. + for fname in (:qr, :detJdV) + v = getfield(cv, fname) + vc = getfield(cvc, fname) + fname === :qr || @test v !== vc + @test v == vc end - @test v == vc end - =# end end diff --git a/test/test_facevalues.jl b/test/test_facevalues.jl index da01ba5b4e..5510ccc4a6 100644 --- a/test/test_facevalues.jl +++ b/test/test_facevalues.jl @@ -93,17 +93,36 @@ for (scalar_interpol, quad_rule) in ( end - # test copy - fvc = copy(fv) - @test typeof(fv) == typeof(fvc) - for fname in fieldnames(typeof(fv)) - v = getfield(fv, fname) - v isa Ferrite.ScalarWrapper && continue - vc = getfield(fvc, fname) - if hasmethod(pointer, Tuple{typeof(v)}) - @test pointer(v) != pointer(vc) + @testset "copy(::FaceValues)" begin + fvc = copy(fv) + @test typeof(fv) == typeof(fvc) + + # Test that all mutable types in FunctionValues and GeometryValues have been copied + for key in (:fun_values, :geo_values) + for i in eachindex(getfield(fv, key)) + val = getfield(fv, key)[i] + valc = getfield(fvc, key)[i] + for fname in fieldnames(typeof(val)) + v = getfield(val, fname) + vc = getfield(valc, fname) + isbits(v) || @test v !== vc + @test v == vc + end + end + end + # Test that qr, detJdV, normals, and current_face are copied as expected. + # Note that qr remain aliased, as defined by `copy(qr)=qr`, see quadrature.jl. + # Make it easy to test scalar wrapper equality + _mock_isequal(a, b) = a == b + _mock_isequal(a::T, b::T) where {T<:Ferrite.ScalarWrapper} = a[] == b[] + for fname in (:qr, :detJdV, :normals, :current_face) + v = getfield(fv, fname) + vc = getfield(fvc, fname) + if fname !== :qr # Test unaliased + @test v !== vc + end + @test _mock_isequal(v, vc) end - @test check_equal_or_nan(v, vc) end end end From 5c33c5bde6181b4f2e18c5e38a2bc39cbba5bec5 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 13:14:11 +0200 Subject: [PATCH 036/145] Fix show of values --- src/FEValues/FaceValues.jl | 17 +++++++++++++++++ src/FEValues/common_values.jl | 4 ---- src/PointEval/point_values.jl | 5 +++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 5202e596e3..6a6e04b838 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -95,6 +95,23 @@ function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, ce end end +function Base.show(io::IO, d::MIME"text/plain", fv::FaceValues) + ip_geo = get_geometric_interpolation(fv) + rdim = getdim(ip_geo) + vdim = isa(shape_value(fv, 1, 1), Vec) ? length(shape_value(fv, 1, 1)) : 0 + sdim = length(shape_gradient(fv, 1, 1)) ÷ length(shape_value(fv, 1, 1)) + vstr = vdim==0 ? "scalar" : "vdim=$vdim" + print(io, "FaceValues(", vstr, ", rdim=$rdim, sdim=$sdim): ") + nqp = getnquadpoints.(fv.qr.face_rules) + if all(n==first(nqp) for n in nqp) + println(io, first(nqp), " quadrature points per face") + else + println(io, tuple(nqp...), " quadrature points on each face") + end + print(io, " Function interpolation: "); show(io, d, get_function_interpolation(fv)) + print(io, "\nGeometric interpolation: "); show(io, d, ip_geo^sdim) +end + """ BCValues(func_interpol::Interpolation, geom_interpol::Interpolation, boundary_type::Union{Type{<:BoundaryIndex}}) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 2e5c2f565f..dc198f3600 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -276,7 +276,3 @@ function spatial_coordinate(fe_v::AbstractValues, q_point::Int, x::AbstractVecto end return vec end - -function Base.show(io::IO, ::MIME"text/plain", fe_v::AbstractValues) - print(io, "$(typeof(fe_v)) with $(getnbasefunctions(fe_v)) shape functions and $(getnquadpoints(fe_v)) quadrature points") -end diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 4d603e93ba..239db54ea5 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -92,3 +92,8 @@ function reinit!(pv::PointValuesInternal{IP}, coord::Vec{dim}) where {dim, shape end return nothing end + +function Base.show(io::IO, d::MIME"text/plain", cv::PointValues) + println(io, "PointValues containing a") + show(io, d, cv.cv) +end \ No newline at end of file From 8b16b97bb834539904276f681b53f660e67b8d8a Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 13:27:08 +0200 Subject: [PATCH 037/145] Fix test on julia 1.6 --- src/FEValues/FunctionValues.jl | 9 ++++----- src/FEValues/GeometryValues.jl | 7 +++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 993751cee5..8f334ccc33 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -49,11 +49,10 @@ function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo precompute_values!(fv, qr) # Precompute N and dNdξ return fv end -function Base.copy(funvals::FunctionValues) - (;ip, N_ξ, N_x, dNdξ, dNdx) = funvals - N_ξ_copy = copy(N_ξ) - N_x_copy = N_ξ === N_x ? N_ξ_copy : copy(N_x) # Preserve aliasing - return FunctionValues(copy(ip), N_x_copy, N_ξ_copy, copy(dNdx), copy(dNdξ)) +function Base.copy(v::FunctionValues) + N_ξ_copy = copy(v.N_ξ) + N_x_copy = v.N_ξ === v.N_x ? N_ξ_copy : copy(v.N_x) # Preserve aliasing + return FunctionValues(copy(v.ip), N_x_copy, N_ξ_copy, copy(v.dNdx), copy(v.dNdξ)) end function precompute_values!(fv::FunctionValues, qr::QuadratureRule) diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index 6c33fa4bfe..ec47cc6a29 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -49,10 +49,9 @@ function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, end return GeometryValues(ip, M, dMdξ, dM2dξ2) end -function Base.copy(geovals::GeometryValues) - (;ip, M, dMdξ, d2Mdξ2) = geovals - d2Mdξ2_copy = d2Mdξ2 === nothing ? nothing : copy(d2Mdξ2) - return GeometryValues(copy(ip), copy(M), copy(dMdξ), d2Mdξ2_copy) +function Base.copy(v::GeometryValues) + d2Mdξ2_copy = v.d2Mdξ2 === nothing ? nothing : copy(v.d2Mdξ2) + return GeometryValues(copy(v.ip), copy(v.M), copy(v.dMdξ), d2Mdξ2_copy) end getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) From ab28d25234656b1765636c2a5d7f3eea22013fe2 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 13:34:22 +0200 Subject: [PATCH 038/145] Relax tolerance for gradient check a bit --- test/InterpolationTestUtils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/InterpolationTestUtils.jl b/test/InterpolationTestUtils.jl index 9d98ceaa19..11e5c08b68 100644 --- a/test/InterpolationTestUtils.jl +++ b/test/InterpolationTestUtils.jl @@ -109,7 +109,7 @@ module InterpolationTestUtils ∇u2 = function_gradient(cv, 2, ue) Δu_ana = 0.5*(∇u1+∇u2) ⋅ Δx # Δu_ana_var = 0.5*(∇u2-∇u1) ⋅ Δx # Relevant to compare magnitude if test fails - @test Δu_num ≈ Δu_ana + @test isapprox(Δu_num, Δu_ana; rtol=1e-6) return nothing end From d5f71917ecfc8565d11b5e04ad3a1e90b41f793d Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 13:41:21 +0200 Subject: [PATCH 039/145] Move to old files --- src/FEValues/CellValues.jl | 89 ----------- src/FEValues/FaceValues.jl | 173 --------------------- src/FEValues/cell_values.jl | 292 ++++++++---------------------------- src/FEValues/face_values.jl | 277 +++++++++++----------------------- 4 files changed, 151 insertions(+), 680 deletions(-) delete mode 100644 src/FEValues/CellValues.jl delete mode 100644 src/FEValues/FaceValues.jl diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl deleted file mode 100644 index 7327b581d0..0000000000 --- a/src/FEValues/CellValues.jl +++ /dev/null @@ -1,89 +0,0 @@ - -include("GeometryValues.jl") -include("FunctionValues.jl") - -function default_geometric_interpolation(::Interpolation{shape}) where {dim, shape <: AbstractRefShape{dim}} - return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) -end - -struct CellValues{FV, GV, QR, detT<:AbstractVector} <: AbstractCellValues - fun_values::FV # FunctionValues - geo_values::GV # GeometryValues - qr::QR # QuadratureRule - detJdV::detT # AbstractVector{<:Number} -end -function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation) where T - geo_values = GeometryValues(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) - fun_values = FunctionValues(T, ip_fun, qr, ip_geo) - detJdV = fill(T(NaN), length(getweights(qr))) - return CellValues(fun_values, geo_values, qr, detJdV) -end - -CellValues(qr::QuadratureRule, ip::Interpolation, args...) = CellValues(Float64, qr, ip, args...) -function CellValues(::Type{T}, qr, ip::Interpolation, ip_geo::ScalarInterpolation=default_geometric_interpolation(ip)) where T - return CellValues(T, qr, ip, VectorizedInterpolation(ip_geo)) -end - -function Base.copy(cv::CellValues) - return CellValues(copy(cv.fun_values), copy(cv.geo_values), copy(cv.qr), copy(cv.detJdV)) -end - -# Access geometry values -for op = (:getngeobasefunctions, :geometric_value) - eval(quote - @propagate_inbounds $op(cv::CellValues, args...) = $op(cv.geo_values, args...) - end) -end -getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] - -# Accessors for function values -getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) -get_function_interpolation(cv::CellValues) = get_function_interpolation(cv.fun_values) -get_geometric_interpolation(cv::CellValues) = get_geometric_interpolation(cv.geo_values) -shape_value_type(cv::CellValues) = shape_value_type(cv.fun_values) -shape_gradient_type(cv::CellValues) = shape_gradient_type(cv.fun_values) - -for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient) - eval(quote - @propagate_inbounds $op(cv::CellValues, i::Int, q_point::Int) = $op(cv.fun_values, i, q_point) - end) -end -# Access quadrature rule values -getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) - -function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) - geo_values = cv.geo_values - fun_values = cv.fun_values - n_geom_basefuncs = getngeobasefunctions(geo_values) - if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs - throw_incompatible_coord_length(length(x), n_geom_basefuncs) - end - @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) - mapping = calculate_mapping(geo_values, q_point, x) - detJ = calculate_detJ(getjacobian(mapping)) - detJ > 0.0 || throw_detJ_not_pos(detJ) - @inbounds cv.detJdV[q_point] = detJ*w - apply_mapping!(fun_values, q_point, mapping, cell) - end - return nothing -end - -function Base.show(io::IO, d::MIME"text/plain", cv::CellValues) - rdim = getdim(cv.geo_values.ip) - vdim = isa(shape_value(cv, 1, 1), Vec) ? length(shape_value(cv, 1, 1)) : 0 - sdim = length(shape_gradient(cv, 1, 1)) ÷ length(shape_value(cv, 1, 1)) - vstr = vdim==0 ? "scalar" : "vdim=$vdim" - print(io, "CellValues(", vstr, ", rdim=$rdim, and sdim=$sdim): ") - print(io, getnquadpoints(cv), " quadrature points") - print(io, "\n Function interpolation: "); show(io, d, cv.fun_values.ip) - print(io, "\nGeometric interpolation: "); show(io, d, cv.geo_values.ip^sdim) -end - -# Temporary for benchmark/test -include("cell_values.jl") -function OldCellValues(cv::CellValues) - ip = cv.fun_values.ip - sdim = length(shape_gradient(cv, 1, 1)) ÷ length(shape_value(cv, 1, 1)) - ip_geo = cv.geo_values.ip^sdim - return OldCellValues(cv.qr, ip, ip_geo) -end \ No newline at end of file diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl deleted file mode 100644 index 6a6e04b838..0000000000 --- a/src/FEValues/FaceValues.jl +++ /dev/null @@ -1,173 +0,0 @@ -struct FaceValues{FV, GV, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GV<:AbstractVector{GV}} <: AbstractFaceValues - fun_values::V_FV # AbstractVector{FunctionValues} - geo_values::V_GV # AbstractVector{GeometryValues} - qr::QR # FaceQuadratureRule - detJdV::detT # AbstractVector{<:Number} - normals::nT # AbstractVector{<:Vec} - current_face::ScalarWrapper{Int} -end - -function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun)) where {T,sdim} - geo_values = [GeometryValues(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) for qr in fqr.face_rules] - fun_values = [FunctionValues(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] - max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) - detJdV = fill(T(NaN), max_nquadpoints) - normals = fill(zero(Vec{sdim,T})*T(NaN), max_nquadpoints) - return FaceValues(fun_values, geo_values, fqr, detJdV, normals, ScalarWrapper(1)) -end - -FaceValues(qr::FaceQuadratureRule, ip::Interpolation, args...) = FaceValues(Float64, qr, ip, args...) -function FaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation, ip_geo::ScalarInterpolation) where T - return FaceValues(T, qr, ip, VectorizedInterpolation(ip_geo)) -end - -function Base.copy(fv::FaceValues) - fun_values = map(copy, fv.fun_values) - geo_values = map(copy, fv.geo_values) - return FaceValues(fun_values, geo_values, copy(fv.qr), copy(fv.detJdV), copy(fv.normals), copy(fv.current_face)) -end - -getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_values(fv)) -getnbasefunctions(fv::FaceValues) = getnbasefunctions(get_fun_values(fv)) -getnquadpoints(fv::FaceValues) = getnquadpoints(fv.qr, getcurrentface(fv)) -getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] - -shape_value_type(fv::FaceValues) = shape_value_type(get_fun_values(fv)) -shape_gradient_type(fv::FaceValues) = shape_gradient_type(get_fun_values(fv)) -get_function_interpolation(fv::FaceValues) = get_function_interpolation(get_fun_values(fv)) -get_geometric_interpolation(fv::FaceValues) = get_geometric_interpolation(get_geo_values(fv)) - -get_geo_values(fv::FaceValues) = @inbounds fv.geo_values[getcurrentface(fv)] -for op = (:getngeobasefunctions, :geometric_value) - eval(quote - @propagate_inbounds $op(fv::FaceValues, args...) = $op(get_geo_values(fv), args...) - end) -end - -get_fun_values(fv::FaceValues) = @inbounds fv.fun_values[getcurrentface(fv)] -for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient, :shape_curl) - eval(quote - @propagate_inbounds $op(fv::FaceValues, i::Int, q_point::Int) = $op(get_fun_values(fv), i, q_point) - end) -end - -""" - getcurrentface(fv::FaceValues) - -Return the current active face of the `FaceValues` object (from last `reinit!`). - -""" -getcurrentface(fv::FaceValues) = fv.current_face[] - -""" - getnormal(fv::FaceValues, qp::Int) - -Return the normal at the quadrature point `qp` for the active face of the -`FaceValues` object(from last `reinit!`). -""" -getnormal(fv::FaceValues, qp::Int) = fv.normals[qp] - -nfaces(fv::FaceValues) = length(fv.geo_values) - -function checkface(fv::FaceValues, face::Int) - 0 < face <= nfaces(fv) || error("Face index out of range.") - return nothing -end - -function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, cell=nothing) where {dim, T} - @boundscheck checkface(fv, face_nr) - n_geom_basefuncs = getngeobasefunctions(fv) - length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) - - fv.current_face[] = face_nr - - geo_values = get_geo_values(fv) - fun_values = get_fun_values(fv) - @inbounds for (q_point, w) in pairs(getweights(fv.qr, face_nr)) - mapping = calculate_mapping(geo_values, q_point, x) - J = getjacobian(mapping) - weight_norm = weighted_normal(J, getrefshape(geo_values.ip), face_nr) - detJ = norm(weight_norm) - detJ > 0.0 || throw_detJ_not_pos(detJ) - @inbounds fv.detJdV[q_point] = detJ*w - @inbounds fv.normals[q_point] = weight_norm / norm(weight_norm) - apply_mapping!(fun_values, q_point, mapping, cell) - end -end - -function Base.show(io::IO, d::MIME"text/plain", fv::FaceValues) - ip_geo = get_geometric_interpolation(fv) - rdim = getdim(ip_geo) - vdim = isa(shape_value(fv, 1, 1), Vec) ? length(shape_value(fv, 1, 1)) : 0 - sdim = length(shape_gradient(fv, 1, 1)) ÷ length(shape_value(fv, 1, 1)) - vstr = vdim==0 ? "scalar" : "vdim=$vdim" - print(io, "FaceValues(", vstr, ", rdim=$rdim, sdim=$sdim): ") - nqp = getnquadpoints.(fv.qr.face_rules) - if all(n==first(nqp) for n in nqp) - println(io, first(nqp), " quadrature points per face") - else - println(io, tuple(nqp...), " quadrature points on each face") - end - print(io, " Function interpolation: "); show(io, d, get_function_interpolation(fv)) - print(io, "\nGeometric interpolation: "); show(io, d, ip_geo^sdim) -end - -""" - BCValues(func_interpol::Interpolation, geom_interpol::Interpolation, boundary_type::Union{Type{<:BoundaryIndex}}) - -`BCValues` stores the shape values at all faces/edges/vertices (depending on `boundary_type`) for the geomatric interpolation (`geom_interpol`), -for each dof-position determined by the `func_interpol`. Used mainly by the `ConstrainHandler`. -""" -struct BCValues{T} - M::Array{T,3} - nqp::Array{Int} - current_entity::ScalarWrapper{Int} -end - -BCValues(func_interpol::Interpolation, geom_interpol::Interpolation, boundary_type::Type{<:BoundaryIndex} = Ferrite.FaceIndex) = - BCValues(Float64, func_interpol, geom_interpol, boundary_type) - -function BCValues(::Type{T}, func_interpol::Interpolation{refshape}, geom_interpol::Interpolation{refshape}, boundary_type::Type{<:BoundaryIndex} = Ferrite.FaceIndex) where {T,dim,refshape <: AbstractRefShape{dim}} - # set up quadrature rules for each boundary entity with dof-positions - # (determined by func_interpol) as the quadrature points - interpolation_coords = reference_coordinates(func_interpol) - - qrs = QuadratureRule{refshape,T,dim}[] - for boundarydofs in dirichlet_boundarydof_indices(boundary_type)(func_interpol) - dofcoords = Vec{dim,T}[] - for boundarydof in boundarydofs - push!(dofcoords, interpolation_coords[boundarydof]) - end - qrf = QuadratureRule{refshape,T}(fill(T(NaN), length(dofcoords)), dofcoords) # weights will not be used - push!(qrs, qrf) - end - - n_boundary_entities = length(qrs) - n_qpoints = n_boundary_entities == 0 ? 0 : maximum(qr->length(getweights(qr)), qrs) # Bound number of qps correctly. - n_geom_basefuncs = getnbasefunctions(geom_interpol) - M = fill(zero(T) * T(NaN), n_geom_basefuncs, n_qpoints, n_boundary_entities) - nqp = zeros(Int,n_boundary_entities) - - for n_boundary_entity in 1:n_boundary_entities - for (qp, ξ) in enumerate(qrs[n_boundary_entity].points), i in 1:n_geom_basefuncs - M[i, qp, n_boundary_entity] = shape_value(geom_interpol, ξ, i) - end - nqp[n_boundary_entity] = length(qrs[n_boundary_entity].points) - end - - BCValues{T}(M, nqp, ScalarWrapper(0)) -end - -getnquadpoints(bcv::BCValues) = bcv.nqp[bcv.current_entity.x] -function spatial_coordinate(bcv::BCValues, q_point::Int, xh::AbstractVector{Vec{dim,T}}) where {dim,T} - n_base_funcs = size(bcv.M, 1) - length(xh) == n_base_funcs || throw_incompatible_coord_length(length(xh), n_base_funcs) - x = zero(Vec{dim,T}) - face = bcv.current_entity[] - @inbounds for i in 1:n_base_funcs - x += bcv.M[i,q_point,face] * xh[i] # geometric_value(fe_v, q_point, i) * xh[i] - end - return x -end - -include("face_values.jl") \ No newline at end of file diff --git a/src/FEValues/cell_values.jl b/src/FEValues/cell_values.jl index d7480df1d8..333c2b5863 100644 --- a/src/FEValues/cell_values.jl +++ b/src/FEValues/cell_values.jl @@ -1,252 +1,80 @@ -""" - OldCellValues([::Type{T},] quad_rule::QuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation]) -A `OldCellValues` object facilitates the process of evaluating values of shape functions, gradients of shape functions, -values of nodal functions, gradients and divergences of nodal functions etc. in the finite element cell. +include("GeometryValues.jl") +include("FunctionValues.jl") -**Arguments:** -* `T`: an optional argument (default to `Float64`) to determine the type the internal data is stored as. -* `quad_rule`: an instance of a [`QuadratureRule`](@ref) -* `func_interpol`: an instance of an [`Interpolation`](@ref) used to interpolate the approximated function -* `geom_interpol`: an optional instance of a [`Interpolation`](@ref) which is used to interpolate the geometry. - By default linear Lagrange interpolation is used. For embedded elements the geometric interpolations should - be vectorized to the spatial dimension. - -**Common methods:** - -* [`reinit!`](@ref) -* [`getnquadpoints`](@ref) -* [`getdetJdV`](@ref) - -* [`shape_value`](@ref) -* [`shape_gradient`](@ref) -* [`shape_symmetric_gradient`](@ref) -* [`shape_divergence`](@ref) - -* [`function_value`](@ref) -* [`function_gradient`](@ref) -* [`function_symmetric_gradient`](@ref) -* [`function_divergence`](@ref) -* [`spatial_coordinate`](@ref) -""" -OldCellValues - -struct OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP} <: AbstractCellValues - N::Matrix{N_t} - dNdx::Matrix{dNdx_t} - dNdξ::Matrix{dNdξ_t} - detJdV::Vector{T} - M::Matrix{T} - dMdξ::Matrix{dMdξ_t} - qr::QR - ip::IP - gip::GIP +function default_geometric_interpolation(::Interpolation{shape}) where {dim, shape <: AbstractRefShape{dim}} + return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) end -# Common initializer code for constructing OldCellValues after the types have been determined -function OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP}(qr::QR, ip::IP, gip::GIP) where { - IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP, -} - @assert isconcretetype(IP) && isconcretetype(N_t) && isconcretetype(dNdx_t) && - isconcretetype(dNdξ_t) && isconcretetype(T) && isconcretetype(dMdξ_t) && - isconcretetype(QR) && isconcretetype(GIP) - n_qpoints = getnquadpoints(qr) - - # Field interpolation - n_func_basefuncs = getnbasefunctions(ip) - N = fill(zero(N_t) * T(NaN), n_func_basefuncs, n_qpoints) - dNdx = fill(zero(dNdx_t) * T(NaN), n_func_basefuncs, n_qpoints) - dNdξ = fill(zero(dNdξ_t) * T(NaN), n_func_basefuncs, n_qpoints) - - # Geometry interpolation - n_geom_basefuncs = getnbasefunctions(gip) - M = fill(zero(T) * T(NaN), n_geom_basefuncs, n_qpoints) - dMdξ = fill(zero(dMdξ_t) * T(NaN), n_geom_basefuncs, n_qpoints) - - for (qp, ξ) in pairs(getpoints(qr)) - for basefunc in 1:n_func_basefuncs - dNdξ[basefunc, qp], N[basefunc, qp] = shape_gradient_and_value(ip, ξ, basefunc) - end - for basefunc in 1:n_geom_basefuncs - dMdξ[basefunc, qp], M[basefunc, qp] = shape_gradient_and_value(gip, ξ, basefunc) - end - end - - detJdV = fill(T(NaN), n_qpoints) - - OldCellValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, GIP}(N, dNdx, dNdξ, detJdV, M, dMdξ, qr, ip, gip) +struct CellValues{FV, GV, QR, detT<:AbstractVector} <: AbstractCellValues + fun_values::FV # FunctionValues + geo_values::GV # GeometryValues + qr::QR # QuadratureRule + detJdV::detT # AbstractVector{<:Number} end - -# Common entry point that fills in the numeric type and geometric interpolation -function OldCellValues(qr::QuadratureRule, ip::Interpolation, - gip::Interpolation = default_geometric_interpolation(ip)) - return OldCellValues(Float64, qr, ip, gip) +function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation) where T + geo_values = GeometryValues(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) + fun_values = FunctionValues(T, ip_fun, qr, ip_geo) + detJdV = fill(T(NaN), length(getweights(qr))) + return CellValues(fun_values, geo_values, qr, detJdV) end -# Common entry point that fills in the geometric interpolation -function OldCellValues(::Type{T}, qr::QuadratureRule, ip::Interpolation) where {T} - return OldCellValues(T, qr, ip, default_geometric_interpolation(ip)) +CellValues(qr::QuadratureRule, ip::Interpolation, args...) = CellValues(Float64, qr, ip, args...) +function CellValues(::Type{T}, qr, ip::Interpolation, ip_geo::ScalarInterpolation=default_geometric_interpolation(ip)) where T + return CellValues(T, qr, ip, VectorizedInterpolation(ip_geo)) end -# Common entry point that vectorizes an input scalar geometric interpolation -function OldCellValues(::Type{T}, qr::QuadratureRule, ip::Interpolation, sgip::ScalarInterpolation) where {T} - return OldCellValues(T, qr, ip, VectorizedInterpolation(sgip)) +function Base.copy(cv::CellValues) + return CellValues(copy(cv.fun_values), copy(cv.geo_values), copy(cv.qr), copy(cv.detJdV)) end -# Entrypoint for `ScalarInterpolation`s (rdim == sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - dim, shape <: AbstractRefShape{dim}, T, - QR <: QuadratureRule{shape}, - IP <: ScalarInterpolation{shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{dim, shape, <:Any, GIP}, -} - # Function interpolation - N_t = T - dNdx_t = dNdξ_t = Vec{dim, T} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{dim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) +# Access geometry values +for op = (:getngeobasefunctions, :geometric_value) + eval(quote + @propagate_inbounds $op(cv::CellValues, args...) = $op(cv.geo_values, args...) + end) end - -# Entrypoint for `VectorInterpolation`s (vdim == rdim == sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - dim, shape <: AbstractRefShape{dim}, T, - QR <: QuadratureRule{shape}, - IP <: VectorInterpolation{dim, shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{dim, shape, <:Any, GIP}, -} - # Field interpolation - N_t = Vec{dim, T} - dNdx_t = dNdξ_t = Tensor{2, dim, T, Tensors.n_components(Tensor{2,dim})} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{dim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) +getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] + +# Accessors for function values +getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) +get_function_interpolation(cv::CellValues) = get_function_interpolation(cv.fun_values) +get_geometric_interpolation(cv::CellValues) = get_geometric_interpolation(cv.geo_values) +shape_value_type(cv::CellValues) = shape_value_type(cv.fun_values) +shape_gradient_type(cv::CellValues) = shape_gradient_type(cv.fun_values) + +for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient) + eval(quote + @propagate_inbounds $op(cv::CellValues, i::Int, q_point::Int) = $op(cv.fun_values, i, q_point) + end) end - -# Entrypoint for `VectorInterpolation`s (vdim != rdim == sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, vgip::VGIP) where { - vdim, dim, shape <: AbstractRefShape{dim}, T, - QR <: QuadratureRule{shape}, - IP <: VectorInterpolation{vdim, shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{dim, shape, <:Any, GIP}, -} - # Field interpolation - N_t = SVector{vdim, T} - dNdx_t = dNdξ_t = SMatrix{vdim, dim, T, vdim*dim} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{dim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, vgip.ip) -end - -# reinit! for regular (non-embedded) elements (rdim == sdim) -function reinit!(cv::OldCellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVector{Vec{dim,T}}) where { - dim, T, vdim, - N_t <: Union{Number, Vec{dim}, SVector{vdim} }, - dNdx_t <: Union{Vec{dim}, Tensor{2, dim}, SMatrix{vdim, dim}}, - dNdξ_t <: Union{Vec{dim}, Tensor{2, dim}, SMatrix{vdim, dim}}, -} - n_geom_basefuncs = getngeobasefunctions(cv) - n_func_basefuncs = getnbasefunctions(cv) - length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) - - @inbounds for (i, w) in pairs(getweights(cv.qr)) - fecv_J = zero(Tensor{2,dim,T}) - for j in 1:n_geom_basefuncs - fecv_J += x[j] ⊗ cv.dMdξ[j, i] - end - detJ = det(fecv_J) - detJ > 0.0 || throw_detJ_not_pos(detJ) - cv.detJdV[i] = detJ * w - Jinv = inv(fecv_J) - for j in 1:n_func_basefuncs - # cv.dNdx[j, i] = cv.dNdξ[j, i] ⋅ Jinv - cv.dNdx[j, i] = dothelper(cv.dNdξ[j, i], Jinv) - end +# Access quadrature rule values +getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) + +function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) + geo_values = cv.geo_values + fun_values = cv.fun_values + n_geom_basefuncs = getngeobasefunctions(geo_values) + if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs + throw_incompatible_coord_length(length(x), n_geom_basefuncs) end -end - -# Entrypoint for embedded `ScalarInterpolation`s (rdim < sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - sdim, rdim, shape <: AbstractRefShape{rdim}, T, - QR <: QuadratureRule{shape}, - IP <: ScalarInterpolation{shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{sdim, shape, <:Any, GIP}, -} - @assert sdim > rdim - # Function interpolation - N_t = T - dNdx_t = SVector{sdim, T} - dNdξ_t = SVector{rdim, T} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{rdim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) -end - -# Entrypoint for embedded `VectorInterpolation`s (rdim < sdim) -function OldCellValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - sdim, vdim, rdim, shape <: AbstractRefShape{rdim}, T, - QR <: QuadratureRule{shape}, - IP <: VectorInterpolation{vdim, shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{sdim, shape, <:Any, GIP}, -} - @assert sdim > rdim - # Function interpolation - N_t = SVector{vdim, T} - dNdx_t = SMatrix{vdim, sdim, T, vdim*sdim} - dNdξ_t = SMatrix{vdim, rdim, T, vdim*rdim} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{rdim, T} - return OldCellValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, GIP}(qr, ip, gip.ip) -end - -# reinit! for embedded elements, rdim < sdim -function reinit!(cv::OldCellValues{<:Any, N_t, dNdx_t, dNdξ_t}, x::AbstractVector{Vec{sdim,T}}) where { - rdim, sdim, vdim, T, - N_t <: Union{Number, SVector{vdim}}, - dNdx_t <: Union{SVector{sdim, T}, SMatrix{vdim, sdim, T}}, - dNdξ_t <: Union{SVector{rdim, T}, SMatrix{vdim, rdim, T}}, -} - @assert sdim > rdim "This reinit only works for embedded elements. Maybe you swapped the reference and spatial dimensions?" - n_geom_basefuncs = getngeobasefunctions(cv) - n_func_basefuncs = getnbasefunctions(cv) - length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) - - @inbounds for (i, w) in pairs(getweights(cv.qr)) - fecv_J = zero(MMatrix{sdim, rdim, T}) # TODO replace with MixedTensor (see https://github.com/Ferrite-FEM/Tensors.jl/pull/188) - for j in 1:n_geom_basefuncs - #fecv_J += x[j] ⊗ cv.dMdξ[j, i] # TODO via Tensors.jl - for k in 1:sdim, l in 1:rdim - fecv_J[k, l] += x[j][k] * cv.dMdξ[j, i][l] - end - end - fecv_J = SMatrix(fecv_J) - detJ = embedding_det(fecv_J) + @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) + mapping = calculate_mapping(geo_values, q_point, x) + detJ = calculate_detJ(getjacobian(mapping)) detJ > 0.0 || throw_detJ_not_pos(detJ) - cv.detJdV[i] = detJ * w - # Compute "left inverse" of J - Jinv = pinv(fecv_J) - for j in 1:n_func_basefuncs - #cv.dNdx[j, i] = cv.dNdξ[j, i] ⋅ Jinv # TODO via Tensors.jl - cv.dNdx[j, i] = dothelper(cv.dNdξ[j, i], Jinv) - end + @inbounds cv.detJdV[q_point] = detJ*w + apply_mapping!(fun_values, q_point, mapping, cell) end return nothing end -function Base.show(io::IO, m::MIME"text/plain", cv::OldCellValues) - println(io, "CellValues with") - println(io, "- Quadrature rule with ", getnquadpoints(cv), " points") - print(io, "- Function interpolation: "); show(io, m, cv.ip) - println(io) - print(io, "- Geometric interpolation: "); show(io, m, cv.gip) +function Base.show(io::IO, d::MIME"text/plain", cv::CellValues) + rdim = getdim(cv.geo_values.ip) + vdim = isa(shape_value(cv, 1, 1), Vec) ? length(shape_value(cv, 1, 1)) : 0 + sdim = length(shape_gradient(cv, 1, 1)) ÷ length(shape_value(cv, 1, 1)) + vstr = vdim==0 ? "scalar" : "vdim=$vdim" + print(io, "CellValues(", vstr, ", rdim=$rdim, and sdim=$sdim): ") + print(io, getnquadpoints(cv), " quadrature points") + print(io, "\n Function interpolation: "); show(io, d, cv.fun_values.ip) + print(io, "\nGeometric interpolation: "); show(io, d, cv.geo_values.ip^sdim) end \ No newline at end of file diff --git a/src/FEValues/face_values.jl b/src/FEValues/face_values.jl index 6bd56105af..e922e0759b 100644 --- a/src/FEValues/face_values.jl +++ b/src/FEValues/face_values.jl @@ -1,191 +1,117 @@ -""" - FaceValues([::Type{T}], quad_rule::FaceQuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation]) - -A `FaceValues` object facilitates the process of evaluating values of shape functions, gradients of shape functions, -values of nodal functions, gradients and divergences of nodal functions etc. on the faces of finite elements. - -**Arguments:** - -* `T`: an optional argument to determine the type the internal data is stored as. -* `quad_rule`: an instance of a [`FaceQuadratureRule`](@ref) -* `func_interpol`: an instance of an [`Interpolation`](@ref) used to interpolate the approximated function -* `geom_interpol`: an optional instance of an [`Interpolation`](@ref) which is used to interpolate the geometry. - By default linear Lagrange interpolation is used. - -**Common methods:** - -* [`reinit!`](@ref) -* [`getnquadpoints`](@ref) -* [`getdetJdV`](@ref) - -* [`shape_value`](@ref) -* [`shape_gradient`](@ref) -* [`shape_symmetric_gradient`](@ref) -* [`shape_divergence`](@ref) - -* [`function_value`](@ref) -* [`function_gradient`](@ref) -* [`function_symmetric_gradient`](@ref) -* [`function_divergence`](@ref) -* [`spatial_coordinate`](@ref) -""" -FaceValues - -struct OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP} <: AbstractFaceValues - N::Array{N_t, 3} - dNdx::Array{dNdx_t, 3} - dNdξ::Array{dNdξ_t, 3} - detJdV::Matrix{T} - normals::Vector{Normal_t} - M::Array{T, 3} - dMdξ::Array{dMdξ_t, 3} - qr::QR +struct FaceValues{FV, GV, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GV<:AbstractVector{GV}} <: AbstractFaceValues + fun_values::V_FV # AbstractVector{FunctionValues} + geo_values::V_GV # AbstractVector{GeometryValues} + qr::QR # FaceQuadratureRule + detJdV::detT # AbstractVector{<:Number} + normals::nT # AbstractVector{<:Vec} current_face::ScalarWrapper{Int} - func_interp::IP - geo_interp::GIP end -# Common initializer code for constructing OldFaceValues after the types have been determined -function OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP}(qr::QR, ip::IP, gip::GIP) where { - IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP, -} - @assert isconcretetype(IP) && isconcretetype(N_t) && isconcretetype(dNdx_t) && - isconcretetype(dNdξ_t) && isconcretetype(T) && isconcretetype(dMdξ_t) && - isconcretetype(QR) && isconcretetype(Normal_t) && isconcretetype(GIP) - # Quadrature - max_n_qpoints = maximum(getnquadpoints, qr.face_rules; init = 0) - n_faces = length(qr.face_rules) +function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun)) where {T,sdim} + geo_values = [GeometryValues(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) for qr in fqr.face_rules] + fun_values = [FunctionValues(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] + max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) + detJdV = fill(T(NaN), max_nquadpoints) + normals = fill(zero(Vec{sdim,T})*T(NaN), max_nquadpoints) + return FaceValues(fun_values, geo_values, fqr, detJdV, normals, ScalarWrapper(1)) +end - # Normals - normals = zeros(Normal_t, max_n_qpoints) +FaceValues(qr::FaceQuadratureRule, ip::Interpolation, args...) = FaceValues(Float64, qr, ip, args...) +function FaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation, ip_geo::ScalarInterpolation) where T + return FaceValues(T, qr, ip, VectorizedInterpolation(ip_geo)) +end - # Field interpolation - n_func_basefuncs = getnbasefunctions(ip) - N = fill(zero(N_t) * T(NaN), n_func_basefuncs, max_n_qpoints, n_faces) - dNdx = fill(zero(dNdx_t) * T(NaN), n_func_basefuncs, max_n_qpoints, n_faces) - dNdξ = fill(zero(dNdξ_t) * T(NaN), n_func_basefuncs, max_n_qpoints, n_faces) +function Base.copy(fv::FaceValues) + fun_values = map(copy, fv.fun_values) + geo_values = map(copy, fv.geo_values) + return FaceValues(fun_values, geo_values, copy(fv.qr), copy(fv.detJdV), copy(fv.normals), copy(fv.current_face)) +end - # Geometry interpolation - n_geom_basefuncs = getnbasefunctions(gip) - M = fill(zero(T) * T(NaN), n_geom_basefuncs, max_n_qpoints, n_faces) - dMdξ = fill(zero(dMdξ_t) * T(NaN), n_geom_basefuncs, max_n_qpoints, n_faces) +getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_values(fv)) +getnbasefunctions(fv::FaceValues) = getnbasefunctions(get_fun_values(fv)) +getnquadpoints(fv::FaceValues) = getnquadpoints(fv.qr, getcurrentface(fv)) +getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] + +shape_value_type(fv::FaceValues) = shape_value_type(get_fun_values(fv)) +shape_gradient_type(fv::FaceValues) = shape_gradient_type(get_fun_values(fv)) +get_function_interpolation(fv::FaceValues) = get_function_interpolation(get_fun_values(fv)) +get_geometric_interpolation(fv::FaceValues) = get_geometric_interpolation(get_geo_values(fv)) + +get_geo_values(fv::FaceValues) = @inbounds fv.geo_values[getcurrentface(fv)] +for op = (:getngeobasefunctions, :geometric_value) + eval(quote + @propagate_inbounds $op(fv::FaceValues, args...) = $op(get_geo_values(fv), args...) + end) +end - for face in 1:n_faces, (qp, ξ) in pairs(getpoints(qr, face)) - for basefunc in 1:n_func_basefuncs - dNdξ[basefunc, qp, face], N[basefunc, qp, face] = shape_gradient_and_value(ip, ξ, basefunc) - end - for basefunc in 1:n_geom_basefuncs - dMdξ[basefunc, qp, face], M[basefunc, qp, face] = shape_gradient_and_value(gip, ξ, basefunc) - end - end +get_fun_values(fv::FaceValues) = @inbounds fv.fun_values[getcurrentface(fv)] +for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient, :shape_curl) + eval(quote + @propagate_inbounds $op(fv::FaceValues, i::Int, q_point::Int) = $op(get_fun_values(fv), i, q_point) + end) +end - detJdV = fill(T(NaN), max_n_qpoints, n_faces) +""" + getcurrentface(fv::FaceValues) - OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, T, dMdξ_t, QR, Normal_t, GIP}(N, dNdx, dNdξ, detJdV, normals, M, dMdξ, qr, ScalarWrapper(0), ip, gip) -end +Return the current active face of the `FaceValues` object (from last `reinit!`). -# Common entry point that fills in the numeric type and geometric interpolation -function OldFaceValues(qr::FaceQuadratureRule, ip::Interpolation, - gip::Interpolation = default_geometric_interpolation(ip)) - return OldFaceValues(Float64, qr, ip, gip) -end +""" +getcurrentface(fv::FaceValues) = fv.current_face[] -# Common entry point that fills in the geometric interpolation -function OldFaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation) where {T} - return OldFaceValues(T, qr, ip, default_geometric_interpolation(ip)) -end +""" + getnormal(fv::FaceValues, qp::Int) -# Common entry point that vectorizes an input scalar geometric interpolation -function OldFaceValues(::Type{T}, qr::FaceQuadratureRule, ip::Interpolation, sgip::ScalarInterpolation) where {T} - return OldFaceValues(T, qr, ip, VectorizedInterpolation(sgip)) -end +Return the normal at the quadrature point `qp` for the active face of the +`FaceValues` object(from last `reinit!`). +""" +getnormal(fv::FaceValues, qp::Int) = fv.normals[qp] -# Entrypoint for `ScalarInterpolation`s (rdim == sdim) -function OldFaceValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - dim, shape <: AbstractRefShape{dim}, T, - QR <: FaceQuadratureRule{shape}, - IP <: ScalarInterpolation{shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{dim, shape, <:Any, GIP}, -} - # Normals - Normal_t = Vec{dim, T} - # Function interpolation - N_t = T - dNdx_t = dNdξ_t = Vec{dim, T} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{dim, T} - return OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, Normal_t, GIP}(qr, ip, gip.ip) -end +nfaces(fv::FaceValues) = length(fv.geo_values) -# Entrypoint for `VectorInterpolation`s (vdim == rdim == sdim) -function OldFaceValues(::Type{T}, qr::QR, ip::IP, gip::VGIP) where { - dim, shape <: AbstractRefShape{dim}, T, - QR <: FaceQuadratureRule{shape}, - IP <: VectorInterpolation{dim, shape}, - GIP <: ScalarInterpolation{shape}, - VGIP <: VectorizedInterpolation{dim, shape, <:Any, GIP}, -} - # Normals - Normal_t = Vec{dim, T} - # Function interpolation - N_t = Vec{dim, T} - dNdx_t = dNdξ_t = Tensor{2, dim, T, Tensors.n_components(Tensor{2,dim})} - # Geometry interpolation - M_t = T - dMdξ_t = Vec{dim, T} - return OldFaceValues{IP, N_t, dNdx_t, dNdξ_t, M_t, dMdξ_t, QR, Normal_t, GIP}(qr, ip, gip.ip) +function checkface(fv::FaceValues, face::Int) + 0 < face <= nfaces(fv) || error("Face index out of range.") + return nothing end -function reinit!(fv::OldFaceValues{<:Any, N_t, dNdx_t}, x::AbstractVector{Vec{dim,T}}, face::Int) where { - dim, T, - N_t <: Union{Number, Vec{dim}}, - dNdx_t <: Union{Vec{dim}, Tensor{2,dim}} -} +function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, cell=nothing) where {dim, T} + @boundscheck checkface(fv, face_nr) n_geom_basefuncs = getngeobasefunctions(fv) - n_func_basefuncs = getnbasefunctions(fv) length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) - @boundscheck checkface(fv, face) - - fv.current_face[] = face - cb = getcurrentface(fv) - - @inbounds for (i, w) in pairs(getweights(fv.qr, cb)) - fefv_J = zero(Tensor{2,dim}) - for j in 1:n_geom_basefuncs - fefv_J += x[j] ⊗ fv.dMdξ[j, i, cb] - end - weight_norm = weighted_normal(fefv_J, fv, cb) - fv.normals[i] = weight_norm / norm(weight_norm) + + fv.current_face[] = face_nr + + geo_values = get_geo_values(fv) + fun_values = get_fun_values(fv) + @inbounds for (q_point, w) in pairs(getweights(fv.qr, face_nr)) + mapping = calculate_mapping(geo_values, q_point, x) + J = getjacobian(mapping) + weight_norm = weighted_normal(J, getrefshape(geo_values.ip), face_nr) detJ = norm(weight_norm) - detJ > 0.0 || throw_detJ_not_pos(detJ) - fv.detJdV[i, cb] = detJ * w - Jinv = inv(fefv_J) - for j in 1:n_func_basefuncs - fv.dNdx[j, i, cb] = fv.dNdξ[j, i, cb] ⋅ Jinv - end + @inbounds fv.detJdV[q_point] = detJ*w + @inbounds fv.normals[q_point] = weight_norm / norm(weight_norm) + apply_mapping!(fun_values, q_point, mapping, cell) end - return nothing end -""" - getcurrentface(fv::OldFaceValues) - -Return the current active face of the `OldFaceValues` object (from last `reinit!`). - -""" -getcurrentface(fv::OldFaceValues) = fv.current_face[] +function Base.show(io::IO, d::MIME"text/plain", fv::FaceValues) + ip_geo = get_geometric_interpolation(fv) + rdim = getdim(ip_geo) + vdim = isa(shape_value(fv, 1, 1), Vec) ? length(shape_value(fv, 1, 1)) : 0 + sdim = length(shape_gradient(fv, 1, 1)) ÷ length(shape_value(fv, 1, 1)) + vstr = vdim==0 ? "scalar" : "vdim=$vdim" + print(io, "FaceValues(", vstr, ", rdim=$rdim, sdim=$sdim): ") + nqp = getnquadpoints.(fv.qr.face_rules) + if all(n==first(nqp) for n in nqp) + println(io, first(nqp), " quadrature points per face") + else + println(io, tuple(nqp...), " quadrature points on each face") + end + print(io, " Function interpolation: "); show(io, d, get_function_interpolation(fv)) + print(io, "\nGeometric interpolation: "); show(io, d, ip_geo^sdim) +end -""" - getnormal(fv::OldFaceValues, qp::Int) - -Return the normal at the quadrature point `qp` for the active face of the -`OldFaceValues` object(from last `reinit!`). -""" -getnormal(fv::OldFaceValues, qp::Int) = fv.normals[qp] -#= Moved to FaceValues.jl """ BCValues(func_interpol::Interpolation, geom_interpol::Interpolation, boundary_type::Union{Type{<:BoundaryIndex}}) @@ -242,25 +168,4 @@ function spatial_coordinate(bcv::BCValues, q_point::Int, xh::AbstractVector{Vec{ x += bcv.M[i,q_point,face] * xh[i] # geometric_value(fe_v, q_point, i) * xh[i] end return x -end - -nfaces(fv::FaceValues) = size(fv.N, 3) - -function checkface(fv::FaceValues, face::Int) - 0 < face <= nfaces(fv) || error("Face index out of range.") - return nothing -end -=# - -function Base.show(io::IO, m::MIME"text/plain", fv::OldFaceValues) - println(io, "FaceValues with") - nqp = getnquadpoints.(fv.qr.face_rules) - if all(n==first(nqp) for n in nqp) - println(io, "- Quadrature rule with ", first(nqp), " points per face") - else - println(io, "- Quadrature rule with ", tuple(nqp...), " points on each face") - end - print(io, "- Function interpolation: "); show(io, m, fv.func_interp) - println(io) - print(io, "- Geometric interpolation: "); show(io, m, fv.geo_interp) -end +end \ No newline at end of file From 7f17ffedcf3ea969de5bddefc5a4826e7b138524 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 13:41:50 +0200 Subject: [PATCH 040/145] Rename files --- src/FEValues/{cell_values.jl => CellValues.jl} | 0 src/FEValues/{face_values.jl => FaceValues.jl} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/FEValues/{cell_values.jl => CellValues.jl} (100%) rename src/FEValues/{face_values.jl => FaceValues.jl} (100%) diff --git a/src/FEValues/cell_values.jl b/src/FEValues/CellValues.jl similarity index 100% rename from src/FEValues/cell_values.jl rename to src/FEValues/CellValues.jl diff --git a/src/FEValues/face_values.jl b/src/FEValues/FaceValues.jl similarity index 100% rename from src/FEValues/face_values.jl rename to src/FEValues/FaceValues.jl From fbed8e5430614072eee57482c967b70e7435e1a5 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 13:47:54 +0200 Subject: [PATCH 041/145] Move includes to top level --- src/FEValues/CellValues.jl | 4 ---- src/Ferrite.jl | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 333c2b5863..bad4d4b093 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -1,7 +1,3 @@ - -include("GeometryValues.jl") -include("FunctionValues.jl") - function default_geometric_interpolation(::Interpolation{shape}) where {dim, shape <: AbstractRefShape{dim}} return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) end diff --git a/src/Ferrite.jl b/src/Ferrite.jl index cdba5ee48d..6965d631ab 100644 --- a/src/Ferrite.jl +++ b/src/Ferrite.jl @@ -82,9 +82,9 @@ include("interpolations.jl") include("Quadrature/quadrature.jl") # FEValues -#include("FEValues/cell_values.jl") +include("FEValues/GeometryValues.jl") +include("FEValues/FunctionValues.jl") include("FEValues/CellValues.jl") -#include("FEValues/face_values.jl") include("FEValues/FaceValues.jl") include("PointEval/point_values.jl") include("FEValues/common_values.jl") From 7bbc5e4b89bf1c4bc48aa0c8224c3766cd55bf85 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 13:49:28 +0200 Subject: [PATCH 042/145] Remove unused example files and notes --- notes/heat_equation_rt_theory.md | 34 ---- notes/maxwell_eigenvalue.jl | 161 ------------------- notes/nedelec_raviartthomas_testing.jl | 72 --------- notes/nedelec_raviartthomas_testing_refel.jl | 61 ------- 4 files changed, 328 deletions(-) delete mode 100644 notes/heat_equation_rt_theory.md delete mode 100644 notes/maxwell_eigenvalue.jl delete mode 100644 notes/nedelec_raviartthomas_testing.jl delete mode 100644 notes/nedelec_raviartthomas_testing_refel.jl diff --git a/notes/heat_equation_rt_theory.md b/notes/heat_equation_rt_theory.md deleted file mode 100644 index 28088bbd3c..0000000000 --- a/notes/heat_equation_rt_theory.md +++ /dev/null @@ -1,34 +0,0 @@ -## Strong form -$$ -\nabla \cdot \boldsymbol{q} = h \in \Omega \\ -\boldsymbol{q} = - k\ \nabla u \in \Omega \\ -\boldsymbol{q}\cdot \boldsymbol{n} = q_n \in \Gamma_\mathrm{N}\\ -u = u_\mathrm{D} \in \Gamma_\mathrm{D} -$$ - -## Weak form -### Part 1 -$$ -\int_{\Omega} \delta u \nabla \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ -\int_{\Gamma} \delta u \boldsymbol{n} \cdot \boldsymbol{q}\ \mathrm{d}\Gamma - -\int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ -$$ - -### Part 2 -$$ -\int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega = - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega -$$ -where no Green-Gauss theorem is applied. - -### Summary -The weak form becomes, find $u\in H^1$ and $\boldsymbol{q} \in H\mathrm{(div)}$, such that -$$ -\begin{align*} --\int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega - -\int_{\Gamma} \delta u\ q_\mathrm{n}\ \mathrm{d}\Gamma -\quad -\forall\ \delta u \in \delta H^1 \\ -\int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega - \quad \forall\ \boldsymbol{\delta q} \in \delta H\mathrm{(div)} -\end{align*} -$$ diff --git a/notes/maxwell_eigenvalue.jl b/notes/maxwell_eigenvalue.jl deleted file mode 100644 index 2c64dfa140..0000000000 --- a/notes/maxwell_eigenvalue.jl +++ /dev/null @@ -1,161 +0,0 @@ -# The Maxwell eigenvalue problem -# Following the Fenics tutorial, -# [*Stable and unstable finite elements for the Maxwell eigenvalue problem*](https://fenicsproject.org/olddocs/dolfin/2019.1.0/python/demos/maxwell-eigenvalues/demo_maxwell-eigenvalues.py.html), -# we show how Nedelec elements can be used -# with Ferrite.jl -# ## Problem description -# ### Strong form -# -# ### Weak form -# ```math -# \int_\Omega \mathrm{curl}(\boldsymbol{\delta u}) \cdot \mathrm{curl}(\boldsymbol{u})\, \mathrm{d}\Omega = \lambda \int_\Omega \boldsymbol{\delta u}\cdot \boldsymbol{u}\ \mathrm{d}\Omega -# ``` -# ### FE form -# ```math -# \begin{align*} -# \int_\Omega \mathrm{curl}(\boldsymbol{\delta N}_i) \cdot \mathrm{curl}(\boldsymbol{N}_j)\, \mathrm{d}\Omega a_j &= \lambda \int_\Omega \boldsymbol{\delta N}_i\cdot \boldsymbol{N}_j\ \mathrm{d}\Omega a_j \\ -# A_{ij} a_j &= \lambda B_{ij} a_j -# \end{align*} -# ``` - -# https://iterativesolvers.julialinearalgebra.org/dev/eigenproblems/lobpcg/ -using Ferrite -import Ferrite: Nedelec, RaviartThomas -import IterativeSolvers: lobpcg -using LinearAlgebra -import CairoMakie as M - -function assemble_cell!(Ae, Be, cv) - n = getnbasefunctions(cv) - for q_point in 1:getnquadpoints(cv) - dΩ = getdetJdV(cv, q_point) - for i in 1:n - δNi = shape_value(cv, q_point, i) - curl_δNi = shape_curl(cv, q_point, i) - for j in 1:n - Nj = shape_value(cv, q_point, j) - curl_Nj = shape_curl(cv, q_point, j) - Ae[i,j] += (curl_δNi ⋅ curl_Nj)*dΩ - Be[i,j] += (δNi ⋅ Nj)*dΩ - end - end - end - return Ae, Be -end - -function plot_shapes(dh, ip, a) - cv = CellValues(QuadratureRule{RefTriangle}(1), ip, Lagrange{RefTriangle,1}()) - grid = dh.grid - n_cells = getncells(grid) - coords = (zeros(n_cells), zeros(n_cells)) - vectors = (zeros(n_cells), zeros(n_cells)) - - for cell_nr in 1:getncells(grid) - x = getcoordinates(grid, cell_nr) - reinit!(cv, x, getcells(grid, cell_nr)) - ue = a[celldofs(dh, cell_nr)] - for q_point in 1:getnquadpoints(cv) - #i = getnquadpoints(cv)*(cell_nr-1) + q_point - i = cell_nr - qp_x = spatial_coordinate(cv, q_point, x) - v = function_value(cv, q_point, ue) - sfac = norm(v) ≈ 0 ? NaN : 1.0 # Skip plotting zero-vector points - coords[1][i] = sfac*qp_x[1] - coords[2][i] = sfac*qp_x[2] - vectors[1][i] = v[1] - vectors[2][i] = v[2] - end - end - vtk_grid("tmp", dh.grid) do vtk - vtk_cell_data(vtk, vectors[1], "u1") - vtk_cell_data(vtk, vectors[2], "u2") - end - nothing, nothing - #= - fig = M.Figure() - for i in 1:2 - ax = M.Axis(fig[i,1]; aspect=M.DataAspect()) - #=for cellnr in 1:getncells(grid) - x = getcoordinates(grid, cellnr) - push!(x, x[1]) - M.lines!(ax, first.(x), last.(x), color=:black) - end=# - M.scatter!(ax, coords..., vectors[i]; lengthscale=0.1) - end - return fig - =# -end - -function doassemble(dh::DofHandler, cv::CellValues) - grid = dh.grid - A, B = create_sparsity_pattern.((dh, dh)) - assemA, assemB = start_assemble.((A, B)) - x = getcoordinates(grid, 1) - n_el_dofs = ndofs_per_cell(dh, 1) - dofs = zeros(Int, n_el_dofs) - Ae, Be = [zeros(n_el_dofs, n_el_dofs) for _ in 1:2] - - for (ic, cell) in pairs(getcells(grid)) - getcoordinates!(x, grid, cell) - celldofs!(dofs, dh, ic) - reinit!(cv, x, cell) - fill!.((Ae, Be), 0) - assemble_cell!(Ae, Be, cv) - assemble!(assemA, dofs, Ae) - assemble!(assemB, dofs, Be) - end - return A, B -end - -function get_matrices(ip::Interpolation; CT=Quadrilateral, nel=40, usebc=true) - RefShape = Ferrite.getrefshape(ip) - grid = generate_grid(CT, (nel,nel), zero(Vec{2}), π*ones(Vec{2})) - dh = DofHandler(grid) - add!(dh, :u, ip) - close!(dh) - ip_geo = Ferrite.default_interpolation(CT) - cv = CellValues(QuadratureRule{RefShape}(2), ip, ip_geo) - A, B = doassemble(dh, cv) - if usebc - ch = ConstraintHandler(dh) - dΩh = union(getfaceset(grid, "left"), getfaceset(grid, "right")) - dΩv = union(getfaceset(grid, "top"), getfaceset(grid, "bottom")) - if ip isa VectorizedInterpolation - add!(ch, Dirichlet(:u, dΩh, Returns(0.0), 2)) # y-component on left-right - add!(ch, Dirichlet(:u, dΩv, Returns(0.0), 1)) # x-component on top-bottom - else - add!(ch, Dirichlet(:u, union!(dΩh,dΩv), Returns(0.0))) - end - close!(ch) - update!(ch, 0.0) - apply!(A, ch) - apply!(B, ch) - end - return A, B, dh -end - -function solve(ip; num_values, kwargs...) - A, B = get_matrices(ip; kwargs...) - n = size(A,1) - r = lobpcg(Symmetric(A), Symmetric(B), false, zeros(n,num_values)) - return r.λ -end - -function solve_single(ip, λ=2; kwargs...) - A, B, dh = get_matrices(ip; kwargs...) - a = (A-λ*B)\zeros(size(A,1)) - return dh, a -end - -ip = Nedelec{2,RefTriangle,1}() -#ip = Lagrange{RefTriangle,1}()^2 -dh, a = solve_single(ip, CT=Triangle) -cv = CellValues(QuadratureRule{RefTriangle}(2), ip, Lagrange{RefTriangle,1}()) -fig = plot_shapes(dh, ip, a) -#λ = solve(ip; CT=Triangle, num_values=10) - -m, n = (1,1) -λ=m^2+n^2 -u(x,y)=Vec((sin(m*x),sin(n*y))) -a = zeros(ndofs) -apply_analytical!() \ No newline at end of file diff --git a/notes/nedelec_raviartthomas_testing.jl b/notes/nedelec_raviartthomas_testing.jl deleted file mode 100644 index 20d5498b79..0000000000 --- a/notes/nedelec_raviartthomas_testing.jl +++ /dev/null @@ -1,72 +0,0 @@ -# Maxwell's equations -# For simplicity, we start with the very basic example from -# https://www.math.colostate.edu/~bangerth/videos.676.33.html -# Specifically, -# ```math -# \int_\Omega \left[\mathrm{curl}(\boldsymbol{\delta u}) \cdot \mathrm{curl}(\boldsymbol{u}) -# + \mathrm{div}(\boldsymbol{\delta u}) \mathrm{div}(\boldsymbol{u})\right] \mathrm{d}\Omega = 0 -# ``` -# As noted in the lecture, standard Lagrange elements are not sufficient to solve this problem accurately, -# and we therefore use the Nedelec interpolation. -import LinearAlgebra: normalize -using StaticArrays -using Test -using Ferrite -import Ferrite: Nedelec, RaviartThomas -import CairoMakie as M -ip = Nedelec{2,RefTriangle,2}() -ip = RaviartThomas{2,RefTriangle,1}() -grid = generate_grid(Triangle, (1,2)) -dh = DofHandler(grid) -add!(dh, :B, ip) -close!(dh) - -ip_geo = Ferrite.default_interpolation(Triangle) -qr = QuadratureRule{RefTriangle}(10) - -qr_points = Vec{2,Float64}[]; n=6 -append!(qr_points, [Vec((0.0, i/(n+1))) for i in 1:n]) -append!(qr_points, [Vec((i/(n+1), 0.0)) for i in 1:n]) -append!(qr_points, [Vec((i/(n+1), 1 - i/(n+1))) for i in 1:n]) -qr = QuadratureRule{RefTriangle}(zeros(length(qr_points)), qr_points) -cv = CellValues(qr, ip, ip_geo) - -function plot_shapes(dh, cv) - grid = dh.grid - n_qp = getncells(grid)*getnquadpoints(cv) - coords = (zeros(n_qp), zeros(n_qp)) - vectors = (zeros(n_qp), zeros(n_qp)) - - for nr in 1:(ndofs(dh)) - u = zeros(ndofs(dh)) - u[nr] = 1.0 - - for cell_nr in 1:getncells(grid) - x = getcoordinates(grid, cell_nr) - reinit!(cv, x, getcells(grid, cell_nr)) - ue = u[celldofs(dh, cell_nr)] - for q_point in 1:getnquadpoints(cv) - i = getnquadpoints(cv)*(cell_nr-1) + q_point - qp_x = spatial_coordinate(cv, q_point, x) - v = function_value(cv, q_point, ue) - sfac = norm(v) ≈ 0 ? NaN : 1.0 # Skip plotting zero-vector points - coords[1][i] = sfac*qp_x[1] - coords[2][i] = sfac*qp_x[2] - vectors[1][i] = v[1] - vectors[2][i] = v[2] - end - end - - fig = M.Figure() - ax = M.Axis(fig[1,1]; aspect=M.DataAspect()) - for cellnr in 1:getncells(grid) - x = getcoordinates(grid, cellnr) - push!(x, x[1]) - M.lines!(ax, first.(x), last.(x), color=:black) - end - M.arrows!(ax, coords..., vectors...; lengthscale=0.1) - display(fig) - end - return nothing -end -plot_shapes(dh, cv) diff --git a/notes/nedelec_raviartthomas_testing_refel.jl b/notes/nedelec_raviartthomas_testing_refel.jl deleted file mode 100644 index 7bbc56c73a..0000000000 --- a/notes/nedelec_raviartthomas_testing_refel.jl +++ /dev/null @@ -1,61 +0,0 @@ -# Maxwell's equations -# For simplicity, we start with the very basic example from -# https://www.math.colostate.edu/~bangerth/videos.676.33.html -# Specifically, -# ```math -# \int_\Omega \left[\mathrm{curl}(\boldsymbol{\delta u}) \cdot \mathrm{curl}(\boldsymbol{u}) -# + \mathrm{div}(\boldsymbol{\delta u}) \mathrm{div}(\boldsymbol{u})\right] \mathrm{d}\Omega = 0 -# ``` -# As noted in the lecture, standard Lagrange elements are not sufficient to solve this problem accurately, -# and we therefore use the Nedelec interpolation. -import CairoMakie as M -using Ferrite -import Ferrite: Nedelec, RaviartThomas -import Ferrite: reference_coordinates -ip = Nedelec{2,RefTriangle,1}() -ip = RaviartThomas{2,RefTriangle,1}() -ip_geo = Lagrange{RefTriangle,1}() -ref_x = reference_coordinates(ip_geo) - -x_vertices = [ref_x..., ref_x[1]] - -function create_testpoints(npts) - inside(x) = (1 - x[1]) > x[2] - x = Vec{2,Float64}[] - for i in 0:(npts-1) - for j in i:(npts-1) - push!(x, Vec((i/(npts-1)), 1 - j/(npts-1))) - end - end - return x -end -x = create_testpoints(10) - -w = ones(length(x))*0.5/length(x) -qr = QuadratureRule{RefTriangle}(w, x) - -fig = M.Figure(resolution=(1000,1000)); -for i in 1:3 - ax=M.Axis(fig[i,1]; aspect=M.DataAspect()); - M.lines!(ax, first.(x_vertices), last.(x_vertices)) - v = shape_value.((ip,), x, i) - M.scatter!(ax, first.(x), last.(x)) - M.arrows!(ax, first.(x), last.(x), first.(v), last.(v); lengthscale=0.25) -end -display(fig) - -fig2 = M.Figure(resolution=(1000,1000)) -cv = CellValues(qr, ip, ip_geo) -ref_x[1] = Vec(4.0,0.0) -reinit!(cv, ref_x, Triangle((1,2,3))) -x_vertices = [ref_x..., ref_x[1]] -for i in 1:3 - ax=M.Axis(fig2[i,1]; aspect=M.DataAspect()); - M.lines!(ax, first.(x_vertices), last.(x_vertices)) - x_qp = spatial_coordinate.((cv,), 1:length(x), (ref_x,)) - @show x_qp ≈ x # should be false - v = shape_value.((cv,), 1:length(x), i) - M.scatter!(ax, first.(x_qp), last.(x_qp)) - M.arrows!(ax, first.(x_qp), last.(x_qp), first.(v), last.(v); lengthscale=0.25) -end -fig2 \ No newline at end of file From d322caf189e3ac3ae9e74ee4e5828dc8e836c619 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 13:54:57 +0200 Subject: [PATCH 043/145] Rename back and re-add docstrings --- .../{CellValues.jl => cell_values.jl} | 33 +++++++++++++++++++ .../{FaceValues.jl => face_values.jl} | 33 +++++++++++++++++++ 2 files changed, 66 insertions(+) rename src/FEValues/{CellValues.jl => cell_values.jl} (73%) rename src/FEValues/{FaceValues.jl => face_values.jl} (86%) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/cell_values.jl similarity index 73% rename from src/FEValues/CellValues.jl rename to src/FEValues/cell_values.jl index bad4d4b093..2bf29cc797 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/cell_values.jl @@ -1,3 +1,36 @@ +""" + CellValues([::Type{T},] quad_rule::QuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation]) + +A `CellValues` object facilitates the process of evaluating values of shape functions, gradients of shape functions, +values of nodal functions, gradients and divergences of nodal functions etc. in the finite element cell. + +**Arguments:** +* `T`: an optional argument (default to `Float64`) to determine the type the internal data is stored as. +* `quad_rule`: an instance of a [`QuadratureRule`](@ref) +* `func_interpol`: an instance of an [`Interpolation`](@ref) used to interpolate the approximated function +* `geom_interpol`: an optional instance of a [`Interpolation`](@ref) which is used to interpolate the geometry. + By default linear Lagrange interpolation is used. For embedded elements the geometric interpolations should + be vectorized to the spatial dimension. + +**Common methods:** + +* [`reinit!`](@ref) +* [`getnquadpoints`](@ref) +* [`getdetJdV`](@ref) + +* [`shape_value`](@ref) +* [`shape_gradient`](@ref) +* [`shape_symmetric_gradient`](@ref) +* [`shape_divergence`](@ref) + +* [`function_value`](@ref) +* [`function_gradient`](@ref) +* [`function_symmetric_gradient`](@ref) +* [`function_divergence`](@ref) +* [`spatial_coordinate`](@ref) +""" +CellValues + function default_geometric_interpolation(::Interpolation{shape}) where {dim, shape <: AbstractRefShape{dim}} return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) end diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/face_values.jl similarity index 86% rename from src/FEValues/FaceValues.jl rename to src/FEValues/face_values.jl index e922e0759b..9aea41af06 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/face_values.jl @@ -1,3 +1,36 @@ +""" + FaceValues([::Type{T}], quad_rule::FaceQuadratureRule, func_interpol::Interpolation, [geom_interpol::Interpolation]) + +A `FaceValues` object facilitates the process of evaluating values of shape functions, gradients of shape functions, +values of nodal functions, gradients and divergences of nodal functions etc. on the faces of finite elements. + +**Arguments:** + +* `T`: an optional argument to determine the type the internal data is stored as. +* `quad_rule`: an instance of a [`FaceQuadratureRule`](@ref) +* `func_interpol`: an instance of an [`Interpolation`](@ref) used to interpolate the approximated function +* `geom_interpol`: an optional instance of an [`Interpolation`](@ref) which is used to interpolate the geometry. + By default linear Lagrange interpolation is used. + +**Common methods:** + +* [`reinit!`](@ref) +* [`getnquadpoints`](@ref) +* [`getdetJdV`](@ref) + +* [`shape_value`](@ref) +* [`shape_gradient`](@ref) +* [`shape_symmetric_gradient`](@ref) +* [`shape_divergence`](@ref) + +* [`function_value`](@ref) +* [`function_gradient`](@ref) +* [`function_symmetric_gradient`](@ref) +* [`function_divergence`](@ref) +* [`spatial_coordinate`](@ref) +""" +FaceValues + struct FaceValues{FV, GV, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GV<:AbstractVector{GV}} <: AbstractFaceValues fun_values::V_FV # AbstractVector{FunctionValues} geo_values::V_GV # AbstractVector{GeometryValues} From 8384d01b898a62c7becb2f30b327edfc1947e184 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 13:55:37 +0200 Subject: [PATCH 044/145] Remove CairoMakie from docs --- docs/Manifest.toml | 607 +-------------------------------------------- docs/Project.toml | 1 - 2 files changed, 5 insertions(+), 603 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 52fe3bffa6..08e315defd 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.9.2" manifest_format = "2.0" -project_hash = "f4ba79c26c9d5fa21c707a95d5a76911eedc0ccf" +project_hash = "8722b6a67abf1b81e2c7808ddfcfb1d737cd0040" [[deps.ADTypes]] git-tree-sha1 = "5d2e21d7b0d8c22f67483ef95ebdc39c0e6b6003" @@ -14,22 +14,6 @@ git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" version = "0.0.1" -[[deps.AbstractFFTs]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.5.0" -weakdeps = ["ChainRulesCore", "Test"] - - [deps.AbstractFFTs.extensions] - AbstractFFTsChainRulesCoreExt = "ChainRulesCore" - AbstractFFTsTestExt = "Test" - -[[deps.AbstractLattices]] -git-tree-sha1 = "f35684b7349da49fcc8a9e520e30e45dbb077166" -uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" -version = "0.2.1" - [[deps.AbstractTrees]] git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" @@ -45,12 +29,6 @@ weakdeps = ["StaticArrays"] [deps.Adapt.extensions] AdaptStaticArraysExt = "StaticArrays" -[[deps.Animations]] -deps = ["Colors"] -git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" -uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" -version = "0.4.1" - [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" version = "1.1.1" @@ -102,24 +80,6 @@ weakdeps = ["SparseArrays"] [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" -[[deps.Automa]] -deps = ["TranscodingStreams"] -git-tree-sha1 = "ef9997b3d5547c48b41c7bd8899e812a917b409d" -uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "0.8.4" - -[[deps.AxisAlgorithms]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] -git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "1.0.1" - -[[deps.AxisArrays]] -deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] -git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" -uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.4.7" - [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" @@ -163,56 +123,18 @@ git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" version = "1.0.8+0" -[[deps.CEnum]] -git-tree-sha1 = "eb4cb44a499229b3b8426dcfb5dd85333951ff90" -uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.4.2" - [[deps.CPUSummary]] deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" version = "0.2.4" -[[deps.CRC32c]] -uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" - -[[deps.CRlibm]] -deps = ["CRlibm_jll"] -git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" -uuid = "96374032-68de-5a5b-8d9e-752f78720389" -version = "1.0.1" - -[[deps.CRlibm_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" -uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" -version = "1.0.1+0" - -[[deps.Cairo]] -deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] -git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b" -uuid = "159f3aea-2a34-519c-b102-8c37f9878175" -version = "1.0.5" - -[[deps.CairoMakie]] -deps = ["Base64", "Cairo", "Colors", "FFTW", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools", "SHA"] -git-tree-sha1 = "74384dc4aba2b377e22703e849154252930c434d" -uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.10.11" - [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" version = "1.16.1+1" -[[deps.Calculus]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.5.1" - [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra", "SparseArrays"] git-tree-sha1 = "e30f2f4e20f7f186dc36529910beaedc60cfa644" @@ -231,12 +153,6 @@ git-tree-sha1 = "02aa26a4cf76381be7f66e020a3eddeb27b0a092" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" version = "0.7.2" -[[deps.ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" @@ -261,11 +177,6 @@ git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.12.10" -[[deps.Combinatorics]] -git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "1.0.2" - [[deps.CommonSolve]] git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" @@ -308,12 +219,15 @@ deps = ["LinearAlgebra"] git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" version = "1.5.4" -weakdeps = ["IntervalSets", "StaticArrays"] [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" ConstructionBaseStaticArraysExt = "StaticArrays" + [deps.ConstructionBase.weakdeps] + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + [[deps.Contour]] git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" @@ -345,12 +259,6 @@ version = "1.0.0" deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" -[[deps.DelaunayTriangulation]] -deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] -git-tree-sha1 = "bea7984f7e09aeb28a3b071c420a0186cb4fabad" -uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "0.8.8" - [[deps.DelimitedFiles]] deps = ["Mmap"] git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" @@ -414,20 +322,6 @@ weakdeps = ["ChainRulesCore", "SparseArrays"] deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" -[[deps.Distributions]] -deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "3d5873f811f582873bb9871fc9c451784d5dc8c7" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.102" - - [deps.Distributions.extensions] - DistributionsChainRulesCoreExt = "ChainRulesCore" - DistributionsDensityInterfaceExt = "DensityInterface" - - [deps.Distributions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" - [[deps.DocStringExtensions]] deps = ["LibGit2"] git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" @@ -451,18 +345,6 @@ deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" -[[deps.DualNumbers]] -deps = ["Calculus", "NaNMath", "SpecialFunctions"] -git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" -uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" -version = "0.6.8" - -[[deps.EarCut_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" -uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" -version = "2.2.4+0" - [[deps.EnumX]] git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" @@ -480,17 +362,6 @@ git-tree-sha1 = "8e9441ee83492030ace98f9789a654a6d0b1f643" uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" version = "0.0.20230411+0" -[[deps.ErrorfreeArithmetic]] -git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" -uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" -version = "0.5.2" - -[[deps.ExactPredicates]] -deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] -git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" -uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" -version = "2.2.5" - [[deps.ExceptionUnwrapping]] deps = ["Test"] git-tree-sha1 = "e90caa41f5a86296e014e148ee061bd6c3edec96" @@ -514,11 +385,6 @@ git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" version = "0.1.10" -[[deps.Extents]] -git-tree-sha1 = "5e1e4c53fa39afe63a7d356e30452249365fba99" -uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.1" - [[deps.FFMPEG]] deps = ["FFMPEG_jll"] git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8" @@ -531,18 +397,6 @@ git-tree-sha1 = "74faea50c1d007c85837327f6775bea60b5492dd" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" version = "4.4.2+2" -[[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "b4fbdd20c889804969571cc589900803edda16b7" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.7.1" - -[[deps.FFTW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" -uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.10+0" - [[deps.FLTK_jll]] deps = ["Artifacts", "Fontconfig_jll", "FreeType2_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll", "Xorg_libXfixes_jll", "Xorg_libXft_jll", "Xorg_libXinerama_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] git-tree-sha1 = "72a4842f93e734f378cf381dae2ca4542f019d23" @@ -566,12 +420,6 @@ git-tree-sha1 = "b12f05108e405dadcc2aff0008db7f831374e051" uuid = "29a986be-02c6-4525-aec4-84b980013641" version = "2.0.0" -[[deps.FastRounding]] -deps = ["ErrorfreeArithmetic", "LinearAlgebra"] -git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" -uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" -version = "0.3.1" - [[deps.Ferrite]] deps = ["EnumX", "LinearAlgebra", "NearestNeighbors", "Preferences", "Reexport", "SparseArrays", "StaticArrays", "Tensors", "WriteVTK"] path = ".." @@ -662,24 +510,12 @@ weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] ForwardDiffStaticArraysExt = "StaticArrays" -[[deps.FreeType]] -deps = ["CEnum", "FreeType2_jll"] -git-tree-sha1 = "50351f83f95282cf903e968d7c6e8d44a5f83d0b" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "4.1.0" - [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" version = "2.13.1+0" -[[deps.FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] -git-tree-sha1 = "38a92e40157100e796690421e34a11c107205c86" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.0" - [[deps.FriBidi_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" @@ -742,18 +578,6 @@ git-tree-sha1 = "fb69b2a645fa69ba5f474af09221b9308b160ce6" uuid = "c145ed77-6b09-5dd9-b285-bf645a82121e" version = "0.5.3" -[[deps.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "d53480c0793b13341c40199190f92c611aa2e93c" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.2" - -[[deps.GeometryBasics]] -deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "424a5a6ce7c5d97cca7bcc4eac551b97294c54af" -uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.4.9" - [[deps.Gettext_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" @@ -772,12 +596,6 @@ git-tree-sha1 = "4d4dedef84147934837c683538467cea54c44d44" uuid = "705231aa-382f-11e9-3f0c-b7cb4346fdeb" version = "0.2.2" -[[deps.Graphics]] -deps = ["Colors", "LinearAlgebra", "NaNMath"] -git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" -uuid = "a2bd30eb-e257-5431-a919-1863eab51364" -version = "1.1.2" - [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" @@ -790,12 +608,6 @@ git-tree-sha1 = "899050ace26649433ef1af25bc17a815b3db52b7" uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" version = "1.9.0" -[[deps.GridLayoutBase]] -deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" -uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.9.2" - [[deps.Grisu]] git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" @@ -825,12 +637,6 @@ git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" version = "0.1.16" -[[deps.HypergeometricFunctions]] -deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" -uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.23" - [[deps.IOCapture]] deps = ["Logging", "Random"] git-tree-sha1 = "d75853a0bdbfb1ac815478bacd89cd27b550ace6" @@ -842,57 +648,11 @@ git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" version = "0.1.1" -[[deps.ImageAxes]] -deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] -git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" -uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -version = "0.6.11" - -[[deps.ImageBase]] -deps = ["ImageCore", "Reexport"] -git-tree-sha1 = "b51bb8cae22c66d0f6357e3bcb6363145ef20835" -uuid = "c817782e-172a-44cc-b673-b171935fbb9e" -version = "0.1.5" - -[[deps.ImageCore]] -deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"] -git-tree-sha1 = "acf614720ef026d38400b3817614c45882d75500" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.9.4" - -[[deps.ImageIO]] -deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] -git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" -uuid = "82e4d734-157c-48bb-816b-45c225c6df19" -version = "0.6.7" - -[[deps.ImageMetadata]] -deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] -git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" -uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" -version = "0.9.9" - -[[deps.Imath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" -uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" -version = "3.1.7+0" - -[[deps.IndirectArrays]] -git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" -uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" -version = "1.0.0" - [[deps.Inflate]] git-tree-sha1 = "5cd07aab533df5170988219191dfad0519391428" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" version = "0.1.3" -[[deps.IntegerMathUtils]] -git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" -uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" -version = "0.1.2" - [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "ad37c091f7d7daf900963171600d7c1c5c3ede32" @@ -903,44 +663,11 @@ version = "2023.2.0+0" deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" -[[deps.Interpolations]] -deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "721ec2cf720536ad005cb38f50dbba7b02419a15" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.14.7" - -[[deps.IntervalArithmetic]] -deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] -git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" -uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.20.9" - -[[deps.IntervalSets]] -deps = ["Dates", "Random"] -git-tree-sha1 = "8e59ea773deee525c99a8018409f64f19fb719e6" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.7" -weakdeps = ["Statistics"] - - [deps.IntervalSets.extensions] - IntervalSetsStatisticsExt = "Statistics" - [[deps.IrrationalConstants]] git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" version = "0.2.2" -[[deps.Isoband]] -deps = ["isoband_jll"] -git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" -uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" -version = "0.1.1" - -[[deps.IterTools]] -git-tree-sha1 = "4ced6667f9974fc5c5943fa5e2ef1ca43ea9e450" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.8.0" - [[deps.IterativeSolvers]] deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] git-tree-sha1 = "1169632f425f79429f245113b775a0e3d121457c" @@ -982,12 +709,6 @@ git-tree-sha1 = "5f0bd0cd69df978fa64ccdcb5c152fbc705455a1" uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692" version = "1.3.0" -[[deps.JpegTurbo]] -deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] -git-tree-sha1 = "d65930fa2bc96b07d7691c652d701dcbe7d9cf0b" -uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" -version = "0.1.4" - [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "6f2675ef130a300a112286de91973805fcc5ffbc" @@ -1000,12 +721,6 @@ git-tree-sha1 = "884c2968c2e8e7e6bf5956af88cb46aa745c854b" uuid = "ef3ab10e-7fda-4108-b977-705223b18434" version = "0.4.1" -[[deps.KernelDensity]] -deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "90442c50e202a5cdf21a7899c66b240fdef14035" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.7" - [[deps.Krylov]] deps = ["LinearAlgebra", "Printf", "SparseArrays"] git-tree-sha1 = "17e462054b42dcdda73e9a9ba0c67754170c88ae" @@ -1076,11 +791,6 @@ version = "0.15.1" deps = ["Artifacts", "Pkg"] uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" -[[deps.LazyModules]] -git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" -uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" -version = "0.3.1" - [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" @@ -1167,12 +877,6 @@ version = "7.2.0" deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -[[deps.LinearAlgebraX]] -deps = ["LinearAlgebra", "Mods", "Permutations", "Primes", "SimplePolynomials"] -git-tree-sha1 = "558a338f1eeabe933f9c2d4052aa7c2c707c3d52" -uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" -version = "0.1.12" - [[deps.LinearElasticity_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "71e8ee0f9fe0e86a8f8c7f28361e5118eab2f93f" @@ -1284,28 +988,11 @@ git-tree-sha1 = "9ee1618cbf5240e6d4e0371d6f24065083f60c48" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.11" -[[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "1d16d20279a145119899b4205258332f0fbeaa94" -uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.19.11" - -[[deps.MakieCore]] -deps = ["Observables", "REPL"] -git-tree-sha1 = "a94bf3fef9c690a2a4ac1d09d86a59ab89c7f8e4" -uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.6.8" - [[deps.ManualMemory]] git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" version = "0.1.8" -[[deps.MappedArrays]] -git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.2" - [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" @@ -1316,17 +1003,6 @@ git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" version = "0.1.2" -[[deps.Match]] -git-tree-sha1 = "1d9bc5c1a6e7ee24effb93f175c9342f9154d97f" -uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf" -version = "1.2.0" - -[[deps.MathTeXEngine]] -deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "Test", "UnicodeFun"] -git-tree-sha1 = "8f52dbaa1351ce4cb847d95568cb29e62a307d93" -uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.5.6" - [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "Random", "Sockets"] git-tree-sha1 = "03a9b9718f5682ecb107ac9f7308991db4ce395b" @@ -1352,17 +1028,6 @@ version = "1.1.0" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" -[[deps.Mods]] -git-tree-sha1 = "61be59e4daffff43a8cec04b5e0dc773cbb5db3a" -uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" -version = "1.3.3" - -[[deps.MosaicViews]] -deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] -git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" -uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" -version = "0.3.4" - [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2022.10.11" @@ -1372,11 +1037,6 @@ git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" version = "0.2.4" -[[deps.Multisets]] -git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" -uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" -version = "0.4.4" - [[deps.NLSolversBase]] deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" @@ -1401,12 +1061,6 @@ git-tree-sha1 = "2c3726ceb3388917602169bed973dbc97f1b51a8" uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" version = "0.4.13" -[[deps.Netpbm]] -deps = ["FileIO", "ImageCore", "ImageMetadata"] -git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" -uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" -version = "1.1.1" - [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" @@ -1423,11 +1077,6 @@ git-tree-sha1 = "acc8099ae8ed10226dc8424fb256ec9fe367a1f0" uuid = "baad4e97-8daa-5946-aac2-2edac59d34e1" version = "7.6.2+2" -[[deps.Observables]] -git-tree-sha1 = "6862738f9796b3edc1c09d0890afce4eca9e7e93" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.5.4" - [[deps.OffsetArrays]] deps = ["Adapt"] git-tree-sha1 = "2ac17d29c523ce1cd38e27785a7d23024853a4bb" @@ -1445,18 +1094,6 @@ deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" version = "0.3.21+4" -[[deps.OpenEXR]] -deps = ["Colors", "FileIO", "OpenEXR_jll"] -git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" -uuid = "52e1d378-f018-4a11-a4be-720524705ac7" -version = "0.3.2" - -[[deps.OpenEXR_jll]] -deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" -uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.1.4+0" - [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" @@ -1508,42 +1145,12 @@ deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" version = "10.42.0+0" -[[deps.PDMats]] -deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "fcf8fd477bd7f33cb8dbb1243653fb0d415c256c" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.25" - -[[deps.PNGFiles]] -deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] -git-tree-sha1 = "9b02b27ac477cad98114584ff964e3052f656a0f" -uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" -version = "0.4.0" - [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" version = "1.0.2" weakdeps = ["Requires", "TOML"] -[[deps.Packing]] -deps = ["GeometryBasics"] -git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.5.0" - -[[deps.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[deps.Pango_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4745216e94f71cb768d58330b059c9b76f32cb66" -uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.50.14+0" - [[deps.Parameters]] deps = ["OrderedCollections", "UnPack"] git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" @@ -1556,12 +1163,6 @@ git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.7.2" -[[deps.Permutations]] -deps = ["Combinatorics", "LinearAlgebra", "Random"] -git-tree-sha1 = "25e2bb0973689836bf164ecb960762f1bb8794dd" -uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" -version = "0.4.17" - [[deps.Pipe]] git-tree-sha1 = "6842804e7867b115ca9de748a0cf6b364523c16d" uuid = "b98c9c47-44ae-5843-9183-064241ee97a0" @@ -1578,12 +1179,6 @@ deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", " uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" version = "1.9.2" -[[deps.PkgVersion]] -deps = ["Pkg"] -git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" -uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.3" - [[deps.PlotThemes]] deps = ["PlotUtils", "Statistics"] git-tree-sha1 = "1f03a2d339f42dca4a4da149c7e15e9b896ad899" @@ -1628,29 +1223,6 @@ git-tree-sha1 = "240d7170f5ffdb285f9427b92333c3463bf65bf6" uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" version = "0.2.1" -[[deps.PolygonOps]] -git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" -uuid = "647866c9-e3ac-4575-94e7-e3d426903924" -version = "0.1.2" - -[[deps.Polynomials]] -deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "ea78a2764f31715093de7ab495e12c0187f231d1" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "4.0.4" - - [deps.Polynomials.extensions] - PolynomialsChainRulesCoreExt = "ChainRulesCore" - PolynomialsFFTWExt = "FFTW" - PolynomialsMakieCoreExt = "MakieCore" - PolynomialsMutableArithmeticsExt = "MutableArithmetics" - - [deps.Polynomials.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" - MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" - MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" - [[deps.PositiveFactorizations]] deps = ["LinearAlgebra"] git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" @@ -1681,12 +1253,6 @@ git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.1" -[[deps.Primes]] -deps = ["IntegerMathUtils"] -git-tree-sha1 = "4c9f306e5d6603ae203c2000dd460d81a5251489" -uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.5.4" - [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" @@ -1697,24 +1263,12 @@ git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" uuid = "92933f4c-e287-5a05-a399-4b506db050ca" version = "1.9.0" -[[deps.QOI]] -deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] -git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" -uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" -version = "1.0.0" - [[deps.Qt6Base_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] git-tree-sha1 = "7c29f0e8c575428bd84dc3c72ece5178caa67336" uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" version = "6.5.2+2" -[[deps.QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9ebcd48c498668c7fa0e97a9cae873fbee7bfee1" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.9.1" - [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" @@ -1723,21 +1277,6 @@ uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" deps = ["SHA", "Serialization"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -[[deps.RangeArrays]] -git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" -uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" -version = "0.3.2" - -[[deps.Ratios]] -deps = ["Requires"] -git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.4.5" -weakdeps = ["FixedPointNumbers"] - - [deps.Ratios.extensions] - RatiosFixedPointNumbersExt = "FixedPointNumbers" - [[deps.RecipesBase]] deps = ["PrecompileTools"] git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" @@ -1797,29 +1336,6 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" -[[deps.RingLists]] -deps = ["Random"] -git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" -uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" -version = "0.2.8" - -[[deps.Rmath]] -deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.7.1" - -[[deps.Rmath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.0+0" - -[[deps.RoundingEmulator]] -git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" -uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" -version = "0.2.1" - [[deps.RuntimeGeneratedFunctions]] deps = ["ExprTools", "SHA", "Serialization"] git-tree-sha1 = "6aacc5eefe8415f47b3e34214c1d79d2674a0ba2" @@ -1892,23 +1408,12 @@ version = "1.2.0" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -[[deps.SetRounding]] -git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" -uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" -version = "0.2.1" - [[deps.Setfield]] deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" version = "1.1.1" -[[deps.ShaderAbstractions]] -deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "db0219befe4507878b1a90e07820fed3e62c289d" -uuid = "65257c39-d410-5151-9873-9b3e5be5013e" -version = "0.4.0" - [[deps.SharedArrays]] deps = ["Distributed", "Mmap", "Random", "Serialization"] uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" @@ -1919,23 +1424,11 @@ git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" version = "1.0.3" -[[deps.SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - [[deps.SimpleBufferStream]] git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" version = "1.1.0" -[[deps.SimpleGraphs]] -deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] -git-tree-sha1 = "b608903049d11cc557c45e03b3a53e9260579c19" -uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" -version = "0.8.4" - [[deps.SimpleNonlinearSolve]] deps = ["ArrayInterface", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "PackageExtensionCompat", "PrecompileTools", "Reexport", "SciMLBase", "StaticArraysCore"] git-tree-sha1 = "4d53b83af904049c493daaf2a225bcae994a3c59" @@ -1948,24 +1441,6 @@ version = "0.1.20" [deps.SimpleNonlinearSolve.weakdeps] NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" -[[deps.SimplePartitions]] -deps = ["AbstractLattices", "DataStructures", "Permutations"] -git-tree-sha1 = "dcc02923a53f316ab97da8ef3136e80b4543dbf1" -uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" -version = "0.3.0" - -[[deps.SimplePolynomials]] -deps = ["Mods", "Multisets", "Polynomials", "Primes"] -git-tree-sha1 = "d537c31cf9995236166e3e9afc424a5a1c59ff9d" -uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" -version = "0.2.14" - -[[deps.SimpleRandom]] -deps = ["Distributions", "LinearAlgebra", "Random"] -git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" -uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" -version = "0.3.1" - [[deps.SimpleTraits]] deps = ["InteractiveUtils", "MacroTools"] git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" @@ -1977,12 +1452,6 @@ git-tree-sha1 = "58e6353e72cde29b90a69527e56df1b5c3d8c437" uuid = "ce78b400-467f-4804-87d8-8f486da07d0a" version = "1.1.0" -[[deps.Sixel]] -deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] -git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" -uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" -version = "0.1.3" - [[deps.SnoopPrecompile]] deps = ["Preferences"] git-tree-sha1 = "e760a70afdcd461cf01a575947738d359234665c" @@ -2034,18 +1503,6 @@ weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" -[[deps.StableHashTraits]] -deps = ["Compat", "SHA", "Tables", "TupleTools"] -git-tree-sha1 = "19df33ca14f24a3ad2df9e89124bd5f5cc8467a2" -uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" -version = "1.0.1" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.1" - [[deps.Static]] deps = ["IfElse"] git-tree-sha1 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" @@ -2095,20 +1552,6 @@ git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" version = "0.34.2" -[[deps.StatsFuns]] -deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.3.0" - - [deps.StatsFuns.extensions] - StatsFunsChainRulesCoreExt = "ChainRulesCore" - StatsFunsInverseFunctionsExt = "InverseFunctions" - - [deps.StatsFuns.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - [[deps.StrideArraysCore]] deps = ["ArrayInterface", "CloseOpenIntervals", "IfElse", "LayoutPointers", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface", "ThreadingUtilities"] git-tree-sha1 = "f02eb61eb5c97b48c153861c72fbbfdddc607e06" @@ -2121,12 +1564,6 @@ git-tree-sha1 = "b765e46ba27ecf6b44faf70df40c57aa3a547dcb" uuid = "69024149-9ee7-55f6-a4c4-859efe599b68" version = "0.3.7" -[[deps.StructArrays]] -deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.16" - [[deps.StructTypes]] deps = ["Dates", "UUIDs"] git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" @@ -2194,12 +1631,6 @@ git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" version = "0.5.2" -[[deps.TiffImages]] -deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] -git-tree-sha1 = "7fd97bd1c5b1ff53a291cbd351d1d3d6ff4da5a5" -uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.6.7" - [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" @@ -2223,22 +1654,12 @@ git-tree-sha1 = "aadb748be58b492045b4f56166b5188aa63ce549" uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" version = "0.1.7" -[[deps.TriplotBase]] -git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" -uuid = "981d1d27-644d-49a2-9326-4793e63143c3" -version = "0.1.0" - [[deps.TruncatedStacktraces]] deps = ["InteractiveUtils", "MacroTools", "Preferences"] git-tree-sha1 = "ea3e54c2bdde39062abf5a9758a23735558705e1" uuid = "781d530d-4396-4725-bb49-402e4bee1e77" version = "1.4.0" -[[deps.TupleTools]] -git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" -uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" -version = "1.4.3" - [[deps.URIs]] git-tree-sha1 = "b7a5e99f24892b6824a954199a45e9ffcc1c70f0" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" @@ -2322,12 +1743,6 @@ git-tree-sha1 = "4528479aa01ee1b3b4cd0e6faef0e04cf16466da" uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91" version = "1.25.0+0" -[[deps.WoodburyMatrices]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "0.5.5" - [[deps.WriteVTK]] deps = ["Base64", "CodecZlib", "FillArrays", "LightXML", "TranscodingStreams", "VTKBase"] git-tree-sha1 = "7b46936613e41cfe1c6a5897d243ddcab8feabec" @@ -2549,12 +1964,6 @@ git-tree-sha1 = "3516a5630f741c9eecb3720b1ec9d8edc3ecc033" uuid = "1a1c6b14-54f6-533d-8383-74cd7377aa70" version = "3.1.1+0" -[[deps.isoband_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" -uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" -version = "0.2.3+0" - [[deps.libaom_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" @@ -2596,12 +2005,6 @@ git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" version = "1.6.38+0" -[[deps.libsixel_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] -git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" -uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" -version = "1.10.3+0" - [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" diff --git a/docs/Project.toml b/docs/Project.toml index 92114eb028..876724cc7f 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,6 +1,5 @@ [deps] BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" -CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244" Ferrite = "c061ca5d-56c9-439f-9c0e-210fe06d3992" From 97eebbebc9820821e4e2104f40ad6bd55e6734d8 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 14:56:45 +0200 Subject: [PATCH 045/145] Add better error message if sdim don't match during reinit --- src/FEValues/FunctionValues.jl | 26 +++++++++++++++++++++++++- src/FEValues/GeometryValues.jl | 1 - src/FEValues/cell_values.jl | 9 ++++++--- src/FEValues/face_values.jl | 1 + src/Ferrite.jl | 4 ++-- test/test_cellvalues.jl | 2 ++ test/test_facevalues.jl | 2 ++ 7 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 8f334ccc33..48f2a4e0e3 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -1,4 +1,11 @@ -# Helpers to get the correct types for FunctionValues for the given function and, if needed, geometric interpolations. +################################################################# +# Note on dimensions: # +# sdim = spatial dimension (dimension of the grid nodes) # +# rdim = reference dimension (dimension in isoparametric space) # +# vdim = vector dimension (dimension of the field) # +################################################################# + +# Helpers to get the correct types for FunctionValues for the given function and, if needed, geometric interpolations. struct SInterpolationDims{rdim,sdim} end struct VInterpolationDims{rdim,sdim,vdim} end function InterpolationDims(::ScalarInterpolation, ip_geo::VectorizedInterpolation{sdim}) where sdim @@ -74,6 +81,23 @@ get_function_interpolation(funvals::FunctionValues) = funvals.ip shape_value_type(funvals::FunctionValues) = eltype(funvals.N_x) shape_gradient_type(funvals::FunctionValues) = eltype(funvals.dNdx) + +# Checks that the user provides the right dimension of coordinates to reinit! methods to ensure good error messages if not +sdim_from_gradtype(::Type{<:AbstractTensor{<:Any,sdim}}) where sdim = sdim +sdim_from_gradtype(::Type{<:SVector{sdim}}) where sdim = sdim +sdim_from_gradtype(::Type{<:SMatrix{<:Any,sdim}}) where sdim = sdim + +# For performance, these must be fully inferrable for the compiler. +# args: valname (:CellValues or :FaceValues), shape_gradient_type, eltype(x) +function check_reinit_sdim_consistency(valname, gradtype, ::Type{<:Vec{sdim}}) where {sdim} + check_reinit_sdim_consistency(valname, Val(sdim_from_gradtype(gradtype)), Val(sdim)) +end +check_reinit_sdim_consistency(_, ::Val{sdim}, ::Val{sdim}) where sdim = nothing +function check_reinit_sdim_consistency(valname, ::Val{sdim_val}, ::Val{sdim_x}) where {sdim_val, sdim_x} + error("""The $valname and coordinates have different spatial dimensions, $sdim_val and $sdim_x. + Could it be that you forgot to vectorize the geometric interpolation when constructing the $valname?""") +end + # Mapping types struct IdentityMapping end struct CovariantPiolaMapping end diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryValues.jl index ec47cc6a29..6df8cb639e 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryValues.jl @@ -82,7 +82,6 @@ end @propagate_inbounds calculate_mapping(geovals::GeometryValues, args...) = calculate_mapping(RequiresHessian(geovals), geovals, args...) @inline function calculate_mapping(::RequiresHessian{false}, geo_values::GeometryValues, q_point, x) - #fecv_J = zero(Tensors.getreturntype(⊗, eltype(x), eltype(geo_values.dMdξ))) fecv_J = zero(otimes_returntype(eltype(x), eltype(geo_values.dMdξ))) @inbounds for j in 1:getngeobasefunctions(geo_values) #fecv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] diff --git a/src/FEValues/cell_values.jl b/src/FEValues/cell_values.jl index 2bf29cc797..8c22470612 100644 --- a/src/FEValues/cell_values.jl +++ b/src/FEValues/cell_values.jl @@ -81,6 +81,7 @@ end getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) + check_reinit_sdim_consistency(:CellValues, shape_gradient_type(cv), eltype(x)) geo_values = cv.geo_values fun_values = cv.fun_values n_geom_basefuncs = getngeobasefunctions(geo_values) @@ -98,12 +99,14 @@ function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) end function Base.show(io::IO, d::MIME"text/plain", cv::CellValues) - rdim = getdim(cv.geo_values.ip) + ip_geo = get_geometric_interpolation(cv) + ip_fun = get_function_interpolation(cv) + rdim = getdim(ip_geo) vdim = isa(shape_value(cv, 1, 1), Vec) ? length(shape_value(cv, 1, 1)) : 0 sdim = length(shape_gradient(cv, 1, 1)) ÷ length(shape_value(cv, 1, 1)) vstr = vdim==0 ? "scalar" : "vdim=$vdim" print(io, "CellValues(", vstr, ", rdim=$rdim, and sdim=$sdim): ") print(io, getnquadpoints(cv), " quadrature points") - print(io, "\n Function interpolation: "); show(io, d, cv.fun_values.ip) - print(io, "\nGeometric interpolation: "); show(io, d, cv.geo_values.ip^sdim) + print(io, "\n Function interpolation: "); show(io, d, ip_fun) + print(io, "\nGeometric interpolation: "); show(io, d, ip_geo^sdim) end \ No newline at end of file diff --git a/src/FEValues/face_values.jl b/src/FEValues/face_values.jl index 9aea41af06..ea985af3a7 100644 --- a/src/FEValues/face_values.jl +++ b/src/FEValues/face_values.jl @@ -108,6 +108,7 @@ function checkface(fv::FaceValues, face::Int) end function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, cell=nothing) where {dim, T} + check_reinit_sdim_consistency(:FaceValues, shape_gradient_type(fv), eltype(x)) @boundscheck checkface(fv, face_nr) n_geom_basefuncs = getngeobasefunctions(fv) length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) diff --git a/src/Ferrite.jl b/src/Ferrite.jl index 6965d631ab..419229c993 100644 --- a/src/Ferrite.jl +++ b/src/Ferrite.jl @@ -84,8 +84,8 @@ include("Quadrature/quadrature.jl") # FEValues include("FEValues/GeometryValues.jl") include("FEValues/FunctionValues.jl") -include("FEValues/CellValues.jl") -include("FEValues/FaceValues.jl") +include("FEValues/cell_values.jl") +include("FEValues/face_values.jl") include("PointEval/point_values.jl") include("FEValues/common_values.jl") include("FEValues/face_integrals.jl") diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 9428684f9b..9c59c68e16 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -329,7 +329,9 @@ end cv_quad = CellValues(QuadratureRule{RefQuadrilateral}(2), Lagrange{RefQuadrilateral,2}()^2) cv_wedge = CellValues(QuadratureRule{RefPrism}(2), Lagrange{RefPrism,2}()) show(stdout, MIME"text/plain"(), cv_quad) + println(stdout) show(stdout, MIME"text/plain"(), cv_wedge) + println(stdout) end end # of testset diff --git a/test/test_facevalues.jl b/test/test_facevalues.jl index 5510ccc4a6..f4bb30301f 100644 --- a/test/test_facevalues.jl +++ b/test/test_facevalues.jl @@ -131,9 +131,11 @@ end # Just smoke test to make sure show doesn't error. fv = FaceValues(FaceQuadratureRule{RefQuadrilateral}(2), Lagrange{RefQuadrilateral,2}()) show(stdout, MIME"text/plain"(), fv) + println(stdout) fv.qr.face_rules[1] = deepcopy(fv.qr.face_rules[1]) push!(Ferrite.getweights(fv.qr.face_rules[1]), 1) show(stdout, MIME"text/plain"(), fv) + println(stdout) end end # of testset From 0cee93618b951c988a20eae56e804bef3078cf2f Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 15:05:15 +0200 Subject: [PATCH 046/145] Docfixes --- src/FEValues/common_values.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index dc198f3600..b1c9b5d537 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -30,11 +30,12 @@ end end """ - reinit!(cv::CellValues, x::Vector) - reinit!(bv::FaceValues, x::Vector, face::Int) + reinit!(cv::CellValues, x::Vector, cell::Union{AbstractCell,Nothing}=nothing) + reinit!(bv::FaceValues, x::Vector, face::Int, cell::Union{AbstractCell,Nothing}=nothing) Update the `CellValues`/`FaceValues` object for a cell or face with coordinates `x`. The derivatives of the shape functions, and the new integration weights are computed. +For interpolations with non-identity mappings, the current `cell` is also required. """ reinit! @@ -59,7 +60,7 @@ finite element cell or face as ``\\int\\limits_\\Gamma f(\\mathbf{x}) d \\Gamma \\approx \\sum\\limits_{q = 1}^{n_q} f(\\mathbf{x}_q) \\det(J(\\mathbf{x})) w_q`` """ -#@propagate_inbounds getdetJdV(bv::FaceValues, q_point::Int) = bv.detJdV[q_point, bv.current_face[]] +function getdetJdV end """ shape_value(fe_v::AbstractValues, q_point::Int, base_function::Int) @@ -68,7 +69,6 @@ Return the value of shape function `base_function` evaluated in quadrature point `q_point`. """ function shape_value end -#@propagate_inbounds shape_value(bv::FaceValues, q_point::Int, base_func::Int) = bv.N[base_func, q_point, bv.current_face[]] """ geometric_value(fe_v::AbstractValues, q_point, base_function::Int) From 90ccab1db2bd2d2e2bb93303ea07892bc606a5b8 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 15:11:26 +0200 Subject: [PATCH 047/145] Show check for triangle mesh for the heat equation --- docs/src/literate-tutorials/heat_equation_triangle.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl index fee7ac52b6..bf312ef04a 100644 --- a/docs/src/literate-tutorials/heat_equation_triangle.jl +++ b/docs/src/literate-tutorials/heat_equation_triangle.jl @@ -213,6 +213,8 @@ end @show norm(u)/length(u) +# ### Postprocessing the total flux + function calculate_flux_lag(dh, dΩ, ip, a) qr = FaceQuadratureRule{RefTriangle}(2) fv = FaceValues(qr, ip, Lagrange{RefTriangle,1}()) From 3f6cd9b6827df831c06de083744089906e1c0146 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 15:51:48 +0200 Subject: [PATCH 048/145] Remove benchmark script --- cv_benchmark.jl | 65 ------------------------------------------------- 1 file changed, 65 deletions(-) delete mode 100644 cv_benchmark.jl diff --git a/cv_benchmark.jl b/cv_benchmark.jl deleted file mode 100644 index db5870c996..0000000000 --- a/cv_benchmark.jl +++ /dev/null @@ -1,65 +0,0 @@ -using Ferrite, BenchmarkTools, StaticArrays - -function get_values(CellType, ::Val{dim}, q_order=2) where dim - grid = generate_grid(CellType, ntuple(_->2, dim)) - ip = Ferrite.default_interpolation(getcelltype(grid)) - RefShape = Ferrite.getrefshape(ip) - qr = QuadratureRule{RefShape}(q_order) - cv_u = CellValues(qr, ip^dim, ip) - cv_p = CellValues(qr, ip, ip) - return cv_u, cv_p, getcoordinates(grid, 1) -end - -function reinit_masterfix!(cv::Ferrite.OldCellValues{<:Any, <:Any, <:Tensor, <:Tensor, T, Vec{dim,T}}, x::AbstractVector{Vec{dim,T}}) where {dim, T} - n_geom_basefuncs = Ferrite.getngeobasefunctions(cv) - n_func_basefuncs = Ferrite.getnbasefunctions(cv) - length(x) == n_geom_basefuncs || Ferrite.throw_incompatible_coord_length(length(x), n_geom_basefuncs) - - @inbounds for (i, w) in pairs(getweights(cv.qr)) - fecv_J = zero(Tensor{2,dim,T}) - for j in 1:n_geom_basefuncs - fecv_J += x[j] ⊗ cv.dMdξ[j, i] - end - detJ = det(fecv_J) - detJ > 0.0 || Ferrite.throw_detJ_not_pos(detJ) - cv.detJdV[i] = detJ * w - Jinv = inv(fecv_J) - for j in 1:n_func_basefuncs - # cv.dNdx[j, i] = cv.dNdξ[j, i] ⋅ Jinv - cv.dNdx[j, i] = Ferrite.dothelper(cv.dNdξ[j, i], Jinv) - end - end -end - -#for (CT, dim) in ((Triangle,2), (QuadraticTriangle,2), (Hexahedron,3), (Tetrahedron,3)) -for (CT, dim) in ((Triangle,2),) - # 2 and 4 fields in 2D - cv_u, cv_p, x = get_values(CT, Val(dim), 2) - ocv_u = Ferrite.OldCellValues(cv_u) - ocv_p = Ferrite.OldCellValues(cv_p) - - print("Scalar : $CT in $(dim)D"); println() - print("1 PR : "); @btime reinit!($cv_p, $x); - print("1 master : "); @btime reinit!($ocv_p, $x); - print("1 master (fix): "); @btime reinit_masterfix!($ocv_p, $x); - - print("Vector : $CT in $(dim)D"); println() - print("1 PR : "); @btime reinit!($cv_u, $x); - print("1 master : "); @btime reinit!($ocv_u, $x); - print("1 master (fix): "); @btime reinit_masterfix!($ocv_u, $x); - # =# - #= - println() - print("2 CellValues : "); @btime reinit2!($cv_u, $cv_p, $x) - print("2 MultiCellValues : "); @btime reinit!($mcv_pu, $x) - print("2 MultiCellValues2 : "); @btime reinit!($mcv2_pu, $x) - println() - # =# - #= - print("4 CellValues : "); @btime reinit4!($cv_u, $cv_p, $cv_u2, $cv_p2, $x) - print("4 MultiValues : "); @btime reinit!($cv4, $x) - print("4 Tuple{CV} : "); @btime reinit_multiple!($x, $cv_u, $cv_p, $cv_u2, $cv_p2) - print("4 ValuesGroup : "); @btime reinit!($cvg4, $x); - println() - # =# -end \ No newline at end of file From 3aad963b0726571052c10053e91415bdd207aa0a Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 8 Oct 2023 18:39:24 +0200 Subject: [PATCH 049/145] Generalize example to try with 2nd order Lagrange --- .../literate-tutorials/heat_equation_rt.jl | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl index 8ff5f2d75c..4679cfa4f4 100644 --- a/docs/src/literate-tutorials/heat_equation_rt.jl +++ b/docs/src/literate-tutorials/heat_equation_rt.jl @@ -45,6 +45,7 @@ using Ferrite, SparseArrays # We start by generating a simple grid with 20x20 quadrilateral elements # using `generate_grid`. The generator defaults to the unit square, # so we don't need to specify the corners of the domain. +#grid = generate_grid(QuadraticTriangle, (20, 20)); grid = generate_grid(Triangle, (20, 20)); # ### Trial and test functions @@ -55,8 +56,8 @@ grid = generate_grid(Triangle, (20, 20)); # based on the two-dimensional reference quadrilateral. We also define a quadrature rule based on # the same reference element. We combine the interpolation and the quadrature rule # to a `CellValues` object. -ip_geo = Lagrange{RefTriangle, 1}() -ipu = Lagrange{RefTriangle, 1}() +ip_geo = Ferrite.default_interpolation(getcelltype(grid)) +ipu = Lagrange{RefTriangle, 1}() # Why does it "explode" for 2nd order ipu? ipq = RaviartThomas{2,RefTriangle,1}() qr = QuadratureRule{RefTriangle}(2) cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) @@ -150,12 +151,12 @@ function assemble_element!(Ke::Matrix, fe::Vector, cv::NamedTuple, dr::NamedTupl δu = shape_value(cvu, q_point, iu) ∇δu = shape_gradient(cvu, q_point, iu) ## Add contribution to fe - fe[Iu] += δu * dΩ + fe[Iu] -= δu * dΩ ## Loop over trial shape functions for (jq, Jq) in pairs(drq) q = shape_value(cvq, q_point, jq) ## Add contribution to Ke - Ke[Iu, Jq] -= (∇δu ⋅ q) * dΩ + Ke[Iu, Jq] += (∇δu ⋅ q) * dΩ end end for (iq, Iq) in pairs(drq) @@ -192,6 +193,7 @@ end # connection between the weak form and the Ferrite implementation. function assemble_global(cellvalues, K::SparseMatrixCSC, dh::DofHandler) + grid = dh.grid ## Allocate the element stiffness matrix and element force vector dofranges = (u = dof_range(dh, :u), q = dof_range(dh, :q)) ncelldofs = ndofs_per_cell(dh) @@ -201,12 +203,12 @@ function assemble_global(cellvalues, K::SparseMatrixCSC, dh::DofHandler) f = zeros(ndofs(dh)) ## Create an assembler assembler = start_assemble(K, f) - x = copy(getcoordinates(dh.grid, 1)) + x = copy(getcoordinates(grid, 1)) dofs = copy(celldofs(dh, 1)) ## Loop over all cels - for cellnr in 1:getncells(dh.grid) + for cellnr in 1:getncells(grid) ## Reinitialize cellvalues for this cell - cell = getcells(dh.grid, cellnr) + cell = getcells(grid, cellnr) getcoordinates!(x, grid, cell) celldofs!(dofs, dh, cellnr) reinit!(cellvalues[:u], x, cell) @@ -251,9 +253,11 @@ end # ## Postprocess the total flux function calculate_flux(dh, dΩ, ip, a) - qr = FaceQuadratureRule{RefTriangle}(4) - fv = FaceValues(qr, ip, Lagrange{RefTriangle,1}()) grid = dh.grid + qr = FaceQuadratureRule{RefTriangle}(4) + ip_geo = Ferrite.default_interpolation(getcelltype(grid)) + fv = FaceValues(qr, ip, ip_geo) + dofrange = dof_range(dh, :q) flux = 0.0 dofs = celldofs(dh, 1) @@ -276,9 +280,10 @@ function calculate_flux(dh, dΩ, ip, a) end function calculate_flux_lag(dh, dΩ, ip, a) - qr = FaceQuadratureRule{RefTriangle}(4) - fv = FaceValues(qr, ip, Lagrange{RefTriangle,1}()) grid = dh.grid + qr = FaceQuadratureRule{RefTriangle}(4) + ip_geo = Ferrite.default_interpolation(getcelltype(grid)) + fv = FaceValues(qr, ip, ip_geo) dofrange = dof_range(dh, :u) flux = 0.0 dofs = celldofs(dh, 1) @@ -303,6 +308,25 @@ end flux = calculate_flux(dh, ∂Ω, ipq, u) flux_lag = calculate_flux_lag(dh, ∂Ω, ipu, u) @show flux, flux_lag + + +function get_Ke(dh, cellvalues; cellnr=1) + dofranges = (u = dof_range(dh, :u), q = dof_range(dh, :q)) + ncelldofs = ndofs_per_cell(dh) + Ke = zeros(ncelldofs, ncelldofs) + fe = zeros(ncelldofs) + x = getcoordinates(grid, cellnr) + cell = getcells(grid, cellnr) + reinit!(cellvalues[:u], x, cell) + reinit!(cellvalues[:q], x, cell) + + ## Reset to 0 + fill!(Ke, 0) + fill!(fe, 0) + ## Compute element contribution + assemble_element!(Ke, fe, cellvalues, dofranges) + return Ke +end #md # ## [Plain program](@id heat_equation-plain-program) #md # #md # Here follows a version of the program without any comments. From 0668d460b4d1f846e9f83aff73fdad94a15efcf4 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 16:25:39 +0200 Subject: [PATCH 050/145] Rename GeometryValues -> GeometryMapping --- .../{GeometryValues.jl => GeometryMapping.jl} | 42 +++++++++---------- src/FEValues/cell_values.jl | 18 ++++---- src/FEValues/face_values.jl | 26 ++++++------ src/Ferrite.jl | 2 +- src/PointEval/point_values.jl | 2 +- test/test_cellvalues.jl | 6 +-- test/test_facevalues.jl | 4 +- 7 files changed, 50 insertions(+), 50 deletions(-) rename src/FEValues/{GeometryValues.jl => GeometryMapping.jl} (76%) diff --git a/src/FEValues/GeometryValues.jl b/src/FEValues/GeometryMapping.jl similarity index 76% rename from src/FEValues/GeometryValues.jl rename to src/FEValues/GeometryMapping.jl index 6df8cb639e..4038f1f460 100644 --- a/src/FEValues/GeometryValues.jl +++ b/src/FEValues/GeometryMapping.jl @@ -19,14 +19,14 @@ function RequiresHessian(ip_fun::Interpolation, ip_geo::Interpolation) RequiresHessian(requires_hessian(get_mapping_type(ip_fun))) end -struct GeometryValues{IP, M_t, dMdξ_t, d2Mdξ2_t} +struct GeometryMapping{IP, M_t, dMdξ_t, d2Mdξ2_t} ip::IP # ::Interpolation Geometric interpolation M::M_t # ::AbstractVector{<:Number} Values of geometric shape functions dMdξ::dMdξ_t # ::AbstractVector{<:Vec} Gradients of geometric shape functions in ref-domain d2Mdξ2::d2Mdξ2_t # ::AbstractVector{<:Tensor{2}} Hessians of geometric shape functions in ref-domain # ::Nothing When hessians are not required end -function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, ::RequiresHessian{RH}) where {T,RH} +function GeometryMapping(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, ::RequiresHessian{RH}) where {T,RH} n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) VT = Vec{getdim(ip),T} @@ -47,18 +47,18 @@ function GeometryValues(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, end end end - return GeometryValues(ip, M, dMdξ, dM2dξ2) + return GeometryMapping(ip, M, dMdξ, dM2dξ2) end -function Base.copy(v::GeometryValues) +function Base.copy(v::GeometryMapping) d2Mdξ2_copy = v.d2Mdξ2 === nothing ? nothing : copy(v.d2Mdξ2) - return GeometryValues(copy(v.ip), copy(v.M), copy(v.dMdξ), d2Mdξ2_copy) + return GeometryMapping(copy(v.ip), copy(v.M), copy(v.dMdξ), d2Mdξ2_copy) end -getngeobasefunctions(geovals::GeometryValues) = size(geovals.M, 1) -@propagate_inbounds geometric_value(geovals::GeometryValues, q_point::Int, base_func::Int) = geovals.M[base_func, q_point] -get_geometric_interpolation(geovals::GeometryValues) = geovals.ip +getngeobasefunctions(geo_mapping::GeometryMapping) = size(geo_mapping.M, 1) +@propagate_inbounds geometric_value(geo_mapping::GeometryMapping, q_point::Int, base_func::Int) = geo_mapping.M[base_func, q_point] +get_geometric_interpolation(geo_mapping::GeometryMapping) = geo_mapping.ip -RequiresHessian(geovals::GeometryValues) = RequiresHessian(geovals.d2Mdξ2 !== nothing) +RequiresHessian(geo_mapping::GeometryMapping) = RequiresHessian(geo_mapping.d2Mdξ2 !== nothing) # Hot-fixes to support embedded elements before MixedTensors are available # See https://github.com/Ferrite-FEM/Tensors.jl/pull/188 @@ -79,23 +79,23 @@ function otimes_returntype(#=typeof(x)=#::Type{<:Vec{dim,Tx}}, #=typeof(d2Mdξ2) return Tensor{3,dim,promote_type(Tx,TM)} end -@propagate_inbounds calculate_mapping(geovals::GeometryValues, args...) = calculate_mapping(RequiresHessian(geovals), geovals, args...) +@propagate_inbounds calculate_mapping(geo_mapping::GeometryMapping, args...) = calculate_mapping(RequiresHessian(geo_mapping), geo_mapping, args...) -@inline function calculate_mapping(::RequiresHessian{false}, geo_values::GeometryValues, q_point, x) - fecv_J = zero(otimes_returntype(eltype(x), eltype(geo_values.dMdξ))) - @inbounds for j in 1:getngeobasefunctions(geo_values) - #fecv_J += x[j] ⊗ geo_values.dMdξ[j, q_point] - fecv_J += otimes_helper(x[j], geo_values.dMdξ[j, q_point]) +@inline function calculate_mapping(::RequiresHessian{false}, geo_mapping::GeometryMapping, q_point, x) + fecv_J = zero(otimes_returntype(eltype(x), eltype(geo_mapping.dMdξ))) + @inbounds for j in 1:getngeobasefunctions(geo_mapping) + #fecv_J += x[j] ⊗ geo_mapping.dMdξ[j, q_point] + fecv_J += otimes_helper(x[j], geo_mapping.dMdξ[j, q_point]) end return MappingValues(fecv_J, nothing) end -@inline function calculate_mapping(::RequiresHessian{true}, geo_values::GeometryValues, q_point, x) - J = zero(otimes_returntype(eltype(x), eltype(geo_values.dMdξ))) - H = zero(otimes_returntype(eltype(x), eltype(geo_values.d2Mdξ2))) - @inbounds for j in 1:getngeobasefunctions(geo_values) - J += x[j] ⊗ geo_values.dMdξ[j, q_point] - H += x[j] ⊗ geo_values.d2Mdξ2[j, q_point] +@inline function calculate_mapping(::RequiresHessian{true}, geo_mapping::GeometryMapping, q_point, x) + J = zero(otimes_returntype(eltype(x), eltype(geo_mapping.dMdξ))) + H = zero(otimes_returntype(eltype(x), eltype(geo_mapping.d2Mdξ2))) + @inbounds for j in 1:getngeobasefunctions(geo_mapping) + J += x[j] ⊗ geo_mapping.dMdξ[j, q_point] + H += x[j] ⊗ geo_mapping.d2Mdξ2[j, q_point] end return MappingValues(J, H) end diff --git a/src/FEValues/cell_values.jl b/src/FEValues/cell_values.jl index 8c22470612..f57c05d145 100644 --- a/src/FEValues/cell_values.jl +++ b/src/FEValues/cell_values.jl @@ -37,15 +37,15 @@ end struct CellValues{FV, GV, QR, detT<:AbstractVector} <: AbstractCellValues fun_values::FV # FunctionValues - geo_values::GV # GeometryValues + geo_mapping::GV # GeometryMapping qr::QR # QuadratureRule detJdV::detT # AbstractVector{<:Number} end function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation) where T - geo_values = GeometryValues(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) + geo_mapping = GeometryMapping(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) fun_values = FunctionValues(T, ip_fun, qr, ip_geo) detJdV = fill(T(NaN), length(getweights(qr))) - return CellValues(fun_values, geo_values, qr, detJdV) + return CellValues(fun_values, geo_mapping, qr, detJdV) end CellValues(qr::QuadratureRule, ip::Interpolation, args...) = CellValues(Float64, qr, ip, args...) @@ -54,13 +54,13 @@ function CellValues(::Type{T}, qr, ip::Interpolation, ip_geo::ScalarInterpolatio end function Base.copy(cv::CellValues) - return CellValues(copy(cv.fun_values), copy(cv.geo_values), copy(cv.qr), copy(cv.detJdV)) + return CellValues(copy(cv.fun_values), copy(cv.geo_mapping), copy(cv.qr), copy(cv.detJdV)) end # Access geometry values for op = (:getngeobasefunctions, :geometric_value) eval(quote - @propagate_inbounds $op(cv::CellValues, args...) = $op(cv.geo_values, args...) + @propagate_inbounds $op(cv::CellValues, args...) = $op(cv.geo_mapping, args...) end) end getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] @@ -68,7 +68,7 @@ getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] # Accessors for function values getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) get_function_interpolation(cv::CellValues) = get_function_interpolation(cv.fun_values) -get_geometric_interpolation(cv::CellValues) = get_geometric_interpolation(cv.geo_values) +get_geometric_interpolation(cv::CellValues) = get_geometric_interpolation(cv.geo_mapping) shape_value_type(cv::CellValues) = shape_value_type(cv.fun_values) shape_gradient_type(cv::CellValues) = shape_gradient_type(cv.fun_values) @@ -82,14 +82,14 @@ getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) check_reinit_sdim_consistency(:CellValues, shape_gradient_type(cv), eltype(x)) - geo_values = cv.geo_values + geo_mapping = cv.geo_mapping fun_values = cv.fun_values - n_geom_basefuncs = getngeobasefunctions(geo_values) + n_geom_basefuncs = getngeobasefunctions(geo_mapping) if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs throw_incompatible_coord_length(length(x), n_geom_basefuncs) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) - mapping = calculate_mapping(geo_values, q_point, x) + mapping = calculate_mapping(geo_mapping, q_point, x) detJ = calculate_detJ(getjacobian(mapping)) detJ > 0.0 || throw_detJ_not_pos(detJ) @inbounds cv.detJdV[q_point] = detJ*w diff --git a/src/FEValues/face_values.jl b/src/FEValues/face_values.jl index ea985af3a7..a2ae02c175 100644 --- a/src/FEValues/face_values.jl +++ b/src/FEValues/face_values.jl @@ -33,7 +33,7 @@ FaceValues struct FaceValues{FV, GV, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GV<:AbstractVector{GV}} <: AbstractFaceValues fun_values::V_FV # AbstractVector{FunctionValues} - geo_values::V_GV # AbstractVector{GeometryValues} + geo_mapping::V_GV # AbstractVector{GeometryMapping} qr::QR # FaceQuadratureRule detJdV::detT # AbstractVector{<:Number} normals::nT # AbstractVector{<:Vec} @@ -41,12 +41,12 @@ struct FaceValues{FV, GV, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GV<:Abstract end function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun)) where {T,sdim} - geo_values = [GeometryValues(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) for qr in fqr.face_rules] + geo_mapping = [GeometryMapping(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) for qr in fqr.face_rules] fun_values = [FunctionValues(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) detJdV = fill(T(NaN), max_nquadpoints) normals = fill(zero(Vec{sdim,T})*T(NaN), max_nquadpoints) - return FaceValues(fun_values, geo_values, fqr, detJdV, normals, ScalarWrapper(1)) + return FaceValues(fun_values, geo_mapping, fqr, detJdV, normals, ScalarWrapper(1)) end FaceValues(qr::FaceQuadratureRule, ip::Interpolation, args...) = FaceValues(Float64, qr, ip, args...) @@ -56,11 +56,11 @@ end function Base.copy(fv::FaceValues) fun_values = map(copy, fv.fun_values) - geo_values = map(copy, fv.geo_values) - return FaceValues(fun_values, geo_values, copy(fv.qr), copy(fv.detJdV), copy(fv.normals), copy(fv.current_face)) + geo_mapping = map(copy, fv.geo_mapping) + return FaceValues(fun_values, geo_mapping, copy(fv.qr), copy(fv.detJdV), copy(fv.normals), copy(fv.current_face)) end -getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_values(fv)) +getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_mapping(fv)) getnbasefunctions(fv::FaceValues) = getnbasefunctions(get_fun_values(fv)) getnquadpoints(fv::FaceValues) = getnquadpoints(fv.qr, getcurrentface(fv)) getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] @@ -68,12 +68,12 @@ getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] shape_value_type(fv::FaceValues) = shape_value_type(get_fun_values(fv)) shape_gradient_type(fv::FaceValues) = shape_gradient_type(get_fun_values(fv)) get_function_interpolation(fv::FaceValues) = get_function_interpolation(get_fun_values(fv)) -get_geometric_interpolation(fv::FaceValues) = get_geometric_interpolation(get_geo_values(fv)) +get_geometric_interpolation(fv::FaceValues) = get_geometric_interpolation(get_geo_mapping(fv)) -get_geo_values(fv::FaceValues) = @inbounds fv.geo_values[getcurrentface(fv)] +get_geo_mapping(fv::FaceValues) = @inbounds fv.geo_mapping[getcurrentface(fv)] for op = (:getngeobasefunctions, :geometric_value) eval(quote - @propagate_inbounds $op(fv::FaceValues, args...) = $op(get_geo_values(fv), args...) + @propagate_inbounds $op(fv::FaceValues, args...) = $op(get_geo_mapping(fv), args...) end) end @@ -100,7 +100,7 @@ Return the normal at the quadrature point `qp` for the active face of the """ getnormal(fv::FaceValues, qp::Int) = fv.normals[qp] -nfaces(fv::FaceValues) = length(fv.geo_values) +nfaces(fv::FaceValues) = length(fv.geo_mapping) function checkface(fv::FaceValues, face::Int) 0 < face <= nfaces(fv) || error("Face index out of range.") @@ -115,12 +115,12 @@ function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, ce fv.current_face[] = face_nr - geo_values = get_geo_values(fv) + geo_mapping = get_geo_mapping(fv) fun_values = get_fun_values(fv) @inbounds for (q_point, w) in pairs(getweights(fv.qr, face_nr)) - mapping = calculate_mapping(geo_values, q_point, x) + mapping = calculate_mapping(geo_mapping, q_point, x) J = getjacobian(mapping) - weight_norm = weighted_normal(J, getrefshape(geo_values.ip), face_nr) + weight_norm = weighted_normal(J, getrefshape(geo_mapping.ip), face_nr) detJ = norm(weight_norm) detJ > 0.0 || throw_detJ_not_pos(detJ) @inbounds fv.detJdV[q_point] = detJ*w diff --git a/src/Ferrite.jl b/src/Ferrite.jl index 419229c993..d30de2ba7e 100644 --- a/src/Ferrite.jl +++ b/src/Ferrite.jl @@ -82,7 +82,7 @@ include("interpolations.jl") include("Quadrature/quadrature.jl") # FEValues -include("FEValues/GeometryValues.jl") +include("FEValues/GeometryMapping.jl") include("FEValues/FunctionValues.jl") include("FEValues/cell_values.jl") include("FEValues/face_values.jl") diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 239db54ea5..083e482990 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -24,7 +24,7 @@ struct PointValues{CV} <: AbstractValues PointValues{CV}(cv::CV) where {CV} = new{CV}(cv) end -PointValues(cv::CellValues) = PointValues(eltype(shape_value(cv,1,1)), cv.fun_values.ip, cv.geo_values.ip) +PointValues(cv::CellValues) = PointValues(eltype(shape_value(cv,1,1)), cv.fun_values.ip, cv.geo_mapping.ip) function PointValues(ip::Interpolation, ipg::Interpolation = default_geometric_interpolation(ip)) return PointValues(Float64, ip, ipg) end diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 9c59c68e16..b6c4b200d0 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -92,8 +92,8 @@ for (scalar_interpol, quad_rule) in ( cvc = copy(cv) @test typeof(cv) == typeof(cvc) - # Test that all mutable types in FunctionValues and GeometryValues have been copied - for key in (:fun_values, :geo_values) + # Test that all mutable types in FunctionValues and GeometryMapping have been copied + for key in (:fun_values, :geo_mapping) val = getfield(cv, key) valc = getfield(cvc, key) for fname in fieldnames(typeof(val)) @@ -294,7 +294,7 @@ end @testset "CellValues constructor entry points" begin qr = QuadratureRule{RefTriangle}(1) - _get_geo_ip(cv::CellValues) = cv.geo_values.ip + _get_geo_ip(cv::CellValues) = cv.geo_mapping.ip for fun_ip in (Lagrange{RefTriangle, 1}(), Lagrange{RefTriangle, 2}()^2) value_type(T) = fun_ip isa ScalarInterpolation ? T : Vec{2, T} grad_type(T) = fun_ip isa ScalarInterpolation ? Vec{2, T} : Tensor{2, 2, T, 4} diff --git a/test/test_facevalues.jl b/test/test_facevalues.jl index f4bb30301f..6eb875e500 100644 --- a/test/test_facevalues.jl +++ b/test/test_facevalues.jl @@ -97,8 +97,8 @@ for (scalar_interpol, quad_rule) in ( fvc = copy(fv) @test typeof(fv) == typeof(fvc) - # Test that all mutable types in FunctionValues and GeometryValues have been copied - for key in (:fun_values, :geo_values) + # Test that all mutable types in FunctionValues and GeometryMapping have been copied + for key in (:fun_values, :geo_mapping) for i in eachindex(getfield(fv, key)) val = getfield(fv, key)[i] valc = getfield(fvc, key)[i] From cf5d39882106eea1e730864e2de34369face409d Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 16:52:38 +0200 Subject: [PATCH 051/145] Correct i to alpha in mapping documentation --- docs/src/assets/fe_mapping.svg | 2470 +++++++++++++++++--------------- docs/src/devdocs/mapping.md | 4 +- 2 files changed, 1349 insertions(+), 1125 deletions(-) diff --git a/docs/src/assets/fe_mapping.svg b/docs/src/assets/fe_mapping.svg index 39fd0e70fb..2933e1b945 100644 --- a/docs/src/assets/fe_mapping.svg +++ b/docs/src/assets/fe_mapping.svg @@ -20,16 +20,16 @@ bordercolor="#666666" borderopacity="1.0" inkscape:pageshadow="2" - inkscape:pageopacity="0.0" + inkscape:pageopacity="1" inkscape:pagecheckerboard="0" inkscape:document-units="mm" showgrid="false" inkscape:snap-object-midpoints="true" - inkscape:zoom="0.69397447" - inkscape:cx="322.05796" - inkscape:cy="271.62383" - inkscape:window-width="1920" - inkscape:window-height="1017" + inkscape:zoom="1.3879489" + inkscape:cx="475.16157" + inkscape:cy="179.04117" + inkscape:window-width="2560" + inkscape:window-height="1377" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" @@ -96,26 +96,233 @@ d="M 5.77,0 -2.88,5 V -5 Z" id="path2269" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + transform="translate(-5.21261,-14.7368)" + style="display:inline"> + x="29.166241" + y="45.750965" /> + id="g11698"> + id="id-15f19f0d-41e7-4032-b7e3-782b12434f56"> - - - - - - - - - - - - - - - - - - + id="id-6af54135-8bcd-4717-8a49-46c60c244028"> + id="id-b7a76413-959c-426d-8a58-c79a4916b1cd"> + id="id-3c273db9-c685-48f3-a7ca-b970ee326867" /> + id="id-440c0518-bed2-4f8b-a8cd-1873505ecfd5"> + id="id-41947899-61f8-4a64-9a9c-0f7fe1e6f761" /> + id="id-e1574a1e-a987-430d-8d9a-dad442b747be"> + id="id-aba619b8-09d6-4d28-916f-ac0957ddf522" /> + id="id-83e6337b-4488-47b1-8b4c-c294e4da8758"> + id="id-71479173-f99d-4ce1-94a2-936d428acd66" /> + id="id-f54d63ac-f44e-4e0f-9864-5210040a0b37"> + id="id-ef97d618-0e56-41ed-a654-977546b94614" /> + id="id-d1dbac30-55b6-494e-9c24-8d93ae6dcb6c"> + id="id-1a050a46-1993-4393-be46-fdb05672a18a" /> + id="id-98b0dd7a-2314-4a20-bdb2-e641ca95df49"> + id="id-7cfb9f67-bb8c-4549-bb25-a429341bbb03" /> + id="id-10fcf22d-3c97-4af9-8241-fa73430a9ee8"> + id="id-4f5968df-f426-463b-95f1-b42c2dc4c6fc" /> + id="id-fb7fb267-ee85-4dd0-8f98-34784de9854b"> + id="id-3fb57a85-22ad-4818-9f0b-0922d601af97" /> + id="id-a47adeea-c04a-4918-ad8d-dfd9f876a972"> + id="id-6062163f-6084-4f38-9b51-9e34cd5d8c64" /> + id="id-ed5139f4-a469-417f-bd1f-ff48504777fd"> + id="id-bb15efae-2920-40e7-9dbf-5c726a3a5de6" /> + id="id-d79faa9b-1e80-4613-8454-b5ecf8fa03de"> - - - - - - + id="id-a53a05fb-d456-444b-a0a0-c86f2c8fd25b" /> + id="id-20bf41f0-01ee-45a1-8fe1-be5e5e59255e"> - - - - - - - - - - - - + id="id-4e022c0b-f4af-4f6a-9582-a15ea3cb089a" /> - - - - - - - - - - + id="id-a4e28b5f-9333-4eda-8be3-144c781fc96e" + transform="translate(-149.056,-127.734)"> + id="id-9eb5e9b5-4459-4641-bf9f-217a6be3b048"> + transform="translate(148.712,134.765)" + id="g11634"> + id="id-08dff843-fb55-4f0b-9e12-6804f75762f8" /> + transform="translate(156.045,134.765)" + id="g11637"> + id="id-bdba2f3b-9884-45c8-843e-31c675b4d9ef" /> + transform="translate(160.473,134.765)" + id="g11640"> + id="id-8f1e324b-2608-4159-ba0f-22aa9f55f485" /> + transform="translate(163.517,134.765)" + id="g11643"> + id="id-d84bade3-aae7-49a2-a397-d19f3333a9cf" /> + transform="translate(167.945,134.765)" + id="g11646"> + id="id-ff6cad7a-a35b-4418-8f6e-bdef7088cd4e" /> + transform="translate(171.847,134.765)" + id="g11649"> + id="id-65bdc089-6734-4ddf-ab23-4bdef0ea82a5" /> + transform="translate(176.275,134.765)" + id="g11652"> + id="id-e6384bd2-dfd9-4b00-9503-772cc3cbd907" /> + transform="translate(181.81,134.765)" + id="g11655"> + id="id-4c4e9262-42fa-412f-adc1-b2d0871d86d2" /> + transform="translate(186.237,134.765)" + id="g11658"> + id="id-94283dae-c759-4b79-b6cf-72a8a8cf2202" /> + id="id-6f93f427-b2f7-4db5-bf43-e3a0ff39c096"> + transform="translate(193.982,134.765)" + id="g11662"> + id="id-30f5076d-7138-4a57-b45b-456af6fb4d4f" /> + + + transform="translate(198.419,134.765)" + id="g11666"> + id="id-3cca727d-4ce1-4d5b-a231-16f77f56a592" /> + id="id-55588960-0bff-4a76-8fac-59614f7f45d4"> + transform="translate(203.67,134.765)" + id="g11670"> + id="id-786dfa6d-43dc-4440-850a-d43261749dd4" /> + transform="translate(208.651,134.765)" + id="g11673"> + id="id-fc89f5d9-d260-4a38-8e5c-5f17901da55e" /> + transform="translate(212.553,134.765)" + id="g11676"> + id="id-cb79a0c3-ba8a-4eae-9833-dbba61a9a7fb" /> + transform="translate(218.089,134.765)" + id="g11679"> + id="id-1fd9255d-f090-4ff8-a4dc-dca75e92b96f" /> + transform="translate(220.856,134.765)" + id="g11682"> + id="id-6214131c-cf3f-410d-ab38-5e4f867c2217" /> + transform="translate(226.391,134.765)" + id="g11685"> + id="id-efa276b5-8b41-49f4-ae72-3c8859cbd682" /> + transform="translate(231.373,134.765)" + id="g11688"> + id="id-05329713-06d1-46e7-8d16-ef7e64e8647a" /> + transform="translate(235.247,134.765)" + id="g11691"> - - - - - - - - - - + id="id-349b3d70-9af3-45e5-83b8-e416edd3516d" /> - - + transform="translate(239.675,134.765)" + id="g11694"> + d="m 2.078125,-1.9375 c 0.21875,0.046875 1.03125,0.203125 1.03125,0.921875 0,0.5 -0.34375,0.90625 -1.125,0.90625 -0.84375,0 -1.203125,-0.5625 -1.390625,-1.421875 C 0.5625,-1.65625 0.5625,-1.6875 0.453125,-1.6875 c -0.125,0 -0.125,0.0625 -0.125,0.234375 V -0.125 c 0,0.171875 0,0.234375 0.109375,0.234375 0.046875,0 0.0625,-0.015625 0.25,-0.203125 0.015625,-0.015625 0.015625,-0.03125 0.203125,-0.21875 0.4375,0.40625 0.890625,0.421875 1.09375,0.421875 1.140625,0 1.609375,-0.671875 1.609375,-1.390625 0,-0.515625 -0.296875,-0.828125 -0.421875,-0.9375 C 2.84375,-2.546875 2.453125,-2.625 2.03125,-2.703125 1.46875,-2.8125 0.8125,-2.9375 0.8125,-3.515625 c 0,-0.359375 0.25,-0.765625 1.109375,-0.765625 1.09375,0 1.15625,0.90625 1.171875,1.203125 0,0.09375 0.09375,0.09375 0.109375,0.09375 0.140625,0 0.140625,-0.046875 0.140625,-0.234375 v -1.015625 c 0,-0.15625 0,-0.234375 -0.109375,-0.234375 -0.046875,0 -0.078125,0 -0.203125,0.125 -0.03125,0.03125 -0.125,0.125 -0.171875,0.15625 -0.375,-0.28125 -0.78125,-0.28125 -0.9375,-0.28125 -1.21875,0 -1.59375,0.671875 -1.59375,1.234375 0,0.34375 0.15625,0.625 0.421875,0.84375 0.328125,0.25 0.609375,0.3125 1.328125,0.453125 z m 0,0" + id="id-1a82d367-6190-4182-9971-0f9be2c10cf3" /> + + + + - + id="id-1e234f8c-7f91-4497-8115-e46870f835f1"> + - - - - + style="stroke:none" + d="" + id="id-bd12d29c-ebd6-4c8a-bbc9-74fb05618652" /> + + - - + id="id-8a2757fc-24e0-4a2e-af4e-747d61d24c2d" /> + + - + id="id-1fc3232e-09e0-4ec7-b156-b34329db0477" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + transform="translate(148.712,134.765)" + id="g13299"> + style="stroke:none" + d="M 2.234375,-3.515625 V -6.09375 c 0,-0.234375 0,-0.359375 0.21875,-0.390625 C 2.546875,-6.5 2.84375,-6.5 3.046875,-6.5 c 0.890625,0 2,0.046875 2,1.484375 0,0.6875 -0.234375,1.5 -1.703125,1.5 z m 2.109375,0.125 C 5.296875,-3.625 6.078125,-4.234375 6.078125,-5.015625 6.078125,-5.96875 4.9375,-6.8125 3.484375,-6.8125 H 0.34375 V -6.5 h 0.25 c 0.765625,0 0.78125,0.109375 0.78125,0.46875 v 5.25 c 0,0.359375 -0.015625,0.46875 -0.78125,0.46875 h -0.25 V 0 c 0.359375,-0.03125 1.078125,-0.03125 1.453125,-0.03125 0.390625,0 1.109375,0 1.46875,0.03125 v -0.3125 h -0.25 c -0.765625,0 -0.78125,-0.109375 -0.78125,-0.46875 V -3.296875 H 3.375 c 0.15625,0 0.578125,0 0.9375,0.34375 0.375,0.34375 0.375,0.65625 0.375,1.328125 0,0.640625 0,1.046875 0.40625,1.421875 0.40625,0.359375 0.953125,0.421875 1.25,0.421875 0.78125,0 0.953125,-0.8125 0.953125,-1.09375 0,-0.0625 0,-0.171875 -0.125,-0.171875 -0.109375,0 -0.109375,0.09375 -0.125,0.15625 C 6.984375,-0.171875 6.640625,0 6.390625,0 5.90625,0 5.828125,-0.515625 5.6875,-1.4375 L 5.546875,-2.234375 C 5.375,-2.875 4.890625,-3.203125 4.34375,-3.390625 Z m 0,0" + id="id-8702d867-e4e8-4b32-9f10-9fca9134d3ba" /> + transform="translate(156.045,134.765)" + id="g13302"> + id="id-5689e5eb-0a1e-4c88-bd3e-c1a890b4c68c" /> + transform="translate(160.473,134.765)" + id="g13305"> + + + + + + + + + + + + + + + + + + + + id="id-1a883094-e2d7-4700-bdb1-97b6e1ae153a" /> + transform="translate(190.111,134.765)" + id="g13325"> + style="stroke:none" + d="m 3.78125,-0.546875 v 0.65625 L 5.25,0 v -0.3125 c -0.6875,0 -0.78125,-0.0625 -0.78125,-0.5625 V -6.921875 L 3.046875,-6.8125 V -6.5 c 0.6875,0 0.765625,0.0625 0.765625,0.5625 v 2.15625 c -0.28125,-0.359375 -0.71875,-0.625 -1.25,-0.625 -1.171875,0 -2.21875,0.984375 -2.21875,2.265625 0,1.265625 0.96875,2.25 2.109375,2.25 0.640625,0 1.078125,-0.34375 1.328125,-0.65625 z m 0,-2.671875 v 2.046875 c 0,0.171875 0,0.1875 -0.109375,0.359375 C 3.375,-0.328125 2.9375,-0.109375 2.5,-0.109375 2.046875,-0.109375 1.6875,-0.375 1.453125,-0.75 1.203125,-1.15625 1.171875,-1.71875 1.171875,-2.140625 1.171875,-2.5 1.1875,-3.09375 1.46875,-3.546875 1.6875,-3.859375 2.0625,-4.1875 2.609375,-4.1875 c 0.34375,0 0.765625,0.15625 1.0625,0.59375 0.109375,0.171875 0.109375,0.1875 0.109375,0.375 z m 0,0" + id="id-26fa981a-8c6e-4180-9fb2-e7f42820742d" /> + transform="translate(195.646,134.765)" + id="g13328"> + + + + id="id-dd647909-9dbf-4393-9d77-a9a5e46d571c" /> + transform="translate(203.949,134.765)" + id="g13334"> + style="stroke:none" + d="m 3.3125,-0.75 c 0.046875,0.390625 0.3125,0.8125 0.78125,0.8125 0.21875,0 0.828125,-0.140625 0.828125,-0.953125 v -0.5625 h -0.25 v 0.5625 c 0,0.578125 -0.25,0.640625 -0.359375,0.640625 -0.328125,0 -0.375,-0.453125 -0.375,-0.5 v -1.984375 c 0,-0.421875 0,-0.8125 -0.359375,-1.1875 C 3.1875,-4.3125 2.6875,-4.46875 2.21875,-4.46875 c -0.828125,0 -1.515625,0.46875 -1.515625,1.125 0,0.296875 0.203125,0.46875 0.46875,0.46875 0.28125,0 0.453125,-0.203125 0.453125,-0.453125 0,-0.125 -0.046875,-0.453125 -0.515625,-0.453125 C 1.390625,-4.140625 1.875,-4.25 2.1875,-4.25 c 0.5,0 1.0625,0.390625 1.0625,1.28125 v 0.359375 c -0.515625,0.03125 -1.203125,0.0625 -1.828125,0.359375 -0.75,0.34375 -1,0.859375 -1,1.296875 0,0.8125 0.96875,1.0625 1.59375,1.0625 0.65625,0 1.109375,-0.40625 1.296875,-0.859375 z M 3.25,-2.390625 v 1 c 0,0.9375 -0.71875,1.28125 -1.171875,1.28125 -0.484375,0 -0.890625,-0.34375 -0.890625,-0.84375 0,-0.546875 0.421875,-1.375 2.0625,-1.4375 z m 0,0" + id="id-27737682-37c6-4a52-b4d0-b1af517d06ca" /> + transform="translate(208.93,134.765)" + id="g13337"> + + + + id="id-708f7958-e595-4606-a161-bd5a0a2c6f75" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id="id-810f602b-b392-411a-990c-4697877ac70d"> + transform="translate(148.712,134.765)" + id="g15017"> + style="stroke:none" + d="M 2.3125,-6.671875 C 2.21875,-6.796875 2.21875,-6.8125 2.03125,-6.8125 H 0.328125 V -6.5 H 0.625 c 0.140625,0 0.34375,0.015625 0.484375,0.015625 0.234375,0.03125 0.25,0.046875 0.25,0.234375 v 5.203125 c 0,0.265625 0,0.734375 -1.03125,0.734375 V 0 C 0.671875,-0.015625 1.171875,-0.03125 1.5,-0.03125 c 0.328125,0 0.8125,0.015625 1.15625,0.03125 v -0.3125 c -1.015625,0 -1.015625,-0.46875 -1.015625,-0.734375 v -5.1875 c 0.046875,0.046875 0.046875,0.0625 0.09375,0.125 L 5.796875,-0.125 C 5.890625,-0.015625 5.90625,0 5.96875,0 6.109375,0 6.109375,-0.0625 6.109375,-0.265625 v -5.5 c 0,-0.265625 0,-0.734375 1.03125,-0.734375 v -0.3125 c -0.359375,0.015625 -0.84375,0.03125 -1.171875,0.03125 -0.328125,0 -0.8125,-0.015625 -1.15625,-0.03125 V -6.5 c 1.015625,0 1.015625,0.46875 1.015625,0.734375 V -1.5 Z m 0,0" + id="id-0ceb136d-c240-4454-aea6-6178e0c09d3a" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + - + id="id-948d42bf-a27e-409e-81e6-b9368bb7df2b"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + d="M 2.5,-6.921875 1.15625,-5.5625 1.328125,-5.390625 2.5,-6.40625 3.640625,-5.390625 3.8125,-5.5625 Z m 0,0" + id="id-7adf7637-0d68-4776-af25-eb40a4c044de" /> + + - - + d="m 1.71875,-3.75 v -0.65625 l -1.4375,0.109375 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5 v 4.65625 C 1.0625,1.625 0.953125,1.625 0.28125,1.625 V 1.9375 C 0.625,1.921875 1.140625,1.90625 1.390625,1.90625 c 0.28125,0 0.78125,0.015625 1.125,0.03125 V 1.625 C 1.859375,1.625 1.75,1.625 1.75,1.171875 V -0.59375 c 0.046875,0.171875 0.46875,0.703125 1.21875,0.703125 1.1875,0 2.21875,-0.984375 2.21875,-2.265625 0,-1.265625 -0.953125,-2.25 -2.078125,-2.25 -0.78125,0 -1.203125,0.4375 -1.390625,0.65625 z M 1.75,-1.140625 v -2.21875 C 2.03125,-3.875 2.515625,-4.15625 3.03125,-4.15625 c 0.734375,0 1.328125,0.875 1.328125,2 0,1.203125 -0.6875,2.046875 -1.421875,2.046875 -0.40625,0 -0.78125,-0.203125 -1.046875,-0.609375 C 1.75,-0.921875 1.75,-0.9375 1.75,-1.140625 Z m 0,0" + id="id-f6511eb1-8893-4b6d-9074-9670b39f9763" /> + + - - + d="m 2.078125,-1.9375 c 0.21875,0.046875 1.03125,0.203125 1.03125,0.921875 0,0.5 -0.34375,0.90625 -1.125,0.90625 -0.84375,0 -1.203125,-0.5625 -1.390625,-1.421875 C 0.5625,-1.65625 0.5625,-1.6875 0.453125,-1.6875 c -0.125,0 -0.125,0.0625 -0.125,0.234375 V -0.125 c 0,0.171875 0,0.234375 0.109375,0.234375 0.046875,0 0.0625,-0.015625 0.25,-0.203125 0.015625,-0.015625 0.015625,-0.03125 0.203125,-0.21875 0.4375,0.40625 0.890625,0.421875 1.09375,0.421875 1.140625,0 1.609375,-0.671875 1.609375,-1.390625 0,-0.515625 -0.296875,-0.828125 -0.421875,-0.9375 C 2.84375,-2.546875 2.453125,-2.625 2.03125,-2.703125 1.46875,-2.8125 0.8125,-2.9375 0.8125,-3.515625 c 0,-0.359375 0.25,-0.765625 1.109375,-0.765625 1.09375,0 1.15625,0.90625 1.171875,1.203125 0,0.09375 0.09375,0.09375 0.109375,0.09375 0.140625,0 0.140625,-0.046875 0.140625,-0.234375 v -1.015625 c 0,-0.15625 0,-0.234375 -0.109375,-0.234375 -0.046875,0 -0.078125,0 -0.203125,0.125 -0.03125,0.03125 -0.125,0.125 -0.171875,0.15625 -0.375,-0.28125 -0.78125,-0.28125 -0.9375,-0.28125 -1.21875,0 -1.59375,0.671875 -1.59375,1.234375 0,0.34375 0.15625,0.625 0.421875,0.84375 0.328125,0.25 0.609375,0.3125 1.328125,0.453125 z m 0,0" + id="id-841cd4b3-7a29-4aac-9841-2de42f95f0a0" /> + + - - + d="M 1.765625,-6.921875 0.328125,-6.8125 V -6.5 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 C 0.65625,-0.015625 1.1875,-0.03125 1.4375,-0.03125 c 0.25,0 0.734375,0.015625 1.109375,0.03125 v -0.3125 c -0.671875,0 -0.78125,0 -0.78125,-0.4375 z m 0,0" + id="id-611d1728-db5f-41dd-b47d-cd12e2021c09" /> + + - - + d="" + id="id-1fd6624c-4f22-4c4a-be50-20bd183d193f" /> + + - - + d="m 2.328125,-3.328125 c -0.0625,-0.15625 -0.09375,-0.34375 -0.09375,-0.515625 0,-0.515625 0.296875,-1.28125 0.84375,-1.65625 0.21875,0.296875 0.5,0.296875 0.734375,0.296875 0.28125,0 1.078125,0 1.078125,-0.53125 0,-0.421875 -0.53125,-0.421875 -0.953125,-0.421875 -0.09375,0 -0.34375,0 -0.625,0.03125 0,-0.3125 0.0625,-0.53125 0.0625,-0.546875 0.03125,-0.09375 0.03125,-0.09375 0.03125,-0.125 0,-0.203125 -0.203125,-0.21875 -0.21875,-0.21875 -0.328125,0 -0.328125,0.59375 -0.328125,0.78125 0,0.0625 0,0.15625 0.015625,0.21875 C 1.625,-5.640625 1,-4.75 1,-3.984375 c 0,0.46875 0.265625,0.84375 0.53125,1.03125 C 0.484375,-2.25 0.234375,-1.3125 0.234375,-0.9375 c 0,0.8125 0.734375,1.21875 1.328125,1.421875 L 2.703125,0.875 c 0.25,0.078125 0.671875,0.234375 0.75,0.265625 0.078125,0.046875 0.125,0.140625 0.125,0.21875 0,0.03125 -0.015625,0.296875 -0.3125,0.296875 -0.0625,0 -0.546875,-0.015625 -1,-0.25 C 2.203125,1.359375 2.1875,1.359375 2.140625,1.359375 2,1.359375 1.9375,1.46875 1.9375,1.53125 c 0,0.25 0.84375,0.484375 1.34375,0.484375 0.78125,0 1.1875,-0.71875 1.1875,-1.1875 0,-0.421875 -0.296875,-0.671875 -0.484375,-0.75 C 3.84375,0.03125 2.90625,-0.296875 2.65625,-0.375 L 2,-0.59375 c -0.34375,-0.125 -0.921875,-0.328125 -0.921875,-0.796875 0,-0.59375 0.75,-1.296875 0.875,-1.296875 0.015625,0 0.015625,0 0.078125,0.015625 C 2.515625,-2.5 2.828125,-2.5 3.09375,-2.5 c 0.3125,0 1.140625,0 1.140625,-0.546875 0,-0.40625 -0.625,-0.40625 -0.953125,-0.40625 -0.1875,0 -0.5,0 -0.953125,0.125 z M 3.40625,-5.71875 c 0.203125,-0.078125 0.375,-0.078125 0.515625,-0.078125 0.3125,0 0.34375,0 0.5,0.0625 0,0.015625 0,0.015625 -0.03125,0.0625 C 4.296875,-5.5625 3.921875,-5.5625 3.8125,-5.5625 c -0.15625,0 -0.3125,0 -0.40625,-0.15625 z M 2.578125,-3 c 0.265625,-0.09375 0.5,-0.09375 0.65625,-0.09375 0.328125,0 0.359375,0 0.515625,0.0625 -0.015625,0.015625 -0.015625,0.046875 -0.03125,0.0625 C 3.625,-2.859375 3.25,-2.859375 3.125,-2.859375 c -0.15625,0 -0.375,0 -0.546875,-0.140625 z m 0,0" + id="id-0754931a-e470-490c-a1d5-47b865d1892e" /> + + - + d="m 5.34375,-4 c -0.359375,0.109375 -0.53125,0.4375 -0.53125,0.6875 0,0.21875 0.15625,0.46875 0.484375,0.46875 0.359375,0 0.71875,-0.296875 0.71875,-0.78125 C 6.015625,-4.15625 5.5,-4.5 4.890625,-4.5 4.3125,-4.5 3.953125,-4.078125 3.8125,-3.890625 3.5625,-4.3125 3.015625,-4.5 2.4375,-4.5 c -1.25,0 -1.921875,1.21875 -1.921875,1.546875 0,0.140625 0.140625,0.140625 0.234375,0.140625 0.125,0 0.1875,0 0.234375,-0.125 0.28125,-0.90625 1,-1.203125 1.40625,-1.203125 0.375,0 0.5625,0.171875 0.5625,0.484375 0,0.203125 -0.140625,0.75 -0.234375,1.109375 L 2.375,-1.1875 c -0.140625,0.609375 -0.5,0.90625 -0.84375,0.90625 -0.046875,0 -0.28125,0 -0.46875,-0.140625 0.359375,-0.109375 0.53125,-0.453125 0.53125,-0.6875 0,-0.21875 -0.171875,-0.46875 -0.5,-0.46875 -0.34375,0 -0.71875,0.296875 -0.71875,0.78125 0,0.53125 0.53125,0.875 1.140625,0.875 0.5625,0 0.9375,-0.421875 1.0625,-0.609375 0.25,0.421875 0.8125,0.609375 1.375,0.609375 1.265625,0 1.9375,-1.21875 1.9375,-1.546875 0,-0.140625 -0.15625,-0.140625 -0.234375,-0.140625 -0.125,0 -0.1875,0 -0.234375,0.125 -0.28125,0.90625 -1,1.203125 -1.421875,1.203125 -0.375,0 -0.546875,-0.171875 -0.546875,-0.5 0,-0.203125 0.125,-0.734375 0.21875,-1.109375 0.0625,-0.25 0.296875,-1.1875 0.34375,-1.34375 0.15625,-0.609375 0.5,-0.90625 0.84375,-0.90625 0.0625,0 0.28125,0 0.484375,0.140625 z m 0,0" + id="id-6dab6b52-72f4-4e79-b04a-2b7965dc9088" /> + + + - - - + id="id-cc2e8c70-51ce-404f-b202-d0f76ddead5a"> + transform="translate(231.983,154.092)" + id="g8083"> + d="m 1.53125,-3.046875 c -1.078125,0.71875 -1.296875,1.65625 -1.296875,2.015625 0,0.46875 0.265625,0.75 0.28125,0.78125 0.328125,0.328125 0.40625,0.375 1.15625,0.65625 L 2.875,0.875 C 3.03125,0.9375 3.234375,1 3.234375,1.296875 c 0,0.234375 -0.1875,0.53125 -0.5,0.53125 -0.4375,0 -0.765625,-0.25 -0.875,-0.328125 C 1.796875,1.46875 1.796875,1.453125 1.75,1.453125 c -0.078125,0 -0.09375,0.078125 -0.09375,0.109375 0,0.125 0.53125,0.484375 1.078125,0.484375 0.625,0 1.046875,-0.578125 1.046875,-1.0625 C 3.78125,0.5 3.40625,0.3125 3.296875,0.265625 3.15625,0.21875 2.828125,0.09375 2.6875,0.046875 2.5,-0.046875 2.296875,-0.125 2.078125,-0.1875 l -0.59375,-0.234375 c -0.453125,-0.1875 -0.75,-0.46875 -0.75,-0.890625 0,-0.40625 0.390625,-1.28125 1.234375,-1.703125 C 2.328125,-2.875 2.625,-2.875 2.84375,-2.875 c 0.296875,0 0.921875,0 0.921875,-0.3125 0,-0.25 -0.421875,-0.265625 -0.8125,-0.265625 -0.1875,0 -0.46875,0 -0.84375,0.109375 -0.25,-0.25 -0.296875,-0.578125 -0.296875,-0.765625 0,-0.5625 0.359375,-1.328125 1.109375,-1.703125 0.171875,0.21875 0.40625,0.21875 0.640625,0.21875 0.25,0 0.890625,0 0.890625,-0.3125 0,-0.25 -0.453125,-0.265625 -0.828125,-0.265625 -0.140625,0 -0.375,0 -0.640625,0.046875 C 2.953125,-6.203125 2.9375,-6.28125 2.9375,-6.453125 c 0,-0.140625 0.046875,-0.34375 0.046875,-0.359375 0,-0.078125 -0.046875,-0.140625 -0.109375,-0.140625 -0.1875,0 -0.1875,0.46875 -0.1875,0.5 0,0.1875 0.0625,0.34375 0.078125,0.375 -1.078125,0.3125 -1.75,1.109375 -1.75,1.875 0,0.359375 0.1875,0.78125 0.65625,1.046875 z m 1.625,-2.859375 C 3.3125,-5.953125 3.515625,-5.953125 3.625,-5.953125 c 0.34375,0 0.375,0.015625 0.5625,0.0625 C 4.109375,-5.859375 4,-5.8125 3.5625,-5.8125 c -0.1875,0 -0.296875,0 -0.40625,-0.09375 z M 2.375,-3.1875 c 0.234375,-0.046875 0.453125,-0.046875 0.5625,-0.046875 0.359375,0 0.390625,0 0.578125,0.046875 -0.09375,0.046875 -0.1875,0.09375 -0.640625,0.09375 -0.234375,0 -0.328125,0 -0.5,-0.09375 z m 0,0" + id="id-2e36e4db-2a89-4e04-827d-7187497fd3b7" /> + id="id-84a3c078-2212-404c-bcd1-c8b95516cbae"> + transform="translate(236.342,155.586)" + id="g8087"> - - - + d="m 2.265625,-4.359375 c 0,-0.109375 -0.09375,-0.265625 -0.28125,-0.265625 -0.1875,0 -0.390625,0.1875 -0.390625,0.390625 0,0.109375 0.078125,0.265625 0.28125,0.265625 0.1875,0 0.390625,-0.203125 0.390625,-0.390625 z M 0.84375,-0.8125 c -0.03125,0.09375 -0.0625,0.171875 -0.0625,0.296875 0,0.328125 0.265625,0.578125 0.65625,0.578125 0.6875,0 1,-0.953125 1,-1.0625 0,-0.09375 -0.09375,-0.09375 -0.109375,-0.09375 -0.09375,0 -0.109375,0.046875 -0.140625,0.125 -0.15625,0.5625 -0.453125,0.84375 -0.734375,0.84375 -0.140625,0 -0.171875,-0.09375 -0.171875,-0.25 0,-0.15625 0.046875,-0.28125 0.109375,-0.4375 C 1.46875,-1 1.546875,-1.1875 1.609375,-1.375 1.671875,-1.546875 1.9375,-2.171875 1.953125,-2.265625 1.984375,-2.328125 2,-2.40625 2,-2.484375 2,-2.8125 1.71875,-3.078125 1.34375,-3.078125 0.640625,-3.078125 0.328125,-2.125 0.328125,-2 c 0,0.078125 0.09375,0.078125 0.125,0.078125 0.09375,0 0.09375,-0.03125 0.125,-0.109375 C 0.75,-2.625 1.0625,-2.875 1.3125,-2.875 c 0.109375,0 0.171875,0.046875 0.171875,0.234375 0,0.171875 -0.03125,0.265625 -0.203125,0.703125 z m 0,0" + id="id-6adee405-1540-437d-b2bd-6212fb26e3d7" /> + id="id-2130f285-c366-4089-bccf-f83deaa31fc1"> + transform="translate(254.189,154.092)" + id="g8091"> + d="M 2.234375,-3.515625 V -6.09375 c 0,-0.234375 0,-0.359375 0.21875,-0.390625 C 2.546875,-6.5 2.84375,-6.5 3.046875,-6.5 c 0.890625,0 2,0.046875 2,1.484375 0,0.6875 -0.234375,1.5 -1.703125,1.5 z m 2.109375,0.125 C 5.296875,-3.625 6.078125,-4.234375 6.078125,-5.015625 6.078125,-5.96875 4.9375,-6.8125 3.484375,-6.8125 H 0.34375 V -6.5 h 0.25 c 0.765625,0 0.78125,0.109375 0.78125,0.46875 v 5.25 c 0,0.359375 -0.015625,0.46875 -0.78125,0.46875 h -0.25 V 0 c 0.359375,-0.03125 1.078125,-0.03125 1.453125,-0.03125 0.390625,0 1.109375,0 1.46875,0.03125 v -0.3125 h -0.25 c -0.765625,0 -0.78125,-0.109375 -0.78125,-0.46875 V -3.296875 H 3.375 c 0.15625,0 0.578125,0 0.9375,0.34375 0.375,0.34375 0.375,0.65625 0.375,1.328125 0,0.640625 0,1.046875 0.40625,1.421875 0.40625,0.359375 0.953125,0.421875 1.25,0.421875 0.78125,0 0.953125,-0.8125 0.953125,-1.09375 0,-0.0625 0,-0.171875 -0.125,-0.171875 -0.109375,0 -0.109375,0.09375 -0.125,0.15625 C 6.984375,-0.171875 6.640625,0 6.390625,0 5.90625,0 5.828125,-0.515625 5.6875,-1.4375 L 5.546875,-2.234375 C 5.375,-2.875 4.890625,-3.203125 4.34375,-3.390625 Z m 0,0" + id="id-d0a82a5f-967c-4e65-8d67-ed5c1736346b" /> + transform="translate(261.522,154.092)" + id="g8094"> + id="id-d76e93ad-0571-4418-b7d2-d36d1169ce91" /> - - + transform="translate(265.95,154.092)" + id="g8097"> + d="m 1.75,-4.296875 v -1.15625 c 0,-0.875 0.46875,-1.359375 0.90625,-1.359375 0.03125,0 0.1875,0 0.328125,0.078125 C 2.875,-6.703125 2.6875,-6.5625 2.6875,-6.3125 c 0,0.21875 0.15625,0.421875 0.4375,0.421875 0.28125,0 0.4375,-0.203125 0.4375,-0.4375 0,-0.375 -0.375,-0.703125 -0.90625,-0.703125 -0.6875,0 -1.546875,0.53125 -1.546875,1.59375 v 1.140625 h -0.78125 v 0.3125 h 0.78125 V -0.75 C 1.109375,-0.3125 1,-0.3125 0.34375,-0.3125 V 0 c 0.390625,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.40625,0 0.875,0 1.265625,0.03125 V -0.3125 H 2.53125 c -0.734375,0 -0.75,-0.109375 -0.75,-0.46875 v -3.203125 h 1.125 v -0.3125 z m 0,0" + id="id-0416874a-8b89-4710-95c1-df269ec95895" /> - - + transform="translate(268.994,154.092)" + id="g8100"> + d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0" + id="id-56d71ba4-346d-41b6-a37d-34e20e178554" /> - - + transform="translate(273.422,154.092)" + id="g8103"> + d="M 1.671875,-3.3125 V -4.40625 L 0.28125,-4.296875 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.390625,-0.015625 0.859375,-0.03125 1.140625,-0.03125 0.390625,0 0.859375,0 1.265625,0.03125 V -0.3125 H 2.46875 c -0.734375,0 -0.75,-0.109375 -0.75,-0.46875 V -2.3125 c 0,-0.984375 0.421875,-1.875 1.171875,-1.875 0.0625,0 0.09375,0 0.109375,0.015625 -0.03125,0 -0.234375,0.125 -0.234375,0.390625 0,0.265625 0.21875,0.421875 0.4375,0.421875 0.171875,0 0.421875,-0.125 0.421875,-0.4375 0,-0.3125 -0.3125,-0.609375 -0.734375,-0.609375 -0.734375,0 -1.09375,0.671875 -1.21875,1.09375 z m 0,0" + id="id-84e66721-29db-42e3-8b28-816190dc9798" /> - - + transform="translate(277.324,154.092)" + id="g8106"> + d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0" + id="id-f972af51-70c0-4a44-b7a5-d0da05a87dc1" /> + transform="translate(281.752,154.092)" + id="g8109"> + d="M 1.09375,-3.421875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.359375,-0.015625 0.859375,-0.03125 1.140625,-0.03125 0.25,0 0.765625,0.015625 1.109375,0.03125 v -0.3125 c -0.671875,0 -0.78125,0 -0.78125,-0.4375 V -2.59375 C 1.78125,-3.625 2.5,-4.1875 3.125,-4.1875 c 0.640625,0 0.75,0.53125 0.75,1.109375 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.34375,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.25,0 0.78125,0.015625 1.109375,0.03125 v -0.3125 c -0.515625,0 -0.765625,0 -0.765625,-0.296875 v -1.90625 c 0,-0.859375 0,-1.15625 -0.3125,-1.515625 -0.140625,-0.171875 -0.46875,-0.375 -1.046875,-0.375 C 2.46875,-4.40625 2,-3.984375 1.71875,-3.359375 V -4.40625 L 0.3125,-4.296875 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 z m 0,0" + id="id-44873e1d-0a60-4cb4-8698-76997f840b45" /> + transform="translate(287.287,154.092)" + id="g8112"> + d="m 1.171875,-2.171875 c 0,-1.625 0.8125,-2.046875 1.34375,-2.046875 0.09375,0 0.71875,0.015625 1.0625,0.375 -0.40625,0.03125 -0.46875,0.328125 -0.46875,0.453125 0,0.265625 0.1875,0.453125 0.453125,0.453125 0.265625,0 0.46875,-0.15625 0.46875,-0.46875 0,-0.671875 -0.765625,-1.0625 -1.53125,-1.0625 -1.25,0 -2.15625,1.078125 -2.15625,2.3125 0,1.28125 0.984375,2.265625 2.140625,2.265625 1.328125,0 1.65625,-1.203125 1.65625,-1.296875 0,-0.09375 -0.109375,-0.09375 -0.140625,-0.09375 -0.078125,0 -0.109375,0.03125 -0.125,0.09375 -0.28125,0.921875 -0.9375,1.046875 -1.296875,1.046875 -0.53125,0 -1.40625,-0.421875 -1.40625,-2.03125 z m 0,0" + id="id-935e9b74-900e-4dd5-8ddd-5c49b0218401" /> + transform="translate(291.714,154.092)" + id="g8115"> + d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0" + id="id-89ea73b6-b193-4dcd-9fbf-21f18fffc306" /> + id="id-e5f8db58-8bf4-4c0b-a694-b694039adceb"> + transform="translate(299.459,154.092)" + id="g8119"> + id="id-593860ab-5b79-4961-b25a-2abf78fc867a" /> + transform="translate(303.886,154.092)" + id="g8122"> + id="id-b0cdcacd-1c56-40f9-b836-1014216f35e8" /> + id="id-9cb6dc5a-dce2-4ce4-a226-2e65d9c7c88e"> + transform="translate(309.147,154.092)" + id="g8126"> + id="id-3898f850-b7b6-44ae-a204-0f669f9e23a4" /> + transform="translate(314.128,154.092)" + id="g8129"> + id="id-7a16b17d-642b-49fe-b247-10ee7500a5a0" /> + transform="translate(318.03,154.092)" + id="g8132"> + id="id-6401e858-4025-4fba-9a65-882ed23d274c" /> + transform="translate(323.566,154.092)" + id="g8135"> + id="id-1bbc9017-f40d-4fe4-9abd-117b761707fb" /> + transform="translate(326.333,154.092)" + id="g8138"> + id="id-8fa718e7-1297-46fc-8030-e9091c4471c4" /> + transform="translate(331.868,154.092)" + id="g8141"> + id="id-d8fb2528-f64e-4ee6-a6a6-3824b02bac0f" /> + transform="translate(336.85,154.092)" + id="g8144"> + id="id-8d2ad06b-9876-4366-bf37-46d1b060f1bd" /> + transform="translate(340.724,154.092)" + id="g8147"> + id="id-3016b8a9-8c50-49e9-bd0d-2d46d018afa5" /> + id="id-946cebb3-1a53-4319-ac7b-14b338bcda0e"> + transform="translate(348.474,154.092)" + id="g8151"> + id="id-e469ad4b-e5b4-4800-ab2a-a41d662321b5" /> + id="id-5211a403-f8b7-4c86-bf46-d61a9bacd905"> + transform="translate(233.448,164.597)" + id="g8155"> + id="id-05a4b714-b7ff-40bc-bd5e-41c7846fdc63" /> + id="id-66f08953-bffb-418e-83e8-538fee8fb9f7"> + transform="translate(231.983,167.226)" + id="g8159"> + d="m 2.328125,-3.328125 c -0.0625,-0.15625 -0.09375,-0.34375 -0.09375,-0.515625 0,-0.515625 0.296875,-1.28125 0.84375,-1.65625 0.21875,0.296875 0.5,0.296875 0.734375,0.296875 0.28125,0 1.078125,0 1.078125,-0.53125 0,-0.421875 -0.53125,-0.421875 -0.953125,-0.421875 -0.09375,0 -0.34375,0 -0.625,0.03125 0,-0.3125 0.0625,-0.53125 0.0625,-0.546875 0.03125,-0.09375 0.03125,-0.09375 0.03125,-0.125 0,-0.203125 -0.203125,-0.21875 -0.21875,-0.21875 -0.328125,0 -0.328125,0.59375 -0.328125,0.78125 0,0.0625 0,0.15625 0.015625,0.21875 C 1.625,-5.640625 1,-4.75 1,-3.984375 c 0,0.46875 0.265625,0.84375 0.53125,1.03125 C 0.484375,-2.25 0.234375,-1.3125 0.234375,-0.9375 c 0,0.8125 0.734375,1.21875 1.328125,1.421875 L 2.703125,0.875 c 0.25,0.078125 0.671875,0.234375 0.75,0.265625 0.078125,0.046875 0.125,0.140625 0.125,0.21875 0,0.03125 -0.015625,0.296875 -0.3125,0.296875 -0.0625,0 -0.546875,-0.015625 -1,-0.25 C 2.203125,1.359375 2.1875,1.359375 2.140625,1.359375 2,1.359375 1.9375,1.46875 1.9375,1.53125 c 0,0.25 0.84375,0.484375 1.34375,0.484375 0.78125,0 1.1875,-0.71875 1.1875,-1.1875 0,-0.421875 -0.296875,-0.671875 -0.484375,-0.75 C 3.84375,0.03125 2.90625,-0.296875 2.65625,-0.375 L 2,-0.59375 c -0.34375,-0.125 -0.921875,-0.328125 -0.921875,-0.796875 0,-0.59375 0.75,-1.296875 0.875,-1.296875 0.015625,0 0.015625,0 0.078125,0.015625 C 2.515625,-2.5 2.828125,-2.5 3.09375,-2.5 c 0.3125,0 1.140625,0 1.140625,-0.546875 0,-0.40625 -0.625,-0.40625 -0.953125,-0.40625 -0.1875,0 -0.5,0 -0.953125,0.125 z M 3.40625,-5.71875 c 0.203125,-0.078125 0.375,-0.078125 0.515625,-0.078125 0.3125,0 0.34375,0 0.5,0.0625 0,0.015625 0,0.015625 -0.03125,0.0625 C 4.296875,-5.5625 3.921875,-5.5625 3.8125,-5.5625 c -0.15625,0 -0.3125,0 -0.40625,-0.15625 z M 2.578125,-3 c 0.265625,-0.09375 0.5,-0.09375 0.65625,-0.09375 0.328125,0 0.359375,0 0.515625,0.0625 -0.015625,0.015625 -0.015625,0.046875 -0.03125,0.0625 C 3.625,-2.859375 3.25,-2.859375 3.125,-2.859375 c -0.15625,0 -0.375,0 -0.546875,-0.140625 z m 0,0" + id="id-8196edc7-ab5b-4fcc-9ae1-d8112ecad80d" /> + id="id-ffb7853b-b2d8-4cb1-989c-64933e0a3dde"> + transform="translate(237.047,168.721)" + id="g8163"> + d="m 3.8125,-0.984375 c 0.640625,-0.65625 0.890625,-1.59375 0.890625,-1.65625 0,-0.09375 -0.078125,-0.09375 -0.109375,-0.09375 C 4.5,-2.734375 4.5,-2.71875 4.453125,-2.5625 4.328125,-2.109375 4.09375,-1.671875 3.796875,-1.296875 3.796875,-1.40625 3.78125,-1.875 3.765625,-1.9375 3.65625,-2.625 3.140625,-3.078125 2.4375,-3.078125 c -1.015625,0 -2,0.953125 -2,1.9375 0,0.640625 0.46875,1.203125 1.265625,1.203125 0.640625,0 1.21875,-0.28125 1.609375,-0.578125 0.171875,0.5 0.515625,0.578125 0.734375,0.578125 0.40625,0 0.65625,-0.328125 0.65625,-0.484375 C 4.703125,-0.5 4.609375,-0.5 4.578125,-0.5 c -0.09375,0 -0.109375,0.03125 -0.125,0.0625 -0.09375,0.265625 -0.3125,0.3125 -0.390625,0.3125 -0.09375,0 -0.21875,0 -0.25,-0.859375 z M 3.265625,-0.75 C 2.578125,-0.1875 2,-0.125 1.734375,-0.125 c -0.46875,0 -0.71875,-0.3125 -0.71875,-0.78125 0,-0.1875 0.09375,-0.953125 0.453125,-1.4375 C 1.796875,-2.765625 2.1875,-2.875 2.4375,-2.875 c 0.546875,0 0.71875,0.53125 0.765625,0.96875 0.046875,0.296875 0.03125,0.796875 0.0625,1.15625 z m 0,0" + id="id-ee0539ad-d967-4b57-bc5d-5591c011cab6" /> + id="id-66088037-ca49-416f-9c98-259d328d780d"> + transform="translate(254.189,167.226)" + id="g8167"> + id="id-0a50712f-7ea7-4ae6-8d2d-8daf19945ac2" /> + transform="translate(261.522,167.226)" + id="g8170"> + id="id-3a0f8bfa-94fd-4ebe-a05b-96c6ac2b2844" /> + transform="translate(265.95,167.226)" + id="g8173"> + d="m 1.75,-4.296875 v -1.15625 c 0,-0.875 0.46875,-1.359375 0.90625,-1.359375 0.03125,0 0.1875,0 0.328125,0.078125 C 2.875,-6.703125 2.6875,-6.5625 2.6875,-6.3125 c 0,0.21875 0.15625,0.421875 0.4375,0.421875 0.28125,0 0.4375,-0.203125 0.4375,-0.4375 0,-0.375 -0.375,-0.703125 -0.90625,-0.703125 -0.6875,0 -1.546875,0.53125 -1.546875,1.59375 v 1.140625 h -0.78125 v 0.3125 h 0.78125 V -0.75 C 1.109375,-0.3125 1,-0.3125 0.34375,-0.3125 V 0 c 0.390625,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.40625,0 0.875,0 1.265625,0.03125 V -0.3125 H 2.53125 c -0.734375,0 -0.75,-0.109375 -0.75,-0.46875 v -3.203125 h 1.125 v -0.3125 z m 0,0" + id="id-f954832d-4f98-412c-a9fe-c885b97117cc" /> + transform="translate(268.994,167.226)" + id="g8176"> + d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0" + id="id-eaa0b83d-7fd0-493b-b9dd-21a4ddc87da3" /> - - + transform="translate(273.422,167.226)" + id="g8179"> + d="M 1.671875,-3.3125 V -4.40625 L 0.28125,-4.296875 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.390625,-0.015625 0.859375,-0.03125 1.140625,-0.03125 0.390625,0 0.859375,0 1.265625,0.03125 V -0.3125 H 2.46875 c -0.734375,0 -0.75,-0.109375 -0.75,-0.46875 V -2.3125 c 0,-0.984375 0.421875,-1.875 1.171875,-1.875 0.0625,0 0.09375,0 0.109375,0.015625 -0.03125,0 -0.234375,0.125 -0.234375,0.390625 0,0.265625 0.21875,0.421875 0.4375,0.421875 0.171875,0 0.421875,-0.125 0.421875,-0.4375 0,-0.3125 -0.3125,-0.609375 -0.734375,-0.609375 -0.734375,0 -1.09375,0.671875 -1.21875,1.09375 z m 0,0" + id="id-b48fa349-fc40-4e4d-aa7a-af4131af83c9" /> - - + transform="translate(277.324,167.226)" + id="g8182"> + d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0" + id="id-6ed3104d-6051-46d2-98b4-d2edea9a2462" /> + transform="translate(281.752,167.226)" + id="g8185"> + d="M 1.09375,-3.421875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.359375,-0.015625 0.859375,-0.03125 1.140625,-0.03125 0.25,0 0.765625,0.015625 1.109375,0.03125 v -0.3125 c -0.671875,0 -0.78125,0 -0.78125,-0.4375 V -2.59375 C 1.78125,-3.625 2.5,-4.1875 3.125,-4.1875 c 0.640625,0 0.75,0.53125 0.75,1.109375 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.34375,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.25,0 0.78125,0.015625 1.109375,0.03125 v -0.3125 c -0.515625,0 -0.765625,0 -0.765625,-0.296875 v -1.90625 c 0,-0.859375 0,-1.15625 -0.3125,-1.515625 -0.140625,-0.171875 -0.46875,-0.375 -1.046875,-0.375 C 2.46875,-4.40625 2,-3.984375 1.71875,-3.359375 V -4.40625 L 0.3125,-4.296875 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 z m 0,0" + id="id-4f329ae3-e646-4269-bf27-90ff3690a42e" /> + transform="translate(287.287,167.226)" + id="g8188"> + d="m 1.171875,-2.171875 c 0,-1.625 0.8125,-2.046875 1.34375,-2.046875 0.09375,0 0.71875,0.015625 1.0625,0.375 -0.40625,0.03125 -0.46875,0.328125 -0.46875,0.453125 0,0.265625 0.1875,0.453125 0.453125,0.453125 0.265625,0 0.46875,-0.15625 0.46875,-0.46875 0,-0.671875 -0.765625,-1.0625 -1.53125,-1.0625 -1.25,0 -2.15625,1.078125 -2.15625,2.3125 0,1.28125 0.984375,2.265625 2.140625,2.265625 1.328125,0 1.65625,-1.203125 1.65625,-1.296875 0,-0.09375 -0.109375,-0.09375 -0.140625,-0.09375 -0.078125,0 -0.109375,0.03125 -0.125,0.09375 -0.28125,0.921875 -0.9375,1.046875 -1.296875,1.046875 -0.53125,0 -1.40625,-0.421875 -1.40625,-2.03125 z m 0,0" + id="id-15eb8a25-d439-43ca-beab-f461abba9c2d" /> + transform="translate(291.714,167.226)" + id="g8191"> + d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0" + id="id-67b2dfd3-db4d-4b49-bf63-b27adce020f4" /> + + + transform="translate(299.459,167.226)" + id="g8195"> + d="m 1.71875,-3.75 v -0.65625 l -1.4375,0.109375 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5 v 4.65625 C 1.0625,1.625 0.953125,1.625 0.28125,1.625 V 1.9375 C 0.625,1.921875 1.140625,1.90625 1.390625,1.90625 c 0.28125,0 0.78125,0.015625 1.125,0.03125 V 1.625 C 1.859375,1.625 1.75,1.625 1.75,1.171875 V -0.59375 c 0.046875,0.171875 0.46875,0.703125 1.21875,0.703125 1.1875,0 2.21875,-0.984375 2.21875,-2.265625 0,-1.265625 -0.953125,-2.25 -2.078125,-2.25 -0.78125,0 -1.203125,0.4375 -1.390625,0.65625 z M 1.75,-1.140625 v -2.21875 C 2.03125,-3.875 2.515625,-4.15625 3.03125,-4.15625 c 0.734375,0 1.328125,0.875 1.328125,2 0,1.203125 -0.6875,2.046875 -1.421875,2.046875 -0.40625,0 -0.78125,-0.203125 -1.046875,-0.609375 C 1.75,-0.921875 1.75,-0.9375 1.75,-1.140625 Z m 0,0" + id="id-70a73384-b133-4b99-a737-6a83b8b3017a" /> + + + transform="translate(305.273,167.226)" + id="g8199"> + id="id-8685d907-800a-4b25-b149-058664f29e36" /> + transform="translate(310.255,167.226)" + id="g8202"> + d="m 2.078125,-1.9375 c 0.21875,0.046875 1.03125,0.203125 1.03125,0.921875 0,0.5 -0.34375,0.90625 -1.125,0.90625 -0.84375,0 -1.203125,-0.5625 -1.390625,-1.421875 C 0.5625,-1.65625 0.5625,-1.6875 0.453125,-1.6875 c -0.125,0 -0.125,0.0625 -0.125,0.234375 V -0.125 c 0,0.171875 0,0.234375 0.109375,0.234375 0.046875,0 0.0625,-0.015625 0.25,-0.203125 0.015625,-0.015625 0.015625,-0.03125 0.203125,-0.21875 0.4375,0.40625 0.890625,0.421875 1.09375,0.421875 1.140625,0 1.609375,-0.671875 1.609375,-1.390625 0,-0.515625 -0.296875,-0.828125 -0.421875,-0.9375 C 2.84375,-2.546875 2.453125,-2.625 2.03125,-2.703125 1.46875,-2.8125 0.8125,-2.9375 0.8125,-3.515625 c 0,-0.359375 0.25,-0.765625 1.109375,-0.765625 1.09375,0 1.15625,0.90625 1.171875,1.203125 0,0.09375 0.09375,0.09375 0.109375,0.09375 0.140625,0 0.140625,-0.046875 0.140625,-0.234375 v -1.015625 c 0,-0.15625 0,-0.234375 -0.109375,-0.234375 -0.046875,0 -0.078125,0 -0.203125,0.125 -0.03125,0.03125 -0.125,0.125 -0.171875,0.15625 -0.375,-0.28125 -0.78125,-0.28125 -0.9375,-0.28125 -1.21875,0 -1.59375,0.671875 -1.59375,1.234375 0,0.34375 0.15625,0.625 0.421875,0.84375 0.328125,0.25 0.609375,0.3125 1.328125,0.453125 z m 0,0" + id="id-0d60ed0e-6c91-49bb-abf9-f9160145e9ba" /> - - + transform="translate(314.184,167.226)" + id="g8205"> + d="M 1.765625,-4.40625 0.375,-4.296875 v 0.3125 c 0.640625,0 0.734375,0.0625 0.734375,0.546875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 C 0.640625,-0.015625 1.1875,-0.03125 1.421875,-0.03125 1.78125,-0.03125 2.125,-0.015625 2.46875,0 v -0.3125 c -0.671875,0 -0.703125,-0.046875 -0.703125,-0.4375 z m 0.03125,-1.734375 c 0,-0.3125 -0.234375,-0.53125 -0.515625,-0.53125 -0.3125,0 -0.53125,0.265625 -0.53125,0.53125 0,0.265625 0.21875,0.53125 0.53125,0.53125 0.28125,0 0.515625,-0.21875 0.515625,-0.53125 z m 0,0" + id="id-df75e786-320d-4b4a-a2cc-1439a4188dd7" /> + transform="translate(316.951,167.226)" + id="g8208"> + d="m 1.71875,-3.984375 h 1.4375 v -0.3125 H 1.71875 V -6.125 h -0.25 c 0,0.8125 -0.296875,1.875 -1.28125,1.921875 v 0.21875 h 0.84375 v 2.75 c 0,1.21875 0.9375,1.34375 1.296875,1.34375 0.703125,0 0.984375,-0.703125 0.984375,-1.34375 v -0.5625 h -0.25 V -1.25 c 0,0.734375 -0.296875,1.109375 -0.671875,1.109375 -0.671875,0 -0.671875,-0.90625 -0.671875,-1.078125 z m 0,0" + id="id-3829cce5-3a8a-41c7-bea0-5563e2b90e42" /> - - + transform="translate(320.826,167.226)" + id="g8211"> + d="M 1.765625,-4.40625 0.375,-4.296875 v 0.3125 c 0.640625,0 0.734375,0.0625 0.734375,0.546875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 C 0.640625,-0.015625 1.1875,-0.03125 1.421875,-0.03125 1.78125,-0.03125 2.125,-0.015625 2.46875,0 v -0.3125 c -0.671875,0 -0.703125,-0.046875 -0.703125,-0.4375 z m 0.03125,-1.734375 c 0,-0.3125 -0.234375,-0.53125 -0.515625,-0.53125 -0.3125,0 -0.53125,0.265625 -0.53125,0.53125 0,0.265625 0.21875,0.53125 0.53125,0.53125 0.28125,0 0.515625,-0.21875 0.515625,-0.53125 z m 0,0" + id="id-432273b7-6f03-4b59-afeb-ab5da89dccc5" /> + transform="translate(323.593,167.226)" + id="g8214"> - - - - - + id="id-322c7e22-0ef4-4262-bea3-c4f3c2c4cd13" /> + transform="translate(328.575,167.226)" + id="g8217"> + d="M 1.09375,-3.421875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.359375,-0.015625 0.859375,-0.03125 1.140625,-0.03125 0.25,0 0.765625,0.015625 1.109375,0.03125 v -0.3125 c -0.671875,0 -0.78125,0 -0.78125,-0.4375 V -2.59375 C 1.78125,-3.625 2.5,-4.1875 3.125,-4.1875 c 0.640625,0 0.75,0.53125 0.75,1.109375 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.34375,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.25,0 0.78125,0.015625 1.109375,0.03125 v -0.3125 c -0.515625,0 -0.765625,0 -0.765625,-0.296875 v -1.90625 c 0,-0.859375 0,-1.15625 -0.3125,-1.515625 -0.140625,-0.171875 -0.46875,-0.375 -1.046875,-0.375 C 2.46875,-4.40625 2,-3.984375 1.71875,-3.359375 V -4.40625 L 0.3125,-4.296875 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 z m 0,0" + id="id-b48c988c-3b51-4538-95d9-045d81e9d9e0" /> + id="id-3e2fb019-f8ba-439a-ab68-15eb7799b05a"> + transform="translate(337.428,167.226)" + id="g8221"> + d="M 4.6875,-2.140625 C 4.6875,-3.40625 3.703125,-4.46875 2.5,-4.46875 c -1.25,0 -2.21875,1.09375 -2.21875,2.328125 0,1.296875 1.03125,2.25 2.203125,2.25 1.203125,0 2.203125,-0.984375 2.203125,-2.25 z m -2.1875,2 c -0.4375,0 -0.875,-0.203125 -1.140625,-0.671875 -0.25,-0.4375 -0.25,-1.046875 -0.25,-1.40625 0,-0.390625 0,-0.921875 0.234375,-1.359375 C 1.609375,-4.03125 2.078125,-4.25 2.484375,-4.25 c 0.4375,0 0.859375,0.21875 1.125,0.65625 0.265625,0.421875 0.265625,1 0.265625,1.375 0,0.359375 0,0.90625 -0.21875,1.34375 C 3.421875,-0.421875 2.984375,-0.140625 2.5,-0.140625 Z m 0,0" + id="id-2faeb17e-a143-4b20-8165-43384d277c32" /> - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + id="id-5609ade9-e83b-4089-b981-c7f3b0a8f73e" /> + + + + - - + d="M 1.09375,-3.421875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.359375,-0.015625 0.859375,-0.03125 1.140625,-0.03125 0.25,0 0.765625,0.015625 1.109375,0.03125 v -0.3125 c -0.671875,0 -0.78125,0 -0.78125,-0.4375 V -2.59375 C 1.78125,-3.625 2.5,-4.1875 3.125,-4.1875 c 0.640625,0 0.75,0.53125 0.75,1.109375 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.34375,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.25,0 0.78125,0.015625 1.109375,0.03125 v -0.3125 c -0.515625,0 -0.765625,0 -0.765625,-0.296875 v -1.90625 c 0,-0.859375 0,-1.15625 -0.3125,-1.515625 -0.140625,-0.171875 -0.46875,-0.375 -1.046875,-0.375 C 2.46875,-4.40625 2,-3.984375 1.71875,-3.359375 V -4.40625 L 0.3125,-4.296875 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 z m 0,0" + id="id-d1d151f0-7487-442a-8a50-332e17bf0aea" /> + + - + d="M 4.6875,-2.140625 C 4.6875,-3.40625 3.703125,-4.46875 2.5,-4.46875 c -1.25,0 -2.21875,1.09375 -2.21875,2.328125 0,1.296875 1.03125,2.25 2.203125,2.25 1.203125,0 2.203125,-0.984375 2.203125,-2.25 z m -2.1875,2 c -0.4375,0 -0.875,-0.203125 -1.140625,-0.671875 -0.25,-0.4375 -0.25,-1.046875 -0.25,-1.40625 0,-0.390625 0,-0.921875 0.234375,-1.359375 C 1.609375,-4.03125 2.078125,-4.25 2.484375,-4.25 c 0.4375,0 0.859375,0.21875 1.125,0.65625 0.265625,0.421875 0.265625,1 0.265625,1.375 0,0.359375 0,0.90625 -0.21875,1.34375 C 3.421875,-0.421875 2.984375,-0.140625 2.5,-0.140625 Z m 0,0" + id="id-e889be02-5714-4212-bd7a-2814a10869fd" /> + - - + id="id-4c716cb2-9589-4e1d-98eb-785da8605724"> + transform="translate(359.566,167.226)" + id="g8235"> + d="m 3.78125,-0.546875 v 0.65625 L 5.25,0 v -0.3125 c -0.6875,0 -0.78125,-0.0625 -0.78125,-0.5625 V -6.921875 L 3.046875,-6.8125 V -6.5 c 0.6875,0 0.765625,0.0625 0.765625,0.5625 v 2.15625 c -0.28125,-0.359375 -0.71875,-0.625 -1.25,-0.625 -1.171875,0 -2.21875,0.984375 -2.21875,2.265625 0,1.265625 0.96875,2.25 2.109375,2.25 0.640625,0 1.078125,-0.34375 1.328125,-0.65625 z m 0,-2.671875 v 2.046875 c 0,0.171875 0,0.1875 -0.109375,0.359375 C 3.375,-0.328125 2.9375,-0.109375 2.5,-0.109375 2.046875,-0.109375 1.6875,-0.375 1.453125,-0.75 1.203125,-1.15625 1.171875,-1.71875 1.171875,-2.140625 1.171875,-2.5 1.1875,-3.09375 1.46875,-3.546875 1.6875,-3.859375 2.0625,-4.1875 2.609375,-4.1875 c 0.34375,0 0.765625,0.15625 1.0625,0.59375 0.109375,0.171875 0.109375,0.1875 0.109375,0.375 z m 0,0" + id="id-97935f58-85f7-4b37-8bca-2fd773b27ecf" /> + transform="translate(365.102,167.226)" + id="g8238"> + id="id-edc1ccd0-1901-4d53-ae6f-202d44cf6720" /> + + + transform="translate(372.855,167.226)" + id="g8242"> + d="m 4.75,-2.359375 c 0,-1.5625 -0.921875,-2.046875 -1.65625,-2.046875 -1.375,0 -2.6875,1.421875 -2.6875,2.828125 0,0.9375 0.59375,1.6875 1.625,1.6875 0.625,0 1.34375,-0.234375 2.09375,-0.84375 0.125,0.53125 0.453125,0.84375 0.90625,0.84375 0.53125,0 0.84375,-0.546875 0.84375,-0.703125 0,-0.078125 -0.0625,-0.109375 -0.125,-0.109375 -0.0625,0 -0.09375,0.03125 -0.125,0.109375 -0.1875,0.484375 -0.546875,0.484375 -0.5625,0.484375 -0.3125,0 -0.3125,-0.78125 -0.3125,-1.015625 0,-0.203125 0,-0.234375 0.109375,-0.34375 C 5.796875,-2.65625 6,-3.8125 6,-3.8125 6,-3.84375 5.984375,-3.921875 5.875,-3.921875 c -0.09375,0 -0.09375,0.03125 -0.140625,0.21875 -0.1875,0.625 -0.515625,1.375 -0.984375,1.96875 z m -0.65625,1.375 c -0.890625,0.765625 -1.65625,0.875 -2.046875,0.875 -0.59375,0 -0.90625,-0.453125 -0.90625,-1.09375 0,-0.484375 0.265625,-1.5625 0.578125,-2.0625 C 2.1875,-4 2.734375,-4.1875 3.078125,-4.1875 c 0.984375,0 0.984375,1.3125 0.984375,2.078125 0,0.375 0,0.953125 0.03125,1.125 z m 0,0" + id="id-f699c56d-2063-458c-b2ea-2d35db7fd3f3" /> + + + transform="translate(231.983,179.181)" + id="g8246"> + d="M 3.328125,-3.015625 C 3.390625,-3.265625 3.625,-4.1875 4.3125,-4.1875 c 0.046875,0 0.296875,0 0.5,0.125 C 4.53125,-4 4.34375,-3.765625 4.34375,-3.515625 c 0,0.15625 0.109375,0.34375 0.375,0.34375 0.21875,0 0.53125,-0.171875 0.53125,-0.578125 0,-0.515625 -0.578125,-0.65625 -0.921875,-0.65625 -0.578125,0 -0.921875,0.53125 -1.046875,0.75 -0.25,-0.65625 -0.78125,-0.75 -1.078125,-0.75 -1.03125,0 -1.609375,1.28125 -1.609375,1.53125 0,0.109375 0.109375,0.109375 0.125,0.109375 0.078125,0 0.109375,-0.03125 0.125,-0.109375 0.34375,-1.0625 1,-1.3125 1.34375,-1.3125 0.1875,0 0.53125,0.09375 0.53125,0.671875 0,0.3125 -0.171875,0.96875 -0.53125,2.375 -0.15625,0.609375 -0.515625,1.03125 -0.953125,1.03125 -0.0625,0 -0.28125,0 -0.5,-0.125 0.25,-0.0625 0.46875,-0.265625 0.46875,-0.546875 0,-0.265625 -0.21875,-0.34375 -0.359375,-0.34375 -0.3125,0 -0.546875,0.25 -0.546875,0.578125 0,0.453125 0.484375,0.65625 0.921875,0.65625 0.671875,0 1.03125,-0.703125 1.046875,-0.75 0.125,0.359375 0.484375,0.75 1.078125,0.75 1.03125,0 1.59375,-1.28125 1.59375,-1.53125 0,-0.109375 -0.078125,-0.109375 -0.109375,-0.109375 -0.09375,0 -0.109375,0.046875 -0.140625,0.109375 -0.328125,1.078125 -1,1.3125 -1.3125,1.3125 -0.390625,0 -0.546875,-0.3125 -0.546875,-0.65625 0,-0.21875 0.046875,-0.4375 0.15625,-0.875 z m 0,0" + id="id-99a0bbf4-08a2-4f3a-b6c1-7f8ca684be0b" /> + + + transform="translate(237.677,180.676)" + id="g8250"> + d="m 2.265625,-4.359375 c 0,-0.109375 -0.09375,-0.265625 -0.28125,-0.265625 -0.1875,0 -0.390625,0.1875 -0.390625,0.390625 0,0.109375 0.078125,0.265625 0.28125,0.265625 0.1875,0 0.390625,-0.203125 0.390625,-0.390625 z M 0.84375,-0.8125 c -0.03125,0.09375 -0.0625,0.171875 -0.0625,0.296875 0,0.328125 0.265625,0.578125 0.65625,0.578125 0.6875,0 1,-0.953125 1,-1.0625 0,-0.09375 -0.09375,-0.09375 -0.109375,-0.09375 -0.09375,0 -0.109375,0.046875 -0.140625,0.125 -0.15625,0.5625 -0.453125,0.84375 -0.734375,0.84375 -0.140625,0 -0.171875,-0.09375 -0.171875,-0.25 0,-0.15625 0.046875,-0.28125 0.109375,-0.4375 C 1.46875,-1 1.546875,-1.1875 1.609375,-1.375 1.671875,-1.546875 1.9375,-2.171875 1.953125,-2.265625 1.984375,-2.328125 2,-2.40625 2,-2.484375 2,-2.8125 1.71875,-3.078125 1.34375,-3.078125 0.640625,-3.078125 0.328125,-2.125 0.328125,-2 c 0,0.078125 0.09375,0.078125 0.125,0.078125 0.09375,0 0.09375,-0.03125 0.125,-0.109375 C 0.75,-2.625 1.0625,-2.875 1.3125,-2.875 c 0.109375,0 0.171875,0.046875 0.171875,0.234375 0,0.171875 -0.03125,0.265625 -0.203125,0.703125 z m 0,0" + id="id-cf07ff32-2ace-4010-bb88-70f446a2bc6f" /> + + + transform="translate(254.189,179.181)" + id="g8254"> + d="M 2.234375,-3.515625 V -6.09375 c 0,-0.234375 0,-0.359375 0.21875,-0.390625 C 2.546875,-6.5 2.84375,-6.5 3.046875,-6.5 c 0.890625,0 2,0.046875 2,1.484375 0,0.6875 -0.234375,1.5 -1.703125,1.5 z m 2.109375,0.125 C 5.296875,-3.625 6.078125,-4.234375 6.078125,-5.015625 6.078125,-5.96875 4.9375,-6.8125 3.484375,-6.8125 H 0.34375 V -6.5 h 0.25 c 0.765625,0 0.78125,0.109375 0.78125,0.46875 v 5.25 c 0,0.359375 -0.015625,0.46875 -0.78125,0.46875 h -0.25 V 0 c 0.359375,-0.03125 1.078125,-0.03125 1.453125,-0.03125 0.390625,0 1.109375,0 1.46875,0.03125 v -0.3125 h -0.25 c -0.765625,0 -0.78125,-0.109375 -0.78125,-0.46875 V -3.296875 H 3.375 c 0.15625,0 0.578125,0 0.9375,0.34375 0.375,0.34375 0.375,0.65625 0.375,1.328125 0,0.640625 0,1.046875 0.40625,1.421875 0.40625,0.359375 0.953125,0.421875 1.25,0.421875 0.78125,0 0.953125,-0.8125 0.953125,-1.09375 0,-0.0625 0,-0.171875 -0.125,-0.171875 -0.109375,0 -0.109375,0.09375 -0.125,0.15625 C 6.984375,-0.171875 6.640625,0 6.390625,0 5.90625,0 5.828125,-0.515625 5.6875,-1.4375 L 5.546875,-2.234375 C 5.375,-2.875 4.890625,-3.203125 4.34375,-3.390625 Z m 0,0" + id="id-150d0f94-f582-4f17-bdf3-da1882451c39" /> + transform="translate(261.522,179.181)" + id="g8257"> + d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0" + id="id-c2e5441f-802a-486c-ab5b-9891bd4d5aff" /> + transform="translate(265.95,179.181)" + id="g8260"> + d="m 3.3125,-0.75 c 0.046875,0.390625 0.3125,0.8125 0.78125,0.8125 0.21875,0 0.828125,-0.140625 0.828125,-0.953125 v -0.5625 h -0.25 v 0.5625 c 0,0.578125 -0.25,0.640625 -0.359375,0.640625 -0.328125,0 -0.375,-0.453125 -0.375,-0.5 v -1.984375 c 0,-0.421875 0,-0.8125 -0.359375,-1.1875 C 3.1875,-4.3125 2.6875,-4.46875 2.21875,-4.46875 c -0.828125,0 -1.515625,0.46875 -1.515625,1.125 0,0.296875 0.203125,0.46875 0.46875,0.46875 0.28125,0 0.453125,-0.203125 0.453125,-0.453125 0,-0.125 -0.046875,-0.453125 -0.515625,-0.453125 C 1.390625,-4.140625 1.875,-4.25 2.1875,-4.25 c 0.5,0 1.0625,0.390625 1.0625,1.28125 v 0.359375 c -0.515625,0.03125 -1.203125,0.0625 -1.828125,0.359375 -0.75,0.34375 -1,0.859375 -1,1.296875 0,0.8125 0.96875,1.0625 1.59375,1.0625 0.65625,0 1.109375,-0.40625 1.296875,-0.859375 z M 3.25,-2.390625 v 1 c 0,0.9375 -0.71875,1.28125 -1.171875,1.28125 -0.484375,0 -0.890625,-0.34375 -0.890625,-0.84375 0,-0.546875 0.421875,-1.375 2.0625,-1.4375 z m 0,0" + id="id-692d1d99-7863-4951-9f89-878aa5b83625" /> + transform="translate(270.931,179.181)" + id="g8263"> + d="M 1.765625,-6.921875 0.328125,-6.8125 V -6.5 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 C 0.65625,-0.015625 1.1875,-0.03125 1.4375,-0.03125 c 0.25,0 0.734375,0.015625 1.109375,0.03125 v -0.3125 c -0.671875,0 -0.78125,0 -0.78125,-0.4375 z m 0,0" + id="id-0de5f172-90a1-4897-842e-bff1c8e6ee97" /> + id="id-c0869544-46ec-4eae-a661-bac16838dac9"> + transform="translate(277.016,179.181)" + id="g8267"> + id="id-0517ee75-14bc-4c78-b2a0-2c99ec360bd5" /> - - + transform="translate(281.444,179.181)" + id="g8270"> + id="id-7e373297-496a-4f3a-84c5-7bf5af444adb" /> + id="id-e5a32e64-1a43-49ac-9a07-e0c3dd738d98"> + transform="translate(286.704,179.181)" + id="g8274"> + id="id-da91b9da-bf93-4b8a-8205-2c6e0e99e2a4" /> + transform="translate(291.685,179.181)" + id="g8277"> + id="id-c1aec226-e6c0-484e-8865-44dc91ae8c50" /> + transform="translate(295.588,179.181)" + id="g8280"> + id="id-30ebfd7f-749b-483a-80ec-0c3e01c1662e" /> + transform="translate(301.123,179.181)" + id="g8283"> + id="id-27867fa5-1891-44ab-9a30-e9ef37e614be" /> + transform="translate(303.89,179.181)" + id="g8286"> + id="id-d168d2da-14e6-4ea4-ab56-33ed3eb630ca" /> + transform="translate(309.426,179.181)" + id="g8289"> + id="id-4c15d512-097c-4630-8b01-ca70d1dcf31d" /> + transform="translate(314.407,179.181)" + id="g8292"> + id="id-51e6e9c9-2488-49b3-aeb0-02272ed22463" /> + transform="translate(318.281,179.181)" + id="g8295"> + id="id-83efe587-a2f7-4f9e-a3c2-939b741f85a0" /> + + + transform="translate(326.031,179.181)" + id="g8299"> + d="m 2.828125,-6.234375 c 0,-0.203125 -0.140625,-0.359375 -0.359375,-0.359375 -0.28125,0 -0.546875,0.265625 -0.546875,0.53125 0,0.1875 0.140625,0.359375 0.375,0.359375 0.234375,0 0.53125,-0.234375 0.53125,-0.53125 z m -0.75,3.75 c 0.109375,-0.28125 0.109375,-0.3125 0.21875,-0.578125 0.078125,-0.203125 0.125,-0.34375 0.125,-0.53125 0,-0.4375 -0.3125,-0.8125 -0.8125,-0.8125 -0.9375,0 -1.3125,1.453125 -1.3125,1.53125 0,0.109375 0.09375,0.109375 0.109375,0.109375 0.109375,0 0.109375,-0.03125 0.15625,-0.1875 0.28125,-0.9375 0.671875,-1.234375 1.015625,-1.234375 0.078125,0 0.25,0 0.25,0.3125 0,0.21875 -0.078125,0.421875 -0.109375,0.53125 -0.078125,0.25 -0.53125,1.40625 -0.6875,1.84375 -0.109375,0.25 -0.234375,0.578125 -0.234375,0.796875 0,0.46875 0.34375,0.8125 0.8125,0.8125 0.9375,0 1.3125,-1.4375 1.3125,-1.53125 0,-0.109375 -0.09375,-0.109375 -0.125,-0.109375 -0.09375,0 -0.09375,0.03125 -0.140625,0.1875 -0.1875,0.625 -0.515625,1.234375 -1.015625,1.234375 -0.171875,0 -0.25,-0.09375 -0.25,-0.328125 0,-0.25 0.0625,-0.390625 0.296875,-1 z m 0,0" + id="id-1c942f0e-88d3-4f50-8456-52b4f13a5454" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + style="fill:#000000;fill-opacity:1" + id="id-1535c85d-b147-4556-ab34-a783297e0cb5"> + - - + style="stroke:none;stroke-width:0" + d="M 2.5,-6.921875 1.15625,-5.5625 1.328125,-5.390625 2.5,-6.40625 3.640625,-5.390625 3.8125,-5.5625 Z m 0,0" + id="id-10ac5f40-cf20-462d-b838-805fe7ad0f95" /> + + + + - - + style="stroke:none;stroke-width:0" + d="m 5.34375,-4 c -0.359375,0.109375 -0.53125,0.4375 -0.53125,0.6875 0,0.21875 0.15625,0.46875 0.484375,0.46875 0.359375,0 0.71875,-0.296875 0.71875,-0.78125 C 6.015625,-4.15625 5.5,-4.5 4.890625,-4.5 4.3125,-4.5 3.953125,-4.078125 3.8125,-3.890625 3.5625,-4.3125 3.015625,-4.5 2.4375,-4.5 c -1.25,0 -1.921875,1.21875 -1.921875,1.546875 0,0.140625 0.140625,0.140625 0.234375,0.140625 0.125,0 0.1875,0 0.234375,-0.125 0.28125,-0.90625 1,-1.203125 1.40625,-1.203125 0.375,0 0.5625,0.171875 0.5625,0.484375 0,0.203125 -0.140625,0.75 -0.234375,1.109375 L 2.375,-1.1875 c -0.140625,0.609375 -0.5,0.90625 -0.84375,0.90625 -0.046875,0 -0.28125,0 -0.46875,-0.140625 0.359375,-0.109375 0.53125,-0.453125 0.53125,-0.6875 0,-0.21875 -0.171875,-0.46875 -0.5,-0.46875 -0.34375,0 -0.71875,0.296875 -0.71875,0.78125 0,0.53125 0.53125,0.875 1.140625,0.875 0.5625,0 0.9375,-0.421875 1.0625,-0.609375 0.25,0.421875 0.8125,0.609375 1.375,0.609375 1.265625,0 1.9375,-1.21875 1.9375,-1.546875 0,-0.140625 -0.15625,-0.140625 -0.234375,-0.140625 -0.125,0 -0.1875,0 -0.234375,0.125 -0.28125,0.90625 -1,1.203125 -1.421875,1.203125 -0.375,0 -0.546875,-0.171875 -0.546875,-0.5 0,-0.203125 0.125,-0.734375 0.21875,-1.109375 0.0625,-0.25 0.296875,-1.1875 0.34375,-1.34375 0.15625,-0.609375 0.5,-0.90625 0.84375,-0.90625 0.0625,0 0.28125,0 0.484375,0.140625 z m 0,0" + id="id-3c104b3c-9cd9-4eb9-9732-d549110240b9" /> + + + + - + style="stroke:none;stroke-width:0" + d="m 3.8125,-0.984375 c 0.640625,-0.65625 0.890625,-1.59375 0.890625,-1.65625 0,-0.09375 -0.078125,-0.09375 -0.109375,-0.09375 C 4.5,-2.734375 4.5,-2.71875 4.453125,-2.5625 4.328125,-2.109375 4.09375,-1.671875 3.796875,-1.296875 3.796875,-1.40625 3.78125,-1.875 3.765625,-1.9375 3.65625,-2.625 3.140625,-3.078125 2.4375,-3.078125 c -1.015625,0 -2,0.953125 -2,1.9375 0,0.640625 0.46875,1.203125 1.265625,1.203125 0.640625,0 1.21875,-0.28125 1.609375,-0.578125 0.171875,0.5 0.515625,0.578125 0.734375,0.578125 0.40625,0 0.65625,-0.328125 0.65625,-0.484375 C 4.703125,-0.5 4.609375,-0.5 4.578125,-0.5 c -0.09375,0 -0.109375,0.03125 -0.125,0.0625 -0.09375,0.265625 -0.3125,0.3125 -0.390625,0.3125 -0.09375,0 -0.21875,0 -0.25,-0.859375 z M 3.265625,-0.75 C 2.578125,-0.1875 2,-0.125 1.734375,-0.125 c -0.46875,0 -0.71875,-0.3125 -0.71875,-0.78125 0,-0.1875 0.09375,-0.953125 0.453125,-1.4375 C 1.796875,-2.765625 2.1875,-2.875 2.4375,-2.875 c 0.546875,0 0.71875,0.53125 0.765625,0.96875 0.046875,0.296875 0.03125,0.796875 0.0625,1.15625 z m 0,0" + id="id-9365e058-f61e-46d9-a219-da7090ec0b9c" /> + - - + id="id-4d2d98ea-bc96-468b-a4e4-1f59ac7fd4d8"> + transform="translate(254.189,191.137)" + id="g8315"> + id="id-ee0eae7d-aafd-44c0-a691-929b638e1830" /> + transform="translate(261.522,191.137)" + id="g8318"> + id="id-867d9392-4e7e-4823-8bb5-a9f9a413eca6" /> + transform="translate(265.95,191.137)" + id="g8321"> + id="id-93d34c5f-12c4-4b67-a843-a4671113c35a" /> + transform="translate(270.931,191.137)" + id="g8324"> + id="id-1e6ca4cb-d874-4da8-b52b-c6b4f17f761b" /> - - - + id="id-d68b3e3e-95be-4d63-b6e2-9dfe71315d12"> + transform="translate(277.016,191.137)" + id="g8328"> + style="stroke:none;stroke-width:0" + d="m 1.71875,-3.75 v -0.65625 l -1.4375,0.109375 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5 v 4.65625 C 1.0625,1.625 0.953125,1.625 0.28125,1.625 V 1.9375 C 0.625,1.921875 1.140625,1.90625 1.390625,1.90625 c 0.28125,0 0.78125,0.015625 1.125,0.03125 V 1.625 C 1.859375,1.625 1.75,1.625 1.75,1.171875 V -0.59375 c 0.046875,0.171875 0.46875,0.703125 1.21875,0.703125 1.1875,0 2.21875,-0.984375 2.21875,-2.265625 0,-1.265625 -0.953125,-2.25 -2.078125,-2.25 -0.78125,0 -1.203125,0.4375 -1.390625,0.65625 z M 1.75,-1.140625 v -2.21875 C 2.03125,-3.875 2.515625,-4.15625 3.03125,-4.15625 c 0.734375,0 1.328125,0.875 1.328125,2 0,1.203125 -0.6875,2.046875 -1.421875,2.046875 -0.40625,0 -0.78125,-0.203125 -1.046875,-0.609375 C 1.75,-0.921875 1.75,-0.9375 1.75,-1.140625 Z m 0,0" + id="id-b672f3a2-646d-4d2f-b7e9-fa0bef7bbc66" /> + id="id-2a2daca9-d900-4bb6-8b84-f4de897fd4e6"> + transform="translate(282.83,191.137)" + id="g8332"> - - - + id="id-d044561c-8602-4e07-ab0d-aada7dde496d" /> + transform="translate(287.812,191.137)" + id="g8335"> + style="stroke:none;stroke-width:0" + d="m 2.078125,-1.9375 c 0.21875,0.046875 1.03125,0.203125 1.03125,0.921875 0,0.5 -0.34375,0.90625 -1.125,0.90625 -0.84375,0 -1.203125,-0.5625 -1.390625,-1.421875 C 0.5625,-1.65625 0.5625,-1.6875 0.453125,-1.6875 c -0.125,0 -0.125,0.0625 -0.125,0.234375 V -0.125 c 0,0.171875 0,0.234375 0.109375,0.234375 0.046875,0 0.0625,-0.015625 0.25,-0.203125 0.015625,-0.015625 0.015625,-0.03125 0.203125,-0.21875 0.4375,0.40625 0.890625,0.421875 1.09375,0.421875 1.140625,0 1.609375,-0.671875 1.609375,-1.390625 0,-0.515625 -0.296875,-0.828125 -0.421875,-0.9375 C 2.84375,-2.546875 2.453125,-2.625 2.03125,-2.703125 1.46875,-2.8125 0.8125,-2.9375 0.8125,-3.515625 c 0,-0.359375 0.25,-0.765625 1.109375,-0.765625 1.09375,0 1.15625,0.90625 1.171875,1.203125 0,0.09375 0.09375,0.09375 0.109375,0.09375 0.140625,0 0.140625,-0.046875 0.140625,-0.234375 v -1.015625 c 0,-0.15625 0,-0.234375 -0.109375,-0.234375 -0.046875,0 -0.078125,0 -0.203125,0.125 -0.03125,0.03125 -0.125,0.125 -0.171875,0.15625 -0.375,-0.28125 -0.78125,-0.28125 -0.9375,-0.28125 -1.21875,0 -1.59375,0.671875 -1.59375,1.234375 0,0.34375 0.15625,0.625 0.421875,0.84375 0.328125,0.25 0.609375,0.3125 1.328125,0.453125 z m 0,0" + id="id-79f93dae-6f67-4e74-9357-df605184e3cb" /> + transform="translate(291.741,191.137)" + id="g8338"> - - - - - - + id="id-6d2a8b49-705c-4236-a728-799a0ee29b97" /> + transform="translate(294.509,191.137)" + id="g8341"> + id="id-a66412af-6df2-46c0-9002-d5d70bcb84e8" /> + transform="translate(298.383,191.137)" + id="g8344"> + style="stroke:none;stroke-width:0" + d="M 1.765625,-4.40625 0.375,-4.296875 v 0.3125 c 0.640625,0 0.734375,0.0625 0.734375,0.546875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 C 0.640625,-0.015625 1.1875,-0.03125 1.421875,-0.03125 1.78125,-0.03125 2.125,-0.015625 2.46875,0 v -0.3125 c -0.671875,0 -0.703125,-0.046875 -0.703125,-0.4375 z m 0.03125,-1.734375 c 0,-0.3125 -0.234375,-0.53125 -0.515625,-0.53125 -0.3125,0 -0.53125,0.265625 -0.53125,0.53125 0,0.265625 0.21875,0.53125 0.53125,0.53125 0.28125,0 0.515625,-0.21875 0.515625,-0.53125 z m 0,0" + id="id-23d8c37f-e12a-431c-ad8d-decb6cc9da04" /> - - - - - - - - - - - - - - - + transform="translate(301.151,191.137)" + id="g8347"> - - - - - - - - - - - + id="id-9eec9787-b2ed-462f-9dfd-52d85d6428b0" /> + + - + id="id-2c59c728-62c3-47a9-93ff-f11cc36155ab" /> + - - - - - + id="id-ad9a1a2f-957d-4836-968f-fd1b00a89254"> + transform="translate(314.985,191.137)" + id="g8354"> + id="id-ed7aedaf-c7ea-432b-a4b4-1397233179e1" /> + transform="translate(319.966,191.137)" + id="g8357"> + style="stroke:none;stroke-width:0" + d="m 1.75,-4.296875 v -1.15625 c 0,-0.875 0.46875,-1.359375 0.90625,-1.359375 0.03125,0 0.1875,0 0.328125,0.078125 C 2.875,-6.703125 2.6875,-6.5625 2.6875,-6.3125 c 0,0.21875 0.15625,0.421875 0.4375,0.421875 0.28125,0 0.4375,-0.203125 0.4375,-0.4375 0,-0.375 -0.375,-0.703125 -0.90625,-0.703125 -0.6875,0 -1.546875,0.53125 -1.546875,1.59375 v 1.140625 h -0.78125 v 0.3125 h 0.78125 V -0.75 C 1.109375,-0.3125 1,-0.3125 0.34375,-0.3125 V 0 c 0.390625,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.40625,0 0.875,0 1.265625,0.03125 V -0.3125 H 2.53125 c -0.734375,0 -0.75,-0.109375 -0.75,-0.46875 v -3.203125 h 1.125 v -0.3125 z m 0,0" + id="id-2c6007b0-ebce-4ff7-816c-d412bbf7220e" /> + + + transform="translate(326.338,191.137)" + id="g8361"> + style="stroke:none;stroke-width:0" + d="M 1.09375,-3.421875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.359375,-0.015625 0.859375,-0.03125 1.140625,-0.03125 0.25,0 0.765625,0.015625 1.109375,0.03125 v -0.3125 c -0.671875,0 -0.78125,0 -0.78125,-0.4375 V -2.59375 C 1.78125,-3.625 2.5,-4.1875 3.125,-4.1875 c 0.640625,0 0.75,0.53125 0.75,1.109375 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.34375,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.25,0 0.78125,0.015625 1.109375,0.03125 v -0.3125 c -0.515625,0 -0.765625,0 -0.765625,-0.296875 v -1.90625 c 0,-0.859375 0,-1.15625 -0.3125,-1.515625 -0.140625,-0.171875 -0.46875,-0.375 -1.046875,-0.375 C 2.46875,-4.40625 2,-3.984375 1.71875,-3.359375 V -4.40625 L 0.3125,-4.296875 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 z m 0,0" + id="id-4227d877-23fb-4915-aed9-f9f204f41c8b" /> + transform="translate(331.873,191.137)" + id="g8364"> + style="stroke:none;stroke-width:0" + d="M 4.6875,-2.140625 C 4.6875,-3.40625 3.703125,-4.46875 2.5,-4.46875 c -1.25,0 -2.21875,1.09375 -2.21875,2.328125 0,1.296875 1.03125,2.25 2.203125,2.25 1.203125,0 2.203125,-0.984375 2.203125,-2.25 z m -2.1875,2 c -0.4375,0 -0.875,-0.203125 -1.140625,-0.671875 -0.25,-0.4375 -0.25,-1.046875 -0.25,-1.40625 0,-0.390625 0,-0.921875 0.234375,-1.359375 C 1.609375,-4.03125 2.078125,-4.25 2.484375,-4.25 c 0.4375,0 0.859375,0.21875 1.125,0.65625 0.265625,0.421875 0.265625,1 0.265625,1.375 0,0.359375 0,0.90625 -0.21875,1.34375 C 3.421875,-0.421875 2.984375,-0.140625 2.5,-0.140625 Z m 0,0" + id="id-058b2714-0322-4ce5-b128-0ced3d7e6ae9" /> + + + transform="translate(337.124,191.137)" + id="g8368"> + style="stroke:none;stroke-width:0" + d="m 3.78125,-0.546875 v 0.65625 L 5.25,0 v -0.3125 c -0.6875,0 -0.78125,-0.0625 -0.78125,-0.5625 V -6.921875 L 3.046875,-6.8125 V -6.5 c 0.6875,0 0.765625,0.0625 0.765625,0.5625 v 2.15625 c -0.28125,-0.359375 -0.71875,-0.625 -1.25,-0.625 -1.171875,0 -2.21875,0.984375 -2.21875,2.265625 0,1.265625 0.96875,2.25 2.109375,2.25 0.640625,0 1.078125,-0.34375 1.328125,-0.65625 z m 0,-2.671875 v 2.046875 c 0,0.171875 0,0.1875 -0.109375,0.359375 C 3.375,-0.328125 2.9375,-0.109375 2.5,-0.109375 2.046875,-0.109375 1.6875,-0.375 1.453125,-0.75 1.203125,-1.15625 1.171875,-1.71875 1.171875,-2.140625 1.171875,-2.5 1.1875,-3.09375 1.46875,-3.546875 1.6875,-3.859375 2.0625,-4.1875 2.609375,-4.1875 c 0.34375,0 0.765625,0.15625 1.0625,0.59375 0.109375,0.171875 0.109375,0.1875 0.109375,0.375 z m 0,0" + id="id-2d0214e4-555b-4c0c-be95-04c62486a47a" /> + transform="translate(342.659,191.137)" + id="g8371"> + style="stroke:none;stroke-width:0" + d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0" + id="id-4dafd578-c0a2-4fb1-b797-3aa30eb2603f" /> + + + transform="translate(350.411,191.137)" + id="g8375"> + style="stroke:none;stroke-width:0" + d="m 4.75,-2.359375 c 0,-1.5625 -0.921875,-2.046875 -1.65625,-2.046875 -1.375,0 -2.6875,1.421875 -2.6875,2.828125 0,0.9375 0.59375,1.6875 1.625,1.6875 0.625,0 1.34375,-0.234375 2.09375,-0.84375 0.125,0.53125 0.453125,0.84375 0.90625,0.84375 0.53125,0 0.84375,-0.546875 0.84375,-0.703125 0,-0.078125 -0.0625,-0.109375 -0.125,-0.109375 -0.0625,0 -0.09375,0.03125 -0.125,0.109375 -0.1875,0.484375 -0.546875,0.484375 -0.5625,0.484375 -0.3125,0 -0.3125,-0.78125 -0.3125,-1.015625 0,-0.203125 0,-0.234375 0.109375,-0.34375 C 5.796875,-2.65625 6,-3.8125 6,-3.8125 6,-3.84375 5.984375,-3.921875 5.875,-3.921875 c -0.09375,0 -0.09375,0.03125 -0.140625,0.21875 -0.1875,0.625 -0.515625,1.375 -0.984375,1.96875 z m -0.65625,1.375 c -0.890625,0.765625 -1.65625,0.875 -2.046875,0.875 -0.59375,0 -0.90625,-0.453125 -0.90625,-1.09375 0,-0.484375 0.265625,-1.5625 0.578125,-2.0625 C 2.1875,-4 2.734375,-4.1875 3.078125,-4.1875 c 0.984375,0 0.984375,1.3125 0.984375,2.078125 0,0.375 0,0.953125 0.03125,1.125 z m 0,0" + id="id-b6f5d68d-a184-43ca-a866-f045fdcc57a1" /> - - diff --git a/docs/src/devdocs/mapping.md b/docs/src/devdocs/mapping.md index 0d9dca4302..8cf8dba0fd 100644 --- a/docs/src/devdocs/mapping.md +++ b/docs/src/devdocs/mapping.md @@ -8,8 +8,8 @@ The geometric mapping of a finite element from the reference coordinates to the This mapping is given by the geometric shape functions, $\hat{N}_i^g(\boldsymbol{\xi})$, such that ```math \begin{align*} - \boldsymbol{x}(\boldsymbol{\xi}) =& \sum_{i}^N \hat{\boldsymbol{x}}_i \hat{N}_i^g(\boldsymbol{\xi}) \\ - \boldsymbol{J} :=& \frac{\mathrm{d}\boldsymbol{x}}{\mathrm{d}\boldsymbol{\xi}} = \sum_{i}^N \hat{\boldsymbol{x}}_i \otimes \frac{\mathrm{d} \hat{N}_i^g}{\mathrm{d}\boldsymbol{\xi}}\\ + \boldsymbol{x}(\boldsymbol{\xi}) =& \sum_{\alpha=1}^N \hat{\boldsymbol{x}}_\alpha \hat{N}_\alpha^g(\boldsymbol{\xi}) \\ + \boldsymbol{J} :=& \frac{\mathrm{d}\boldsymbol{x}}{\mathrm{d}\boldsymbol{\xi}} = \sum_{\alpha=1}^N \hat{\boldsymbol{x}}_\alpha \otimes \frac{\mathrm{d} \hat{N}_\alpha^g}{\mathrm{d}\boldsymbol{\xi}}\\ \boldsymbol{\mathcal{H}} :=& \frac{\mathrm{d} \boldsymbol{J}}{\mathrm{d} \boldsymbol{\xi}} = \sum_{\alpha=1}^N \hat{\boldsymbol{x}}_\alpha \otimes \frac{\mathrm{d}^2 \hat{N}^g_\alpha}{\mathrm{d} \boldsymbol{\xi}^2} \end{align*} From 2c67048f2b9b101c442a956761a585d3c17690df Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 17:37:09 +0200 Subject: [PATCH 052/145] Add white background to make visible in dark mode --- docs/src/assets/fe_mapping.svg | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/src/assets/fe_mapping.svg b/docs/src/assets/fe_mapping.svg index 2933e1b945..a377c77528 100644 --- a/docs/src/assets/fe_mapping.svg +++ b/docs/src/assets/fe_mapping.svg @@ -3,8 +3,8 @@ + + + Date: Fri, 13 Oct 2023 17:55:33 +0200 Subject: [PATCH 053/145] Add error if cell===nothing for non-identity mappings --- src/FEValues/cell_values.jl | 6 +++++- src/FEValues/face_values.jl | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/FEValues/cell_values.jl b/src/FEValues/cell_values.jl index f57c05d145..9a507e8830 100644 --- a/src/FEValues/cell_values.jl +++ b/src/FEValues/cell_values.jl @@ -81,10 +81,14 @@ end getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) - check_reinit_sdim_consistency(:CellValues, shape_gradient_type(cv), eltype(x)) geo_mapping = cv.geo_mapping fun_values = cv.fun_values n_geom_basefuncs = getngeobasefunctions(geo_mapping) + + check_reinit_sdim_consistency(:CellValues, shape_gradient_type(cv), eltype(x)) + if cell === nothing && !isa(get_mapping_type(fun_values), IdentityMapping) + throw(ArgumentError("The cell::AbstractCell input is required to reinit! non-identity function mappings")) + end if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs throw_incompatible_coord_length(length(x), n_geom_basefuncs) end diff --git a/src/FEValues/face_values.jl b/src/FEValues/face_values.jl index a2ae02c175..acd32c932b 100644 --- a/src/FEValues/face_values.jl +++ b/src/FEValues/face_values.jl @@ -109,14 +109,22 @@ end function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, cell=nothing) where {dim, T} check_reinit_sdim_consistency(:FaceValues, shape_gradient_type(fv), eltype(x)) - @boundscheck checkface(fv, face_nr) + checkface(fv, face_nr) + fv.current_face[] = face_nr + n_geom_basefuncs = getngeobasefunctions(fv) - length(x) == n_geom_basefuncs || throw_incompatible_coord_length(length(x), n_geom_basefuncs) + if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs + throw_incompatible_coord_length(length(x), n_geom_basefuncs) + end - fv.current_face[] = face_nr - + # Must be done after setting current face, which should be done after checkface geo_mapping = get_geo_mapping(fv) fun_values = get_fun_values(fv) + + if cell === nothing && !isa(get_mapping_type(fun_values), IdentityMapping) + throw(ArgumentError("The cell::AbstractCell input is required to reinit! non-identity function mappings")) + end + @inbounds for (q_point, w) in pairs(getweights(fv.qr, face_nr)) mapping = calculate_mapping(geo_mapping, q_point, x) J = getjacobian(mapping) From 35e87903494733652d1b5ace0352ac8bdd325568 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 19:51:22 +0200 Subject: [PATCH 054/145] Move mapping docs to topics and add walkthrough of SimpleCellValues --- docs/make.jl | 2 + docs/src/assets/references.bib | 11 ++- docs/src/devdocs/index.md | 2 +- .../mapping.md => topics/FEValues.md} | 34 ++++++- docs/src/topics/SimpleCellValues.jl | 98 +++++++++++++++++++ 5 files changed, 141 insertions(+), 6 deletions(-) rename docs/src/{devdocs/mapping.md => topics/FEValues.md} (74%) create mode 100644 docs/src/topics/SimpleCellValues.jl diff --git a/docs/make.jl b/docs/make.jl index fb4338b7a3..ced312cb19 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -63,6 +63,8 @@ bibtex_plugin = CitationBibliography( "Topic guides" => [ "Topic guide overview" => "topics/index.md", "topics/fe_intro.md", + #"topics/interpolations.md", + "topics/FEValues.md", "topics/degrees_of_freedom.md", "topics/assembly.md", "topics/boundary_conditions.md", diff --git a/docs/src/assets/references.bib b/docs/src/assets/references.bib index 2366a92481..a237a86296 100644 --- a/docs/src/assets/references.bib +++ b/docs/src/assets/references.bib @@ -60,6 +60,15 @@ @article{Scroggs2022 @phdthesis{Cenanovic2017, author={Mirza Cenanovic}, title={Finite element methods for surface problems}, - school={J\o{}pk\o{}ping University, School of Engineering}, + school={Jönköping University, School of Engineering}, year=2017 } +@misc{Kirby2017, + title={A general approach to transforming finite elements}, + author={Robert C. Kirby}, + year={2017}, + eprint={1706.09017}, + doi={10.48550/arXiv.1706.09017}, + archivePrefix={arXiv}, + primaryClass={math.NA} +} \ No newline at end of file diff --git a/docs/src/devdocs/index.md b/docs/src/devdocs/index.md index 75b50844c6..3560eff4a1 100644 --- a/docs/src/devdocs/index.md +++ b/docs/src/devdocs/index.md @@ -5,5 +5,5 @@ developing the library. ```@contents Depth = 1 -Pages = ["reference_cells.md", "interpolations.md", "elements.md", "mapping.md", "dofhandler.md", "performance.md"] +Pages = ["reference_cells.md", "interpolations.md", "elements.md", "dofhandler.md", "performance.md"] ``` diff --git a/docs/src/devdocs/mapping.md b/docs/src/topics/FEValues.md similarity index 74% rename from docs/src/devdocs/mapping.md rename to docs/src/topics/FEValues.md index 8cf8dba0fd..2273c528d2 100644 --- a/docs/src/devdocs/mapping.md +++ b/docs/src/topics/FEValues.md @@ -1,4 +1,7 @@ -# Mapping of finite elements +# FEValues +A key type of object in `Ferrite.jl` are the so-called `FEValues`, where the most common ones are `CellValues` and `FaceValues`. These objects are used inside the element routines and are used to query the integration weights, shape function values and gradients, and much more, see [`CellValues`](@ref) and [`FaceValues`](@ref). In order for these values to be correct, it is necessary to reinitialize these for the current cell by using the [`reinit!`](@ref) function. This maps the values from the reference cell to the actual cell, a process which is described in detail below, see [Mapping of finite elements](@ref mapping_theory). Thereafter, we show an implementation of a [`SimpleCellValues`](@ref SimpleCellValues) type for the most standard case, excluding the generalizations and optimization that complicates the code for e.g. `CellValues`. + +## [Mapping of finite elements](@id mapping_theory) The shape functions and gradients stored in an `FEValues` object, is reinitialized for each cell by calling the `reinit!` function. The main part of this calculation, considers how to map the functions described on the reference cell, to the actual cell. The geometric mapping of a finite element from the reference coordinates to the real coordinates is shown in the following illustration. @@ -26,7 +29,7 @@ We require that the mapping from reference coordinates to real coordinates is [d ``` Depending on the function interpolation, we may want different types of mappings to conserve certain properties of the fields. This results in the different mapping types described below. -## Identity mapping +### Identity mapping `Ferrite.IdentityMapping` For scalar fields, we always use scalar base functions. For tensorial fields (non-scalar, e.g. vector-fields), the base functions can be constructed from scalar base functions, by using e.g. `VectorizedInterpolation`. From the perspective of the mapping, however, each component is mapped as an individual scalar base function. And for scalar base functions, we only require that the value of the base function is invariant to the element shape (real coordinate), and only depends on the reference coordinate, i.e. @@ -37,7 +40,7 @@ For scalar fields, we always use scalar base functions. For tensorial fields (no \end{align*} ``` -## Covariant Piola mapping, H(curl) +### Covariant Piola mapping, H(curl) `Ferrite.CovariantPiolaMapping` The covariant Piola mapping of a vectorial base function preserves the tangential components. For the value, the mapping is defined as @@ -69,7 +72,7 @@ which yields the gradient, \end{align*} ``` -## Contravariant Piola mapping, H(div) +### Contravariant Piola mapping, H(div) `Ferrite.ContravariantPiolaMapping` The covariant Piola mapping of a vectorial base function preserves the normal components. For the value, the mapping is defined as @@ -101,3 +104,26 @@ This gives the gradient \end{align*} ``` +## [Walkthrough: Creating `SimpleCellValues`](@id SimpleCellValues) +In the following, we walk through how to create a `SimpleCellValues` type which +works similar to `Ferrite.jl`'s `CellValues`, but is not performance optimized and not as general. The main purpose is to explain how the `CellValues` works for the standard case of `IdentityMapping` described above. +Please note that several internal functions are used, and these may change without a major version increment. Please see the [Developer documentation](@ref) for their documentation. + +```@eval +# Include the example here, but modify the Literate output to suit being embedded +using Literate, Markdown +filename = "SimpleCellValues" +Literate.markdown(filename*".jl"; execute=true) +contents = read(filename*".md", String) +Literate.script(filename*".jl"; name="SimpleCellValues") +rm(filename*".jl") +rm(filename*".md") +header_end = last(findnext("```", contents, 4))+1 +Markdown.parse(replace(contents[header_end:end], + "*This page was generated using [Literate.jl]"=>"*This example was generated using [Literate.jl]") + ) +``` + +## Further reading +* [defelement.com](https://defelement.com/ciarlet.html#Mapping+finite+elements) +* Kirby (2017) [Kirby2017](@cite) diff --git a/docs/src/topics/SimpleCellValues.jl b/docs/src/topics/SimpleCellValues.jl new file mode 100644 index 0000000000..968c5b8a61 --- /dev/null +++ b/docs/src/topics/SimpleCellValues.jl @@ -0,0 +1,98 @@ +# We start by including `Ferrite` and `Test`, +# to allow us to verify our implementation. +using Ferrite, Test + +# Define a simple version of the cell values object, which only supports +# identity mapping of scalar interpolations, without embedding. +struct SimpleCellValues{T, dim} <: Ferrite.AbstractCellValues + N::Matrix{T} # Precalculated shape values + dNdξ::Matrix{Vec{dim,T}} # Precalculated shape gradients in the reference domain + dNdx::Matrix{Vec{dim,T}} # Cache for shape gradients in the real domain + M::Matrix{T} # Precalculated geometric shape values + dMdξ::Matrix{Vec{dim,T}} # Precalculated geometric shape gradients + weights::Vector{T} # Given quadrature weights in the reference domain + detJdV::Vector{T} # Cache for quadrature weights in the real domain +end; + +# To make it easier to initiate this struct, we create a constructor function +# with the same input as `CellValues`. However, we skip some consistency checking here. +function SimpleCellValues(qr::QuadratureRule, ip_fun::Interpolation, ip_geo::Interpolation, T=Float64) + dim = Ferrite.getdim(ip_fun) + ## Quadrature weights and coordinates (in reference cell) + weights = Ferrite.getweights(qr) + n_qpoints = length(weights) + + ## Function interpolation + n_func_basefuncs = getnbasefunctions(ip_fun) + N = zeros(T, n_func_basefuncs, n_qpoints) + dNdx = zeros(Vec{dim,T}, n_func_basefuncs, n_qpoints) + dNdξ = zeros(Vec{dim,T}, n_func_basefuncs, n_qpoints) + + ## Geometry interpolation + n_geom_basefuncs = getnbasefunctions(ip_geo) + M = zeros(T, n_geom_basefuncs, n_qpoints) + dMdξ = zeros(Vec{dim,T}, n_geom_basefuncs, n_qpoints) + + ## Precalculate function and geometric shape values and gradients + for (qp, ξ) in pairs(Ferrite.getpoints(qr)) + for i in 1:n_func_basefuncs + dNdξ[i, qp], N[i, qp] = Ferrite.shape_gradient_and_value(ip_fun, ξ, i) + end + for i in 1:n_geom_basefuncs + dMdξ[i, qp], M[i, qp] = Ferrite.shape_gradient_and_value(ip_geo, ξ, i) + end + end + + detJdV = zeros(T, n_qpoints) + SimpleCellValues(N, dNdξ, dNdx, M, dMdξ, weights, detJdV) +end; + +# We first define the `getnbasefunctions` +Ferrite.getnbasefunctions(cv::SimpleCellValues) = size(cv.N, 1); + +# Before we define the `reinit!` function to calculate the cached +# values `dNdx` and `detJdV` for the current cell +function Ferrite.reinit!(cv::SimpleCellValues, x::Vector{Vec{dim,T}}) where {dim,T} + for (q_point, w) in pairs(cv.weights) # Loop over each quadrature point + ## Calculate the jacobian, J + J = zero(Tensor{2,dim,T}) + for i in eachindex(x) + J += x[i] ⊗ cv.dMdξ[i, q_point] + end + ## Calculate the correct integration weight for the current q_point + cv.detJdV[q_point] = det(J)*w + ## map the shape gradients to the current geometry + Jinv = inv(J) + for i in 1:getnbasefunctions(cv) + cv.dNdx[i, q_point] = cv.dNdξ[i, q_point] ⋅ Jinv + end + end +end; + +# To make our `SimpleCellValues` work in standard Ferrite code, we need to define how +# to get the shape value and graident: +Ferrite.shape_value(cv::SimpleCellValues, q_point::Int, i::Int) = cv.N[i, q_point] +Ferrite.shape_gradient(cv::SimpleCellValues, q_point::Int, i::Int) = cv.dNdx[i, q_point] + +# Currently, we must also define the following functions (TODO in Ferrite.jl) +Ferrite.shape_value_type(cv::SimpleCellValues) = typeof(shape_value(cv, 1, 1)) +Ferrite.shape_gradient_type(cv::SimpleCellValues) = typeof(shape_gradient(cv, 1, 1)) + +# We are now ready to test, so let's create an instance of our new and the regular cell values +qr = QuadratureRule{RefQuadrilateral}(2) +ip = Lagrange{RefQuadrilateral,1}() +simple_cv = SimpleCellValues(qr, ip, ip) +cv = CellValues(qr, ip, ip) + +# The first thing to try is to reinitialize the cell values to a given cell +grid = generate_grid(Quadrilateral, (2,2)) +x = getcoordinates(grid, 2) +reinit!(simple_cv, x) +reinit!(cv, x) + +# If we now pretend we are inside an element, where we have a vector of element +# degree of freedom values, we can check that the function values and gradients match +ue = rand(getnbasefunctions(simple_cv)) +q_point = 2 +@test function_value(cv, q_point, ue) ≈ function_value(simple_cv, q_point, ue) +@test function_gradient(cv, q_point, ue) ≈ function_gradient(simple_cv, q_point, ue) \ No newline at end of file From c76c0afa7cd80502e8e5ed686369997998b776de Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 20:11:52 +0200 Subject: [PATCH 055/145] Add performance annotations and rename checkface to boundscheck_face --- src/FEValues/face_values.jl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/FEValues/face_values.jl b/src/FEValues/face_values.jl index acd32c932b..0f67746926 100644 --- a/src/FEValues/face_values.jl +++ b/src/FEValues/face_values.jl @@ -62,8 +62,8 @@ end getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_mapping(fv)) getnbasefunctions(fv::FaceValues) = getnbasefunctions(get_fun_values(fv)) -getnquadpoints(fv::FaceValues) = getnquadpoints(fv.qr, getcurrentface(fv)) -getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] +getnquadpoints(fv::FaceValues) = @inbounds getnquadpoints(fv.qr, getcurrentface(fv)) +@propagate_inbounds getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] shape_value_type(fv::FaceValues) = shape_value_type(get_fun_values(fv)) shape_gradient_type(fv::FaceValues) = shape_gradient_type(get_fun_values(fv)) @@ -102,14 +102,17 @@ getnormal(fv::FaceValues, qp::Int) = fv.normals[qp] nfaces(fv::FaceValues) = length(fv.geo_mapping) -function checkface(fv::FaceValues, face::Int) - 0 < face <= nfaces(fv) || error("Face index out of range.") +function boundscheck_face(fv::FaceValues, face_nr::Int) + checkbounds(Bool, 1:nfaces(fv), face_nr) || throw(ArgumentError("Face index out of range.")) return nothing end function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, cell=nothing) where {dim, T} check_reinit_sdim_consistency(:FaceValues, shape_gradient_type(fv), eltype(x)) - checkface(fv, face_nr) + + # Checking face_nr before setting current_face allows us to use @inbounds + # when indexing by getcurrentface(fv) in other places! + boundscheck_face(fv, face_nr) fv.current_face[] = face_nr n_geom_basefuncs = getngeobasefunctions(fv) @@ -117,7 +120,8 @@ function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, ce throw_incompatible_coord_length(length(x), n_geom_basefuncs) end - # Must be done after setting current face, which should be done after checkface + # Must be done after setting current face, + # which should be done after boundscheck_face geo_mapping = get_geo_mapping(fv) fun_values = get_fun_values(fv) From b5e412165ee501d78ab578dd74f043e9558f5176 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 20:24:42 +0200 Subject: [PATCH 056/145] Improve PointValues constructor from CellValues --- src/PointEval/point_values.jl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 083e482990..ee4842c7d5 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -24,7 +24,12 @@ struct PointValues{CV} <: AbstractValues PointValues{CV}(cv::CV) where {CV} = new{CV}(cv) end -PointValues(cv::CellValues) = PointValues(eltype(shape_value(cv,1,1)), cv.fun_values.ip, cv.geo_mapping.ip) +function PointValues(cv::CellValues) + T = typeof(getdetJdV(cv, 1)) + ip_fun = get_function_interpolation(cv) + ip_geo = get_geometric_interpolation(cv) + return PointValues(T, ip_fun, ip_geo) +end function PointValues(ip::Interpolation, ipg::Interpolation = default_geometric_interpolation(ip)) return PointValues(Float64, ip, ipg) end From 089c42a2a9847ce355ac263d4ca990cd234438e7 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 20:25:05 +0200 Subject: [PATCH 057/145] Use internal functions for geometric ip when testing cellvalues --- test/test_cellvalues.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index b6c4b200d0..21ce9a1f84 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -294,7 +294,7 @@ end @testset "CellValues constructor entry points" begin qr = QuadratureRule{RefTriangle}(1) - _get_geo_ip(cv::CellValues) = cv.geo_mapping.ip + for fun_ip in (Lagrange{RefTriangle, 1}(), Lagrange{RefTriangle, 2}()^2) value_type(T) = fun_ip isa ScalarInterpolation ? T : Vec{2, T} grad_type(T) = fun_ip isa ScalarInterpolation ? Vec{2, T} : Tensor{2, 2, T, 4} @@ -302,24 +302,24 @@ end cv = CellValues(qr, fun_ip) @test Ferrite.shape_value_type(cv) == value_type(Float64) @test Ferrite.shape_gradient_type(cv) == grad_type(Float64) - @test _get_geo_ip(cv) == Lagrange{RefTriangle, 1}() + @test Ferrite.get_geometric_interpolation(cv) == Lagrange{RefTriangle, 1}() # Numeric type + quadrature + scalar function cv = CellValues(Float32, qr, fun_ip) @test Ferrite.shape_value_type(cv) == value_type(Float32) @test Ferrite.shape_gradient_type(cv) == grad_type(Float32) - @test _get_geo_ip(cv) == Lagrange{RefTriangle, 1}() + @test Ferrite.get_geometric_interpolation(cv) == Lagrange{RefTriangle, 1}() for geo_ip in (Lagrange{RefTriangle, 2}(), Lagrange{RefTriangle, 2}()^2) scalar_ip(ip) = ip isa VectorizedInterpolation ? ip.ip : ip # Quadrature + scalar function + geo cv = CellValues(qr, fun_ip, geo_ip) @test Ferrite.shape_value_type(cv) == value_type(Float64) @test Ferrite.shape_gradient_type(cv) == grad_type(Float64) - @test _get_geo_ip(cv) == scalar_ip(geo_ip) + @test Ferrite.get_geometric_interpolation(cv) == scalar_ip(geo_ip) # Numeric type + quadrature + scalar function + scalar geo cv = CellValues(Float32, qr, fun_ip, geo_ip) @test Ferrite.shape_value_type(cv) == value_type(Float32) @test Ferrite.shape_gradient_type(cv) == grad_type(Float32) - @test _get_geo_ip(cv) == scalar_ip(geo_ip) + @test Ferrite.get_geometric_interpolation(cv) == scalar_ip(geo_ip) end end end From 07e3851b6d4a83c8428672107ee0f32340f2d142 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 21:33:58 +0200 Subject: [PATCH 058/145] Add devdocs, other docfixes, and fallback for shape value and gradient type --- docs/src/devdocs/FEValues.md | 17 +++++++++++++++++ docs/src/devdocs/index.md | 2 +- docs/src/devdocs/interpolations.md | 1 + docs/src/topics/FEValues.md | 2 +- ...lValues.jl => SimpleCellValues_literate.jl} | 4 ---- src/FEValues/FunctionValues.jl | 15 +++++++++++++++ src/FEValues/GeometryMapping.jl | 18 ++++++++++++++++++ src/FEValues/common_values.jl | 14 ++++++++------ src/PointEval/point_values.jl | 2 +- src/interpolations.jl | 11 +++++++++++ test/test_cellvalues.jl | 4 ++++ 11 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 docs/src/devdocs/FEValues.md rename docs/src/topics/{SimpleCellValues.jl => SimpleCellValues_literate.jl} (94%) diff --git a/docs/src/devdocs/FEValues.md b/docs/src/devdocs/FEValues.md new file mode 100644 index 0000000000..81a349ac27 --- /dev/null +++ b/docs/src/devdocs/FEValues.md @@ -0,0 +1,17 @@ +# [FEValues](@id devdocs-fevalues) + +## Type definitions +* `AbstractValues` + * `AbstractCellValues` + * [`CellValues`](@ref) + * `AbstractFaceValues` + * [`FaceValues`](@ref) + * [`PointValues`](@ref) + * `PointValuesInternal` (Optimized version of PointValues) + +## Internal types +```@docs +Ferrite.GeometryMapping +Ferrite.MappingValues +Ferrite.FunctionValues +``` \ No newline at end of file diff --git a/docs/src/devdocs/index.md b/docs/src/devdocs/index.md index 3560eff4a1..9c16b83d7c 100644 --- a/docs/src/devdocs/index.md +++ b/docs/src/devdocs/index.md @@ -5,5 +5,5 @@ developing the library. ```@contents Depth = 1 -Pages = ["reference_cells.md", "interpolations.md", "elements.md", "dofhandler.md", "performance.md"] +Pages = ["reference_cells.md", "interpolations.md", "elements.md", "FEValues.md", "dofhandler.md", "performance.md"] ``` diff --git a/docs/src/devdocs/interpolations.md b/docs/src/devdocs/interpolations.md index 23b3ec1a0a..3a54d5c92a 100644 --- a/docs/src/devdocs/interpolations.md +++ b/docs/src/devdocs/interpolations.md @@ -37,6 +37,7 @@ Ferrite.reference_coordinates(::Interpolation) Ferrite.face_to_element_transformation Ferrite.is_discontinuous(::Interpolation) Ferrite.adjust_dofs_during_distribution(::Interpolation) +Ferrite.get_mapping_type ``` for all entities which exist on that reference element. The dof functions default to having no diff --git a/docs/src/topics/FEValues.md b/docs/src/topics/FEValues.md index 2273c528d2..67826b7000 100644 --- a/docs/src/topics/FEValues.md +++ b/docs/src/topics/FEValues.md @@ -112,7 +112,7 @@ Please note that several internal functions are used, and these may change witho ```@eval # Include the example here, but modify the Literate output to suit being embedded using Literate, Markdown -filename = "SimpleCellValues" +filename = "SimpleCellValues_literate" Literate.markdown(filename*".jl"; execute=true) contents = read(filename*".md", String) Literate.script(filename*".jl"; name="SimpleCellValues") diff --git a/docs/src/topics/SimpleCellValues.jl b/docs/src/topics/SimpleCellValues_literate.jl similarity index 94% rename from docs/src/topics/SimpleCellValues.jl rename to docs/src/topics/SimpleCellValues_literate.jl index 968c5b8a61..8f6b2469a7 100644 --- a/docs/src/topics/SimpleCellValues.jl +++ b/docs/src/topics/SimpleCellValues_literate.jl @@ -74,10 +74,6 @@ end; Ferrite.shape_value(cv::SimpleCellValues, q_point::Int, i::Int) = cv.N[i, q_point] Ferrite.shape_gradient(cv::SimpleCellValues, q_point::Int, i::Int) = cv.dNdx[i, q_point] -# Currently, we must also define the following functions (TODO in Ferrite.jl) -Ferrite.shape_value_type(cv::SimpleCellValues) = typeof(shape_value(cv, 1, 1)) -Ferrite.shape_gradient_type(cv::SimpleCellValues) = typeof(shape_gradient(cv, 1, 1)) - # We are now ready to test, so let's create an instance of our new and the regular cell values qr = QuadratureRule{RefQuadrilateral}(2) ip = Lagrange{RefQuadrilateral,1}() diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 48f2a4e0e3..0a2d84cba6 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -29,6 +29,14 @@ typeof_dNdξ(::Type{T}, ::SInterpolationDims{rdim}) where {T,rdim} = SVector{rdi typeof_dNdξ(::Type{T}, ::VInterpolationDims{dim,dim,dim}) where {T,dim} = Tensor{2,dim,T} typeof_dNdξ(::Type{T}, ::VInterpolationDims{rdim,<:Any,vdim}) where {T,rdim,vdim} = SMatrix{vdim,rdim,T} # If vdim=rdim!=sdim Tensor would be possible... +""" + FunctionValues(::Type{T}, ip_fun, qr::QuadratureRule, ip_geo::VectorizedInterpolation) + +Create a `FunctionValues` object containing the shape values and gradients for both the reference +cell (precalculated) and the real cell (updated in `reinit!`). +""" +FunctionValues + struct FunctionValues{IP, N_t, dNdx_t, dNdξ_t} ip::IP # ::Interpolation N_x::N_t # ::AbstractMatrix{Union{<:Tensor,<:Number}} @@ -108,6 +116,13 @@ struct ContravariantPiolaMapping end get_mapping_type(fv::FunctionValues) = get_mapping_type(fv.ip) +""" + requires_hessian(mapping) + +Does the `mapping` type require the hessian, d²M/dx², +to map the function values and gradients from the reference cell +to the real cell geometry? +""" requires_hessian(::IdentityMapping) = false requires_hessian(::ContravariantPiolaMapping) = true requires_hessian(::CovariantPiolaMapping) = true diff --git a/src/FEValues/GeometryMapping.jl b/src/FEValues/GeometryMapping.jl index 4038f1f460..4673427401 100644 --- a/src/FEValues/GeometryMapping.jl +++ b/src/FEValues/GeometryMapping.jl @@ -1,3 +1,13 @@ +""" + MappingValues(J, H) + +The mapping values are calculated based on a +`geometric_mapping::GeometryMapping` along with the cell coordinates, +and the stored jacobian, `J`, and potentially hessian, `H`, are +used when mapping the `FunctionValues` to the current cell during `reinit!`. +""" +MappingValues + struct MappingValues{JT, HT<:Union{Nothing,AbstractTensor{3}}} J::JT # dx/dξ # Jacobian H::HT # dJ/dξ # Hessian @@ -19,6 +29,14 @@ function RequiresHessian(ip_fun::Interpolation, ip_geo::Interpolation) RequiresHessian(requires_hessian(get_mapping_type(ip_fun))) end +""" + GeometryMapping(::Type{T}, ip_geo, qr::QuadratureRule, ::RequiresHessian{B}) + +Create a `GeometryMapping` object which contains the geometric shape, gradients, and, +if `B==true`, the hessian values. `T<:AbstractFloat` gives the numeric type of the values. +""" +GeometryMapping + struct GeometryMapping{IP, M_t, dMdξ_t, d2Mdξ2_t} ip::IP # ::Interpolation Geometric interpolation M::M_t # ::AbstractVector{<:Number} Values of geometric shape functions diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index b1c9b5d537..e5aa90a4c8 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -137,14 +137,15 @@ function function_value(fe_v::AbstractValues, q_point::Int, u::AbstractVector, d return val end -# TODO: Implement fallback or require this to be defined? -# Alt: shape_value_type(cv) = typeof(shape_value(cv, qp=1, i=1)) """ shape_value_type(fe_v::AbstractValues) Return the type of `shape_value(fe_v, q_point, base_function)` """ -function shape_value_type end +function shape_value_type(fe_v::AbstractValues) + # Default fallback + return typeof(shape_value(fe_v, 1, 1)) +end function_value_init(cv::AbstractValues, ::AbstractVector{T}) where {T} = zero(shape_value_type(cv)) * zero(T) @@ -188,14 +189,15 @@ function function_gradient(fe_v::AbstractValues, q_point::Int, u::AbstractVector return grad end -# TODO: Implement fallback or require this to be defined? -# Alt: shape_gradient_type(cv) = typeof(shape_gradient(cv, qp=1, i=1)) """ shape_gradient_type(fe_v::AbstractValues) Return the type of `shape_gradient(fe_v, q_point, base_function)` """ -function shape_gradient_type end +function shape_gradient_type(fe_v::AbstractValues) + # Default fallback + return typeof(shape_gradient(fe_v, 1, 1)) +end function function_gradient_init(cv::AbstractValues, ::AbstractVector{T}) where {T} return zero(shape_gradient_type(cv)) * zero(T) diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index ee4842c7d5..13e75b1104 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -71,7 +71,7 @@ function reinit!(pv::PointValues, x::AbstractVector{<:Vec{D}}, ξ::Vec{D}) where return nothing end -# Optimized version of PointScalarValues which avoids i) recomputation of dNdξ and +# Optimized version of PointValues which avoids i) recomputation of dNdξ and # ii) recomputation of dNdx. Only allows function evaluation (no gradients) which is # what is used in evaluate_at_points. struct PointValuesInternal{IP, N_t} <: AbstractValues diff --git a/src/interpolations.jl b/src/interpolations.jl index f8235f2bb0..009ab6b7bd 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1514,6 +1514,17 @@ end reference_coordinates(ip::VectorizedInterpolation) = reference_coordinates(ip.ip) is_discontinuous(::Type{<:VectorizedInterpolation{<:Any, <:Any, <:Any, ip}}) where {ip} = is_discontinuous(ip) + +""" + get_mapping_type(ip::Interpolation) + +Get the type of mapping from the reference cell to the real cell for an +interpolation `ip`. Subtypes of `ScalarInterpolation` and `VectorizedInterpolation` +return `IdentityMapping()`, but other non-scalar interpolations may request different +mapping types. +""" +function get_mapping_type end + get_mapping_type(::ScalarInterpolation) = IdentityMapping() get_mapping_type(::VectorizedInterpolation) = IdentityMapping() diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 21ce9a1f84..eecccb7dca 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -334,4 +334,8 @@ end println(stdout) end +@testset "SimpleCellValues" begin + include(joinpath(@__DIR__, "../docs/src/topics/SimpleCellValues_literate.jl")) +end + end # of testset From f3e6564cc1f2dcc6dbf6448a091145422508a987 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 22:15:34 +0200 Subject: [PATCH 059/145] Fix so that API docs for FEValues is ok again --- docs/src/reference/fevalues.md | 24 +++++++++++++++--------- src/FEValues/common_values.jl | 10 +++++----- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/docs/src/reference/fevalues.md b/docs/src/reference/fevalues.md index 9aa00fee29..757760fbc6 100644 --- a/docs/src/reference/fevalues.md +++ b/docs/src/reference/fevalues.md @@ -5,12 +5,22 @@ DocTestSetup = :(using Ferrite) # FEValues -## [CellValues](@id reference-cellvalues) +## Main types +[`CellValues`](@ref) and [`FaceValues`](@ref) are the most common +subtypes of `Ferrite.AbstractValues`. ```@docs CellValues +FaceValues +``` + +## Applicable functions +The following functions are applicable to both `CellValues` +and `FaceValues`. + +```@docs reinit! -getnquadpoints(::CellValues) +getnquadpoints getdetJdV shape_value @@ -25,13 +35,9 @@ function_divergence spatial_coordinate ``` -## [FaceValues](@id reference-facevalues) - -All of the methods for [`CellValues`](@ref) apply for `FaceValues` as well. -In addition, there are some methods that are unique for `FaecValues`: +In addition, there are some methods that are unique for `FaceValues`. ```@docs -FaceValues -getcurrentface -getnquadpoints(::FaceValues) +Ferrite.getcurrentface +getnormal ``` diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index e5aa90a4c8..82e0632606 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -1,4 +1,4 @@ -# Common methods for all `Values` objects +# Common methods for all `AbstractValues` objects using Base: @propagate_inbounds @@ -31,7 +31,7 @@ end """ reinit!(cv::CellValues, x::Vector, cell::Union{AbstractCell,Nothing}=nothing) - reinit!(bv::FaceValues, x::Vector, face::Int, cell::Union{AbstractCell,Nothing}=nothing) + reinit!(fv::FaceValues, x::Vector, face::Int, cell::Union{AbstractCell,Nothing}=nothing) Update the `CellValues`/`FaceValues` object for a cell or face with coordinates `x`. The derivatives of the shape functions, and the new integration weights are computed. @@ -40,10 +40,10 @@ For interpolations with non-identity mappings, the current `cell` is also requir reinit! """ - getnquadpoints(fv::FaceValues) + getnquadpoints(fe_v::AbstractValues) -Return the number of quadrature points in `fv`s quadrature for the current -(most recently [`reinit!`](@ref)ed) face. +Return the number of quadrature points. For `FaceValues`, +this is the number for the current face. """ function getnquadpoints end From f5c662c85df3a45bba3357ea979220e29e25333c Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 22:20:56 +0200 Subject: [PATCH 060/145] Rename xx_values.jl to XxValues.jl --- src/FEValues/{cell_values.jl => CellValues.jl} | 0 src/FEValues/{face_values.jl => FaceValues.jl} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/FEValues/{cell_values.jl => CellValues.jl} (100%) rename src/FEValues/{face_values.jl => FaceValues.jl} (100%) diff --git a/src/FEValues/cell_values.jl b/src/FEValues/CellValues.jl similarity index 100% rename from src/FEValues/cell_values.jl rename to src/FEValues/CellValues.jl diff --git a/src/FEValues/face_values.jl b/src/FEValues/FaceValues.jl similarity index 100% rename from src/FEValues/face_values.jl rename to src/FEValues/FaceValues.jl From f9e9aa5e7ef302321d344186d11ca64a114a2878 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 22:21:35 +0200 Subject: [PATCH 061/145] Rename at include too --- src/Ferrite.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ferrite.jl b/src/Ferrite.jl index d30de2ba7e..a5e9507155 100644 --- a/src/Ferrite.jl +++ b/src/Ferrite.jl @@ -84,8 +84,8 @@ include("Quadrature/quadrature.jl") # FEValues include("FEValues/GeometryMapping.jl") include("FEValues/FunctionValues.jl") -include("FEValues/cell_values.jl") -include("FEValues/face_values.jl") +include("FEValues/CellValues.jl") +include("FEValues/FaceValues.jl") include("PointEval/point_values.jl") include("FEValues/common_values.jl") include("FEValues/face_integrals.jl") From c418594fc38111c9bbadef4886e57dfe02a24ab0 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 22:30:24 +0200 Subject: [PATCH 062/145] Merge docs/Manifest from master --- docs/Manifest.toml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 08e315defd..e79fd3ef2e 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.9.2" +julia_version = "1.9.1" manifest_format = "2.0" -project_hash = "8722b6a67abf1b81e2c7808ddfcfb1d737cd0040" +project_hash = "a0caf5d07899f1863658c7736f8530d20d28db07" [[deps.ADTypes]] git-tree-sha1 = "5d2e21d7b0d8c22f67483ef95ebdc39c0e6b6003" @@ -166,10 +166,14 @@ uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.11.4" [[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"] -git-tree-sha1 = "600cc5508d66b78aae350f7accdb58763ac18589" +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.9.10" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] @@ -201,7 +205,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.5+0" +version = "1.0.2+0" [[deps.ConcreteStructs]] git-tree-sha1 = "f749037478283d372048690eb3b5f92a79432b34" @@ -1177,7 +1181,7 @@ version = "0.42.2+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.9.2" +version = "1.9.0" [[deps.PlotThemes]] deps = ["PlotUtils", "Statistics"] @@ -1615,9 +1619,7 @@ version = "0.1.1" [[deps.Tensors]] deps = ["ForwardDiff", "LinearAlgebra", "PrecompileTools", "SIMD", "StaticArrays", "Statistics"] -git-tree-sha1 = "09650779b3c5124b8742986904d6e69f854be0bd" -repo-rev = "kam/3rd_order" -repo-url = "https://github.com/KnutAM/Tensors.jl.git" +git-tree-sha1 = "bcbb366323add300742c9e4a5447e584640aeff2" uuid = "48a634ad-e948-5137-8d70-aa71f2a747f4" version = "1.15.0" From d47ae33fcda924232fb3b382ea4ca8c55df1c9bd Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 23:11:29 +0200 Subject: [PATCH 063/145] Minor formatting fixes according to review --- src/FEValues/FaceValues.jl | 3 ++- src/PointEval/point_values.jl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 0f67746926..3681d78ce1 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -132,6 +132,7 @@ function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, ce @inbounds for (q_point, w) in pairs(getweights(fv.qr, face_nr)) mapping = calculate_mapping(geo_mapping, q_point, x) J = getjacobian(mapping) + # See the `Ferrite.embedded_det` docstring for more background weight_norm = weighted_normal(J, getrefshape(geo_mapping.ip), face_nr) detJ = norm(weight_norm) detJ > 0.0 || throw_detJ_not_pos(detJ) @@ -214,4 +215,4 @@ function spatial_coordinate(bcv::BCValues, q_point::Int, xh::AbstractVector{Vec{ x += bcv.M[i,q_point,face] * xh[i] # geometric_value(fe_v, q_point, i) * xh[i] end return x -end \ No newline at end of file +end diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 13e75b1104..b2f025574e 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -101,4 +101,4 @@ end function Base.show(io::IO, d::MIME"text/plain", cv::PointValues) println(io, "PointValues containing a") show(io, d, cv.cv) -end \ No newline at end of file +end From b5085561ee3f0b549f15635bf3fc61380bf7a735 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 13 Oct 2023 23:46:36 +0200 Subject: [PATCH 064/145] Forgot rename of type param --- src/FEValues/CellValues.jl | 4 ++-- src/FEValues/FaceValues.jl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 9a507e8830..484d0f4131 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -35,9 +35,9 @@ function default_geometric_interpolation(::Interpolation{shape}) where {dim, sha return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) end -struct CellValues{FV, GV, QR, detT<:AbstractVector} <: AbstractCellValues +struct CellValues{FV, GM, QR, detT<:AbstractVector} <: AbstractCellValues fun_values::FV # FunctionValues - geo_mapping::GV # GeometryMapping + geo_mapping::GM # GeometryMapping qr::QR # QuadratureRule detJdV::detT # AbstractVector{<:Number} end diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 3681d78ce1..1b1e473242 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -31,9 +31,9 @@ values of nodal functions, gradients and divergences of nodal functions etc. on """ FaceValues -struct FaceValues{FV, GV, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GV<:AbstractVector{GV}} <: AbstractFaceValues +struct FaceValues{FV, GM, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GM<:AbstractVector{GM}} <: AbstractFaceValues fun_values::V_FV # AbstractVector{FunctionValues} - geo_mapping::V_GV # AbstractVector{GeometryMapping} + geo_mapping::V_GM # AbstractVector{GeometryMapping} qr::QR # FaceQuadratureRule detJdV::detT # AbstractVector{<:Number} normals::nT # AbstractVector{<:Vec} From 4451fac323b2f2600d8927d25f9727c9ff11c104 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 16 Oct 2023 18:34:54 +0200 Subject: [PATCH 065/145] Use new functions --- src/FEValues/FunctionValues.jl | 2 +- src/FEValues/GeometryMapping.jl | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 1098ef296e..54e7075ae8 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -72,7 +72,7 @@ end function precompute_values!(fv::FunctionValues, qr::QuadratureRule) for (qp, ξ) in pairs(getpoints(qr)) - shape_gradients_and_values!(@view(fv.dNdξ[:, qp]), @view(fv.N[:, qp]), fv.ip, ξ) + shape_gradients_and_values!(@view(fv.dNdξ[:, qp]), @view(fv.N_ξ[:, qp]), fv.ip, ξ) end end diff --git a/src/FEValues/GeometryMapping.jl b/src/FEValues/GeometryMapping.jl index ab4538f249..0b71be0abc 100644 --- a/src/FEValues/GeometryMapping.jl +++ b/src/FEValues/GeometryMapping.jl @@ -53,11 +53,11 @@ function GeometryMapping(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, # Hessian (if needed, else nothing) HT = Tensor{2,getdim(ip),T} - dM2dξ2 = RH ? zeros(HT, n_shape, n_qpoints) : nothing + d2Mdξ2 = RH ? zeros(HT, n_shape, n_qpoints) : nothing - geo_mapping = GeometryMapping(ip, M, dMdξ, dM2dξ2) + geo_mapping = GeometryMapping(ip, M, dMdξ, d2Mdξ2) precompute_values!(geo_mapping, qr) - return GeometryMapping(ip, M, dMdξ, dM2dξ2) + return geo_mapping end function Base.copy(v::GeometryMapping) d2Mdξ2_copy = v.d2Mdξ2 === nothing ? nothing : copy(v.d2Mdξ2) @@ -77,7 +77,7 @@ function precompute_values!(gm::GeometryMapping, ::RequiresHessian{true}, qr::Qu ip = get_geometric_interpolation(gm) for (qp, ξ) in pairs(getpoints(qr)) for i in 1:getngeobasefunctions(gm) - gm.dM2dξ2[i, qp], gm.dMdξ[i, qp], gm.M[i, qp] = shape_hessian_gradient_and_value(ip, ξ, i) + gm.d2Mdξ2[i, qp], gm.dMdξ[i, qp], gm.M[i, qp] = shape_hessian_gradient_and_value(ip, ξ, i) end end end From 72e4404998da68bfe6ecb8a88692f7b6d0e35e57 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 16 Oct 2023 20:01:07 +0200 Subject: [PATCH 066/145] Update docs manifest --- docs/Manifest.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index e79fd3ef2e..fbf0d5570e 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.9.1" +julia_version = "1.9.3" manifest_format = "2.0" -project_hash = "a0caf5d07899f1863658c7736f8530d20d28db07" +project_hash = "8722b6a67abf1b81e2c7808ddfcfb1d737cd0040" [[deps.ADTypes]] git-tree-sha1 = "5d2e21d7b0d8c22f67483ef95ebdc39c0e6b6003" @@ -205,7 +205,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.2+0" +version = "1.0.5+0" [[deps.ConcreteStructs]] git-tree-sha1 = "f749037478283d372048690eb3b5f92a79432b34" @@ -1181,7 +1181,7 @@ version = "0.42.2+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.9.0" +version = "1.9.2" [[deps.PlotThemes]] deps = ["PlotUtils", "Statistics"] @@ -1619,9 +1619,9 @@ version = "0.1.1" [[deps.Tensors]] deps = ["ForwardDiff", "LinearAlgebra", "PrecompileTools", "SIMD", "StaticArrays", "Statistics"] -git-tree-sha1 = "bcbb366323add300742c9e4a5447e584640aeff2" +git-tree-sha1 = "3b0c974579e89b0dd35a6ee6a9f10caf5e304d6c" uuid = "48a634ad-e948-5137-8d70-aa71f2a747f4" -version = "1.15.0" +version = "1.16.0" [[deps.Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] From 3049dc43152027eced98bb274f871a32c2a5ce1d Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 14:28:36 +0200 Subject: [PATCH 067/145] Move svg to gh-pages --- .github/workflows/ci.yml | 8 +- docs/Manifest.toml | 118 +- docs/src/assets/fe_mapping.svg | 3325 -------------------------------- docs/src/topics/FEValues.md | 2 +- 4 files changed, 69 insertions(+), 3384 deletions(-) delete mode 100644 docs/src/assets/fe_mapping.svg diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 516ff96937..4679271fad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,13 +26,7 @@ jobs: - uses: julia-actions/setup-julia@v1 with: version: ${{ matrix.julia-version }} - #- uses: julia-actions/julia-buildpkg@v1 - - run: | - julia --color=yes --project=. -e ' - using Pkg - Pkg.add(url="https://github.com/KnutAM/Tensors.jl.git", rev="kam/3rd_order") - Pkg.instantiate()' - shell: bash + - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 with: diff --git a/docs/Manifest.toml b/docs/Manifest.toml index fbf0d5570e..2c9f66289c 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -84,9 +84,9 @@ uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" [[deps.BibInternal]] -git-tree-sha1 = "3a760b38ba8da19e64d29244f06104823ff26f25" +git-tree-sha1 = "0c62b284a52ec39ee831e10bf62c17d587dde75f" uuid = "2027ae74-3657-4b95-ae00-e2f7d55c3e64" -version = "0.3.4" +version = "0.3.5" [[deps.BibParser]] deps = ["BibInternal", "DataStructures", "Dates", "JSONSchema", "YAML"] @@ -96,9 +96,9 @@ version = "0.2.1" [[deps.Bibliography]] deps = ["BibInternal", "BibParser", "DataStructures", "Dates", "FileIO", "YAML"] -git-tree-sha1 = "b506db2482a8e110622ddf1fd0f78bce381af032" +git-tree-sha1 = "520c679daed011ce835d9efa7778863aad6687ed" uuid = "f1be7e48-bf82-45af-a471-ae754a193061" -version = "0.2.19" +version = "0.2.20" [[deps.BitFlags]] git-tree-sha1 = "43b1a4a8f797c1cddadf60499a8a077d4af2cd2d" @@ -136,10 +136,14 @@ uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" version = "1.16.1+1" [[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "e30f2f4e20f7f186dc36529910beaedc60cfa644" +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "e0af648f0692ec1691b5d094b8724ba1346281cf" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.16.0" +version = "1.18.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.CloseOpenIntervals]] deps = ["Static", "StaticArrayInterface"] @@ -149,9 +153,9 @@ version = "0.1.12" [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "02aa26a4cf76381be7f66e020a3eddeb27b0a092" +git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.2" +version = "0.7.3" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] @@ -271,9 +275,9 @@ version = "1.9.1" [[deps.DiffEqBase]] deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "766ab4574433d22ff75ab28e9081114e73cef5d5" +git-tree-sha1 = "95b6df71e218379a831874215b0effaac791d7d7" uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "6.132.0" +version = "6.133.1" [deps.DiffEqBase.extensions] DiffEqBaseDistributionsExt = "Distributions" @@ -334,9 +338,9 @@ version = "0.9.3" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "Dates", "DocStringExtensions", "Downloads", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "Test", "Unicode"] -git-tree-sha1 = "f667b805e90d643aeb1ca70189827f991a7cc115" +git-tree-sha1 = "147a3cbb6ddcd9448fe5e6c426b347efc68f9c86" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.1.0" +version = "1.1.1" [[deps.DocumenterCitations]] deps = ["AbstractTrees", "Bibliography", "Documenter", "Markdown", "MarkdownAST", "OrderedCollections", "Unicode"] @@ -356,9 +360,9 @@ version = "1.0.4" [[deps.EnzymeCore]] deps = ["Adapt"] -git-tree-sha1 = "1091d4bbc2f2f7840a65fc0496c782b955dd82fb" +git-tree-sha1 = "d8701002a745c450c03b890f10d53636d1a8a7ea" uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" -version = "0.6.0" +version = "0.6.2" [[deps.EpollShim_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -409,9 +413,9 @@ version = "1.3.8+0" [[deps.FastBroadcast]] deps = ["ArrayInterface", "LinearAlgebra", "Polyester", "Static", "StaticArrayInterface", "StrideArraysCore"] -git-tree-sha1 = "aa9925a229d45fe3018715238956766fa21804d1" +git-tree-sha1 = "9d77cb1caf03e67514ba60bcfc47c6e131b1950c" uuid = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -version = "0.2.6" +version = "0.2.7" [[deps.FastClosures]] git-tree-sha1 = "acebe244d53ee1b461970f8910c235b259e772ef" @@ -461,9 +465,9 @@ uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FillArrays]] deps = ["LinearAlgebra", "Random"] -git-tree-sha1 = "a20eaa3ad64254c61eeb5f230d9306e937405434" +git-tree-sha1 = "35f0c0f345bff2c6d636f95fdb136323b5a796ef" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.6.1" +version = "1.7.0" weakdeps = ["SparseArrays", "Statistics"] [deps.FillArrays.extensions] @@ -653,9 +657,9 @@ uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" version = "0.1.1" [[deps.Inflate]] -git-tree-sha1 = "5cd07aab533df5170988219191dfad0519391428" +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.3" +version = "0.1.4" [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -685,9 +689,9 @@ version = "1.0.0" [[deps.JLFzf]] deps = ["Pipe", "REPL", "Random", "fzf_jll"] -git-tree-sha1 = "f377670cda23b6b7c1c0b3893e37451c5c1a2185" +git-tree-sha1 = "9fb0b890adab1c0a4a475d4210d51f228bfc250d" uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" -version = "0.1.5" +version = "0.1.6" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -889,11 +893,12 @@ version = "5.0.0+0" [[deps.LinearSolve]] deps = ["ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnumX", "EnzymeCore", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "Libdl", "LinearAlgebra", "MKL_jll", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "SuiteSparse", "UnPack"] -git-tree-sha1 = "435ab14ca589757a0feae6e3e347bc37addda42d" +git-tree-sha1 = "158e45dd35cec1ecade0e554c0104ee89e772d82" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "2.9.2" +version = "2.11.1" [deps.LinearSolve.extensions] + LinearSolveBandedMatricesExt = "BandedMatrices" LinearSolveBlockDiagonalsExt = "BlockDiagonals" LinearSolveCUDAExt = "CUDA" LinearSolveEnzymeExt = "Enzyme" @@ -903,8 +908,10 @@ version = "2.9.2" LinearSolveKrylovKitExt = "KrylovKit" LinearSolveMetalExt = "Metal" LinearSolvePardisoExt = "Pardiso" + LinearSolveRecursiveArrayToolsExt = "RecursiveArrayTools" [deps.LinearSolve.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" @@ -914,6 +921,7 @@ version = "2.9.2" KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" + RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" [[deps.Literate]] deps = ["Base64", "IOCapture", "JSON", "REPL"] @@ -1071,9 +1079,17 @@ version = "1.2.0" [[deps.NonlinearSolve]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "EnumX", "FiniteDiff", "ForwardDiff", "LineSearches", "LinearAlgebra", "LinearSolve", "PrecompileTools", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "445a7ba86794e1f8ee9da3b3b7becf284e2625fd" +git-tree-sha1 = "9203b3333c9610664de2e8cbc23cfd726663df7d" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "2.1.0" +version = "2.4.0" + + [deps.NonlinearSolve.extensions] + NonlinearSolveFastLevenbergMarquardtExt = "FastLevenbergMarquardt" + NonlinearSolveLeastSquaresOptimExt = "LeastSquaresOptim" + + [deps.NonlinearSolve.weakdeps] + FastLevenbergMarquardt = "7a0df574-e128-4d35-8cbd-3d84502bf7ce" + LeastSquaresOptim = "0fc2ff8b-aaa3-5acd-a817-1944a5e08891" [[deps.OCCT_jll]] deps = ["Artifacts", "FreeType2_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll", "Xorg_libXfixes_jll", "Xorg_libXft_jll", "Xorg_libXinerama_jll", "Xorg_libXrender_jll"] @@ -1123,9 +1139,9 @@ version = "0.5.5+0" [[deps.Optim]] deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "963b004d15216f8129f6c0f7d187efa136570be0" +git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.7.7" +version = "1.7.8" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1217,9 +1233,9 @@ version = "1.39.0" [[deps.Polyester]] deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Requires", "Static", "StaticArrayInterface", "StrideArraysCore", "ThreadingUtilities"] -git-tree-sha1 = "c7dc9720390fcc296bf757b3f833f9e41c68a086" +git-tree-sha1 = "398f91235beaac50445557c937ecb0145d171842" uuid = "f517fe37-dbe3-4b94-8317-1923a5111588" -version = "0.7.7" +version = "0.7.8" [[deps.PolyesterWeave]] deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] @@ -1330,9 +1346,9 @@ version = "0.1.0" [[deps.RelocatableFolders]] deps = ["SHA", "Scratch"] -git-tree-sha1 = "90bc7a7c96410424509e4263e277e43250c05691" +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.0" +version = "1.0.1" [[deps.Requires]] deps = ["UUIDs"] @@ -1375,9 +1391,9 @@ version = "0.6.39" [[deps.SciMLBase]] deps = ["ADTypes", "ArrayInterface", "ChainRulesCore", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FillArrays", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "1e09c5c89f5502eb4e3657730b0fb6817a1bca8d" +git-tree-sha1 = "151c322c309d879d114d1c0bee69c61d5933357f" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.3.0" +version = "2.4.3" [deps.SciMLBase.extensions] SciMLBasePyCallExt = "PyCall" @@ -1435,9 +1451,9 @@ version = "1.1.0" [[deps.SimpleNonlinearSolve]] deps = ["ArrayInterface", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "PackageExtensionCompat", "PrecompileTools", "Reexport", "SciMLBase", "StaticArraysCore"] -git-tree-sha1 = "4d53b83af904049c493daaf2a225bcae994a3c59" +git-tree-sha1 = "15ff97fa4881133caa324dacafe28b5ac47ad8a2" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "0.1.20" +version = "0.1.23" [deps.SimpleNonlinearSolve.extensions] SimpleNonlinearSolveNNlibExt = "NNlib" @@ -1467,9 +1483,9 @@ uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "c60ec5c62180f27efea3ba2908480f8055e17cee" +git-tree-sha1 = "5165dfb9fd131cf0c6957a3a7605dede376e7b63" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.1.1" +version = "1.2.0" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] @@ -1477,9 +1493,9 @@ uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [[deps.SparseDiffTools]] deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Random", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] -git-tree-sha1 = "0a4538040f6eeae9016043104056dc6c13e1d8c1" +git-tree-sha1 = "336fd944a1bbb8873bfa8171387608ca93317d68" uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804" -version = "2.7.0" +version = "2.8.0" [deps.SparseDiffTools.extensions] SparseDiffToolsEnzymeExt = "Enzyme" @@ -1602,9 +1618,9 @@ version = "1.0.1" [[deps.Tables]] deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.0" +version = "1.11.1" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -1652,9 +1668,9 @@ uuid = "d5829a12-d9aa-46ab-831f-fb7c9ab06edf" version = "0.1.19" [[deps.Tricks]] -git-tree-sha1 = "aadb748be58b492045b4f56166b5188aa63ce549" +git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f" uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" -version = "0.1.7" +version = "0.1.8" [[deps.TruncatedStacktraces]] deps = ["InteractiveUtils", "MacroTools", "Preferences"] @@ -1663,9 +1679,9 @@ uuid = "781d530d-4396-4725-bb49-402e4bee1e77" version = "1.4.0" [[deps.URIs]] -git-tree-sha1 = "b7a5e99f24892b6824a954199a45e9ffcc1c70f0" +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.5.0" +version = "1.5.1" [[deps.UUIDs]] deps = ["Random", "SHA"] @@ -1747,9 +1763,9 @@ version = "1.25.0+0" [[deps.WriteVTK]] deps = ["Base64", "CodecZlib", "FillArrays", "LightXML", "TranscodingStreams", "VTKBase"] -git-tree-sha1 = "7b46936613e41cfe1c6a5897d243ddcab8feabec" +git-tree-sha1 = "41f0dc2a8f6fd860c266b91fd5cdf4fead65ae69" uuid = "64499a7a-5c06-52f2-abe2-ccb03c286192" -version = "1.18.0" +version = "1.18.1" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] @@ -1950,9 +1966,9 @@ version = "3.2.9+0" [[deps.fzf_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "868e669ccb12ba16eaf50cb2957ee2ff61261c56" +git-tree-sha1 = "47cf33e62e138b920039e8ff9f9841aafe1b733e" uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" -version = "0.29.0+0" +version = "0.35.1+0" [[deps.gmsh_jll]] deps = ["Artifacts", "Cairo_jll", "CompilerSupportLibraries_jll", "FLTK_jll", "FreeType2_jll", "GLU_jll", "GMP_jll", "HDF5_jll", "JLLWrappers", "JpegTurbo_jll", "LLVMOpenMP_jll", "Libdl", "Libglvnd_jll", "METIS_jll", "MMG_jll", "OCCT_jll", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll", "Xorg_libXfixes_jll", "Xorg_libXft_jll", "Xorg_libXinerama_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] diff --git a/docs/src/assets/fe_mapping.svg b/docs/src/assets/fe_mapping.svg deleted file mode 100644 index a377c77528..0000000000 --- a/docs/src/assets/fe_mapping.svg +++ /dev/null @@ -1,3325 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/src/topics/FEValues.md b/docs/src/topics/FEValues.md index 67826b7000..2039f2846c 100644 --- a/docs/src/topics/FEValues.md +++ b/docs/src/topics/FEValues.md @@ -6,7 +6,7 @@ The shape functions and gradients stored in an `FEValues` object, is reinitializ The geometric mapping of a finite element from the reference coordinates to the real coordinates is shown in the following illustration. -![mapping_figure](../assets/fe_mapping.svg) +![mapping_figure](https://raw.githubusercontent.com/Ferrite-FEM/Ferrite.jl/gh-pages/assets/fe_mapping.svg) This mapping is given by the geometric shape functions, $\hat{N}_i^g(\boldsymbol{\xi})$, such that ```math From 24591b5ce2e7641d25e71f074739a32fcfda6b12 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 14:55:56 +0200 Subject: [PATCH 068/145] Use shape_x_x_and_x instead of precompute_values --- src/FEValues/FunctionValues.jl | 30 +++++++++----------------- src/FEValues/GeometryMapping.jl | 38 ++++++++++----------------------- src/FEValues/common_values.jl | 13 +++++++++++ src/interpolations.jl | 15 +++++++++++++ 4 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 54e7075ae8..7ff052a8db 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -46,36 +46,26 @@ struct FunctionValues{IP, N_t, dNdx_t, dNdξ_t} end function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T ip_dims = InterpolationDims(ip, ip_geo) - N_t = typeof_N(T, ip_dims) - dNdx_t = typeof_dNdx(T, ip_dims) - dNdξ_t = typeof_dNdξ(T, ip_dims) n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) - N_ξ = zeros(N_t, n_shape, n_qpoints) - if isa(get_mapping_type(ip), IdentityMapping) - N_x = N_ξ - else - N_x = zeros(N_t, n_shape, n_qpoints) - end - dNdξ = zeros(dNdξ_t, n_shape, n_qpoints) - dNdx = fill(zero(dNdx_t) * T(NaN), n_shape, n_qpoints) - fv = FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) - precompute_values!(fv, qr) # Precompute N and dNdξ - return fv + N_ξ = zeros(typeof_N(T, ip_dims), n_shape, n_qpoints) + N_x = isa(get_mapping_type(ip), IdentityMapping) ? N_ξ : similar(N_ξ) + + dNdξ = zeros(typeof_dNdξ(T, ip_dims), n_shape, n_qpoints) + dNdx = fill(zero(typeof_dNdx(T, ip_dims)) * T(NaN), n_shape, n_qpoints) + + shape_gradients_and_values!(dNdξ, N_ξ, ip, qr) # Compute N_ξ and dNdξ + + return FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) end + function Base.copy(v::FunctionValues) N_ξ_copy = copy(v.N_ξ) N_x_copy = v.N_ξ === v.N_x ? N_ξ_copy : copy(v.N_x) # Preserve aliasing return FunctionValues(copy(v.ip), N_x_copy, N_ξ_copy, copy(v.dNdx), copy(v.dNdξ)) end -function precompute_values!(fv::FunctionValues, qr::QuadratureRule) - for (qp, ξ) in pairs(getpoints(qr)) - shape_gradients_and_values!(@view(fv.dNdξ[:, qp]), @view(fv.N_ξ[:, qp]), fv.ip, ξ) - end -end - getnbasefunctions(funvals::FunctionValues) = size(funvals.N_x, 1) @propagate_inbounds shape_value(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.N_x[base_func, q_point] @propagate_inbounds shape_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.dNdx[base_func, q_point] diff --git a/src/FEValues/GeometryMapping.jl b/src/FEValues/GeometryMapping.jl index 0b71be0abc..519f6b8d8d 100644 --- a/src/FEValues/GeometryMapping.jl +++ b/src/FEValues/GeometryMapping.jl @@ -47,41 +47,25 @@ end function GeometryMapping(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, ::RequiresHessian{RH}) where {T,RH} n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) - VT = Vec{getdim(ip),T} - M = zeros(T, n_shape, n_qpoints) - dMdξ = zeros(VT, n_shape, n_qpoints) + M = zeros(T, n_shape, n_qpoints) + dMdξ = zeros(Vec{getdim(ip),T}, n_shape, n_qpoints) - # Hessian (if needed, else nothing) - HT = Tensor{2,getdim(ip),T} - d2Mdξ2 = RH ? zeros(HT, n_shape, n_qpoints) : nothing + if RH # RequiresHessian + d2Mdξ2 = zeros(Tensor{2,getdim(ip),T}, n_shape, n_qpoints) + shape_hessians_gradients_and_values!(d2Mdξ2, dMdξ, M, ip, qr) + else + d2Mdξ2 = nothing + shape_gradients_and_values!(dMdξ, M, ip, qr) + end - geo_mapping = GeometryMapping(ip, M, dMdξ, d2Mdξ2) - precompute_values!(geo_mapping, qr) - return geo_mapping + return GeometryMapping(ip, M, dMdξ, d2Mdξ2) end + function Base.copy(v::GeometryMapping) d2Mdξ2_copy = v.d2Mdξ2 === nothing ? nothing : copy(v.d2Mdξ2) return GeometryMapping(copy(v.ip), copy(v.M), copy(v.dMdξ), d2Mdξ2_copy) end -precompute_values!(gm::GeometryMapping, qr::QuadratureRule) = precompute_values!(gm, RequiresHessian(gm), qr) - -function precompute_values!(gm::GeometryMapping, ::RequiresHessian{false}, qr::QuadratureRule) - ip = get_geometric_interpolation(gm) - for (qp, ξ) in pairs(getpoints(qr)) - shape_gradients_and_values!(@view(gm.dMdξ[:, qp]), @view(gm.M[:, qp]), ip, ξ) - end -end - -function precompute_values!(gm::GeometryMapping, ::RequiresHessian{true}, qr::QuadratureRule) - ip = get_geometric_interpolation(gm) - for (qp, ξ) in pairs(getpoints(qr)) - for i in 1:getngeobasefunctions(gm) - gm.d2Mdξ2[i, qp], gm.dMdξ[i, qp], gm.M[i, qp] = shape_hessian_gradient_and_value(ip, ξ, i) - end - end -end - getngeobasefunctions(geo_mapping::GeometryMapping) = size(geo_mapping.M, 1) @propagate_inbounds geometric_value(geo_mapping::GeometryMapping, q_point::Int, base_func::Int) = geo_mapping.M[base_func, q_point] get_geometric_interpolation(geo_mapping::GeometryMapping) = geo_mapping.ip diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 82e0632606..9cf44e0c0a 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -278,3 +278,16 @@ function spatial_coordinate(fe_v::AbstractValues, q_point::Int, x::AbstractVecto end return vec end + + +function shape_gradients_and_values!(gradients::AbstractMatrix, values::AbstractMatrix, ip, qr::QuadratureRule) + for (qp, ξ) in pairs(getpoints(qr)) + shape_gradients_and_values!(@view(gradients[:, qp]), @view(values[:, qp]), ip, ξ) + end +end + +function shape_hessians_gradients_and_values!(hessians::AbstractMatrix, gradients::AbstractMatrix, values::AbstractMatrix, ip, qr::QuadratureRule) + for (qp, ξ) in pairs(getpoints(qr)) + shape_hessians_gradients_and_values!(@view(hessians[:, qp]), @view(gradients[:, qp]), @view(values[:, qp]), ip, ξ) + end +end \ No newline at end of file diff --git a/src/interpolations.jl b/src/interpolations.jl index 1f60b118c9..5f96c181c2 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -243,6 +243,21 @@ function shape_gradients_and_values!(gradients::GAT, values::SAT, ip::IP, ξ::Ve end end +""" + shape_hessians_gradients_and_values!(hessians::AbstractVector, gradients::AbstractVector, values::AbstractVector, ip::Interpolation, ξ::Vec) + +Evaluate all shape function hessians, gradients and values of `ip` at once at the reference point `ξ` +and store them in `hessians`, `gradients`, and `values`. +""" +@propagate_inbounds function shape_hessians_gradients_and_values!(hessians::AbstractVector, gradients::AbstractVector, values::AbstractVector, ip::Interpolation, ξ::Vec) + @boundscheck checkbounds(hessians, 1:getnbasefunctions(ip)) + @boundscheck checkbounds(gradients, 1:getnbasefunctions(ip)) + @boundscheck checkbounds(values, 1:getnbasefunctions(ip)) + @inbounds for i in 1:getnbasefunctions(ip) + hessians[i], gradients[i], values[i] = shape_hessian_gradient_and_value(ip, ξ, i) + end +end + """ shape_value(ip::Interpolation, ξ::Vec, i::Int) From 9dfceeba9c3bb21a64b29e079cdcefbf690950d2 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 15:41:39 +0200 Subject: [PATCH 069/145] Reintroduce precompute_values --- src/FEValues/CellValues.jl | 12 ++++++++++++ src/FEValues/FunctionValues.jl | 10 +++++++--- src/FEValues/GeometryMapping.jl | 22 +++++++++++++--------- src/PointEval/point_values.jl | 3 ++- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 484d0f4131..091813651d 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -57,6 +57,18 @@ function Base.copy(cv::CellValues) return CellValues(copy(cv.fun_values), copy(cv.geo_mapping), copy(cv.qr), copy(cv.detJdV)) end +""" + precompute_values!(cv::CellValues) + +Precompute all values for the current quadrature rule in `cv`. This method allows you to modify +the quadrature positions, and then update all relevant parts of `cv` accordingly. +Used by `PointValues`. +""" +function precompute_values!(cv::CellValues) + precompute_values!(cv.fun_values, cv.qr) + precompute_values!(cv.geo_mapping, cv.qr) +end + # Access geometry values for op = (:getngeobasefunctions, :geometric_value) eval(quote diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 7ff052a8db..3ad7f657ad 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -55,9 +55,13 @@ function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo dNdξ = zeros(typeof_dNdξ(T, ip_dims), n_shape, n_qpoints) dNdx = fill(zero(typeof_dNdx(T, ip_dims)) * T(NaN), n_shape, n_qpoints) - shape_gradients_and_values!(dNdξ, N_ξ, ip, qr) # Compute N_ξ and dNdξ - - return FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) + fv = FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) + precompute_values!(fv, qr) # Separate function for qr point update in PointValues + return fv +end + +function precompute_values!(fv::FunctionValues, qr) + shape_gradients_and_values!(fv.dNdξ, fv.N_ξ, fv.ip, qr) end function Base.copy(v::FunctionValues) diff --git a/src/FEValues/GeometryMapping.jl b/src/FEValues/GeometryMapping.jl index 519f6b8d8d..fe3cb0a442 100644 --- a/src/FEValues/GeometryMapping.jl +++ b/src/FEValues/GeometryMapping.jl @@ -47,18 +47,22 @@ end function GeometryMapping(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, ::RequiresHessian{RH}) where {T,RH} n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) + M = zeros(T, n_shape, n_qpoints) dMdξ = zeros(Vec{getdim(ip),T}, n_shape, n_qpoints) - - if RH # RequiresHessian - d2Mdξ2 = zeros(Tensor{2,getdim(ip),T}, n_shape, n_qpoints) - shape_hessians_gradients_and_values!(d2Mdξ2, dMdξ, M, ip, qr) - else - d2Mdξ2 = nothing - shape_gradients_and_values!(dMdξ, M, ip, qr) - end + d2Mdξ2 = RH ? zeros(Tensor{2,getdim(ip),T}, n_shape, n_qpoints) : nothing - return GeometryMapping(ip, M, dMdξ, d2Mdξ2) + gm = GeometryMapping(ip, M, dMdξ, d2Mdξ2) + precompute_values!(gm, qr) # Separate function for qr point update in PointValues + return gm +end + +precompute_values!(gm::GeometryMapping, qr) = precompute_values!(gm, qr, RequiresHessian(gm)) +function precompute_values!(gm::GeometryMapping, qr, ::RequiresHessian{false}) + shape_gradients_and_values!(gm.dMdξ, gm.M, gm.ip, qr) +end +function precompute_values!(gm::GeometryMapping, qr, ::RequiresHessian{true}) + shape_hessians_gradients_and_values!(gm.d2Mdξ2, gm.dMdξ, gm.M, gm.ip, qr) end function Base.copy(v::GeometryMapping) diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 57f16864fb..0be54d0c0b 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -65,7 +65,8 @@ function reinit!(pv::PointValues, x::AbstractVector{<:Vec{D}}, ξ::Vec{D}) where # Update the quadrature point location qr_points = getpoints(pv.cv.qr) qr_points[1] = ξ - precompute_values!(pv.cv.fun_values, pv.cv.qr) # See Issue #763, should also update dMdξ!, but separate issue + # Precompute all values again to reflect the updated ξ coordinate + precompute_values!(pv.cv) # Regular reinit reinit!(pv.cv, x) return nothing From ea7e33efad7a36874db24537fe4d938d78f99fe2 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 16:22:01 +0200 Subject: [PATCH 070/145] Fix test of show --- test/test_cellvalues.jl | 12 +++++++----- test/test_facevalues.jl | 10 ++++++---- test/test_utils.jl | 7 +++++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index f85245c07e..25ba7992bf 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -325,13 +325,15 @@ end end @testset "show" begin - # Just smoke test cv_quad = CellValues(QuadratureRule{RefQuadrilateral}(2), Lagrange{RefQuadrilateral,2}()^2) + showstring = show_as_string(cv_quad) + @test startswith(showstring, "CellValues(vdim=2, rdim=2, and sdim=2): 4 quadrature points") + @test contains(showstring, "Lagrange{RefQuadrilateral, 2}()^2") + cv_wedge = CellValues(QuadratureRule{RefPrism}(2), Lagrange{RefPrism,2}()) - show(stdout, MIME"text/plain"(), cv_quad) - println(stdout) - show(stdout, MIME"text/plain"(), cv_wedge) - println(stdout) + showstring = show_as_string(cv_wedge) + @test startswith(showstring, "CellValues(scalar, rdim=3, and sdim=3): 5 quadrature points") + @test contains(showstring, "Lagrange{RefPrism, 2}()") end @testset "SimpleCellValues" begin diff --git a/test/test_facevalues.jl b/test/test_facevalues.jl index 6eb875e500..e4b113b224 100644 --- a/test/test_facevalues.jl +++ b/test/test_facevalues.jl @@ -130,12 +130,14 @@ end @testset "show" begin # Just smoke test to make sure show doesn't error. fv = FaceValues(FaceQuadratureRule{RefQuadrilateral}(2), Lagrange{RefQuadrilateral,2}()) - show(stdout, MIME"text/plain"(), fv) - println(stdout) + showstring = show_as_string(fv) + @test startswith(showstring, "FaceValues(scalar, rdim=2, sdim=2): 2 quadrature points per face") + @test contains(showstring, "Function interpolation: Lagrange{RefQuadrilateral, 2}()") + @test contains(showstring, "Geometric interpolation: Lagrange{RefQuadrilateral, 1}()^2") fv.qr.face_rules[1] = deepcopy(fv.qr.face_rules[1]) push!(Ferrite.getweights(fv.qr.face_rules[1]), 1) - show(stdout, MIME"text/plain"(), fv) - println(stdout) + showstring = show_as_string(fv) + @test startswith(showstring, "FaceValues(scalar, rdim=2, sdim=2): (3, 2, 2, 2) quadrature points on each face") end end # of testset diff --git a/test/test_utils.jl b/test/test_utils.jl index d51fb8866c..a5a4d6ba8e 100644 --- a/test/test_utils.jl +++ b/test/test_utils.jl @@ -259,3 +259,10 @@ getfacerefshape(::Hexahedron, ::Int) = RefQuadrilateral getfacerefshape(::Tetrahedron, ::Int) = RefTriangle getfacerefshape(::Pyramid, face::Int) = face == 1 ? RefQuadrilateral : RefTriangle getfacerefshape(::Wedge, face::Int) = face ∈ (1,5) ? RefTriangle : RefQuadrilateral + +# For testing of show of various types +function show_as_string(value, mime=MIME"text/plain"()) + io = IOBuffer() + show(IOContext(io), mime, value) + return String(take!(io)) +end \ No newline at end of file From 1a7e9c91012e65ce87a937a1d8840ed2509af01e Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 17:06:20 +0200 Subject: [PATCH 071/145] Remove unused internal methods --- src/FEValues/common_values.jl | 3 --- src/FEValues/face_integrals.jl | 5 +---- src/PointEval/point_values.jl | 1 + 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 9cf44e0c0a..a180f3c294 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -4,9 +4,6 @@ using Base: @propagate_inbounds @noinline throw_detJ_not_pos(detJ) = throw(ArgumentError("det(J) is not positive: det(J) = $(detJ)")) -getnbasefunctions(cv::AbstractValues) = size(cv.N, 1) -getngeobasefunctions(cv::AbstractValues) = size(cv.M, 1) - function checkquadpoint(cv::Union{CellValues, FaceValues, PointValues}, qp::Int) 0 < qp <= getnquadpoints(cv) || error("quadrature point out of range") return nothing diff --git a/src/FEValues/face_integrals.jl b/src/FEValues/face_integrals.jl index e001eb5f3d..a4974110c0 100644 --- a/src/FEValues/face_integrals.jl +++ b/src/FEValues/face_integrals.jl @@ -7,16 +7,13 @@ cell's face. face_to_element_transformation """ - weighted_normal(J::AbstractTensor, fv::FaceValues, face::Int) weighted_normal(J::AbstractTensor, ::Type{<:AbstractRefShape}, face::Int) Compute the vector normal to the face weighted by the area ratio between the face and the reference face. This is computed by taking the cross product of the Jacobian components that align to the face local axis. """ -function weighted_normal(J::AbstractTensor, fv::FaceValues, face::Int) - return weighted_normal(J, getrefshape(fv.func_interp), face) -end +function weighted_normal end """ create_face_quad_rule(::Type{RefShape}, w::Vector{T}, p::Vector{Vec{N, T}}) diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 0be54d0c0b..5128c1b459 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -86,6 +86,7 @@ function PointValuesInternal(ξ::Vec{dim, T}, ip::IP) where {dim, T, shape <: Ab return PointValuesInternal{IP, eltype(N)}(N, ip) end +getnbasefunctions(pv::PointValuesInternal) = size(pv.N, 1) getnquadpoints(pv::PointValuesInternal) = 1 shape_value_type(::PointValuesInternal{<:Any, N_t}) where {N_t} = N_t shape_value(pv::PointValuesInternal, qp::Int, i::Int) = (@assert qp == 1; pv.N[i]) From 41ae092166dfe1e37f8f1095b745802dc1c42ac8 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 17:40:19 +0200 Subject: [PATCH 072/145] Test error paths --- src/FEValues/FunctionValues.jl | 3 +-- test/test_cellvalues.jl | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 3ad7f657ad..a73c07107d 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -93,8 +93,7 @@ function check_reinit_sdim_consistency(valname, gradtype, ::Type{<:Vec{sdim}}) w end check_reinit_sdim_consistency(_, ::Val{sdim}, ::Val{sdim}) where sdim = nothing function check_reinit_sdim_consistency(valname, ::Val{sdim_val}, ::Val{sdim_x}) where {sdim_val, sdim_x} - error("""The $valname and coordinates have different spatial dimensions, $sdim_val and $sdim_x. - Could it be that you forgot to vectorize the geometric interpolation when constructing the $valname?""") + throw(ArgumentError("The $valname (sdim=$sdim_val) and coordinates (sdim=$sdim_x) have different spatial dimensions.")) end # Mapping types diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 25ba7992bf..316c0f8d41 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -137,18 +137,26 @@ end @testset "error paths in function_* and reinit!" begin dim = 2 qp = 1 + cell = Triangle((1,2,3)) ip = Lagrange{RefTriangle,1}() + ip_nedelec = Nedelec{2,RefTriangle,1}() qr = QuadratureRule{RefTriangle}(1) qr_f = FaceQuadratureRule{RefTriangle}(1) csv = CellValues(qr, ip) cvv = CellValues(qr, VectorizedInterpolation(ip)) + csv_embedded = CellValues(qr, ip, ip^3) + cv_nedelec = CellValues(qr, ip_nedelec, ip) fsv = FaceValues(qr_f, ip) fvv = FaceValues(qr_f, VectorizedInterpolation(ip)) + fsv_embedded = FaceValues(qr_f, ip, ip^3) + fv_nedelec = FaceValues(qr_f, ip_nedelec, ip) x, n = valid_coordinates_and_normals(ip) reinit!(csv, x) reinit!(cvv, x) reinit!(fsv, x, 1) reinit!(fvv, x, 1) + reinit!(cv_nedelec, x, cell) + reinit!(fv_nedelec, x, 1, cell) # Wrong number of coordinates xx = [x; x] @@ -162,6 +170,14 @@ end @test_throws ArgumentError spatial_coordinate(fsv, qp, xx) @test_throws ArgumentError spatial_coordinate(fvv, qp, xx) + # Wrong dimension of coordinates + @test_throws ArgumentError reinit!(csv_embedded, x) + @test_throws ArgumentError reinit!(fsv_embedded, x, 1) + + # Missing cell input when required + @test_throws ArgumentError reinit!(cv_nedelec, x) + @test_throws ArgumentError reinit!(fv_nedelec, x, 1) + # Wrong number of (local) dofs # Scalar values, scalar dofs ue = rand(getnbasefunctions(csv) + 1) From 9b020da0de310792945c40672a23d5171cc837a7 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 17:52:18 +0200 Subject: [PATCH 073/145] Remove unused test-code --- src/Grid/grid.jl | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/Grid/grid.jl b/src/Grid/grid.jl index 310fbc13ac..d3b7bc68cd 100644 --- a/src/Grid/grid.jl +++ b/src/Grid/grid.jl @@ -773,22 +773,6 @@ end ################################# #### Orientation of Entities #### ################################# -function face_sign(::AbstractCell{<:AbstractRefShape{1}}, facenr) - error("Not defined") -end -function face_sign(cell::AbstractCell{<:AbstractRefShape{2}}, facenr) - vertices = faces(cell)[facenr] - return vertices[1] < vertices[2] ? 1 : -1 -end -function face_sign(::AbstractCell{<:AbstractRefShape{3}}, facenr) - error("Implement me") -end - -function edge_sign(cell::AbstractCell, edgenr) - vertices = edges(cell)[edgenr] - return vertices[1] < vertices[2] ? 1 : -1 -end - # @TODO merge this code with into the logic in `ConstraintHandler`. """ From 00e2e4fff01d9432f23385d289ef25afd6fc743e Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 17:54:11 +0200 Subject: [PATCH 074/145] Test show(::PointValues) --- test/test_cellvalues.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 316c0f8d41..728588d34f 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -350,6 +350,11 @@ end showstring = show_as_string(cv_wedge) @test startswith(showstring, "CellValues(scalar, rdim=3, and sdim=3): 5 quadrature points") @test contains(showstring, "Lagrange{RefPrism, 2}()") + + pv = PointValues(cv_wedge) + pv_showstring = show_as_string(pv) + @test startswith(pv_showstring, "PointValues containing") + @test contains(pv_showstring, showstring) end @testset "SimpleCellValues" begin From 09cf607cbfaa0517b08ffa4be0ae55ffb456daf5 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 17:59:09 +0200 Subject: [PATCH 075/145] Fix test of show(::PointValues) --- test/test_cellvalues.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 728588d34f..5ff1e72f24 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -344,17 +344,17 @@ end cv_quad = CellValues(QuadratureRule{RefQuadrilateral}(2), Lagrange{RefQuadrilateral,2}()^2) showstring = show_as_string(cv_quad) @test startswith(showstring, "CellValues(vdim=2, rdim=2, and sdim=2): 4 quadrature points") - @test contains(showstring, "Lagrange{RefQuadrilateral, 2}()^2") + @test contains(showstring, "Function interpolation: Lagrange{RefQuadrilateral, 2}()^2") cv_wedge = CellValues(QuadratureRule{RefPrism}(2), Lagrange{RefPrism,2}()) showstring = show_as_string(cv_wedge) @test startswith(showstring, "CellValues(scalar, rdim=3, and sdim=3): 5 quadrature points") - @test contains(showstring, "Lagrange{RefPrism, 2}()") + @test contains(showstring, "Function interpolation: Lagrange{RefPrism, 2}()") pv = PointValues(cv_wedge) pv_showstring = show_as_string(pv) @test startswith(pv_showstring, "PointValues containing") - @test contains(pv_showstring, showstring) + @test contains(pv_showstring, "Function interpolation: Lagrange{RefPrism, 2}()") end @testset "SimpleCellValues" begin From 43970f35f6632d776dcf49805c12ce6d8dc1d7b2 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 21 Oct 2023 18:59:31 +0200 Subject: [PATCH 076/145] Remove unused methods --- src/FEValues/CellValues.jl | 11 +++++------ src/FEValues/FaceValues.jl | 6 +----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 091813651d..3f7e00d1a8 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -70,17 +70,15 @@ function precompute_values!(cv::CellValues) end # Access geometry values -for op = (:getngeobasefunctions, :geometric_value) - eval(quote - @propagate_inbounds $op(cv::CellValues, args...) = $op(cv.geo_mapping, args...) - end) -end +@propagate_inbounds getngeobasefunctions(cv::CellValues) = getngeobasefunctions(cv.geo_mapping) +@propagate_inbounds geometric_value(cv::CellValues, args...) = geometric_value(cv.geo_mapping, args...) +get_geometric_interpolation(cv::CellValues) = get_geometric_interpolation(cv.geo_mapping) + getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] # Accessors for function values getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) get_function_interpolation(cv::CellValues) = get_function_interpolation(cv.fun_values) -get_geometric_interpolation(cv::CellValues) = get_geometric_interpolation(cv.geo_mapping) shape_value_type(cv::CellValues) = shape_value_type(cv.fun_values) shape_gradient_type(cv::CellValues) = shape_gradient_type(cv.fun_values) @@ -89,6 +87,7 @@ for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient) @propagate_inbounds $op(cv::CellValues, i::Int, q_point::Int) = $op(cv.fun_values, i, q_point) end) end + # Access quadrature rule values getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 1b1e473242..04b99a3ea2 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -71,11 +71,7 @@ get_function_interpolation(fv::FaceValues) = get_function_interpolation(get_fun_ get_geometric_interpolation(fv::FaceValues) = get_geometric_interpolation(get_geo_mapping(fv)) get_geo_mapping(fv::FaceValues) = @inbounds fv.geo_mapping[getcurrentface(fv)] -for op = (:getngeobasefunctions, :geometric_value) - eval(quote - @propagate_inbounds $op(fv::FaceValues, args...) = $op(get_geo_mapping(fv), args...) - end) -end +@propagate_inbounds geometric_value(fv::FaceValues, args...) = geometric_value(get_geo_mapping(fv), args...) get_fun_values(fv::FaceValues) = @inbounds fv.fun_values[getcurrentface(fv)] for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient, :shape_curl) From 005659af63fe16a38d5f985d731bebe63621a344 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 23 Oct 2023 17:45:04 +0200 Subject: [PATCH 077/145] Grammar and stylistic fixes --- docs/make.jl | 1 - docs/src/assets/references.bib | 2 +- docs/src/reference/fevalues.md | 3 ++- docs/src/topics/FEValues.md | 8 +++++--- docs/src/topics/SimpleCellValues_literate.jl | 2 +- src/FEValues/CellValues.jl | 2 +- test/test_utils.jl | 2 +- 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index ced312cb19..6a8635ea4f 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -63,7 +63,6 @@ bibtex_plugin = CitationBibliography( "Topic guides" => [ "Topic guide overview" => "topics/index.md", "topics/fe_intro.md", - #"topics/interpolations.md", "topics/FEValues.md", "topics/degrees_of_freedom.md", "topics/assembly.md", diff --git a/docs/src/assets/references.bib b/docs/src/assets/references.bib index a237a86296..46f189bb15 100644 --- a/docs/src/assets/references.bib +++ b/docs/src/assets/references.bib @@ -71,4 +71,4 @@ @misc{Kirby2017 doi={10.48550/arXiv.1706.09017}, archivePrefix={arXiv}, primaryClass={math.NA} -} \ No newline at end of file +} diff --git a/docs/src/reference/fevalues.md b/docs/src/reference/fevalues.md index 757760fbc6..3bc1e5c988 100644 --- a/docs/src/reference/fevalues.md +++ b/docs/src/reference/fevalues.md @@ -7,7 +7,8 @@ DocTestSetup = :(using Ferrite) ## Main types [`CellValues`](@ref) and [`FaceValues`](@ref) are the most common -subtypes of `Ferrite.AbstractValues`. +subtypes of `Ferrite.AbstractValues`. For more details about how +these work, please see the related [topic guide](@ref fevalues_topicguide). ```@docs CellValues diff --git a/docs/src/topics/FEValues.md b/docs/src/topics/FEValues.md index 2039f2846c..11831e91f2 100644 --- a/docs/src/topics/FEValues.md +++ b/docs/src/topics/FEValues.md @@ -1,8 +1,10 @@ -# FEValues -A key type of object in `Ferrite.jl` are the so-called `FEValues`, where the most common ones are `CellValues` and `FaceValues`. These objects are used inside the element routines and are used to query the integration weights, shape function values and gradients, and much more, see [`CellValues`](@ref) and [`FaceValues`](@ref). In order for these values to be correct, it is necessary to reinitialize these for the current cell by using the [`reinit!`](@ref) function. This maps the values from the reference cell to the actual cell, a process which is described in detail below, see [Mapping of finite elements](@ref mapping_theory). Thereafter, we show an implementation of a [`SimpleCellValues`](@ref SimpleCellValues) type for the most standard case, excluding the generalizations and optimization that complicates the code for e.g. `CellValues`. +# [FEValues](@id fevalues_topicguide) +A key type of object in `Ferrite.jl` is the so-called `FEValues`, where the most common ones are `CellValues` and `FaceValues`. These objects are used inside the element routines and are used to query the integration weights, shape function values and gradients, and much more; see [`CellValues`](@ref) and [`FaceValues`](@ref). For these values to be correct, it is necessary to reinitialize these for the current cell by using the [`reinit!`](@ref) function. This function maps the values from the reference cell to the actual cell, a process described in detail below, see [Mapping of finite elements](@ref mapping-theory). After that, we show an implementation of a [`SimpleCellValues`](@ref SimpleCellValues) type to illustrate how `CellValues` work for the most standard case, excluding the generalizations and optimization that complicates the actual code. ## [Mapping of finite elements](@id mapping_theory) -The shape functions and gradients stored in an `FEValues` object, is reinitialized for each cell by calling the `reinit!` function. The main part of this calculation, considers how to map the functions described on the reference cell, to the actual cell. +The shape functions and gradients stored in an `FEValues` object, are reinitialized for each cell by calling the `reinit!` function. +The main part of this calculation, considers how to map the values and derivatives of the shape functions, +defined on the reference cell, to the actual cell. The geometric mapping of a finite element from the reference coordinates to the real coordinates is shown in the following illustration. diff --git a/docs/src/topics/SimpleCellValues_literate.jl b/docs/src/topics/SimpleCellValues_literate.jl index 8f6b2469a7..f648f728eb 100644 --- a/docs/src/topics/SimpleCellValues_literate.jl +++ b/docs/src/topics/SimpleCellValues_literate.jl @@ -91,4 +91,4 @@ reinit!(cv, x) ue = rand(getnbasefunctions(simple_cv)) q_point = 2 @test function_value(cv, q_point, ue) ≈ function_value(simple_cv, q_point, ue) -@test function_gradient(cv, q_point, ue) ≈ function_gradient(simple_cv, q_point, ue) \ No newline at end of file +@test function_gradient(cv, q_point, ue) ≈ function_gradient(simple_cv, q_point, ue) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 3f7e00d1a8..a363cc7f3d 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -124,4 +124,4 @@ function Base.show(io::IO, d::MIME"text/plain", cv::CellValues) print(io, getnquadpoints(cv), " quadrature points") print(io, "\n Function interpolation: "); show(io, d, ip_fun) print(io, "\nGeometric interpolation: "); show(io, d, ip_geo^sdim) -end \ No newline at end of file +end diff --git a/test/test_utils.jl b/test/test_utils.jl index a5a4d6ba8e..1a40b54c84 100644 --- a/test/test_utils.jl +++ b/test/test_utils.jl @@ -265,4 +265,4 @@ function show_as_string(value, mime=MIME"text/plain"()) io = IOBuffer() show(IOContext(io), mime, value) return String(take!(io)) -end \ No newline at end of file +end From 69b50b42bfc67019f87b851c9637447001c4c531 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 23 Oct 2023 18:00:04 +0200 Subject: [PATCH 078/145] Add further devdoc explanations --- docs/src/devdocs/FEValues.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/src/devdocs/FEValues.md b/docs/src/devdocs/FEValues.md index 81a349ac27..9bc4a93571 100644 --- a/docs/src/devdocs/FEValues.md +++ b/docs/src/devdocs/FEValues.md @@ -14,4 +14,15 @@ Ferrite.GeometryMapping Ferrite.MappingValues Ferrite.FunctionValues -``` \ No newline at end of file +``` + +## Interface +* The function interpolation, `ip_fun`, determines how it should be mapped, by defining `get_mapping_type(ip_fun)` for its type. +* The mapping type, e.g. `IdentityMapping`, decides the requirements for `GeometryValues`, specifically if the `hessian` $\partial^2M/\partial\xi^2$, + of the geometric shape functions, $M(\xi)$, on the reference cell should be precalculated or not. + ***Note:*** *This should also in the future be determined by the required order of derivatives to be mapped in `FunctionValues`* +* As the first part of `reinit!`, the `MappingValues` are calculated based on the cell's coordinates. If the `GeometricMapping` contains the hessian + on the reference cell, the `hessian` on the actual cell, $\partial^2M/\partial x^2$, is calculated and returned in `MappingValues`. Otherwise, only + the jacobian, $\partial M/\partial x$, is calculated. +* In the second part of `reinit!`, The `MappingValues`, containing sufficient information for the current quadrature point, is given to `apply_mapping!`. + This allows the shape values and gradients stored in `FunctionValues`, to be mapped to the current cell by calling `apply_mapping!`. From f829e8881df0ebde666259f0d8170c081a39c0fd Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 4 Nov 2023 13:07:16 +0100 Subject: [PATCH 079/145] Describe FEValues interface --- docs/src/devdocs/FEValues.md | 16 +++++++++++++++- docs/src/topics/SimpleCellValues_literate.jl | 3 ++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/src/devdocs/FEValues.md b/docs/src/devdocs/FEValues.md index 9bc4a93571..04beb263ad 100644 --- a/docs/src/devdocs/FEValues.md +++ b/docs/src/devdocs/FEValues.md @@ -16,7 +16,7 @@ Ferrite.MappingValues Ferrite.FunctionValues ``` -## Interface +## How CellValues and FaceValues works * The function interpolation, `ip_fun`, determines how it should be mapped, by defining `get_mapping_type(ip_fun)` for its type. * The mapping type, e.g. `IdentityMapping`, decides the requirements for `GeometryValues`, specifically if the `hessian` $\partial^2M/\partial\xi^2$, of the geometric shape functions, $M(\xi)$, on the reference cell should be precalculated or not. @@ -26,3 +26,17 @@ Ferrite.FunctionValues the jacobian, $\partial M/\partial x$, is calculated. * In the second part of `reinit!`, The `MappingValues`, containing sufficient information for the current quadrature point, is given to `apply_mapping!`. This allows the shape values and gradients stored in `FunctionValues`, to be mapped to the current cell by calling `apply_mapping!`. + +## Custom FEValues +Custom FEValues, `fe_v`, should normally implement the `reinit!` method. +Additionally, for normal functionality the `getnquadpoints` should be implemented. +Note that asking for the `n`th quadrature point must be inside array bounds if +`1<=n<:getnquadpoints(fe_v)` +(`checkquadpoint` can, alternatively, be dispatched to check that `n` is inbounds.) + +Supporting `function_value`, `function_gradient`, `function_symmetric_gradient`, `function_divergence`, and `function_curl`, +requires implementing `getnbasefunctions`, `shape_value`, and `shape_gradient`. +Note that asking for the `i`th shape value or gradient must be inside array bounds if `1<=i<:getnbasefunctions(fe_v)` + +Supporting `spatial_coordinate` requires implementing `getngeobasefunctions` and `geometric_value`. +Note that asking for the `i`th geometric value must be inside array bounds if `1<=i<:getngeobasefunctions(fe_v)` \ No newline at end of file diff --git a/docs/src/topics/SimpleCellValues_literate.jl b/docs/src/topics/SimpleCellValues_literate.jl index f648f728eb..0bbbe9a220 100644 --- a/docs/src/topics/SimpleCellValues_literate.jl +++ b/docs/src/topics/SimpleCellValues_literate.jl @@ -47,8 +47,9 @@ function SimpleCellValues(qr::QuadratureRule, ip_fun::Interpolation, ip_geo::Int SimpleCellValues(N, dNdξ, dNdx, M, dMdξ, weights, detJdV) end; -# We first define the `getnbasefunctions` +# We first define `getnbasefunctions` and `getnquadpoints` Ferrite.getnbasefunctions(cv::SimpleCellValues) = size(cv.N, 1); +Ferrite.getnquadpoints(cv::SimpleCellValues) = size(cv.N, 2); # Before we define the `reinit!` function to calculate the cached # values `dNdx` and `detJdV` for the current cell From d4c36c25dd2bb713d5f4bd40e800243945db1058 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 4 Nov 2023 13:08:24 +0100 Subject: [PATCH 080/145] Delete checkquadpoint method that causes illegal (at)inbounds --- src/FEValues/common_values.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index a180f3c294..07e94c0fd4 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -4,11 +4,10 @@ using Base: @propagate_inbounds @noinline throw_detJ_not_pos(detJ) = throw(ArgumentError("det(J) is not positive: det(J) = $(detJ)")) -function checkquadpoint(cv::Union{CellValues, FaceValues, PointValues}, qp::Int) - 0 < qp <= getnquadpoints(cv) || error("quadrature point out of range") +function checkquadpoint(fe_v::AbstractValues, qp::Int) + 0 < qp <= getnquadpoints(fe_v) || error("quadrature point out of range") return nothing end -checkquadpoint(_, _::Int) = nothing @noinline function throw_incompatible_dof_length(length_ue, n_base_funcs) throw(ArgumentError( From 2550a75b209fb94a75e009f13ce9fa81772326c0 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 4 Nov 2023 15:49:07 +0100 Subject: [PATCH 081/145] Fix typo in devdocs --- docs/src/devdocs/FEValues.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/devdocs/FEValues.md b/docs/src/devdocs/FEValues.md index 04beb263ad..d4cbc8c9bf 100644 --- a/docs/src/devdocs/FEValues.md +++ b/docs/src/devdocs/FEValues.md @@ -31,12 +31,12 @@ Ferrite.FunctionValues Custom FEValues, `fe_v`, should normally implement the `reinit!` method. Additionally, for normal functionality the `getnquadpoints` should be implemented. Note that asking for the `n`th quadrature point must be inside array bounds if -`1<=n<:getnquadpoints(fe_v)` +`1 <= n <= getnquadpoints(fe_v)` (`checkquadpoint` can, alternatively, be dispatched to check that `n` is inbounds.) Supporting `function_value`, `function_gradient`, `function_symmetric_gradient`, `function_divergence`, and `function_curl`, requires implementing `getnbasefunctions`, `shape_value`, and `shape_gradient`. -Note that asking for the `i`th shape value or gradient must be inside array bounds if `1<=i<:getnbasefunctions(fe_v)` +Note that asking for the `i`th shape value or gradient must be inside array bounds if `1 <= i <= getnbasefunctions(fe_v)` Supporting `spatial_coordinate` requires implementing `getngeobasefunctions` and `geometric_value`. -Note that asking for the `i`th geometric value must be inside array bounds if `1<=i<:getngeobasefunctions(fe_v)` \ No newline at end of file +Note that asking for the `i`th geometric value must be inside array bounds if `1 <= i <= getngeobasefunctions(fe_v)` \ No newline at end of file From acefcde0d082197db6987088f69889f3c23af5ca Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 5 Nov 2023 13:26:05 +0100 Subject: [PATCH 082/145] Add type specification to shape_value and shape_gradient docstring spec --- docs/src/reference/fevalues.md | 4 ++-- src/FEValues/common_values.jl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/src/reference/fevalues.md b/docs/src/reference/fevalues.md index 3bc1e5c988..98f85f252b 100644 --- a/docs/src/reference/fevalues.md +++ b/docs/src/reference/fevalues.md @@ -24,8 +24,8 @@ reinit! getnquadpoints getdetJdV -shape_value -shape_gradient +shape_value(::Ferrite.AbstractValues, ::Int, ::Int) +shape_gradient(::Ferrite.AbstractValues, ::Int, ::Int) shape_symmetric_gradient shape_divergence diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 07e94c0fd4..fec2c19080 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -64,7 +64,7 @@ function getdetJdV end Return the value of shape function `base_function` evaluated in quadrature point `q_point`. """ -function shape_value end +shape_value(fe_v::AbstractValues, q_point::Int, base_function::Int) """ geometric_value(fe_v::AbstractValues, q_point, base_function::Int) @@ -72,7 +72,7 @@ function shape_value end Return the value of the geometric shape function `base_function` evaluated in quadrature point `q_point`. """ -function geometric_value end +geometric_value(fe_v::AbstractValues, q_point::Int, base_function::Int) """ shape_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int) @@ -80,7 +80,7 @@ function geometric_value end Return the gradient of shape function `base_function` evaluated in quadrature point `q_point`. """ -function shape_gradient end +shape_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int) """ shape_symmetric_gradient(fe_v::AbstractValues, q_point::Int, base_function::Int) From 94c174f11e628fb7daeeb384bf99bfb4b3d050b2 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 10 Nov 2023 19:49:22 +0100 Subject: [PATCH 083/145] Testing it out --- src/FEValues/CellValues.jl | 10 +++- src/FEValues/FaceValues.jl | 11 +++- src/FEValues/FunctionValues.jl | 87 ++++++++++++++++++++++++----- src/FEValues/GeometryMapping.jl | 98 +++++++++++++++++++++------------ src/FEValues/common_values.jl | 5 ++ 5 files changed, 155 insertions(+), 56 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index a363cc7f3d..9fc4997d19 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -41,9 +41,13 @@ struct CellValues{FV, GM, QR, detT<:AbstractVector} <: AbstractCellValues qr::QR # QuadratureRule detJdV::detT # AbstractVector{<:Number} end -function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation) where T - geo_mapping = GeometryMapping(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) - fun_values = FunctionValues(T, ip_fun, qr, ip_geo) +function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; difforder=Val(1)) where T + _difforder(::Val{N}) where N = N + _difforder(N::Int) = N + GeoDiffOrder = increased_diff_order(get_mapping_type(ip_fun)) + _difforder(difforder) + FunDiffOrder = _difforder(difforder) + geo_mapping = GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) + fun_values = FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) detJdV = fill(T(NaN), length(getweights(qr))) return CellValues(fun_values, geo_mapping, qr, detJdV) end diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 04b99a3ea2..3ca56c39e0 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -40,9 +40,14 @@ struct FaceValues{FV, GM, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GM<:Abstract current_face::ScalarWrapper{Int} end -function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun)) where {T,sdim} - geo_mapping = [GeometryMapping(T, ip_geo.ip, qr, RequiresHessian(ip_fun, ip_geo)) for qr in fqr.face_rules] - fun_values = [FunctionValues(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] +function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun); difforder=Val(1)) where {T,sdim} + _difforder(::Val{N}) where N = N + _difforder(N::Int) = N + GeoDiffOrder = increased_diff_order(get_mapping_type(ip_fun)) + _difforder(difforder) + FunDiffOrder = _difforder(difforder) + + geo_mapping = [GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) for qr in fqr.face_rules] + fun_values = [FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) detJdV = fill(T(NaN), max_nquadpoints) normals = fill(zero(Vec{sdim,T})*T(NaN), max_nquadpoints) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index a73c07107d..82da88c074 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -37,14 +37,35 @@ cell (precalculated) and the real cell (updated in `reinit!`). """ FunctionValues -struct FunctionValues{IP, N_t, dNdx_t, dNdξ_t} +struct FunctionValues{DiffOrder, IP, N_t, dNdx_t, dNdξ_t} ip::IP # ::Interpolation N_x::N_t # ::AbstractMatrix{Union{<:Tensor,<:Number}} N_ξ::N_t # ::AbstractMatrix{Union{<:Tensor,<:Number}} - dNdx::dNdx_t # ::AbstractMatrix{Union{<:Tensor,<:StaticArray}} - dNdξ::dNdξ_t # ::AbstractMatrix{Union{<:Tensor,<:StaticArray}} + dNdx::dNdx_t # ::AbstractMatrix{Union{<:Tensor,<:StaticArray}} or Nothing + dNdξ::dNdξ_t # ::AbstractMatrix{Union{<:Tensor,<:StaticArray}} or Nothing + function FunctionValues(ip::Interpolation, N_x::N_t, N_ξ::N_t, ::Nothing, ::Nothing) where {N_t<:AbstractMatrix} + return new{0, typeof(ip), N_t, Nothing, Nothing}(ip, N_x, N_ξ, nothing, nothing) + end + function FunctionValues(ip::Interpolation, N_x::N_t, N_ξ::N_t, dNdx::AbstractMatrix, dNdξ::AbstractMatrix) where {N_t<:AbstractMatrix} + return new{1, typeof(ip), N_t, typeof(dNdx), typeof(dNdξ)}(ip, N_x, N_ξ, dNdx, dNdξ) + end end function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T + return FunctionValues{1}(T, ip, qr, ip_geo) +end +function FunctionValues{0}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T + ip_dims = InterpolationDims(ip, ip_geo) + n_shape = getnbasefunctions(ip) + n_qpoints = getnquadpoints(qr) + + N_ξ = zeros(typeof_N(T, ip_dims), n_shape, n_qpoints) + N_x = isa(get_mapping_type(ip), IdentityMapping) ? N_ξ : similar(N_ξ) + + fv = FunctionValues(ip, N_x, N_ξ, nothing, nothing) + precompute_values!(fv, qr) # Separate function for qr point update in PointValues + return fv +end +function FunctionValues{1}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T ip_dims = InterpolationDims(ip, ip_geo) n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) @@ -60,14 +81,19 @@ function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo return fv end -function precompute_values!(fv::FunctionValues, qr) +function precompute_values!(fv::FunctionValues{0}, qr) + shape_values!(fv.N_ξ, fv.ip, qr) +end +function precompute_values!(fv::FunctionValues{1}, qr) shape_gradients_and_values!(fv.dNdξ, fv.N_ξ, fv.ip, qr) end function Base.copy(v::FunctionValues) N_ξ_copy = copy(v.N_ξ) N_x_copy = v.N_ξ === v.N_x ? N_ξ_copy : copy(v.N_x) # Preserve aliasing - return FunctionValues(copy(v.ip), N_x_copy, N_ξ_copy, copy(v.dNdx), copy(v.dNdξ)) + copy_or_nothing(x) = copy(x) + copy_or_nothing(::Nothing) = nothing + return FunctionValues(copy(v.ip), N_x_copy, N_ξ_copy, copy_or_nothing(v.dNdx), copy_or_nothing(v.dNdξ)) end getnbasefunctions(funvals::FunctionValues) = size(funvals.N_x, 1) @@ -107,15 +133,15 @@ struct ContravariantPiolaMapping end get_mapping_type(fv::FunctionValues) = get_mapping_type(fv.ip) """ - requires_hessian(mapping) + increased_diff_order(mapping) -Does the `mapping` type require the hessian, d²M/dx², +How many order higher geometric derivatives are required to to map the function values and gradients from the reference cell to the real cell geometry? """ -requires_hessian(::IdentityMapping) = false -requires_hessian(::ContravariantPiolaMapping) = true -requires_hessian(::CovariantPiolaMapping) = true +increased_diff_order(::IdentityMapping) = 0 +increased_diff_order(::ContravariantPiolaMapping) = 1 +increased_diff_order(::CovariantPiolaMapping) = 1 # Support for embedded elements calculate_Jinv(J::Tensor{2}) = inv(J) @@ -131,11 +157,19 @@ calculate_Jinv(J::SMatrix) = pinv(J) # Vector interpolations with sdim > rdim @inline dothelper(B::SMatrix{vdim, rdim}, A::SMatrix{rdim, sdim}) where {vdim, rdim, sdim} = B * A -@inline function apply_mapping!(funvals::FunctionValues, args...) - return apply_mapping!(funvals, get_mapping_type(funvals), args...) +# ============= +# Apply mapping +# ============= +@inline function apply_mapping!(funvals::FunctionValues, q_point::Int, args...) + return apply_mapping!(funvals, get_mapping_type(funvals), q_point, args...) end -@inline function apply_mapping!(funvals::FunctionValues, ::IdentityMapping, q_point::Int, mapping_values, args...) +# Identity mapping +@inline function apply_mapping!(::FunctionValues{0}, ::IdentityMapping, ::Int, mapping_values, args...) + return nothing +end + +@inline function apply_mapping!(funvals::FunctionValues{1}, ::IdentityMapping, q_point::Int, mapping_values, args...) Jinv = calculate_Jinv(getjacobian(mapping_values)) @inbounds for j in 1:getnbasefunctions(funvals) #funvals.dNdx[j, q_point] = funvals.dNdξ[j, q_point] ⋅ Jinv # TODO via Tensors.jl @@ -144,7 +178,18 @@ end return nothing end -@inline function apply_mapping!(funvals::FunctionValues, ::CovariantPiolaMapping, q_point::Int, mapping_values, cell) +# Covariant Piola Mapping +@inline function apply_mapping!(funvals::FunctionValues{0}, ::CovariantPiolaMapping, q_point::Int, mapping_values, cell) + Jinv = inv(getjacobian(mapping_values)) + @inbounds for j in 1:getnbasefunctions(funvals) + d = get_direction(funvals.ip, j, cell) + N_ξ = funvals.N_ξ[j, q_point] + funvals.N_x[j, q_point] = d*(N_ξ ⋅ Jinv) + end + return nothing +end + +@inline function apply_mapping!(funvals::FunctionValues{1}, ::CovariantPiolaMapping, q_point::Int, mapping_values, cell) H = gethessian(mapping_values) Jinv = inv(getjacobian(mapping_values)) @inbounds for j in 1:getnbasefunctions(funvals) @@ -157,7 +202,19 @@ end return nothing end -@inline function apply_mapping!(funvals::FunctionValues, ::ContravariantPiolaMapping, q_point::Int, mapping_values, cell) +# Contravariant Piola Mapping +@inline function apply_mapping!(funvals::FunctionValues{0}, ::ContravariantPiolaMapping, q_point::Int, mapping_values, cell) + J = getjacobian(mapping_values) + detJ = det(J) + @inbounds for j in 1:getnbasefunctions(funvals) + d = get_direction(funvals.ip, j, cell) + N_ξ = funvals.N_ξ[j, q_point] + funvals.N_x[j, q_point] = d*(J ⋅ N_ξ)/detJ + end + return nothing +end + +@inline function apply_mapping!(funvals::FunctionValues{1}, ::ContravariantPiolaMapping, q_point::Int, mapping_values, cell) H = gethessian(mapping_values) J = getjacobian(mapping_values) Jinv = inv(J) diff --git a/src/FEValues/GeometryMapping.jl b/src/FEValues/GeometryMapping.jl index fe3cb0a442..6c72563373 100644 --- a/src/FEValues/GeometryMapping.jl +++ b/src/FEValues/GeometryMapping.jl @@ -8,74 +8,100 @@ used when mapping the `FunctionValues` to the current cell during `reinit!`. """ MappingValues -struct MappingValues{JT, HT<:Union{Nothing,AbstractTensor{3}}} +struct MappingValues{JT, HT} J::JT # dx/dξ # Jacobian H::HT # dJ/dξ # Hessian end -@inline getjacobian(mv::MappingValues) = mv.J +@inline getjacobian(mv::MappingValues{<:Union{AbstractTensor, SMatrix}}) = mv.J @inline gethessian(mv::MappingValues{<:Any,<:AbstractTensor}) = mv.H -# This will be needed for optimizing away the hessian calculation/updates -# for cases when this is known to be zero (due to the geometric interpolation) -#@inline gethessian(::MappingValues{JT,Nothing}) where JT = _make_hessian(JT) -#@inline _make_hessian(::Type{Tensor{2,dim,T}}) where {dim,T} = zero(Tensor{3,dim,T}) +""" + GeometryMapping{DiffOrder}(::Type{T}, ip_geo, qr::QuadratureRule) -struct RequiresHessian{B} end -RequiresHessian(B::Bool) = RequiresHessian{B}() -function RequiresHessian(ip_fun::Interpolation, ip_geo::Interpolation) - # Leave ip_geo as input, because for later the hessian can also be avoided - # for fully linear geometric elements (e.g. triangle and tetrahedron) - # This optimization is left out for now. - RequiresHessian(requires_hessian(get_mapping_type(ip_fun))) -end +Create a `GeometryMapping` object which contains the geometric -""" - GeometryMapping(::Type{T}, ip_geo, qr::QuadratureRule, ::RequiresHessian{B}) +* shape values +* gradient values (if DiffOrder ≥ 1) +* hessians values (if DiffOrder ≥ 2) -Create a `GeometryMapping` object which contains the geometric shape, gradients, and, -if `B==true`, the hessian values. `T<:AbstractFloat` gives the numeric type of the values. +`T<:AbstractFloat` gives the numeric type of the values. """ GeometryMapping -struct GeometryMapping{IP, M_t, dMdξ_t, d2Mdξ2_t} +struct GeometryMapping{DiffOrder, IP, M_t, dMdξ_t, d2Mdξ2_t} ip::IP # ::Interpolation Geometric interpolation - M::M_t # ::AbstractVector{<:Number} Values of geometric shape functions - dMdξ::dMdξ_t # ::AbstractVector{<:Vec} Gradients of geometric shape functions in ref-domain - d2Mdξ2::d2Mdξ2_t # ::AbstractVector{<:Tensor{2}} Hessians of geometric shape functions in ref-domain - # ::Nothing When hessians are not required + M::M_t # ::AbstractMatrix{<:Number} Values of geometric shape functions + dMdξ::dMdξ_t # ::AbstractMatrix{<:Vec} Gradients of geometric shape functions in ref-domain + d2Mdξ2::d2Mdξ2_t # ::AbstractMatrix{<:Tensor{2}} Hessians of geometric shape functions in ref-domain + # ::Nothing When not required + function GeometryMapping( + ip::IP, M::M_t, ::Nothing, ::Nothing + ) where {IP <: ScalarInterpolation, M_t<:AbstractMatrix{<:Number}} + return new{0, IP, M_t, Nothing, Nothing}(ip, M, nothing, nothing) + end + function GeometryMapping( + ip::IP, M::M_t, dMdξ::dMdξ_t, ::Nothing + ) where {IP <: ScalarInterpolation, M_t<:AbstractMatrix{<:Number}, dMdξ_t <: AbstractMatrix{<:Vec}} + return new{1, IP, M_t, dMdξ_t, Nothing}(ip, M, dMdξ, nothing) + end + function GeometryMapping( + ip::IP, M::M_t, dMdξ::dMdξ_t, d2Mdξ2::d2Mdξ2_t) where + {IP <: ScalarInterpolation, M_t<:AbstractMatrix{<:Number}, + dMdξ_t <: AbstractMatrix{<:Vec}, d2Mdξ2_t <: AbstractMatrix{<:Tensor{2}}} + return new{2, IP, M_t, dMdξ_t, d2Mdξ2_t}(ip, M, dMdξ, d2Mdξ2) + end +end +function GeometryMapping{0}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T + n_shape = getnbasefunctions(ip) + n_qpoints = getnquadpoints(qr) + gm = GeometryMapping(ip, zeros(T, n_shape, n_qpoints), nothing, nothing) + precompute_values!(gm, qr) # Separate function for qr point update in PointValues + return gm end -function GeometryMapping(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule, ::RequiresHessian{RH}) where {T,RH} +function GeometryMapping{1}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) M = zeros(T, n_shape, n_qpoints) dMdξ = zeros(Vec{getdim(ip),T}, n_shape, n_qpoints) - d2Mdξ2 = RH ? zeros(Tensor{2,getdim(ip),T}, n_shape, n_qpoints) : nothing + + gm = GeometryMapping(ip, M, dMdξ, nothing) + precompute_values!(gm, qr) # Separate function for qr point update in PointValues + return gm +end +function GeometryMapping{2}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T + n_shape = getnbasefunctions(ip) + n_qpoints = getnquadpoints(qr) + + M = zeros(T, n_shape, n_qpoints) + dMdξ = zeros(Vec{getdim(ip),T}, n_shape, n_qpoints) + d2Mdξ2 = zeros(Tensor{2,getdim(ip),T}, n_shape, n_qpoints) gm = GeometryMapping(ip, M, dMdξ, d2Mdξ2) precompute_values!(gm, qr) # Separate function for qr point update in PointValues return gm end -precompute_values!(gm::GeometryMapping, qr) = precompute_values!(gm, qr, RequiresHessian(gm)) -function precompute_values!(gm::GeometryMapping, qr, ::RequiresHessian{false}) +function precompute_values!(gm::GeometryMapping{0}, qr) + shape_values!(gm.M, gm.ip, qr) +end +function precompute_values!(gm::GeometryMapping{1}, qr) shape_gradients_and_values!(gm.dMdξ, gm.M, gm.ip, qr) end -function precompute_values!(gm::GeometryMapping, qr, ::RequiresHessian{true}) +function precompute_values!(gm::GeometryMapping{2}, qr) shape_hessians_gradients_and_values!(gm.d2Mdξ2, gm.dMdξ, gm.M, gm.ip, qr) end function Base.copy(v::GeometryMapping) - d2Mdξ2_copy = v.d2Mdξ2 === nothing ? nothing : copy(v.d2Mdξ2) - return GeometryMapping(copy(v.ip), copy(v.M), copy(v.dMdξ), d2Mdξ2_copy) + copy_or_nothing(x) = copy(x) + copy_or_nothing(::Nothing) = nothing + return GeometryMapping(copy(v.ip), copy(v.M), copy_or_nothing(v.dMdξ), copy_or_nothing(v.d2Mdξ2)) end getngeobasefunctions(geo_mapping::GeometryMapping) = size(geo_mapping.M, 1) @propagate_inbounds geometric_value(geo_mapping::GeometryMapping, q_point::Int, base_func::Int) = geo_mapping.M[base_func, q_point] get_geometric_interpolation(geo_mapping::GeometryMapping) = geo_mapping.ip -RequiresHessian(geo_mapping::GeometryMapping) = RequiresHessian(geo_mapping.d2Mdξ2 !== nothing) - # Hot-fixes to support embedded elements before MixedTensors are available # See https://github.com/Ferrite-FEM/Tensors.jl/pull/188 @inline otimes_helper(x::Vec{dim}, dMdξ::Vec{dim}) where dim = x ⊗ dMdξ @@ -95,9 +121,11 @@ function otimes_returntype(#=typeof(x)=#::Type{<:Vec{dim,Tx}}, #=typeof(d2Mdξ2) return Tensor{3,dim,promote_type(Tx,TM)} end -@propagate_inbounds calculate_mapping(geo_mapping::GeometryMapping, args...) = calculate_mapping(RequiresHessian(geo_mapping), geo_mapping, args...) +@inline function calculate_mapping(::GeometryMapping{0}, q_point, x) + return MappingValues(nothing, nothing) +end -@inline function calculate_mapping(::RequiresHessian{false}, geo_mapping::GeometryMapping, q_point, x) +@inline function calculate_mapping(geo_mapping::GeometryMapping{1}, q_point, x) fecv_J = zero(otimes_returntype(eltype(x), eltype(geo_mapping.dMdξ))) @inbounds for j in 1:getngeobasefunctions(geo_mapping) #fecv_J += x[j] ⊗ geo_mapping.dMdξ[j, q_point] @@ -106,7 +134,7 @@ end return MappingValues(fecv_J, nothing) end -@inline function calculate_mapping(::RequiresHessian{true}, geo_mapping::GeometryMapping, q_point, x) +@inline function calculate_mapping(geo_mapping::GeometryMapping{2}, q_point, x) J = zero(otimes_returntype(eltype(x), eltype(geo_mapping.dMdξ))) H = zero(otimes_returntype(eltype(x), eltype(geo_mapping.d2Mdξ2))) @inbounds for j in 1:getngeobasefunctions(geo_mapping) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index fec2c19080..6d43e9b441 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -275,6 +275,11 @@ function spatial_coordinate(fe_v::AbstractValues, q_point::Int, x::AbstractVecto return vec end +function shape_gradients_and_values!(values::AbstractMatrix, ip, qr::QuadratureRule) + for (qp, ξ) in pairs(getpoints(qr)) + shape_values!(@view(values[:, qp]), ip, ξ) + end +end function shape_gradients_and_values!(gradients::AbstractMatrix, values::AbstractMatrix, ip, qr::QuadratureRule) for (qp, ξ) in pairs(getpoints(qr)) From c36ffdaa5595d87931341c4f15e2478f5218cbe2 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 11 Nov 2023 22:08:29 +0100 Subject: [PATCH 084/145] Passing tests --- src/FEValues/CellValues.jl | 25 +++++++++++++++---------- src/FEValues/FunctionValues.jl | 4 +++- src/FEValues/common_values.jl | 2 +- src/deprecations.jl | 2 +- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 9fc4997d19..b790966db5 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -35,26 +35,26 @@ function default_geometric_interpolation(::Interpolation{shape}) where {dim, sha return VectorizedInterpolation{dim}(Lagrange{shape, 1}()) end -struct CellValues{FV, GM, QR, detT<:AbstractVector} <: AbstractCellValues +struct CellValues{FV, GM, QR, detT} <: AbstractCellValues fun_values::FV # FunctionValues geo_mapping::GM # GeometryMapping qr::QR # QuadratureRule detJdV::detT # AbstractVector{<:Number} end -function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; difforder=Val(1)) where T +function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; difforder=Val(1), save_detJ=true) where T _difforder(::Val{N}) where N = N _difforder(N::Int) = N - GeoDiffOrder = increased_diff_order(get_mapping_type(ip_fun)) + _difforder(difforder) + GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + _difforder(difforder), save_detJ) FunDiffOrder = _difforder(difforder) geo_mapping = GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) fun_values = FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) - detJdV = fill(T(NaN), length(getweights(qr))) + detJdV = save_detJ ? fill(T(NaN), length(getweights(qr))) : nothing return CellValues(fun_values, geo_mapping, qr, detJdV) end -CellValues(qr::QuadratureRule, ip::Interpolation, args...) = CellValues(Float64, qr, ip, args...) -function CellValues(::Type{T}, qr, ip::Interpolation, ip_geo::ScalarInterpolation=default_geometric_interpolation(ip)) where T - return CellValues(T, qr, ip, VectorizedInterpolation(ip_geo)) +CellValues(qr::QuadratureRule, ip::Interpolation, args...; kwargs...) = CellValues(Float64, qr, ip, args...; kwargs...) +function CellValues(::Type{T}, qr, ip::Interpolation, ip_geo::ScalarInterpolation=default_geometric_interpolation(ip); kwargs...) where T + return CellValues(T, qr, ip, VectorizedInterpolation(ip_geo); kwargs...) end function Base.copy(cv::CellValues) @@ -95,6 +95,13 @@ end # Access quadrature rule values getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) +@propagate_inbounds function _update_detJdV!(detJvec::AbstractVector, q_point::Int, w, mapping) + detJ = calculate_detJ(getjacobian(mapping)) + detJ > 0.0 || throw_detJ_not_pos(detJ) + @inbounds detJvec[q_point] = detJ*w +end +@inline _update_detJdV!(::Nothing, q_point, w, mapping) = nothing + function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) geo_mapping = cv.geo_mapping fun_values = cv.fun_values @@ -109,9 +116,7 @@ function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) mapping = calculate_mapping(geo_mapping, q_point, x) - detJ = calculate_detJ(getjacobian(mapping)) - detJ > 0.0 || throw_detJ_not_pos(detJ) - @inbounds cv.detJdV[q_point] = detJ*w + @inline _update_detJdV!(cv.detJdV, q_point, w, mapping) apply_mapping!(fun_values, q_point, mapping, cell) end return nothing diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 82da88c074..5b51140b72 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -105,6 +105,7 @@ get_function_interpolation(funvals::FunctionValues) = funvals.ip shape_value_type(funvals::FunctionValues) = eltype(funvals.N_x) shape_gradient_type(funvals::FunctionValues) = eltype(funvals.dNdx) +shape_gradient_type(::FunctionValues{0}) = nothing # Checks that the user provides the right dimension of coordinates to reinit! methods to ensure good error messages if not @@ -114,9 +115,10 @@ sdim_from_gradtype(::Type{<:SMatrix{<:Any,sdim}}) where sdim = sdim # For performance, these must be fully inferrable for the compiler. # args: valname (:CellValues or :FaceValues), shape_gradient_type, eltype(x) -function check_reinit_sdim_consistency(valname, gradtype, ::Type{<:Vec{sdim}}) where {sdim} +function check_reinit_sdim_consistency(valname, gradtype::Type, ::Type{<:Vec{sdim}}) where {sdim} check_reinit_sdim_consistency(valname, Val(sdim_from_gradtype(gradtype)), Val(sdim)) end +check_reinit_sdim_consistency(_, ::Nothing, ::Type{<:Vec}) = nothing # gradient not stored, cannot check check_reinit_sdim_consistency(_, ::Val{sdim}, ::Val{sdim}) where sdim = nothing function check_reinit_sdim_consistency(valname, ::Val{sdim_val}, ::Val{sdim_x}) where {sdim_val, sdim_x} throw(ArgumentError("The $valname (sdim=$sdim_val) and coordinates (sdim=$sdim_x) have different spatial dimensions.")) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 6d43e9b441..55b01381d2 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -275,7 +275,7 @@ function spatial_coordinate(fe_v::AbstractValues, q_point::Int, x::AbstractVecto return vec end -function shape_gradients_and_values!(values::AbstractMatrix, ip, qr::QuadratureRule) +function shape_values!(values::AbstractMatrix, ip, qr::QuadratureRule) for (qp, ξ) in pairs(getpoints(qr)) shape_values!(@view(values[:, qp]), ip, ξ) end diff --git a/src/deprecations.jl b/src/deprecations.jl index cb0c2f3cd8..7f81cf443d 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -156,7 +156,7 @@ end # TODO: Are these needed to be deprecated - harder? with the new parameterization # (Cell|Face)Values with vector dofs -const _VectorValues = Union{CellValues{<:FV}, FaceValues{<:FV}} where {FV <: FunctionValues{<:VectorInterpolation}} +const _VectorValues = Union{CellValues{<:FV}, FaceValues{<:FV}} where {FV <: FunctionValues{<:Any,<:VectorInterpolation}} @deprecate function_value(fe_v::_VectorValues, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T} function_value(fe_v, q_point, reinterpret(T, u)) @deprecate function_gradient(fe_v::_VectorValues, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T} function_gradient(fe_v, q_point, reinterpret(T, u)) @deprecate function_divergence(fe_v::_VectorValues, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T} function_divergence(fe_v, q_point, reinterpret(T, u)) From 4ab9ba2354263675750e6e84603ed6fd875f9371 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 11 Nov 2023 22:24:25 +0100 Subject: [PATCH 085/145] Fix performance annotations to come on par with master --- src/FEValues/CellValues.jl | 4 ++-- src/FEValues/FunctionValues.jl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index b790966db5..60448364c7 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -95,7 +95,7 @@ end # Access quadrature rule values getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) -@propagate_inbounds function _update_detJdV!(detJvec::AbstractVector, q_point::Int, w, mapping) +@inline function _update_detJdV!(detJvec::AbstractVector, q_point::Int, w, mapping) detJ = calculate_detJ(getjacobian(mapping)) detJ > 0.0 || throw_detJ_not_pos(detJ) @inbounds detJvec[q_point] = detJ*w @@ -116,7 +116,7 @@ function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) mapping = calculate_mapping(geo_mapping, q_point, x) - @inline _update_detJdV!(cv.detJdV, q_point, w, mapping) + _update_detJdV!(cv.detJdV, q_point, w, mapping) apply_mapping!(fun_values, q_point, mapping, cell) end return nothing diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 5b51140b72..902a81c3be 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -146,8 +146,8 @@ increased_diff_order(::ContravariantPiolaMapping) = 1 increased_diff_order(::CovariantPiolaMapping) = 1 # Support for embedded elements -calculate_Jinv(J::Tensor{2}) = inv(J) -calculate_Jinv(J::SMatrix) = pinv(J) +@inline calculate_Jinv(J::Tensor{2}) = inv(J) +@inline calculate_Jinv(J::SMatrix) = pinv(J) # Hotfix to get the dots right for embedded elements until mixed tensors are merged. # Scalar/Vector interpolations with sdim == rdim (== vdim) From cc0c806e020161d58b6cb7b4e1f3830ef1505cf1 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Tue, 21 Nov 2023 17:55:21 +0100 Subject: [PATCH 086/145] Move utils to common_values --- src/FEValues/CellValues.jl | 6 ++---- src/FEValues/FaceValues.jl | 14 ++++++-------- src/FEValues/FunctionValues.jl | 15 ++++++--------- src/FEValues/GeometryMapping.jl | 4 +--- src/FEValues/common_values.jl | 8 ++++++++ 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 60448364c7..3777fe6fcd 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -42,10 +42,8 @@ struct CellValues{FV, GM, QR, detT} <: AbstractCellValues detJdV::detT # AbstractVector{<:Number} end function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; difforder=Val(1), save_detJ=true) where T - _difforder(::Val{N}) where N = N - _difforder(N::Int) = N - GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + _difforder(difforder), save_detJ) - FunDiffOrder = _difforder(difforder) + GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + _extract_val(difforder), save_detJ) + FunDiffOrder = _extract_val(difforder) geo_mapping = GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) fun_values = FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) detJdV = save_detJ ? fill(T(NaN), length(getweights(qr))) : nothing diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 3ca56c39e0..77d8f7a4ce 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -32,19 +32,17 @@ values of nodal functions, gradients and divergences of nodal functions etc. on FaceValues struct FaceValues{FV, GM, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GM<:AbstractVector{GM}} <: AbstractFaceValues - fun_values::V_FV # AbstractVector{FunctionValues} + fun_values::V_FV # AbstractVector{FunctionValues} geo_mapping::V_GM # AbstractVector{GeometryMapping} - qr::QR # FaceQuadratureRule - detJdV::detT # AbstractVector{<:Number} - normals::nT # AbstractVector{<:Vec} + qr::QR # FaceQuadratureRule + detJdV::detT # AbstractVector{<:Number} + normals::nT # AbstractVector{<:Vec} current_face::ScalarWrapper{Int} end function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun); difforder=Val(1)) where {T,sdim} - _difforder(::Val{N}) where N = N - _difforder(N::Int) = N - GeoDiffOrder = increased_diff_order(get_mapping_type(ip_fun)) + _difforder(difforder) - FunDiffOrder = _difforder(difforder) + GeoDiffOrder = increased_diff_order(get_mapping_type(ip_fun)) + _extract_val(difforder) + FunDiffOrder = _extract_val(difforder) geo_mapping = [GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) for qr in fqr.face_rules] fun_values = [FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 902a81c3be..dfe3f3243c 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -30,10 +30,10 @@ typeof_dNdξ(::Type{T}, ::VInterpolationDims{dim,dim,dim}) where {T,dim} = Tenso typeof_dNdξ(::Type{T}, ::VInterpolationDims{rdim,<:Any,vdim}) where {T,rdim,vdim} = SMatrix{vdim,rdim,T} # If vdim=rdim!=sdim Tensor would be possible... """ - FunctionValues(::Type{T}, ip_fun, qr::QuadratureRule, ip_geo::VectorizedInterpolation) + FunctionValues{DiffOrder}(::Type{T}, ip_fun, qr::QuadratureRule, ip_geo::VectorizedInterpolation) -Create a `FunctionValues` object containing the shape values and gradients for both the reference -cell (precalculated) and the real cell (updated in `reinit!`). +Create a `FunctionValues` object containing the shape values and gradients (up to order `DiffOrder`) +for both the reference cell (precalculated) and the real cell (updated in `reinit!`). """ FunctionValues @@ -50,9 +50,6 @@ struct FunctionValues{DiffOrder, IP, N_t, dNdx_t, dNdξ_t} return new{1, typeof(ip), N_t, typeof(dNdx), typeof(dNdξ)}(ip, N_x, N_ξ, dNdx, dNdξ) end end -function FunctionValues(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T - return FunctionValues{1}(T, ip, qr, ip_geo) -end function FunctionValues{0}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T ip_dims = InterpolationDims(ip, ip_geo) n_shape = getnbasefunctions(ip) @@ -91,9 +88,9 @@ end function Base.copy(v::FunctionValues) N_ξ_copy = copy(v.N_ξ) N_x_copy = v.N_ξ === v.N_x ? N_ξ_copy : copy(v.N_x) # Preserve aliasing - copy_or_nothing(x) = copy(x) - copy_or_nothing(::Nothing) = nothing - return FunctionValues(copy(v.ip), N_x_copy, N_ξ_copy, copy_or_nothing(v.dNdx), copy_or_nothing(v.dNdξ)) + dNdx_copy = _copy_or_nothing(v.dNdx) + dNdξ_copy = _copy_or_nothing(v.dNdξ) + return FunctionValues(copy(v.ip), N_x_copy, N_ξ_copy, dNdx_copy, dNdξ_copy) end getnbasefunctions(funvals::FunctionValues) = size(funvals.N_x, 1) diff --git a/src/FEValues/GeometryMapping.jl b/src/FEValues/GeometryMapping.jl index 6c72563373..ee6386519f 100644 --- a/src/FEValues/GeometryMapping.jl +++ b/src/FEValues/GeometryMapping.jl @@ -93,9 +93,7 @@ function precompute_values!(gm::GeometryMapping{2}, qr) end function Base.copy(v::GeometryMapping) - copy_or_nothing(x) = copy(x) - copy_or_nothing(::Nothing) = nothing - return GeometryMapping(copy(v.ip), copy(v.M), copy_or_nothing(v.dMdξ), copy_or_nothing(v.d2Mdξ2)) + return GeometryMapping(copy(v.ip), copy(v.M), _copy_or_nothing(v.dMdξ), _copy_or_nothing(v.d2Mdξ2)) end getngeobasefunctions(geo_mapping::GeometryMapping) = size(geo_mapping.M, 1) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 55b01381d2..da4158d92c 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -275,6 +275,14 @@ function spatial_coordinate(fe_v::AbstractValues, q_point::Int, x::AbstractVecto return vec end + +# Utility functions used by GeometryMapping, FunctionValues, FaceValues, CellValues +_copy_or_nothing(x) = copy(x) +_copy_or_nothing(::Nothing) = nothing + +_extract_val(v) = v +_extract_val(::Val{N}) where N = N + function shape_values!(values::AbstractMatrix, ip, qr::QuadratureRule) for (qp, ξ) in pairs(getpoints(qr)) shape_values!(@view(values[:, qp]), ip, ξ) From e109c9bf8c2903f4416e337bb12abd609e76e3bf Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Tue, 21 Nov 2023 19:18:30 +0100 Subject: [PATCH 087/145] Remove PointValuesInternal --- src/FEValues/CellValues.jl | 15 +++++++------ src/FEValues/FaceValues.jl | 1 + src/FEValues/FunctionValues.jl | 2 +- src/PointEval/PointEvalHandler.jl | 12 ++++++----- src/PointEval/point_values.jl | 36 ++++++------------------------- 5 files changed, 24 insertions(+), 42 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 3777fe6fcd..1f9d64dfaa 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -41,12 +41,12 @@ struct CellValues{FV, GM, QR, detT} <: AbstractCellValues qr::QR # QuadratureRule detJdV::detT # AbstractVector{<:Number} end -function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; difforder=Val(1), save_detJ=true) where T - GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + _extract_val(difforder), save_detJ) +function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; difforder=Val(1), save_detJ=Val(true)) where T + GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + _extract_val(difforder), _extract_val(save_detJ)) FunDiffOrder = _extract_val(difforder) geo_mapping = GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) fun_values = FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) - detJdV = save_detJ ? fill(T(NaN), length(getweights(qr))) : nothing + detJdV = _extract_val(save_detJ) ? fill(T(NaN), length(getweights(qr))) : nothing return CellValues(fun_values, geo_mapping, qr, detJdV) end @@ -81,6 +81,7 @@ getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] # Accessors for function values getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) get_function_interpolation(cv::CellValues) = get_function_interpolation(cv.fun_values) +get_function_difforder(cv::CellValues) = get_function_difforder(cv.fun_values) shape_value_type(cv::CellValues) = shape_value_type(cv.fun_values) shape_gradient_type(cv::CellValues) = shape_gradient_type(cv.fun_values) @@ -125,10 +126,12 @@ function Base.show(io::IO, d::MIME"text/plain", cv::CellValues) ip_fun = get_function_interpolation(cv) rdim = getdim(ip_geo) vdim = isa(shape_value(cv, 1, 1), Vec) ? length(shape_value(cv, 1, 1)) : 0 - sdim = length(shape_gradient(cv, 1, 1)) ÷ length(shape_value(cv, 1, 1)) + GradT = shape_gradient_type(cv) + sdim = GradT === nothing ? nothing : sdim_from_gradtype(GradT) vstr = vdim==0 ? "scalar" : "vdim=$vdim" print(io, "CellValues(", vstr, ", rdim=$rdim, and sdim=$sdim): ") print(io, getnquadpoints(cv), " quadrature points") print(io, "\n Function interpolation: "); show(io, d, ip_fun) - print(io, "\nGeometric interpolation: "); show(io, d, ip_geo^sdim) -end + print(io, "\nGeometric interpolation: "); + sdim === nothing ? show(io, d, ip_geo) : show(io, d, ip_geo^sdim) +end \ No newline at end of file diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 77d8f7a4ce..c902612e30 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -71,6 +71,7 @@ getnquadpoints(fv::FaceValues) = @inbounds getnquadpoints(fv.qr, getcurrentface( shape_value_type(fv::FaceValues) = shape_value_type(get_fun_values(fv)) shape_gradient_type(fv::FaceValues) = shape_gradient_type(get_fun_values(fv)) get_function_interpolation(fv::FaceValues) = get_function_interpolation(get_fun_values(fv)) +get_function_difforder(fv::FaceValues) = get_function_difforder(get_fun_values(fv)) get_geometric_interpolation(fv::FaceValues) = get_geometric_interpolation(get_geo_mapping(fv)) get_geo_mapping(fv::FaceValues) = @inbounds fv.geo_mapping[getcurrentface(fv)] diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index dfe3f3243c..b3a7a69a0f 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -99,7 +99,7 @@ getnbasefunctions(funvals::FunctionValues) = size(funvals.N_x, 1) @propagate_inbounds shape_symmetric_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = symmetric(shape_gradient(funvals, q_point, base_func)) get_function_interpolation(funvals::FunctionValues) = funvals.ip - +get_function_difforder(::FunctionValues{DiffOrder}) where DiffOrder = DiffOrder shape_value_type(funvals::FunctionValues) = eltype(funvals.N_x) shape_gradient_type(funvals::FunctionValues) = eltype(funvals.dNdx) shape_gradient_type(::FunctionValues{0}) = nothing diff --git a/src/PointEval/PointEvalHandler.jl b/src/PointEval/PointEvalHandler.jl index db9d16fc93..0d23f0aafb 100644 --- a/src/PointEval/PointEvalHandler.jl +++ b/src/PointEval/PointEvalHandler.jl @@ -183,9 +183,9 @@ end function evaluate_at_points(ph::PointEvalHandler{<:Any, dim, T1}, dh::AbstractDofHandler, dof_vals::AbstractVector{T2}, fname::Symbol=find_single_field(dh)) where {dim, T1, T2} npoints = length(ph.cells) - # Figure out the value type by creating a dummy PointValuesInternal + # Figure out the value type by creating a dummy PointValues ip = getfieldinterpolation(dh, find_field(dh, fname)) - pv = PointValuesInternal(zero(Vec{dim, T1}), ip) + pv = PointValues(T1, ip; difforder=Val(0)) zero_val = function_value_init(pv, dof_vals) # Allocate the output as NaNs nanv = convert(typeof(zero_val), NaN * zero_val) @@ -241,11 +241,12 @@ function _evaluate_at_points!( # preallocate some stuff specific to this cellset idx = findfirst(!isnothing, local_coords) idx === nothing && return out_vals - pv = PointValuesInternal(local_coords[idx], ip) + pv = PointValues(local_coords[idx], ip; difforder=Val(0)) first_cell = cellset === nothing ? 1 : first(cellset) cell_dofs = Vector{Int}(undef, ndofs_per_cell(dh, first_cell)) u_e = Vector{T}(undef, ndofs_per_cell(dh, first_cell)) - + grid = get_grid(dh) + x = getcoordinates(grid, first_cell) # compute point values for pointid in eachindex(ph.cells) cellid = ph.cells[pointid] @@ -255,7 +256,8 @@ function _evaluate_at_points!( for (i, I) in pairs(cell_dofs) u_e[i] = dof_vals[I] end - reinit!(pv, local_coords[pointid]) + getcoordinates!(x, grid, cellid) + reinit!(pv, x, local_coords[pointid]) out_vals[pointid] = function_value(pv, 1, u_e, dofrange) end return out_vals diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 5128c1b459..29d668fe96 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -28,18 +28,19 @@ function PointValues(cv::CellValues) T = typeof(getdetJdV(cv, 1)) ip_fun = get_function_interpolation(cv) ip_geo = get_geometric_interpolation(cv) - return PointValues(T, ip_fun, ip_geo) + FunDiffOrder = get_function_difforder(cv) + return PointValues(T, ip_fun, ip_geo; difforder=Val(FunDiffOrder)) end -function PointValues(ip::Interpolation, ipg::Interpolation = default_geometric_interpolation(ip)) - return PointValues(Float64, ip, ipg) +function PointValues(ip::Interpolation, ipg::Interpolation = default_geometric_interpolation(ip); kwargs...) + return PointValues(Float64, ip, ipg; kwargs...) end -function PointValues(::Type{T}, ip::IP, ipg::GIP = default_geometric_interpolation(ip)) where { +function PointValues(::Type{T}, ip::IP, ipg::GIP = default_geometric_interpolation(ip); kwargs...) where { T, dim, shape <: AbstractRefShape{dim}, IP <: Interpolation{shape}, GIP <: Interpolation{shape} } qr = QuadratureRule{shape, T}([one(T)], [zero(Vec{dim, T})]) - cv = CellValues(T, qr, ip, ipg) + cv = CellValues(T, qr, ip, ipg; save_detJ=Val(false), kwargs...) return PointValues{typeof(cv)}(cv) end @@ -72,31 +73,6 @@ function reinit!(pv::PointValues, x::AbstractVector{<:Vec{D}}, ξ::Vec{D}) where return nothing end -# Optimized version of PointValues which avoids i) recomputation of dNdξ and -# ii) recomputation of dNdx. Only allows function evaluation (no gradients) which is -# what is used in evaluate_at_points. -struct PointValuesInternal{IP, N_t} <: AbstractValues - N::Vector{N_t} - ip::IP -end - -function PointValuesInternal(ξ::Vec{dim, T}, ip::IP) where {dim, T, shape <: AbstractRefShape{dim}, IP <: Interpolation{shape}} - n_func_basefuncs = getnbasefunctions(ip) - N = [shape_value(ip, ξ, i) for i in 1:n_func_basefuncs] - return PointValuesInternal{IP, eltype(N)}(N, ip) -end - -getnbasefunctions(pv::PointValuesInternal) = size(pv.N, 1) -getnquadpoints(pv::PointValuesInternal) = 1 -shape_value_type(::PointValuesInternal{<:Any, N_t}) where {N_t} = N_t -shape_value(pv::PointValuesInternal, qp::Int, i::Int) = (@assert qp == 1; pv.N[i]) - -# allow on-the-fly updating -function reinit!(pv::PointValuesInternal{IP}, coord::Vec{dim}) where {dim, shape <: AbstractRefShape{dim}, IP <: Interpolation{shape}} - shape_values!(pv.N, pv.ip, coord) - return nothing -end - function Base.show(io::IO, d::MIME"text/plain", cv::PointValues) println(io, "PointValues containing a") show(io, d, cv.cv) From 34beb70d9971d724bfd1b616fbd8f64dbc7807cb Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Tue, 21 Nov 2023 20:23:32 +0100 Subject: [PATCH 088/145] Fix test --- src/PointEval/PointEvalHandler.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/PointEval/PointEvalHandler.jl b/src/PointEval/PointEvalHandler.jl index 0d23f0aafb..6bf47a615e 100644 --- a/src/PointEval/PointEvalHandler.jl +++ b/src/PointEval/PointEvalHandler.jl @@ -241,11 +241,12 @@ function _evaluate_at_points!( # preallocate some stuff specific to this cellset idx = findfirst(!isnothing, local_coords) idx === nothing && return out_vals - pv = PointValues(local_coords[idx], ip; difforder=Val(0)) first_cell = cellset === nothing ? 1 : first(cellset) - cell_dofs = Vector{Int}(undef, ndofs_per_cell(dh, first_cell)) - u_e = Vector{T}(undef, ndofs_per_cell(dh, first_cell)) grid = get_grid(dh) + ip_geo = default_interpolation(getcelltype(grid, first_cell)) + pv = PointValues(eltype(local_coords[idx]), ip, ip_geo; difforder=Val(0)) + cell_dofs = Vector{Int}(undef, ndofs_per_cell(dh, first_cell)) + u_e = Vector{T}(undef, ndofs_per_cell(dh, first_cell)) x = getcoordinates(grid, first_cell) # compute point values for pointid in eachindex(ph.cells) From 05fab53f7125491e88bc90420f6c5b94346e5b66 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 22 Nov 2023 18:26:29 +0100 Subject: [PATCH 089/145] Add custom values instructions to devdocs --- docs/src/devdocs/FEValues.md | 41 +++++++++++++++++------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/docs/src/devdocs/FEValues.md b/docs/src/devdocs/FEValues.md index d4cbc8c9bf..dc7b4005f6 100644 --- a/docs/src/devdocs/FEValues.md +++ b/docs/src/devdocs/FEValues.md @@ -16,27 +16,24 @@ Ferrite.MappingValues Ferrite.FunctionValues ``` -## How CellValues and FaceValues works -* The function interpolation, `ip_fun`, determines how it should be mapped, by defining `get_mapping_type(ip_fun)` for its type. -* The mapping type, e.g. `IdentityMapping`, decides the requirements for `GeometryValues`, specifically if the `hessian` $\partial^2M/\partial\xi^2$, - of the geometric shape functions, $M(\xi)$, on the reference cell should be precalculated or not. - ***Note:*** *This should also in the future be determined by the required order of derivatives to be mapped in `FunctionValues`* -* As the first part of `reinit!`, the `MappingValues` are calculated based on the cell's coordinates. If the `GeometricMapping` contains the hessian - on the reference cell, the `hessian` on the actual cell, $\partial^2M/\partial x^2$, is calculated and returned in `MappingValues`. Otherwise, only - the jacobian, $\partial M/\partial x$, is calculated. -* In the second part of `reinit!`, The `MappingValues`, containing sufficient information for the current quadrature point, is given to `apply_mapping!`. - This allows the shape values and gradients stored in `FunctionValues`, to be mapped to the current cell by calling `apply_mapping!`. - ## Custom FEValues -Custom FEValues, `fe_v`, should normally implement the `reinit!` method. -Additionally, for normal functionality the `getnquadpoints` should be implemented. -Note that asking for the `n`th quadrature point must be inside array bounds if -`1 <= n <= getnquadpoints(fe_v)` -(`checkquadpoint` can, alternatively, be dispatched to check that `n` is inbounds.) - -Supporting `function_value`, `function_gradient`, `function_symmetric_gradient`, `function_divergence`, and `function_curl`, -requires implementing `getnbasefunctions`, `shape_value`, and `shape_gradient`. -Note that asking for the `i`th shape value or gradient must be inside array bounds if `1 <= i <= getnbasefunctions(fe_v)` +Custom FEValues, `fe_v::AbstractValues`, should normally implement the [`reinit!`](@ref) method. Subtypes of `AbstractValues` have default implementations for some functions, but require some lower-level access functions, specifically + +* [`function_value`](@ref), requires + * [`shape_value`](@ref) + * [`getnquadpoints`](@ref) + * [`getnbasefunctions`](@ref) +* [`function_gradient`](@ref), [`function_divergence`](@ref), [`function_symmetric_gradient`](@ref), and [`function_curl`](@ref) requires + * [`shape_gradient`](@ref) + * [`getnquadpoints`](@ref) + * [`getnbasefunctions`](@ref) +* [`spatial_coordinate`](@ref), requires + * [`geometric_value`](@ref) + * [`getngeobasefunctions`](@ref) + * [`getnquadpoints`](@ref) + -Supporting `spatial_coordinate` requires implementing `getngeobasefunctions` and `geometric_value`. -Note that asking for the `i`th geometric value must be inside array bounds if `1 <= i <= getngeobasefunctions(fe_v)` \ No newline at end of file +### Array bounds +* Asking for the `n`th quadrature point must be inside array bounds if `1 <= n <= getnquadpoints(fe_v)`. (`checkquadpoint` can, alternatively, be dispatched to check that `n` is inbounds.) +* Asking for the `i`th shape value or gradient must be inside array bounds if `1 <= i <= getnbasefunctions(fe_v)` +* Asking for the `i`th geometric value must be inside array bounds if `1 <= i <= getngeobasefunctions(fe_v)` From be6daf8a903084dacef4e10072285654c06001b5 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 22 Nov 2023 18:26:53 +0100 Subject: [PATCH 090/145] Add test that check instructions in devdocs for custom FEValues --- test/test_cellvalues.jl | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 5ff1e72f24..7edebe90bc 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -357,8 +357,41 @@ end @test contains(pv_showstring, "Function interpolation: Lagrange{RefPrism, 2}()") end -@testset "SimpleCellValues" begin - include(joinpath(@__DIR__, "../docs/src/topics/SimpleCellValues_literate.jl")) +@testset "CustomCellValues" begin + + @testset "SimpleCellValues" begin + include(joinpath(@__DIR__, "../docs/src/topics/SimpleCellValues_literate.jl")) + end + + @testset "TestCustomCellValues" begin + + struct TestCustomCellValues{CV<:CellValues} <: Ferrite.AbstractValues + cv::CV + end + # Check that the list in devdocs/FEValues.md is true + # If changes are made that makes the following tests fails, + # the devdocs should be updated accordingly. + for op = (:shape_value, :shape_gradient, :getnquadpoints, :getnbasefunctions, :geometric_value, :getngeobasefunctions) + eval(quote + Ferrite.$op(cv::TestCustomCellValues, args...; kwargs...) = Ferrite.$op(cv.cv, args...; kwargs...) + end) + end + ip = Lagrange{RefQuadrilateral,1}()^2 + qr = QuadratureRule{RefQuadrilateral}(2) + cv = CellValues(qr, ip) + grid = generate_grid(Quadrilateral, (1,1)) + x = getcoordinates(grid, 1) + cell = getcells(grid, 1) + reinit!(cv, x, cell) + ae = rand(getnbasefunctions(cv)) + q_point = rand(1:getnquadpoints(cv)) + cv_custom = TestCustomCellValues(cv) + for fun in (function_value, function_gradient, + function_divergence, function_symmetric_gradient, function_curl) + @test fun(cv_custom, q_point, ae) == fun(cv, q_point, ae) + end + @test spatial_coordinate(cv_custom, q_point, x) == spatial_coordinate(cv, q_point, x) + end end end # of testset From 66bf56d4a48f682933e4703e5fb6b95abf2e9ec2 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 24 Nov 2023 23:33:28 +0100 Subject: [PATCH 091/145] Address Dennis' comments on SimpleCellValues --- docs/src/topics/SimpleCellValues_literate.jl | 39 ++++++++++++-------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/docs/src/topics/SimpleCellValues_literate.jl b/docs/src/topics/SimpleCellValues_literate.jl index 0bbbe9a220..ecfb71b549 100644 --- a/docs/src/topics/SimpleCellValues_literate.jl +++ b/docs/src/topics/SimpleCellValues_literate.jl @@ -3,25 +3,32 @@ using Ferrite, Test # Define a simple version of the cell values object, which only supports -# identity mapping of scalar interpolations, without embedding. +# scalar interpolations using an identity mapping from reference to physical +# elements. Here we assume that the element has the same dimension +# as the physical space, which excludes for example surface elements. struct SimpleCellValues{T, dim} <: Ferrite.AbstractCellValues - N::Matrix{T} # Precalculated shape values - dNdξ::Matrix{Vec{dim,T}} # Precalculated shape gradients in the reference domain - dNdx::Matrix{Vec{dim,T}} # Cache for shape gradients in the real domain - M::Matrix{T} # Precalculated geometric shape values - dMdξ::Matrix{Vec{dim,T}} # Precalculated geometric shape gradients - weights::Vector{T} # Given quadrature weights in the reference domain - detJdV::Vector{T} # Cache for quadrature weights in the real domain + N::Matrix{T} # Precalculated shape values, N[i, q_point] where i is the +# # shape function number and q_point the integration point + dNdξ::Matrix{Vec{dim,T}} # Precalculated shape gradients in the reference domain, dNdξ[i, q_point] + dNdx::Matrix{Vec{dim,T}} # Cache for shape gradients in the physical domain, dNdx[i, q_point] + M::Matrix{T} # Precalculated geometric shape values, M[j, q_point] where j is the +# # geometric shape function number + dMdξ::Matrix{Vec{dim,T}} # Precalculated geometric shape gradients, dMdξ[j, q_point] + weights::Vector{T} # Given quadrature weights in the reference domain, weights[q_point] + detJdV::Vector{T} # Cache for quadrature weights in the physical domain, detJdV[q_point], i.e. +# # det(J)*weight[q_point], where J is the jacobian of the geometric mapping +# # at the quadrature point, q_point. end; -# To make it easier to initiate this struct, we create a constructor function +# To make it easier to initialize this struct, we create a constructor function # with the same input as `CellValues`. However, we skip some consistency checking here. -function SimpleCellValues(qr::QuadratureRule, ip_fun::Interpolation, ip_geo::Interpolation, T=Float64) +function SimpleCellValues(qr::QuadratureRule, ip_fun::Interpolation, ip_geo::Interpolation) dim = Ferrite.getdim(ip_fun) ## Quadrature weights and coordinates (in reference cell) weights = Ferrite.getweights(qr) n_qpoints = length(weights) - + T = eltype(weights) + ## Function interpolation n_func_basefuncs = getnbasefunctions(ip_fun) N = zeros(T, n_func_basefuncs, n_qpoints) @@ -47,12 +54,13 @@ function SimpleCellValues(qr::QuadratureRule, ip_fun::Interpolation, ip_geo::Int SimpleCellValues(N, dNdξ, dNdx, M, dMdξ, weights, detJdV) end; -# We first define `getnbasefunctions` and `getnquadpoints` +# We first create a dispatch of `getnbasefunctions` and `getnquadpoints` +# for our SimpleCellValues Ferrite.getnbasefunctions(cv::SimpleCellValues) = size(cv.N, 1); Ferrite.getnquadpoints(cv::SimpleCellValues) = size(cv.N, 2); -# Before we define the `reinit!` function to calculate the cached -# values `dNdx` and `detJdV` for the current cell +# Before we define the dispatch of `reinit!` function to calculate +# the cached values `dNdx` and `detJdV` for the current cell function Ferrite.reinit!(cv::SimpleCellValues, x::Vector{Vec{dim,T}}) where {dim,T} for (q_point, w) in pairs(cv.weights) # Loop over each quadrature point ## Calculate the jacobian, J @@ -81,7 +89,8 @@ ip = Lagrange{RefQuadrilateral,1}() simple_cv = SimpleCellValues(qr, ip, ip) cv = CellValues(qr, ip, ip) -# The first thing to try is to reinitialize the cell values to a given cell +# The first thing to try is to reinitialize the cell +# values to a given cell, in this case cell nr. 2 grid = generate_grid(Quadrilateral, (2,2)) x = getcoordinates(grid, 2) reinit!(simple_cv, x) From b31e821c091befd417bc45bff495e80e02c14514 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 24 Nov 2023 23:36:28 +0100 Subject: [PATCH 092/145] Address Dennis' comments on common values --- src/FEValues/common_values.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index fec2c19080..9395867f28 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -26,8 +26,10 @@ end end """ - reinit!(cv::CellValues, x::Vector, cell::Union{AbstractCell,Nothing}=nothing) - reinit!(fv::FaceValues, x::Vector, face::Int, cell::Union{AbstractCell,Nothing}=nothing) + reinit!(cv::CellValues, x::Vector, cell::AbstractCell) + reinit!(cv::CellValues, x::Vector) + reinit!(fv::FaceValues, x::Vector, face::Int, cell::AbstractCell) + reinit!(fv::FaceValues, x::Vector, face::Int) Update the `CellValues`/`FaceValues` object for a cell or face with coordinates `x`. The derivatives of the shape functions, and the new integration weights are computed. @@ -286,4 +288,4 @@ function shape_hessians_gradients_and_values!(hessians::AbstractMatrix, gradient for (qp, ξ) in pairs(getpoints(qr)) shape_hessians_gradients_and_values!(@view(hessians[:, qp]), @view(gradients[:, qp]), @view(values[:, qp]), ip, ξ) end -end \ No newline at end of file +end From 0bbc09dad3c513d81fa7825caa51bbeb231f7872 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 1 Dec 2023 11:09:14 +0100 Subject: [PATCH 093/145] Simplifications --- src/FEValues/CellValues.jl | 7 +++---- src/FEValues/FaceValues.jl | 6 ++---- src/FEValues/FunctionValues.jl | 2 +- src/FEValues/common_values.jl | 5 +---- src/PointEval/point_values.jl | 5 ++--- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 1f9d64dfaa..04fce8a816 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -41,12 +41,11 @@ struct CellValues{FV, GM, QR, detT} <: AbstractCellValues qr::QR # QuadratureRule detJdV::detT # AbstractVector{<:Number} end -function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; difforder=Val(1), save_detJ=Val(true)) where T - GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + _extract_val(difforder), _extract_val(save_detJ)) - FunDiffOrder = _extract_val(difforder) +function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; FunDiffOrder=1, save_detJ=true) where T + GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + FunDiffOrder, save_detJ) geo_mapping = GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) fun_values = FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) - detJdV = _extract_val(save_detJ) ? fill(T(NaN), length(getweights(qr))) : nothing + detJdV = save_detJ ? fill(T(NaN), length(getweights(qr))) : nothing return CellValues(fun_values, geo_mapping, qr, detJdV) end diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index c902612e30..575c592e8a 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -40,10 +40,8 @@ struct FaceValues{FV, GM, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GM<:Abstract current_face::ScalarWrapper{Int} end -function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun); difforder=Val(1)) where {T,sdim} - GeoDiffOrder = increased_diff_order(get_mapping_type(ip_fun)) + _extract_val(difforder) - FunDiffOrder = _extract_val(difforder) - +function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun); FunDiffOrder=1) where {T,sdim} + GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + FunDiffOrder, 1) geo_mapping = [GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) for qr in fqr.face_rules] fun_values = [FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index b3a7a69a0f..bdca47c460 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -136,7 +136,7 @@ get_mapping_type(fv::FunctionValues) = get_mapping_type(fv.ip) How many order higher geometric derivatives are required to to map the function values and gradients from the reference cell -to the real cell geometry? +to the physical cell geometry? """ increased_diff_order(::IdentityMapping) = 0 increased_diff_order(::ContravariantPiolaMapping) = 1 diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index da4158d92c..d507ca0545 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -276,13 +276,10 @@ function spatial_coordinate(fe_v::AbstractValues, q_point::Int, x::AbstractVecto end -# Utility functions used by GeometryMapping, FunctionValues, FaceValues, CellValues +# Utility functions used by GeometryMapping, FunctionValues _copy_or_nothing(x) = copy(x) _copy_or_nothing(::Nothing) = nothing -_extract_val(v) = v -_extract_val(::Val{N}) where N = N - function shape_values!(values::AbstractMatrix, ip, qr::QuadratureRule) for (qp, ξ) in pairs(getpoints(qr)) shape_values!(@view(values[:, qp]), ip, ξ) diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 29d668fe96..8c1c2d8e06 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -28,8 +28,7 @@ function PointValues(cv::CellValues) T = typeof(getdetJdV(cv, 1)) ip_fun = get_function_interpolation(cv) ip_geo = get_geometric_interpolation(cv) - FunDiffOrder = get_function_difforder(cv) - return PointValues(T, ip_fun, ip_geo; difforder=Val(FunDiffOrder)) + return PointValues(T, ip_fun, ip_geo; FunDiffOrder = get_function_difforder(cv)) end function PointValues(ip::Interpolation, ipg::Interpolation = default_geometric_interpolation(ip); kwargs...) return PointValues(Float64, ip, ipg; kwargs...) @@ -40,7 +39,7 @@ function PointValues(::Type{T}, ip::IP, ipg::GIP = default_geometric_interpolati GIP <: Interpolation{shape} } qr = QuadratureRule{shape, T}([one(T)], [zero(Vec{dim, T})]) - cv = CellValues(T, qr, ip, ipg; save_detJ=Val(false), kwargs...) + cv = CellValues(T, qr, ip, ipg; save_detJ=false, kwargs...) return PointValues{typeof(cv)}(cv) end From ae80cfbc6bccf92c6ae5ffc9938956c7a9c282e1 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 3 Dec 2023 13:08:53 +0100 Subject: [PATCH 094/145] Fix PointValues usage in PointEvalHandler --- src/PointEval/PointEvalHandler.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PointEval/PointEvalHandler.jl b/src/PointEval/PointEvalHandler.jl index 6bf47a615e..551b18b11b 100644 --- a/src/PointEval/PointEvalHandler.jl +++ b/src/PointEval/PointEvalHandler.jl @@ -185,7 +185,7 @@ function evaluate_at_points(ph::PointEvalHandler{<:Any, dim, T1}, dh::AbstractDo npoints = length(ph.cells) # Figure out the value type by creating a dummy PointValues ip = getfieldinterpolation(dh, find_field(dh, fname)) - pv = PointValues(T1, ip; difforder=Val(0)) + pv = PointValues(T1, ip; FunDiffOrder=0) zero_val = function_value_init(pv, dof_vals) # Allocate the output as NaNs nanv = convert(typeof(zero_val), NaN * zero_val) @@ -244,7 +244,7 @@ function _evaluate_at_points!( first_cell = cellset === nothing ? 1 : first(cellset) grid = get_grid(dh) ip_geo = default_interpolation(getcelltype(grid, first_cell)) - pv = PointValues(eltype(local_coords[idx]), ip, ip_geo; difforder=Val(0)) + pv = PointValues(eltype(local_coords[idx]), ip, ip_geo; FunDiffOrder=0) cell_dofs = Vector{Int}(undef, ndofs_per_cell(dh, first_cell)) u_e = Vector{T}(undef, ndofs_per_cell(dh, first_cell)) x = getcoordinates(grid, first_cell) From 1d5b9f175ed79cbf9b277712237da6686d4507e3 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 3 Dec 2023 14:26:26 +0100 Subject: [PATCH 095/145] Fix tests after merge --- src/FEValues/CellValues.jl | 12 ------------ src/FEValues/FunctionValues.jl | 12 ++++++------ src/FEValues/GeometryMapping.jl | 18 +++++++++--------- src/FEValues/common_values.jl | 12 ++++++------ src/FEValues/interface_values.jl | 7 +++---- src/PointEval/point_values.jl | 3 ++- test/test_interfacevalues.jl | 8 ++++---- 7 files changed, 30 insertions(+), 42 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 04fce8a816..c9cc811917 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -58,18 +58,6 @@ function Base.copy(cv::CellValues) return CellValues(copy(cv.fun_values), copy(cv.geo_mapping), copy(cv.qr), copy(cv.detJdV)) end -""" - precompute_values!(cv::CellValues) - -Precompute all values for the current quadrature rule in `cv`. This method allows you to modify -the quadrature positions, and then update all relevant parts of `cv` accordingly. -Used by `PointValues`. -""" -function precompute_values!(cv::CellValues) - precompute_values!(cv.fun_values, cv.qr) - precompute_values!(cv.geo_mapping, cv.qr) -end - # Access geometry values @propagate_inbounds getngeobasefunctions(cv::CellValues) = getngeobasefunctions(cv.geo_mapping) @propagate_inbounds geometric_value(cv::CellValues, args...) = geometric_value(cv.geo_mapping, args...) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index bdca47c460..ffbff26449 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -59,7 +59,7 @@ function FunctionValues{0}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_ N_x = isa(get_mapping_type(ip), IdentityMapping) ? N_ξ : similar(N_ξ) fv = FunctionValues(ip, N_x, N_ξ, nothing, nothing) - precompute_values!(fv, qr) # Separate function for qr point update in PointValues + precompute_values!(fv, getpoints(qr)) # Separate function for qr point update in PointValues return fv end function FunctionValues{1}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T @@ -74,15 +74,15 @@ function FunctionValues{1}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_ dNdx = fill(zero(typeof_dNdx(T, ip_dims)) * T(NaN), n_shape, n_qpoints) fv = FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) - precompute_values!(fv, qr) # Separate function for qr point update in PointValues + precompute_values!(fv, getpoints(qr)) # Separate function for qr point update in PointValues return fv end -function precompute_values!(fv::FunctionValues{0}, qr) - shape_values!(fv.N_ξ, fv.ip, qr) +function precompute_values!(fv::FunctionValues{0}, qr_points::Vector{<:Vec}) + shape_values!(fv.N_ξ, fv.ip, qr_points) end -function precompute_values!(fv::FunctionValues{1}, qr) - shape_gradients_and_values!(fv.dNdξ, fv.N_ξ, fv.ip, qr) +function precompute_values!(fv::FunctionValues{1}, qr_points::Vector{<:Vec}) + shape_gradients_and_values!(fv.dNdξ, fv.N_ξ, fv.ip, qr_points) end function Base.copy(v::FunctionValues) diff --git a/src/FEValues/GeometryMapping.jl b/src/FEValues/GeometryMapping.jl index ee6386519f..b3a283dfed 100644 --- a/src/FEValues/GeometryMapping.jl +++ b/src/FEValues/GeometryMapping.jl @@ -55,7 +55,7 @@ function GeometryMapping{0}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRu n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) gm = GeometryMapping(ip, zeros(T, n_shape, n_qpoints), nothing, nothing) - precompute_values!(gm, qr) # Separate function for qr point update in PointValues + precompute_values!(gm, getpoints(qr)) return gm end function GeometryMapping{1}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T @@ -66,7 +66,7 @@ function GeometryMapping{1}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRu dMdξ = zeros(Vec{getdim(ip),T}, n_shape, n_qpoints) gm = GeometryMapping(ip, M, dMdξ, nothing) - precompute_values!(gm, qr) # Separate function for qr point update in PointValues + precompute_values!(gm, getpoints(qr)) return gm end function GeometryMapping{2}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T @@ -78,18 +78,18 @@ function GeometryMapping{2}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRu d2Mdξ2 = zeros(Tensor{2,getdim(ip),T}, n_shape, n_qpoints) gm = GeometryMapping(ip, M, dMdξ, d2Mdξ2) - precompute_values!(gm, qr) # Separate function for qr point update in PointValues + precompute_values!(gm, getpoints(qr)) return gm end -function precompute_values!(gm::GeometryMapping{0}, qr) - shape_values!(gm.M, gm.ip, qr) +function precompute_values!(gm::GeometryMapping{0}, qr_points::Vector{<:Vec}) + shape_values!(gm.M, gm.ip, qr_points) end -function precompute_values!(gm::GeometryMapping{1}, qr) - shape_gradients_and_values!(gm.dMdξ, gm.M, gm.ip, qr) +function precompute_values!(gm::GeometryMapping{1}, qr_points::Vector{<:Vec}) + shape_gradients_and_values!(gm.dMdξ, gm.M, gm.ip, qr_points) end -function precompute_values!(gm::GeometryMapping{2}, qr) - shape_hessians_gradients_and_values!(gm.d2Mdξ2, gm.dMdξ, gm.M, gm.ip, qr) +function precompute_values!(gm::GeometryMapping{2}, qr_points::Vector{<:Vec}) + shape_hessians_gradients_and_values!(gm.d2Mdξ2, gm.dMdξ, gm.M, gm.ip, qr_points) end function Base.copy(v::GeometryMapping) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index f9d6fa44c0..9d8292d051 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -288,20 +288,20 @@ end _copy_or_nothing(x) = copy(x) _copy_or_nothing(::Nothing) = nothing -function shape_values!(values::AbstractMatrix, ip, qr::QuadratureRule) - for (qp, ξ) in pairs(getpoints(qr)) +function shape_values!(values::AbstractMatrix, ip, qr_points::Vector{<:Vec}) + for (qp, ξ) in pairs(qr_points) shape_values!(@view(values[:, qp]), ip, ξ) end end -function shape_gradients_and_values!(gradients::AbstractMatrix, values::AbstractMatrix, ip, qr::QuadratureRule) - for (qp, ξ) in pairs(getpoints(qr)) +function shape_gradients_and_values!(gradients::AbstractMatrix, values::AbstractMatrix, ip, qr_points::Vector{<:Vec}) + for (qp, ξ) in pairs(qr_points) shape_gradients_and_values!(@view(gradients[:, qp]), @view(values[:, qp]), ip, ξ) end end -function shape_hessians_gradients_and_values!(hessians::AbstractMatrix, gradients::AbstractMatrix, values::AbstractMatrix, ip, qr::QuadratureRule) - for (qp, ξ) in pairs(getpoints(qr)) +function shape_hessians_gradients_and_values!(hessians::AbstractMatrix, gradients::AbstractMatrix, values::AbstractMatrix, ip, qr_points::Vector{<:Vec}) + for (qp, ξ) in pairs(qr_points) shape_hessians_gradients_and_values!(@view(hessians[:, qp]), @view(gradients[:, qp]), @view(values[:, qp]), ip, ξ) end end \ No newline at end of file diff --git a/src/FEValues/interface_values.jl b/src/FEValues/interface_values.jl index 1765b51fb2..3f13140e92 100644 --- a/src/FEValues/interface_values.jl +++ b/src/FEValues/interface_values.jl @@ -127,18 +127,17 @@ function reinit!( reinit!(iv.here, coords_here, face_here) dim == 1 && return reinit!(iv.there, coords_there, face_there) # Transform the quadrature points from the here side to the there side - set_current_face!(iv.there, face_there) + set_current_face!(iv.there, face_there) # Includes boundscheck interface_transformation = InterfaceOrientationInfo(cell_here, cell_there, face_here, face_there) quad_points_a = getpoints(iv.here.qr, face_here) quad_points_b = getpoints(iv.there.qr, face_there) transform_interface_points!(quad_points_b, quad_points_a, interface_transformation) - @boundscheck checkface(iv.there, face_there) # TODO: This is the bottleneck, cache it? @assert length(quad_points_a) <= length(quad_points_b) # Re-evalutate shape functions in the transformed quadrature points - precompute_values!(iv.there.fun_values, quad_points_b) - precompute_values!(iv.there.geo_mapping, quad_points_b) + precompute_values!(get_fun_values(iv.there), quad_points_b) + precompute_values!(get_geo_mapping(iv.there), quad_points_b) # reinit! the "there" side reinit!(iv.there, coords_there, face_there) diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 8c1c2d8e06..aa3d3b5401 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -66,7 +66,8 @@ function reinit!(pv::PointValues, x::AbstractVector{<:Vec{D}}, ξ::Vec{D}) where qr_points = getpoints(pv.cv.qr) qr_points[1] = ξ # Precompute all values again to reflect the updated ξ coordinate - precompute_values!(pv.cv) + precompute_values!(pv.cv.fun_values, qr_points) + precompute_values!(pv.cv.geo_mapping, qr_points) # Regular reinit reinit!(pv.cv, x) return nothing diff --git a/test/test_interfacevalues.jl b/test/test_interfacevalues.jl index cfdf467a7c..6a19eafa25 100644 --- a/test/test_interfacevalues.jl +++ b/test/test_interfacevalues.jl @@ -1,7 +1,7 @@ @testset "InterfaceValues" begin function test_interfacevalues(grid::Ferrite.AbstractGrid, iv::InterfaceValues; tol = 0) - ip_here = iv.here.func_interp - ip_there = iv.there.func_interp + ip_here = Ferrite.get_function_interpolation(iv.here) + ip_there = Ferrite.get_function_interpolation(iv.there) ndim = Ferrite.getdim(ip_here) n_basefuncs = getnbasefunctions(ip_here) + getnbasefunctions(ip_there) @@ -252,8 +252,8 @@ @test_throws ArgumentError("transformation is not implemented") Ferrite.get_transformation_matrix(it) end @testset "show" begin - # Just smoke test to make sure show doesn't error. iv = InterfaceValues(FaceQuadratureRule{RefQuadrilateral}(2), Lagrange{RefQuadrilateral,2}()) - show(stdout, MIME"text/plain"(), iv) + showstring = show_as_string(iv) + @test contains(showstring, "InterfaceValues with") end end # of testset From 76a9312dc1cf3c6cb643c6947db812a045eed34a Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 3 Dec 2023 15:04:05 +0100 Subject: [PATCH 096/145] Fix missing double-comment for literate --- docs/src/topics/SimpleCellValues_literate.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/topics/SimpleCellValues_literate.jl b/docs/src/topics/SimpleCellValues_literate.jl index ecfb71b549..78429af17e 100644 --- a/docs/src/topics/SimpleCellValues_literate.jl +++ b/docs/src/topics/SimpleCellValues_literate.jl @@ -8,16 +8,16 @@ using Ferrite, Test # as the physical space, which excludes for example surface elements. struct SimpleCellValues{T, dim} <: Ferrite.AbstractCellValues N::Matrix{T} # Precalculated shape values, N[i, q_point] where i is the -# # shape function number and q_point the integration point +## # shape function number and q_point the integration point dNdξ::Matrix{Vec{dim,T}} # Precalculated shape gradients in the reference domain, dNdξ[i, q_point] dNdx::Matrix{Vec{dim,T}} # Cache for shape gradients in the physical domain, dNdx[i, q_point] M::Matrix{T} # Precalculated geometric shape values, M[j, q_point] where j is the -# # geometric shape function number +## # geometric shape function number dMdξ::Matrix{Vec{dim,T}} # Precalculated geometric shape gradients, dMdξ[j, q_point] weights::Vector{T} # Given quadrature weights in the reference domain, weights[q_point] detJdV::Vector{T} # Cache for quadrature weights in the physical domain, detJdV[q_point], i.e. -# # det(J)*weight[q_point], where J is the jacobian of the geometric mapping -# # at the quadrature point, q_point. +## # det(J)*weight[q_point], where J is the jacobian of the geometric mapping +## # at the quadrature point, q_point. end; # To make it easier to initialize this struct, we create a constructor function From 679a4ac01f4c80253b8a5db57c686e7fb59b1f33 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 3 Dec 2023 16:26:32 +0100 Subject: [PATCH 097/145] Improved naming/interfaces --- src/FEValues/CellValues.jl | 11 ++++++----- src/FEValues/FaceValues.jl | 15 +++++++-------- src/FEValues/FunctionValues.jl | 14 +++++++------- src/FEValues/interface_values.jl | 4 ++-- src/PointEval/point_values.jl | 2 +- test/test_facevalues.jl | 8 ++++---- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index c9cc811917..4bbdf33deb 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -39,13 +39,13 @@ struct CellValues{FV, GM, QR, detT} <: AbstractCellValues fun_values::FV # FunctionValues geo_mapping::GM # GeometryMapping qr::QR # QuadratureRule - detJdV::detT # AbstractVector{<:Number} + detJdV::detT # AbstractVector{<:Number} or Nothing end -function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; FunDiffOrder=1, save_detJ=true) where T - GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + FunDiffOrder, save_detJ) +function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; FunDiffOrder=1, save_detJdV=true) where T + GeoDiffOrder = max(required_geo_diff_order(get_mapping_type(ip_fun), FunDiffOrder), save_detJdV) geo_mapping = GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) fun_values = FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) - detJdV = save_detJ ? fill(T(NaN), length(getweights(qr))) : nothing + detJdV = save_detJdV ? fill(T(NaN), length(getweights(qr))) : nothing return CellValues(fun_values, geo_mapping, qr, detJdV) end @@ -55,7 +55,7 @@ function CellValues(::Type{T}, qr, ip::Interpolation, ip_geo::ScalarInterpolatio end function Base.copy(cv::CellValues) - return CellValues(copy(cv.fun_values), copy(cv.geo_mapping), copy(cv.qr), copy(cv.detJdV)) + return CellValues(copy(cv.fun_values), copy(cv.geo_mapping), copy(cv.qr), _copy_or_nothing(cv.detJdV)) end # Access geometry values @@ -64,6 +64,7 @@ end get_geometric_interpolation(cv::CellValues) = get_geometric_interpolation(cv.geo_mapping) getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] +getdetJdV(::CellValues{<:Any, <:Any, <:Any, Nothing}, ::Int) = throw(ArgumentError("detJdV is not saved in CellValues")) # Accessors for function values getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 6b2090e4e4..f788f11dda 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -31,17 +31,17 @@ values of nodal functions, gradients and divergences of nodal functions etc. on """ FaceValues -struct FaceValues{FV, GM, QR, detT, nT, V_FV<:AbstractVector{FV}, V_GM<:AbstractVector{GM}} <: AbstractFaceValues +struct FaceValues{FV, GM, FQR, detT, nT, V_FV<:AbstractVector{FV}, V_GM<:AbstractVector{GM}} <: AbstractFaceValues fun_values::V_FV # AbstractVector{FunctionValues} geo_mapping::V_GM # AbstractVector{GeometryMapping} - qr::QR # FaceQuadratureRule + fqr::FQR # FaceQuadratureRule detJdV::detT # AbstractVector{<:Number} normals::nT # AbstractVector{<:Vec} current_face::ScalarWrapper{Int} end function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun); FunDiffOrder=1) where {T,sdim} - GeoDiffOrder = max(increased_diff_order(get_mapping_type(ip_fun)) + FunDiffOrder, 1) + GeoDiffOrder = max(required_geo_diff_order(get_mapping_type(ip_fun), FunDiffOrder), 1) geo_mapping = [GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) for qr in fqr.face_rules] fun_values = [FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) @@ -58,12 +58,12 @@ end function Base.copy(fv::FaceValues) fun_values = map(copy, fv.fun_values) geo_mapping = map(copy, fv.geo_mapping) - return FaceValues(fun_values, geo_mapping, copy(fv.qr), copy(fv.detJdV), copy(fv.normals), copy(fv.current_face)) + return FaceValues(fun_values, geo_mapping, copy(fv.fqr), copy(fv.detJdV), copy(fv.normals), copy(fv.current_face)) end getngeobasefunctions(fv::FaceValues) = getngeobasefunctions(get_geo_mapping(fv)) getnbasefunctions(fv::FaceValues) = getnbasefunctions(get_fun_values(fv)) -getnquadpoints(fv::FaceValues) = @inbounds getnquadpoints(fv.qr, getcurrentface(fv)) +getnquadpoints(fv::FaceValues) = @inbounds getnquadpoints(fv.fqr, getcurrentface(fv)) @propagate_inbounds getdetJdV(fv::FaceValues, q_point) = fv.detJdV[q_point] shape_value_type(fv::FaceValues) = shape_value_type(get_fun_values(fv)) @@ -86,7 +86,6 @@ end getcurrentface(fv::FaceValues) Return the current active face of the `FaceValues` object (from last `reinit!`). - """ getcurrentface(fv::FaceValues) = fv.current_face[] @@ -127,7 +126,7 @@ function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, ce throw(ArgumentError("The cell::AbstractCell input is required to reinit! non-identity function mappings")) end - @inbounds for (q_point, w) in pairs(getweights(fv.qr, face_nr)) + @inbounds for (q_point, w) in pairs(getweights(fv.fqr, face_nr)) mapping = calculate_mapping(geo_mapping, q_point, x) J = getjacobian(mapping) # See the `Ferrite.embedded_det` docstring for more background @@ -147,7 +146,7 @@ function Base.show(io::IO, d::MIME"text/plain", fv::FaceValues) sdim = length(shape_gradient(fv, 1, 1)) ÷ length(shape_value(fv, 1, 1)) vstr = vdim==0 ? "scalar" : "vdim=$vdim" print(io, "FaceValues(", vstr, ", rdim=$rdim, sdim=$sdim): ") - nqp = getnquadpoints.(fv.qr.face_rules) + nqp = getnquadpoints.(fv.fqr.face_rules) if all(n==first(nqp) for n in nqp) println(io, first(nqp), " quadrature points per face") else diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index ffbff26449..c4e08b4c81 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -132,15 +132,15 @@ struct ContravariantPiolaMapping end get_mapping_type(fv::FunctionValues) = get_mapping_type(fv.ip) """ - increased_diff_order(mapping) + required_geo_diff_order(fun_mapping, fun_diff_order::Int) -How many order higher geometric derivatives are required to -to map the function values and gradients from the reference cell -to the physical cell geometry? +Return the required order of geometric derivatives to map +the function values and gradients from the reference cell +to the physical cell geometry. """ -increased_diff_order(::IdentityMapping) = 0 -increased_diff_order(::ContravariantPiolaMapping) = 1 -increased_diff_order(::CovariantPiolaMapping) = 1 +required_geo_diff_order(::IdentityMapping, fun_diff_order::Int) = fun_diff_order +required_geo_diff_order(::ContravariantPiolaMapping, fun_diff_order::Int) = 1 + fun_diff_order +required_geo_diff_order(::CovariantPiolaMapping, fun_diff_order::Int) = 1 + fun_diff_order # Support for embedded elements @inline calculate_Jinv(J::Tensor{2}) = inv(J) diff --git a/src/FEValues/interface_values.jl b/src/FEValues/interface_values.jl index 3f13140e92..dcee07d045 100644 --- a/src/FEValues/interface_values.jl +++ b/src/FEValues/interface_values.jl @@ -129,8 +129,8 @@ function reinit!( # Transform the quadrature points from the here side to the there side set_current_face!(iv.there, face_there) # Includes boundscheck interface_transformation = InterfaceOrientationInfo(cell_here, cell_there, face_here, face_there) - quad_points_a = getpoints(iv.here.qr, face_here) - quad_points_b = getpoints(iv.there.qr, face_there) + quad_points_a = getpoints(iv.here.fqr, face_here) + quad_points_b = getpoints(iv.there.fqr, face_there) transform_interface_points!(quad_points_b, quad_points_a, interface_transformation) # TODO: This is the bottleneck, cache it? @assert length(quad_points_a) <= length(quad_points_b) diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index aa3d3b5401..268b8cdbaf 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -39,7 +39,7 @@ function PointValues(::Type{T}, ip::IP, ipg::GIP = default_geometric_interpolati GIP <: Interpolation{shape} } qr = QuadratureRule{shape, T}([one(T)], [zero(Vec{dim, T})]) - cv = CellValues(T, qr, ip, ipg; save_detJ=false, kwargs...) + cv = CellValues(T, qr, ip, ipg; save_detJdV=false, kwargs...) return PointValues{typeof(cv)}(cv) end diff --git a/test/test_facevalues.jl b/test/test_facevalues.jl index e4b113b224..1b09c2db75 100644 --- a/test/test_facevalues.jl +++ b/test/test_facevalues.jl @@ -115,10 +115,10 @@ for (scalar_interpol, quad_rule) in ( # Make it easy to test scalar wrapper equality _mock_isequal(a, b) = a == b _mock_isequal(a::T, b::T) where {T<:Ferrite.ScalarWrapper} = a[] == b[] - for fname in (:qr, :detJdV, :normals, :current_face) + for fname in (:fqr, :detJdV, :normals, :current_face) v = getfield(fv, fname) vc = getfield(fvc, fname) - if fname !== :qr # Test unaliased + if fname !== :fqr # Test unaliased @test v !== vc end @test _mock_isequal(v, vc) @@ -134,8 +134,8 @@ end @test startswith(showstring, "FaceValues(scalar, rdim=2, sdim=2): 2 quadrature points per face") @test contains(showstring, "Function interpolation: Lagrange{RefQuadrilateral, 2}()") @test contains(showstring, "Geometric interpolation: Lagrange{RefQuadrilateral, 1}()^2") - fv.qr.face_rules[1] = deepcopy(fv.qr.face_rules[1]) - push!(Ferrite.getweights(fv.qr.face_rules[1]), 1) + fv.fqr.face_rules[1] = deepcopy(fv.fqr.face_rules[1]) + push!(Ferrite.getweights(fv.fqr.face_rules[1]), 1) showstring = show_as_string(fv) @test startswith(showstring, "FaceValues(scalar, rdim=2, sdim=2): (3, 2, 2, 2) quadrature points on each face") end From a913c9bfee6b2e98740cf4dd9e9a1863f8fe733f Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 3 Dec 2023 16:32:42 +0100 Subject: [PATCH 098/145] Fix formatting of SimpleCellValues example --- docs/src/topics/SimpleCellValues_literate.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/topics/SimpleCellValues_literate.jl b/docs/src/topics/SimpleCellValues_literate.jl index 78429af17e..e604ecf81a 100644 --- a/docs/src/topics/SimpleCellValues_literate.jl +++ b/docs/src/topics/SimpleCellValues_literate.jl @@ -8,16 +8,16 @@ using Ferrite, Test # as the physical space, which excludes for example surface elements. struct SimpleCellValues{T, dim} <: Ferrite.AbstractCellValues N::Matrix{T} # Precalculated shape values, N[i, q_point] where i is the -## # shape function number and q_point the integration point + ## shape function number and q_point the integration point dNdξ::Matrix{Vec{dim,T}} # Precalculated shape gradients in the reference domain, dNdξ[i, q_point] dNdx::Matrix{Vec{dim,T}} # Cache for shape gradients in the physical domain, dNdx[i, q_point] M::Matrix{T} # Precalculated geometric shape values, M[j, q_point] where j is the -## # geometric shape function number + ## geometric shape function number dMdξ::Matrix{Vec{dim,T}} # Precalculated geometric shape gradients, dMdξ[j, q_point] weights::Vector{T} # Given quadrature weights in the reference domain, weights[q_point] detJdV::Vector{T} # Cache for quadrature weights in the physical domain, detJdV[q_point], i.e. -## # det(J)*weight[q_point], where J is the jacobian of the geometric mapping -## # at the quadrature point, q_point. + ## det(J)*weight[q_point], where J is the jacobian of the geometric mapping + ## at the quadrature point, q_point. end; # To make it easier to initialize this struct, we create a constructor function From 8b6c097aeacd08e40da247fdb4a085cc5deec357 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 3 Dec 2023 16:53:18 +0100 Subject: [PATCH 099/145] Simplify text in SimpleCellValues example --- docs/src/topics/SimpleCellValues_literate.jl | 49 +++++++++----------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/docs/src/topics/SimpleCellValues_literate.jl b/docs/src/topics/SimpleCellValues_literate.jl index e604ecf81a..06ba44b779 100644 --- a/docs/src/topics/SimpleCellValues_literate.jl +++ b/docs/src/topics/SimpleCellValues_literate.jl @@ -1,11 +1,11 @@ -# We start by including `Ferrite` and `Test`, -# to allow us to verify our implementation. +# We start by including `Ferrite` and `Test` (to check our implementation). using Ferrite, Test -# Define a simple version of the cell values object, which only supports -# scalar interpolations using an identity mapping from reference to physical -# elements. Here we assume that the element has the same dimension -# as the physical space, which excludes for example surface elements. +# Then, we define a simple version of the cell values object, which only supports +# * Scalar interpolations +# * Identity mapping from reference to physical cell. +# * The cell shape has the same dimension as the physical space (excludes so-called embedded cells). + struct SimpleCellValues{T, dim} <: Ferrite.AbstractCellValues N::Matrix{T} # Precalculated shape values, N[i, q_point] where i is the ## shape function number and q_point the integration point @@ -20,8 +20,7 @@ struct SimpleCellValues{T, dim} <: Ferrite.AbstractCellValues ## at the quadrature point, q_point. end; -# To make it easier to initialize this struct, we create a constructor function -# with the same input as `CellValues`. However, we skip some consistency checking here. +# Next, we create a constructor with the same input as `CellValues` function SimpleCellValues(qr::QuadratureRule, ip_fun::Interpolation, ip_geo::Interpolation) dim = Ferrite.getdim(ip_fun) ## Quadrature weights and coordinates (in reference cell) @@ -54,13 +53,16 @@ function SimpleCellValues(qr::QuadratureRule, ip_fun::Interpolation, ip_geo::Int SimpleCellValues(N, dNdξ, dNdx, M, dMdξ, weights, detJdV) end; -# We first create a dispatch of `getnbasefunctions` and `getnquadpoints` -# for our SimpleCellValues -Ferrite.getnbasefunctions(cv::SimpleCellValues) = size(cv.N, 1); -Ferrite.getnquadpoints(cv::SimpleCellValues) = size(cv.N, 2); +# To make our `SimpleCellValues` work in standard Ferrite code, +# we need to dispatch some access functions: +Ferrite.getnbasefunctions(cv::SimpleCellValues) = size(cv.N, 1) +Ferrite.getnquadpoints(cv::SimpleCellValues) = size(cv.N, 2) +Ferrite.shape_value(cv::SimpleCellValues, q_point::Int, i::Int) = cv.N[i, q_point] +Ferrite.shape_gradient(cv::SimpleCellValues, q_point::Int, i::Int) = cv.dNdx[i, q_point]; -# Before we define the dispatch of `reinit!` function to calculate -# the cached values `dNdx` and `detJdV` for the current cell +# The last step is then to dispatch `reinit!` for our `SimpleCellValues` to calculate +# the cached values `dNdx` and `detJdV` for the current cell according to the +# theory for `IdentityMapping` above. function Ferrite.reinit!(cv::SimpleCellValues, x::Vector{Vec{dim,T}}) where {dim,T} for (q_point, w) in pairs(cv.weights) # Loop over each quadrature point ## Calculate the jacobian, J @@ -78,27 +80,22 @@ function Ferrite.reinit!(cv::SimpleCellValues, x::Vector{Vec{dim,T}}) where {dim end end; -# To make our `SimpleCellValues` work in standard Ferrite code, we need to define how -# to get the shape value and graident: -Ferrite.shape_value(cv::SimpleCellValues, q_point::Int, i::Int) = cv.N[i, q_point] -Ferrite.shape_gradient(cv::SimpleCellValues, q_point::Int, i::Int) = cv.dNdx[i, q_point] - -# We are now ready to test, so let's create an instance of our new and the regular cell values +# To test our implementation, we create instances of our `SimpleCellValues` and the standard `CellValues`: qr = QuadratureRule{RefQuadrilateral}(2) ip = Lagrange{RefQuadrilateral,1}() simple_cv = SimpleCellValues(qr, ip, ip) -cv = CellValues(qr, ip, ip) +cv = CellValues(qr, ip, ip); -# The first thing to try is to reinitialize the cell -# values to a given cell, in this case cell nr. 2 +# The first thing to try is to reinitialize the cell values to a given cell, in this case cell nr. 2 grid = generate_grid(Quadrilateral, (2,2)) x = getcoordinates(grid, 2) reinit!(simple_cv, x) -reinit!(cv, x) +reinit!(cv, x); -# If we now pretend we are inside an element, where we have a vector of element -# degree of freedom values, we can check that the function values and gradients match +# If we now pretend we are inside an element routine and have a vector of element degree of freedom values, +# `ue`. Then, we can check that our function values and gradients match `Ferrite`'s builtin `CellValues`: ue = rand(getnbasefunctions(simple_cv)) q_point = 2 @test function_value(cv, q_point, ue) ≈ function_value(simple_cv, q_point, ue) @test function_gradient(cv, q_point, ue) ≈ function_gradient(simple_cv, q_point, ue) + From 96a9766c1028817e211765c4662f67d1cf4de63f Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 3 Dec 2023 17:17:31 +0100 Subject: [PATCH 100/145] Consistent code formatting and minimize diff --- src/FEValues/CellValues.jl | 6 +++--- src/FEValues/FaceValues.jl | 17 ++++++----------- src/PointEval/PointEvalHandler.jl | 4 ++-- src/PointEval/point_values.jl | 2 +- src/iterators.jl | 3 ++- test/runtests.jl | 2 +- 6 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 4bbdf33deb..6d7f1522ce 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -41,7 +41,7 @@ struct CellValues{FV, GM, QR, detT} <: AbstractCellValues qr::QR # QuadratureRule detJdV::detT # AbstractVector{<:Number} or Nothing end -function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; FunDiffOrder=1, save_detJdV=true) where T +function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; FunDiffOrder = 1, save_detJdV = true) where T GeoDiffOrder = max(required_geo_diff_order(get_mapping_type(ip_fun), FunDiffOrder), save_detJdV) geo_mapping = GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) fun_values = FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) @@ -85,7 +85,7 @@ getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) @inline function _update_detJdV!(detJvec::AbstractVector, q_point::Int, w, mapping) detJ = calculate_detJ(getjacobian(mapping)) detJ > 0.0 || throw_detJ_not_pos(detJ) - @inbounds detJvec[q_point] = detJ*w + @inbounds detJvec[q_point] = detJ * w end @inline _update_detJdV!(::Nothing, q_point, w, mapping) = nothing @@ -98,7 +98,7 @@ function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) if cell === nothing && !isa(get_mapping_type(fun_values), IdentityMapping) throw(ArgumentError("The cell::AbstractCell input is required to reinit! non-identity function mappings")) end - if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs + if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x) != n_geom_basefuncs throw_incompatible_coord_length(length(x), n_geom_basefuncs) end @inbounds for (q_point, w) in enumerate(getweights(cv.qr)) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index f788f11dda..25d31c3009 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -40,13 +40,13 @@ struct FaceValues{FV, GM, FQR, detT, nT, V_FV<:AbstractVector{FV}, V_GM<:Abstrac current_face::ScalarWrapper{Int} end -function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim}=default_geometric_interpolation(ip_fun); FunDiffOrder=1) where {T,sdim} +function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim} = default_geometric_interpolation(ip_fun); FunDiffOrder = 1) where {T,sdim} GeoDiffOrder = max(required_geo_diff_order(get_mapping_type(ip_fun), FunDiffOrder), 1) geo_mapping = [GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) for qr in fqr.face_rules] fun_values = [FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) - detJdV = fill(T(NaN), max_nquadpoints) - normals = fill(zero(Vec{sdim,T})*T(NaN), max_nquadpoints) + detJdV = fill(T(NaN), max_nquadpoints) + normals = fill(zero(Vec{sdim, T}) * T(NaN), max_nquadpoints) return FaceValues(fun_values, geo_mapping, fqr, detJdV, normals, ScalarWrapper(1)) end @@ -106,19 +106,14 @@ function set_current_face!(fv::FaceValues, face_nr::Int) fv.current_face[] = face_nr end -function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, cell=nothing) where {dim, T} +function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim, T}}, face_nr::Int, cell = nothing) where {dim, T} check_reinit_sdim_consistency(:FaceValues, shape_gradient_type(fv), eltype(x)) - - set_current_face!(fv, face_nr) - n_geom_basefuncs = getngeobasefunctions(fv) - if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x)!=n_geom_basefuncs + if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x) != n_geom_basefuncs throw_incompatible_coord_length(length(x), n_geom_basefuncs) end - # Must be done after setting current face, - # which should be done after boundscheck_face geo_mapping = get_geo_mapping(fv) fun_values = get_fun_values(fv) @@ -133,7 +128,7 @@ function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim,T}}, face_nr::Int, ce weight_norm = weighted_normal(J, getrefshape(geo_mapping.ip), face_nr) detJ = norm(weight_norm) detJ > 0.0 || throw_detJ_not_pos(detJ) - @inbounds fv.detJdV[q_point] = detJ*w + @inbounds fv.detJdV[q_point] = detJ * w @inbounds fv.normals[q_point] = weight_norm / norm(weight_norm) apply_mapping!(fun_values, q_point, mapping, cell) end diff --git a/src/PointEval/PointEvalHandler.jl b/src/PointEval/PointEvalHandler.jl index 551b18b11b..4da29b765b 100644 --- a/src/PointEval/PointEvalHandler.jl +++ b/src/PointEval/PointEvalHandler.jl @@ -244,9 +244,9 @@ function _evaluate_at_points!( first_cell = cellset === nothing ? 1 : first(cellset) grid = get_grid(dh) ip_geo = default_interpolation(getcelltype(grid, first_cell)) - pv = PointValues(eltype(local_coords[idx]), ip, ip_geo; FunDiffOrder=0) + pv = PointValues(eltype(local_coords[idx]), ip, ip_geo; FunDiffOrder = 0) cell_dofs = Vector{Int}(undef, ndofs_per_cell(dh, first_cell)) - u_e = Vector{T}(undef, ndofs_per_cell(dh, first_cell)) + u_e = Vector{T}(undef, ndofs_per_cell(dh, first_cell)) x = getcoordinates(grid, first_cell) # compute point values for pointid in eachindex(ph.cells) diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 268b8cdbaf..20b43842c9 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -39,7 +39,7 @@ function PointValues(::Type{T}, ip::IP, ipg::GIP = default_geometric_interpolati GIP <: Interpolation{shape} } qr = QuadratureRule{shape, T}([one(T)], [zero(Vec{dim, T})]) - cv = CellValues(T, qr, ip, ipg; save_detJdV=false, kwargs...) + cv = CellValues(T, qr, ip, ipg; save_detJdV = false, kwargs...) return PointValues{typeof(cv)}(cv) end diff --git a/src/iterators.jl b/src/iterators.jl index ba0f36e6b5..7a1e4617a0 100644 --- a/src/iterators.jl +++ b/src/iterators.jl @@ -365,6 +365,7 @@ function InterfaceIterator(gridordh::Union{Grid,AbstractDofHandler}, return InterfaceIterator(InterfaceCache(gridordh), grid, topology) end + # Iterator interface function Base.iterate(ii::InterfaceIterator, state...) grid_dim = getdim(ii.grid) @@ -415,4 +416,4 @@ function _check_same_celltype(grid::AbstractGrid, faceset::Set{FaceIndex}) if !all(getcelltype(grid, face[1]) == celltype for face in faceset) error("The cells in the faceset are not all of the same celltype.") end -end \ No newline at end of file +end diff --git a/test/runtests.jl b/test/runtests.jl index 3393e295f7..e31028893a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -21,7 +21,7 @@ include("test_utils.jl") # Unit tests include("test_interpolations.jl") -include("test_cellvalues.jl") +include("test_cellvalues.jl") include("test_facevalues.jl") include("test_interfacevalues.jl") include("test_quadrules.jl") From a807738d05edb855b534d64e0f294870a57f89a2 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sun, 3 Dec 2023 17:19:09 +0100 Subject: [PATCH 101/145] Removed wrong whitespace --- src/iterators.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/iterators.jl b/src/iterators.jl index 7a1e4617a0..ddab91900b 100644 --- a/src/iterators.jl +++ b/src/iterators.jl @@ -365,7 +365,6 @@ function InterfaceIterator(gridordh::Union{Grid,AbstractDofHandler}, return InterfaceIterator(InterfaceCache(gridordh), grid, topology) end - # Iterator interface function Base.iterate(ii::InterfaceIterator, state...) grid_dim = getdim(ii.grid) @@ -386,6 +385,7 @@ function Base.iterate(ii::InterfaceIterator, state...) end end + # Iterator interface for CellIterator/FaceIterator const GridIterators{C} = Union{CellIterator{C}, FaceIterator{C}, InterfaceIterator{C}} From 9833fe80c39874dd58738a2773cd9430d5d7ba9a Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 12:54:08 +0100 Subject: [PATCH 102/145] Use sprint(show, ...) instead of helper fun for testing --- test/test_cellvalues.jl | 6 +++--- test/test_facevalues.jl | 4 ++-- test/test_interfacevalues.jl | 2 +- test/test_utils.jl | 7 ------- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 7edebe90bc..7f90d0ccde 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -342,17 +342,17 @@ end @testset "show" begin cv_quad = CellValues(QuadratureRule{RefQuadrilateral}(2), Lagrange{RefQuadrilateral,2}()^2) - showstring = show_as_string(cv_quad) + showstring = sprint(show, MIME"text/plain"(), cv_quad) @test startswith(showstring, "CellValues(vdim=2, rdim=2, and sdim=2): 4 quadrature points") @test contains(showstring, "Function interpolation: Lagrange{RefQuadrilateral, 2}()^2") cv_wedge = CellValues(QuadratureRule{RefPrism}(2), Lagrange{RefPrism,2}()) - showstring = show_as_string(cv_wedge) + showstring = sprint(show, MIME"text/plain"(), cv_wedge) @test startswith(showstring, "CellValues(scalar, rdim=3, and sdim=3): 5 quadrature points") @test contains(showstring, "Function interpolation: Lagrange{RefPrism, 2}()") pv = PointValues(cv_wedge) - pv_showstring = show_as_string(pv) + pv_showstring = sprint(show, MIME"text/plain"(), pv) @test startswith(pv_showstring, "PointValues containing") @test contains(pv_showstring, "Function interpolation: Lagrange{RefPrism, 2}()") end diff --git a/test/test_facevalues.jl b/test/test_facevalues.jl index 1b09c2db75..bb781a51ff 100644 --- a/test/test_facevalues.jl +++ b/test/test_facevalues.jl @@ -130,13 +130,13 @@ end @testset "show" begin # Just smoke test to make sure show doesn't error. fv = FaceValues(FaceQuadratureRule{RefQuadrilateral}(2), Lagrange{RefQuadrilateral,2}()) - showstring = show_as_string(fv) + showstring = sprint(show, MIME"text/plain"(), fv) @test startswith(showstring, "FaceValues(scalar, rdim=2, sdim=2): 2 quadrature points per face") @test contains(showstring, "Function interpolation: Lagrange{RefQuadrilateral, 2}()") @test contains(showstring, "Geometric interpolation: Lagrange{RefQuadrilateral, 1}()^2") fv.fqr.face_rules[1] = deepcopy(fv.fqr.face_rules[1]) push!(Ferrite.getweights(fv.fqr.face_rules[1]), 1) - showstring = show_as_string(fv) + showstring = sprint(show, MIME"text/plain"(), fv) @test startswith(showstring, "FaceValues(scalar, rdim=2, sdim=2): (3, 2, 2, 2) quadrature points on each face") end diff --git a/test/test_interfacevalues.jl b/test/test_interfacevalues.jl index 6a19eafa25..f69a49c227 100644 --- a/test/test_interfacevalues.jl +++ b/test/test_interfacevalues.jl @@ -253,7 +253,7 @@ end @testset "show" begin iv = InterfaceValues(FaceQuadratureRule{RefQuadrilateral}(2), Lagrange{RefQuadrilateral,2}()) - showstring = show_as_string(iv) + showstring = sprint(show, MIME"text/plain"(), iv) @test contains(showstring, "InterfaceValues with") end end # of testset diff --git a/test/test_utils.jl b/test/test_utils.jl index 43a172bd24..140954df8b 100644 --- a/test/test_utils.jl +++ b/test/test_utils.jl @@ -282,13 +282,6 @@ getfacerefshape(::Tetrahedron, ::Int) = RefTriangle getfacerefshape(::Pyramid, face::Int) = face == 1 ? RefQuadrilateral : RefTriangle getfacerefshape(::Wedge, face::Int) = face ∈ (1,5) ? RefTriangle : RefQuadrilateral -# For testing of show of various types -function show_as_string(value, mime=MIME"text/plain"()) - io = IOBuffer() - show(IOContext(io), mime, value) - return String(take!(io)) -end - ###################################################### # Dummy RefShape to test get_transformation_matrix # ###################################################### From c76b57f7fe10feccddb6540f8642be9d7262a6c1 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 12:56:14 +0100 Subject: [PATCH 103/145] Use (at)eval instead of eval(quote --- src/FEValues/CellValues.jl | 4 +--- src/FEValues/FaceValues.jl | 4 +--- test/test_cellvalues.jl | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 6d7f1522ce..556a855213 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -74,9 +74,7 @@ shape_value_type(cv::CellValues) = shape_value_type(cv.fun_values) shape_gradient_type(cv::CellValues) = shape_gradient_type(cv.fun_values) for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient) - eval(quote - @propagate_inbounds $op(cv::CellValues, i::Int, q_point::Int) = $op(cv.fun_values, i, q_point) - end) + @eval @propagate_inbounds $op(cv::CellValues, i::Int, q_point::Int) = $op(cv.fun_values, i, q_point) end # Access quadrature rule values diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 25d31c3009..28d6818a93 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -77,9 +77,7 @@ get_geo_mapping(fv::FaceValues) = @inbounds fv.geo_mapping[getcurrentface(fv)] get_fun_values(fv::FaceValues) = @inbounds fv.fun_values[getcurrentface(fv)] for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient, :shape_curl) - eval(quote - @propagate_inbounds $op(fv::FaceValues, i::Int, q_point::Int) = $op(get_fun_values(fv), i, q_point) - end) + @eval @propagate_inbounds $op(fv::FaceValues, i::Int, q_point::Int) = $op(get_fun_values(fv), i, q_point) end """ diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 7f90d0ccde..a6cefb2e47 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -372,9 +372,7 @@ end # If changes are made that makes the following tests fails, # the devdocs should be updated accordingly. for op = (:shape_value, :shape_gradient, :getnquadpoints, :getnbasefunctions, :geometric_value, :getngeobasefunctions) - eval(quote - Ferrite.$op(cv::TestCustomCellValues, args...; kwargs...) = Ferrite.$op(cv.cv, args...; kwargs...) - end) + @eval Ferrite.$op(cv::TestCustomCellValues, args...; kwargs...) = Ferrite.$op(cv.cv, args...; kwargs...) end ip = Lagrange{RefQuadrilateral,1}()^2 qr = QuadratureRule{RefQuadrilateral}(2) From 6fe3fc697578fdf82d5d0d55abef7f247c200139 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 13:19:47 +0100 Subject: [PATCH 104/145] Include missed code from master merge --- src/FEValues/FaceValues.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 28d6818a93..ec4ad5d0d1 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -186,8 +186,8 @@ function BCValues(::Type{T}, func_interpol::Interpolation{refshape}, geom_interp nqp = zeros(Int,n_boundary_entities) for n_boundary_entity in 1:n_boundary_entities - for (qp, ξ) in enumerate(qrs[n_boundary_entity].points), i in 1:n_geom_basefuncs - M[i, qp, n_boundary_entity] = shape_value(geom_interpol, ξ, i) + for (qp, ξ) in pairs(qrs[n_boundary_entity].points) + shape_values!(@view(M[:, qp, n_boundary_entity]), geom_interpol, ξ) end nqp[n_boundary_entity] = length(qrs[n_boundary_entity].points) end From 7d497d0eba18c7461a4fc28e7fab859e2801c75f Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 13:50:13 +0100 Subject: [PATCH 105/145] Change order or args for reinit --- docs/src/literate-tutorials/heat_equation_rt.jl | 12 ++++++------ .../src/literate-tutorials/heat_equation_triangle.jl | 2 +- src/FEValues/CellValues.jl | 6 +++++- src/FEValues/FaceValues.jl | 6 +++++- test/InterpolationTestUtils.jl | 6 +++--- test/test_cellvalues.jl | 4 ++-- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl index 4679cfa4f4..25bcb5999b 100644 --- a/docs/src/literate-tutorials/heat_equation_rt.jl +++ b/docs/src/literate-tutorials/heat_equation_rt.jl @@ -211,8 +211,8 @@ function assemble_global(cellvalues, K::SparseMatrixCSC, dh::DofHandler) cell = getcells(grid, cellnr) getcoordinates!(x, grid, cell) celldofs!(dofs, dh, cellnr) - reinit!(cellvalues[:u], x, cell) - reinit!(cellvalues[:q], x, cell) + reinit!(cellvalues[:u], cell, x) + reinit!(cellvalues[:q], cell, x) ## Reset to 0 fill!(Ke, 0) fill!(fe, 0) @@ -268,7 +268,7 @@ function calculate_flux(dh, dΩ, ip, a) cell = getcells(grid, cellnr) celldofs!(dofs, dh, cellnr) map!(i->a[i], ae, dofs) - reinit!(fv, x, facenr, cell) + reinit!(fv, cell, x, facenr) for q_point in 1:getnquadpoints(fv) dΓ = getdetJdV(fv, q_point) n = getnormal(fv, q_point) @@ -294,7 +294,7 @@ function calculate_flux_lag(dh, dΩ, ip, a) cell = getcells(grid, cellnr) celldofs!(dofs, dh, cellnr) map!(i->a[i], ae, dofs) - reinit!(fv, x, facenr, cell) + reinit!(fv, cell, x, facenr) for q_point in 1:getnquadpoints(fv) dΓ = getdetJdV(fv, q_point) n = getnormal(fv, q_point) @@ -317,8 +317,8 @@ function get_Ke(dh, cellvalues; cellnr=1) fe = zeros(ncelldofs) x = getcoordinates(grid, cellnr) cell = getcells(grid, cellnr) - reinit!(cellvalues[:u], x, cell) - reinit!(cellvalues[:q], x, cell) + reinit!(cellvalues[:u], cell, x) + reinit!(cellvalues[:q], cell, x) ## Reset to 0 fill!(Ke, 0) diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl index bf312ef04a..414a7f9195 100644 --- a/docs/src/literate-tutorials/heat_equation_triangle.jl +++ b/docs/src/literate-tutorials/heat_equation_triangle.jl @@ -229,7 +229,7 @@ function calculate_flux_lag(dh, dΩ, ip, a) cell = getcells(grid, cellnr) celldofs!(dofs, dh, cellnr) map!(i->a[i], ae, dofs) - reinit!(fv, x, facenr, cell) + reinit!(fv, cell, x, facenr) for q_point in 1:getnquadpoints(fv) dΓ = getdetJdV(fv, q_point) n = getnormal(fv, q_point) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 556a855213..48aac986ee 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -87,7 +87,11 @@ getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) end @inline _update_detJdV!(::Nothing, q_point, w, mapping) = nothing -function reinit!(cv::CellValues, x::AbstractVector{<:Vec}, cell=nothing) +@inline function reinit!(cv::CellValues, x::AbstractVector) + return reinit!(cv::FaceValues, nothing, x::AbstractVector) +end + +function reinit!(cv::CellValues, cell, x::AbstractVector{<:Vec}) geo_mapping = cv.geo_mapping fun_values = cv.fun_values n_geom_basefuncs = getngeobasefunctions(geo_mapping) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index ec4ad5d0d1..68d56a2374 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -104,7 +104,11 @@ function set_current_face!(fv::FaceValues, face_nr::Int) fv.current_face[] = face_nr end -function reinit!(fv::FaceValues, x::AbstractVector{Vec{dim, T}}, face_nr::Int, cell = nothing) where {dim, T} +@inline function reinit!(fv::FaceValues, x::AbstractVector, face_nr::Int) + return reinit!(fv::FaceValues, nothing, x::AbstractVector, face_nr::Int) +end + +function reinit!(fv::FaceValues, cell, x::AbstractVector{Vec{dim, T}}, face_nr::Int) where {dim, T} check_reinit_sdim_consistency(:FaceValues, shape_gradient_type(fv), eltype(x)) set_current_face!(fv, face_nr) n_geom_basefuncs = getngeobasefunctions(fv) diff --git a/test/InterpolationTestUtils.jl b/test/InterpolationTestUtils.jl index 11e5c08b68..563241e042 100644 --- a/test/InterpolationTestUtils.jl +++ b/test/InterpolationTestUtils.jl @@ -51,7 +51,7 @@ module InterpolationTestUtils point_coords = zeros(eltype(cell_coords), length(inds)) point_normal = similar(point_coords) fun_vals = zeros(typeof(shape_value(fv, 1, 1)), length(inds)) - reinit!(fv, cell_coords, facenr, cell) + reinit!(fv, cell, cell_coords, facenr) ue = u[celldofs(dh, cellnr)] for (i, q_point) in enumerate(inds) point_coords[i] = spatial_coordinate(fv, q_point, cell_coords) @@ -67,7 +67,7 @@ module InterpolationTestUtils ξs = collect(last.(local_coords)) # Extract the local coordinates qr = QuadratureRule{RefShape}(zeros(length(ξs)), ξs) cv = CellValues(qr, ip_fun, ip_geo) - reinit!(cv, cell_coords2, cell2) + reinit!(cv, cell2, cell_coords2) fun_vals2 = similar(fun_vals) ue2 = u[celldofs(dh, face2[1])] for q_point in 1:getnquadpoints(cv) @@ -102,7 +102,7 @@ module InterpolationTestUtils ip_fun = Ferrite.getfieldinterpolation(dh, (1,1)) qr = create_gradcheck_qr(ip_geo, ΔL) cv = CellValues(qr, ip_fun, ip_geo) - reinit!(cv, x, cell) + reinit!(cv, cell, x) Δu_num = function_value(cv, 2, ue) - function_value(cv, 1, ue) Δx = spatial_coordinate(cv, 2, x) - spatial_coordinate(cv, 1, x) ∇u1 = function_gradient(cv, 1, ue) diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index a6cefb2e47..44378383b7 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -155,8 +155,8 @@ end reinit!(cvv, x) reinit!(fsv, x, 1) reinit!(fvv, x, 1) - reinit!(cv_nedelec, x, cell) - reinit!(fv_nedelec, x, 1, cell) + reinit!(cv_nedelec, cell, x) + reinit!(fv_nedelec, cell, x, 1) # Wrong number of coordinates xx = [x; x] From 86655d97faec7acceef0d97845818b57aff7b5e9 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 14:36:06 +0100 Subject: [PATCH 106/145] Fix errors due to changed order --- src/FEValues/CellValues.jl | 2 +- src/FEValues/FaceValues.jl | 2 +- test/test_cellvalues.jl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 48aac986ee..61fb61fa87 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -88,7 +88,7 @@ end @inline _update_detJdV!(::Nothing, q_point, w, mapping) = nothing @inline function reinit!(cv::CellValues, x::AbstractVector) - return reinit!(cv::FaceValues, nothing, x::AbstractVector) + return reinit!(cv, nothing, x) end function reinit!(cv::CellValues, cell, x::AbstractVector{<:Vec}) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 68d56a2374..78b6b4df70 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -105,7 +105,7 @@ function set_current_face!(fv::FaceValues, face_nr::Int) end @inline function reinit!(fv::FaceValues, x::AbstractVector, face_nr::Int) - return reinit!(fv::FaceValues, nothing, x::AbstractVector, face_nr::Int) + return reinit!(fv, nothing, x, face_nr) end function reinit!(fv::FaceValues, cell, x::AbstractVector{Vec{dim, T}}, face_nr::Int) where {dim, T} diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 44378383b7..851855b3a8 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -380,7 +380,7 @@ end grid = generate_grid(Quadrilateral, (1,1)) x = getcoordinates(grid, 1) cell = getcells(grid, 1) - reinit!(cv, x, cell) + reinit!(cv, cell, x) ae = rand(getnbasefunctions(cv)) q_point = rand(1:getnquadpoints(cv)) cv_custom = TestCustomCellValues(cv) From 8f160664658ee1bc52c239e5bd20912d483edb92 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 14:53:07 +0100 Subject: [PATCH 107/145] Update docstrings to new order in reinit --- src/FEValues/common_values.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 2e651b2ba9..dad7f8b50c 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -26,9 +26,9 @@ end end """ - reinit!(cv::CellValues, x::Vector, cell::AbstractCell) + reinit!(cv::CellValues, cell::AbstractCell, x::Vector) reinit!(cv::CellValues, x::Vector) - reinit!(fv::FaceValues, x::Vector, face::Int, cell::AbstractCell) + reinit!(fv::FaceValues, cell::AbstractCell, x::Vector, face::Int) reinit!(fv::FaceValues, x::Vector, face::Int) Update the `CellValues`/`FaceValues` object for a cell or face with coordinates `x`. From 08a67afd5e95ca3a1f9a506d656471f63379f907 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 15:30:29 +0100 Subject: [PATCH 108/145] Change input kwargs --- src/FEValues/CellValues.jl | 9 ++++++--- src/FEValues/FaceValues.jl | 5 ++++- src/PointEval/PointEvalHandler.jl | 4 ++-- src/PointEval/point_values.jl | 5 +++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index 61fb61fa87..df989fc7bd 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -41,11 +41,14 @@ struct CellValues{FV, GM, QR, detT} <: AbstractCellValues qr::QR # QuadratureRule detJdV::detT # AbstractVector{<:Number} or Nothing end -function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; FunDiffOrder = 1, save_detJdV = true) where T - GeoDiffOrder = max(required_geo_diff_order(get_mapping_type(ip_fun), FunDiffOrder), save_detJdV) +function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; + update_gradients = true, update_detJdV = true) where T + + FunDiffOrder = convert(Int, update_gradients) # Logic must change when supporting update_hessian kwargs + GeoDiffOrder = max(required_geo_diff_order(get_mapping_type(ip_fun), FunDiffOrder), update_detJdV) geo_mapping = GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) fun_values = FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) - detJdV = save_detJdV ? fill(T(NaN), length(getweights(qr))) : nothing + detJdV = update_detJdV ? fill(T(NaN), length(getweights(qr))) : nothing return CellValues(fun_values, geo_mapping, qr, detJdV) end diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index 78b6b4df70..e170b4a716 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -40,7 +40,10 @@ struct FaceValues{FV, GM, FQR, detT, nT, V_FV<:AbstractVector{FV}, V_GM<:Abstrac current_face::ScalarWrapper{Int} end -function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim} = default_geometric_interpolation(ip_fun); FunDiffOrder = 1) where {T,sdim} +function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim} = default_geometric_interpolation(ip_fun); + update_gradients = true) where {T,sdim} + + FunDiffOrder = convert(Int, update_gradients) # Logic must change when supporting update_hessian kwargs GeoDiffOrder = max(required_geo_diff_order(get_mapping_type(ip_fun), FunDiffOrder), 1) geo_mapping = [GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) for qr in fqr.face_rules] fun_values = [FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] diff --git a/src/PointEval/PointEvalHandler.jl b/src/PointEval/PointEvalHandler.jl index 4da29b765b..e8da115a07 100644 --- a/src/PointEval/PointEvalHandler.jl +++ b/src/PointEval/PointEvalHandler.jl @@ -185,7 +185,7 @@ function evaluate_at_points(ph::PointEvalHandler{<:Any, dim, T1}, dh::AbstractDo npoints = length(ph.cells) # Figure out the value type by creating a dummy PointValues ip = getfieldinterpolation(dh, find_field(dh, fname)) - pv = PointValues(T1, ip; FunDiffOrder=0) + pv = PointValues(T1, ip; update_gradients = false) zero_val = function_value_init(pv, dof_vals) # Allocate the output as NaNs nanv = convert(typeof(zero_val), NaN * zero_val) @@ -244,7 +244,7 @@ function _evaluate_at_points!( first_cell = cellset === nothing ? 1 : first(cellset) grid = get_grid(dh) ip_geo = default_interpolation(getcelltype(grid, first_cell)) - pv = PointValues(eltype(local_coords[idx]), ip, ip_geo; FunDiffOrder = 0) + pv = PointValues(eltype(local_coords[idx]), ip, ip_geo; update_gradients = false) cell_dofs = Vector{Int}(undef, ndofs_per_cell(dh, first_cell)) u_e = Vector{T}(undef, ndofs_per_cell(dh, first_cell)) x = getcoordinates(grid, first_cell) diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 20b43842c9..044a851afd 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -28,7 +28,8 @@ function PointValues(cv::CellValues) T = typeof(getdetJdV(cv, 1)) ip_fun = get_function_interpolation(cv) ip_geo = get_geometric_interpolation(cv) - return PointValues(T, ip_fun, ip_geo; FunDiffOrder = get_function_difforder(cv)) + update_gradients = get_function_difforder(cv) == 1 + return PointValues(T, ip_fun, ip_geo; update_gradients) end function PointValues(ip::Interpolation, ipg::Interpolation = default_geometric_interpolation(ip); kwargs...) return PointValues(Float64, ip, ipg; kwargs...) @@ -39,7 +40,7 @@ function PointValues(::Type{T}, ip::IP, ipg::GIP = default_geometric_interpolati GIP <: Interpolation{shape} } qr = QuadratureRule{shape, T}([one(T)], [zero(Vec{dim, T})]) - cv = CellValues(T, qr, ip, ipg; save_detJdV = false, kwargs...) + cv = CellValues(T, qr, ip, ipg; update_detJdV = false, kwargs...) return PointValues{typeof(cv)}(cv) end From be5d910a71786fec50b1be16ae3580f2ea5d8652 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 15:46:31 +0100 Subject: [PATCH 109/145] Simplify code for FunctionValues construction --- src/FEValues/FunctionValues.jl | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index c4e08b4c81..03edcc191f 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -50,30 +50,24 @@ struct FunctionValues{DiffOrder, IP, N_t, dNdx_t, dNdξ_t} return new{1, typeof(ip), N_t, typeof(dNdx), typeof(dNdξ)}(ip, N_x, N_ξ, dNdx, dNdξ) end end -function FunctionValues{0}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T +function FunctionValues{DiffOrder}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where {DiffOrder, T} ip_dims = InterpolationDims(ip, ip_geo) n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) N_ξ = zeros(typeof_N(T, ip_dims), n_shape, n_qpoints) N_x = isa(get_mapping_type(ip), IdentityMapping) ? N_ξ : similar(N_ξ) - - fv = FunctionValues(ip, N_x, N_ξ, nothing, nothing) - precompute_values!(fv, getpoints(qr)) # Separate function for qr point update in PointValues - return fv -end -function FunctionValues{1}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where T - ip_dims = InterpolationDims(ip, ip_geo) - n_shape = getnbasefunctions(ip) - n_qpoints = getnquadpoints(qr) - - N_ξ = zeros(typeof_N(T, ip_dims), n_shape, n_qpoints) - N_x = isa(get_mapping_type(ip), IdentityMapping) ? N_ξ : similar(N_ξ) - - dNdξ = zeros(typeof_dNdξ(T, ip_dims), n_shape, n_qpoints) - dNdx = fill(zero(typeof_dNdx(T, ip_dims)) * T(NaN), n_shape, n_qpoints) - - fv = FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) + + if DiffOrder == 0 + dNdξ = dNdx = nothing + elseif DiffOrder > 1 + throw(ArgumentError("Currently only values and gradients can be updated in FunctionValues")) + else + dNdξ = zeros(typeof_dNdξ(T, ip_dims), n_shape, n_qpoints) + dNdx = fill(zero(typeof_dNdx(T, ip_dims)) * T(NaN), n_shape, n_qpoints) + end + + fv = FunctionValues(ip, N_x, N_ξ, dNdξ, dNdx) precompute_values!(fv, getpoints(qr)) # Separate function for qr point update in PointValues return fv end From 41c92c4669f81bd8aebec2a2ca69a17d726cf253 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 17:05:01 +0100 Subject: [PATCH 110/145] Fix order of args --- src/FEValues/FunctionValues.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 03edcc191f..955de431c5 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -67,7 +67,7 @@ function FunctionValues{DiffOrder}(::Type{T}, ip::Interpolation, qr::QuadratureR dNdx = fill(zero(typeof_dNdx(T, ip_dims)) * T(NaN), n_shape, n_qpoints) end - fv = FunctionValues(ip, N_x, N_ξ, dNdξ, dNdx) + fv = FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) precompute_values!(fv, getpoints(qr)) # Separate function for qr point update in PointValues return fv end From 36c018ecf7666dbca5b4d087aaea7c2c4c1bd7f5 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 4 Dec 2023 17:17:49 +0100 Subject: [PATCH 111/145] More logic if in FunctionValues --- src/FEValues/FunctionValues.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 955de431c5..398336b23b 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -60,11 +60,11 @@ function FunctionValues{DiffOrder}(::Type{T}, ip::Interpolation, qr::QuadratureR if DiffOrder == 0 dNdξ = dNdx = nothing - elseif DiffOrder > 1 - throw(ArgumentError("Currently only values and gradients can be updated in FunctionValues")) - else + elseif DiffOrder == 1 dNdξ = zeros(typeof_dNdξ(T, ip_dims), n_shape, n_qpoints) dNdx = fill(zero(typeof_dNdx(T, ip_dims)) * T(NaN), n_shape, n_qpoints) + else + throw(ArgumentError("Currently only values and gradients can be updated in FunctionValues")) end fv = FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) From c7d7a0e770d61ee93ae4f83ff4320ab2fcb988ae Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Tue, 5 Dec 2023 11:31:39 +0100 Subject: [PATCH 112/145] Remove use of (at)eval and be explicit instead --- src/FEValues/CellValues.jl | 6 +++--- src/FEValues/FaceValues.jl | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index df989fc7bd..ef1bfebef8 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -76,9 +76,9 @@ get_function_difforder(cv::CellValues) = get_function_difforder(cv.fun_values) shape_value_type(cv::CellValues) = shape_value_type(cv.fun_values) shape_gradient_type(cv::CellValues) = shape_gradient_type(cv.fun_values) -for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient) - @eval @propagate_inbounds $op(cv::CellValues, i::Int, q_point::Int) = $op(cv.fun_values, i, q_point) -end +@propagate_inbounds shape_value(cv::CellValues, i::Int, q_point::Int) = shape_value(cv.fun_values, i, q_point) +@propagate_inbounds shape_gradient(cv::CellValues, i::Int, q_point::Int) = shape_gradient(cv.fun_values, i, q_point) +@propagate_inbounds shape_symmetric_gradient(cv::CellValues, i::Int, q_point::Int) = shape_symmetric_gradient(cv.fun_values, i, q_point) # Access quadrature rule values getnquadpoints(cv::CellValues) = getnquadpoints(cv.qr) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index e170b4a716..c6a0e50f6e 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -79,9 +79,10 @@ get_geo_mapping(fv::FaceValues) = @inbounds fv.geo_mapping[getcurrentface(fv)] @propagate_inbounds geometric_value(fv::FaceValues, args...) = geometric_value(get_geo_mapping(fv), args...) get_fun_values(fv::FaceValues) = @inbounds fv.fun_values[getcurrentface(fv)] -for op = (:shape_value, :shape_gradient, :shape_symmetric_gradient, :shape_curl) - @eval @propagate_inbounds $op(fv::FaceValues, i::Int, q_point::Int) = $op(get_fun_values(fv), i, q_point) -end + +@propagate_inbounds shape_value(fv::FaceValues, i::Int, q_point::Int) = shape_value(get_fun_values(fv), i, q_point) +@propagate_inbounds shape_gradient(fv::FaceValues, i::Int, q_point::Int) = shape_gradient(get_fun_values(fv), i, q_point) +@propagate_inbounds shape_symmetric_gradient(fv::FaceValues, i::Int, q_point::Int) = shape_symmetric_gradient(get_fun_values(fv), i, q_point) """ getcurrentface(fv::FaceValues) From 65e916ec78300a0073c9621b5c7b3b6b13f878fe Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Tue, 5 Dec 2023 13:24:35 +0100 Subject: [PATCH 113/145] Remove credit from SimpleCellValues literate --- docs/src/topics/FEValues.md | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/docs/src/topics/FEValues.md b/docs/src/topics/FEValues.md index 11831e91f2..c2c8a23f53 100644 --- a/docs/src/topics/FEValues.md +++ b/docs/src/topics/FEValues.md @@ -113,17 +113,10 @@ Please note that several internal functions are used, and these may change witho ```@eval # Include the example here, but modify the Literate output to suit being embedded -using Literate, Markdown -filename = "SimpleCellValues_literate" -Literate.markdown(filename*".jl"; execute=true) -contents = read(filename*".md", String) -Literate.script(filename*".jl"; name="SimpleCellValues") -rm(filename*".jl") -rm(filename*".md") -header_end = last(findnext("```", contents, 4))+1 -Markdown.parse(replace(contents[header_end:end], - "*This page was generated using [Literate.jl]"=>"*This example was generated using [Literate.jl]") - ) +using Literate +Literate.markdown("SimpleCellValues_literate.jl"; name = "SimpleCellValues", + execute = true, credit = false) +Literate.script("SimpleCellValues_literate.jl"; name="SimpleCellValues") ``` ## Further reading From 8faecd4916fd2bdf9e990e57b2f777cf051e3bd5 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Tue, 5 Dec 2023 15:22:29 +0100 Subject: [PATCH 114/145] Parse the generated file and return the MD string to show it --- docs/src/topics/FEValues.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/src/topics/FEValues.md b/docs/src/topics/FEValues.md index c2c8a23f53..1a4f836be8 100644 --- a/docs/src/topics/FEValues.md +++ b/docs/src/topics/FEValues.md @@ -113,10 +113,13 @@ Please note that several internal functions are used, and these may change witho ```@eval # Include the example here, but modify the Literate output to suit being embedded -using Literate -Literate.markdown("SimpleCellValues_literate.jl"; name = "SimpleCellValues", - execute = true, credit = false) -Literate.script("SimpleCellValues_literate.jl"; name="SimpleCellValues") +using Literate, Markdown +base_name = "SimpleCellValues_literate" +Literate.markdown(string(base_name, ".jl"); name = base_name, execute = true, credit = false, documenter=false) +content = read(string(base_name, ".md"), String) +rm(string(base_name, ".md")) +rm(string(base_name, ".jl")) +Markdown.parse(content) ``` ## Further reading From 5c757703555b00d9356366fb4e5a695cf7462123 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 6 Dec 2023 08:59:40 +0100 Subject: [PATCH 115/145] Apply review suggestions --- docs/src/devdocs/interpolations.md | 2 +- src/Dofs/DofHandler.jl | 2 +- src/FEValues/CellValues.jl | 18 ++++----- src/FEValues/FaceValues.jl | 18 ++++----- src/FEValues/FunctionValues.jl | 62 +++++++++++++++--------------- src/FEValues/GeometryMapping.jl | 2 +- src/PointEval/point_values.jl | 6 +-- src/interpolations.jl | 12 +++--- test/test_cellvalues.jl | 8 ++-- test/test_interfacevalues.jl | 4 +- 10 files changed, 67 insertions(+), 67 deletions(-) diff --git a/docs/src/devdocs/interpolations.md b/docs/src/devdocs/interpolations.md index 6d8cfafcce..540d288280 100644 --- a/docs/src/devdocs/interpolations.md +++ b/docs/src/devdocs/interpolations.md @@ -39,7 +39,7 @@ Ferrite.getnbasefunctions(::Interpolation) Ferrite.reference_coordinates(::Interpolation) Ferrite.is_discontinuous(::Interpolation) Ferrite.adjust_dofs_during_distribution(::Interpolation) -Ferrite.get_mapping_type +Ferrite.mapping_type ``` for all entities which exist on that reference element. The dof functions default to having no diff --git a/src/Dofs/DofHandler.jl b/src/Dofs/DofHandler.jl index 2ac3d8e9ea..e6e88dff19 100644 --- a/src/Dofs/DofHandler.jl +++ b/src/Dofs/DofHandler.jl @@ -957,7 +957,7 @@ function _evaluate_at_grid_nodes!(data::Union{Vector,Matrix}, sdh::SubDofHandler u::Vector{T}, cv::CellValues, drange::UnitRange, ::Type{RT}) where {T, RT} ue = zeros(T, length(drange)) # TODO: Remove this hack when embedding works... - if RT <: Vec && get_function_interpolation(cv) isa ScalarInterpolation + if RT <: Vec && function_interpolation(cv) isa ScalarInterpolation uer = reinterpret(RT, ue) else uer = ue diff --git a/src/FEValues/CellValues.jl b/src/FEValues/CellValues.jl index ef1bfebef8..362f14ab40 100644 --- a/src/FEValues/CellValues.jl +++ b/src/FEValues/CellValues.jl @@ -42,10 +42,10 @@ struct CellValues{FV, GM, QR, detT} <: AbstractCellValues detJdV::detT # AbstractVector{<:Number} or Nothing end function CellValues(::Type{T}, qr::QuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation; - update_gradients = true, update_detJdV = true) where T + update_gradients::Bool = true, update_detJdV::Bool = true) where T FunDiffOrder = convert(Int, update_gradients) # Logic must change when supporting update_hessian kwargs - GeoDiffOrder = max(required_geo_diff_order(get_mapping_type(ip_fun), FunDiffOrder), update_detJdV) + GeoDiffOrder = max(required_geo_diff_order(mapping_type(ip_fun), FunDiffOrder), update_detJdV) geo_mapping = GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) fun_values = FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) detJdV = update_detJdV ? fill(T(NaN), length(getweights(qr))) : nothing @@ -64,15 +64,15 @@ end # Access geometry values @propagate_inbounds getngeobasefunctions(cv::CellValues) = getngeobasefunctions(cv.geo_mapping) @propagate_inbounds geometric_value(cv::CellValues, args...) = geometric_value(cv.geo_mapping, args...) -get_geometric_interpolation(cv::CellValues) = get_geometric_interpolation(cv.geo_mapping) +geometric_interpolation(cv::CellValues) = geometric_interpolation(cv.geo_mapping) getdetJdV(cv::CellValues, q_point::Int) = cv.detJdV[q_point] getdetJdV(::CellValues{<:Any, <:Any, <:Any, Nothing}, ::Int) = throw(ArgumentError("detJdV is not saved in CellValues")) # Accessors for function values getnbasefunctions(cv::CellValues) = getnbasefunctions(cv.fun_values) -get_function_interpolation(cv::CellValues) = get_function_interpolation(cv.fun_values) -get_function_difforder(cv::CellValues) = get_function_difforder(cv.fun_values) +function_interpolation(cv::CellValues) = function_interpolation(cv.fun_values) +function_difforder(cv::CellValues) = function_difforder(cv.fun_values) shape_value_type(cv::CellValues) = shape_value_type(cv.fun_values) shape_gradient_type(cv::CellValues) = shape_gradient_type(cv.fun_values) @@ -94,13 +94,13 @@ end return reinit!(cv, nothing, x) end -function reinit!(cv::CellValues, cell, x::AbstractVector{<:Vec}) +function reinit!(cv::CellValues, cell::Union{AbstractCell, Nothing}, x::AbstractVector{<:Vec}) geo_mapping = cv.geo_mapping fun_values = cv.fun_values n_geom_basefuncs = getngeobasefunctions(geo_mapping) check_reinit_sdim_consistency(:CellValues, shape_gradient_type(cv), eltype(x)) - if cell === nothing && !isa(get_mapping_type(fun_values), IdentityMapping) + if cell === nothing && !isa(mapping_type(fun_values), IdentityMapping) throw(ArgumentError("The cell::AbstractCell input is required to reinit! non-identity function mappings")) end if !checkbounds(Bool, x, 1:n_geom_basefuncs) || length(x) != n_geom_basefuncs @@ -115,8 +115,8 @@ function reinit!(cv::CellValues, cell, x::AbstractVector{<:Vec}) end function Base.show(io::IO, d::MIME"text/plain", cv::CellValues) - ip_geo = get_geometric_interpolation(cv) - ip_fun = get_function_interpolation(cv) + ip_geo = geometric_interpolation(cv) + ip_fun = function_interpolation(cv) rdim = getdim(ip_geo) vdim = isa(shape_value(cv, 1, 1), Vec) ? length(shape_value(cv, 1, 1)) : 0 GradT = shape_gradient_type(cv) diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/FaceValues.jl index c6a0e50f6e..69bf96e29f 100644 --- a/src/FEValues/FaceValues.jl +++ b/src/FEValues/FaceValues.jl @@ -41,10 +41,10 @@ struct FaceValues{FV, GM, FQR, detT, nT, V_FV<:AbstractVector{FV}, V_GM<:Abstrac end function FaceValues(::Type{T}, fqr::FaceQuadratureRule, ip_fun::Interpolation, ip_geo::VectorizedInterpolation{sdim} = default_geometric_interpolation(ip_fun); - update_gradients = true) where {T,sdim} + update_gradients::Bool = true) where {T,sdim} FunDiffOrder = convert(Int, update_gradients) # Logic must change when supporting update_hessian kwargs - GeoDiffOrder = max(required_geo_diff_order(get_mapping_type(ip_fun), FunDiffOrder), 1) + GeoDiffOrder = max(required_geo_diff_order(mapping_type(ip_fun), FunDiffOrder), 1) geo_mapping = [GeometryMapping{GeoDiffOrder}(T, ip_geo.ip, qr) for qr in fqr.face_rules] fun_values = [FunctionValues{FunDiffOrder}(T, ip_fun, qr, ip_geo) for qr in fqr.face_rules] max_nquadpoints = maximum(qr->length(getweights(qr)), fqr.face_rules) @@ -71,9 +71,9 @@ getnquadpoints(fv::FaceValues) = @inbounds getnquadpoints(fv.fqr, getcurrentface shape_value_type(fv::FaceValues) = shape_value_type(get_fun_values(fv)) shape_gradient_type(fv::FaceValues) = shape_gradient_type(get_fun_values(fv)) -get_function_interpolation(fv::FaceValues) = get_function_interpolation(get_fun_values(fv)) -get_function_difforder(fv::FaceValues) = get_function_difforder(get_fun_values(fv)) -get_geometric_interpolation(fv::FaceValues) = get_geometric_interpolation(get_geo_mapping(fv)) +function_interpolation(fv::FaceValues) = function_interpolation(get_fun_values(fv)) +function_difforder(fv::FaceValues) = function_difforder(get_fun_values(fv)) +geometric_interpolation(fv::FaceValues) = geometric_interpolation(get_geo_mapping(fv)) get_geo_mapping(fv::FaceValues) = @inbounds fv.geo_mapping[getcurrentface(fv)] @propagate_inbounds geometric_value(fv::FaceValues, args...) = geometric_value(get_geo_mapping(fv), args...) @@ -112,7 +112,7 @@ end return reinit!(fv, nothing, x, face_nr) end -function reinit!(fv::FaceValues, cell, x::AbstractVector{Vec{dim, T}}, face_nr::Int) where {dim, T} +function reinit!(fv::FaceValues, cell::Union{AbstractCell, Nothing}, x::AbstractVector{Vec{dim, T}}, face_nr::Int) where {dim, T} check_reinit_sdim_consistency(:FaceValues, shape_gradient_type(fv), eltype(x)) set_current_face!(fv, face_nr) n_geom_basefuncs = getngeobasefunctions(fv) @@ -123,7 +123,7 @@ function reinit!(fv::FaceValues, cell, x::AbstractVector{Vec{dim, T}}, face_nr:: geo_mapping = get_geo_mapping(fv) fun_values = get_fun_values(fv) - if cell === nothing && !isa(get_mapping_type(fun_values), IdentityMapping) + if cell === nothing && !isa(mapping_type(fun_values), IdentityMapping) throw(ArgumentError("The cell::AbstractCell input is required to reinit! non-identity function mappings")) end @@ -141,7 +141,7 @@ function reinit!(fv::FaceValues, cell, x::AbstractVector{Vec{dim, T}}, face_nr:: end function Base.show(io::IO, d::MIME"text/plain", fv::FaceValues) - ip_geo = get_geometric_interpolation(fv) + ip_geo = geometric_interpolation(fv) rdim = getdim(ip_geo) vdim = isa(shape_value(fv, 1, 1), Vec) ? length(shape_value(fv, 1, 1)) : 0 sdim = length(shape_gradient(fv, 1, 1)) ÷ length(shape_value(fv, 1, 1)) @@ -153,7 +153,7 @@ function Base.show(io::IO, d::MIME"text/plain", fv::FaceValues) else println(io, tuple(nqp...), " quadrature points on each face") end - print(io, " Function interpolation: "); show(io, d, get_function_interpolation(fv)) + print(io, " Function interpolation: "); show(io, d, function_interpolation(fv)) print(io, "\nGeometric interpolation: "); show(io, d, ip_geo^sdim) end diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 398336b23b..c45a50df61 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -39,15 +39,15 @@ FunctionValues struct FunctionValues{DiffOrder, IP, N_t, dNdx_t, dNdξ_t} ip::IP # ::Interpolation - N_x::N_t # ::AbstractMatrix{Union{<:Tensor,<:Number}} - N_ξ::N_t # ::AbstractMatrix{Union{<:Tensor,<:Number}} + Nx::N_t # ::AbstractMatrix{Union{<:Tensor,<:Number}} + Nξ::N_t # ::AbstractMatrix{Union{<:Tensor,<:Number}} dNdx::dNdx_t # ::AbstractMatrix{Union{<:Tensor,<:StaticArray}} or Nothing dNdξ::dNdξ_t # ::AbstractMatrix{Union{<:Tensor,<:StaticArray}} or Nothing - function FunctionValues(ip::Interpolation, N_x::N_t, N_ξ::N_t, ::Nothing, ::Nothing) where {N_t<:AbstractMatrix} - return new{0, typeof(ip), N_t, Nothing, Nothing}(ip, N_x, N_ξ, nothing, nothing) + function FunctionValues(ip::Interpolation, Nx::N_t, Nξ::N_t, ::Nothing, ::Nothing) where {N_t<:AbstractMatrix} + return new{0, typeof(ip), N_t, Nothing, Nothing}(ip, Nx, Nξ, nothing, nothing) end - function FunctionValues(ip::Interpolation, N_x::N_t, N_ξ::N_t, dNdx::AbstractMatrix, dNdξ::AbstractMatrix) where {N_t<:AbstractMatrix} - return new{1, typeof(ip), N_t, typeof(dNdx), typeof(dNdξ)}(ip, N_x, N_ξ, dNdx, dNdξ) + function FunctionValues(ip::Interpolation, Nx::N_t, Nξ::N_t, dNdx::AbstractMatrix, dNdξ::AbstractMatrix) where {N_t<:AbstractMatrix} + return new{1, typeof(ip), N_t, typeof(dNdx), typeof(dNdξ)}(ip, Nx, Nξ, dNdx, dNdξ) end end function FunctionValues{DiffOrder}(::Type{T}, ip::Interpolation, qr::QuadratureRule, ip_geo::VectorizedInterpolation) where {DiffOrder, T} @@ -55,8 +55,8 @@ function FunctionValues{DiffOrder}(::Type{T}, ip::Interpolation, qr::QuadratureR n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) - N_ξ = zeros(typeof_N(T, ip_dims), n_shape, n_qpoints) - N_x = isa(get_mapping_type(ip), IdentityMapping) ? N_ξ : similar(N_ξ) + Nξ = zeros(typeof_N(T, ip_dims), n_shape, n_qpoints) + Nx = isa(mapping_type(ip), IdentityMapping) ? Nξ : similar(Nξ) if DiffOrder == 0 dNdξ = dNdx = nothing @@ -67,34 +67,34 @@ function FunctionValues{DiffOrder}(::Type{T}, ip::Interpolation, qr::QuadratureR throw(ArgumentError("Currently only values and gradients can be updated in FunctionValues")) end - fv = FunctionValues(ip, N_x, N_ξ, dNdx, dNdξ) + fv = FunctionValues(ip, Nx, Nξ, dNdx, dNdξ) precompute_values!(fv, getpoints(qr)) # Separate function for qr point update in PointValues return fv end function precompute_values!(fv::FunctionValues{0}, qr_points::Vector{<:Vec}) - shape_values!(fv.N_ξ, fv.ip, qr_points) + shape_values!(fv.Nξ, fv.ip, qr_points) end function precompute_values!(fv::FunctionValues{1}, qr_points::Vector{<:Vec}) - shape_gradients_and_values!(fv.dNdξ, fv.N_ξ, fv.ip, qr_points) + shape_gradients_and_values!(fv.dNdξ, fv.Nξ, fv.ip, qr_points) end function Base.copy(v::FunctionValues) - N_ξ_copy = copy(v.N_ξ) - N_x_copy = v.N_ξ === v.N_x ? N_ξ_copy : copy(v.N_x) # Preserve aliasing + Nξ_copy = copy(v.Nξ) + Nx_copy = v.Nξ === v.Nx ? Nξ_copy : copy(v.Nx) # Preserve aliasing dNdx_copy = _copy_or_nothing(v.dNdx) dNdξ_copy = _copy_or_nothing(v.dNdξ) - return FunctionValues(copy(v.ip), N_x_copy, N_ξ_copy, dNdx_copy, dNdξ_copy) + return FunctionValues(copy(v.ip), Nx_copy, Nξ_copy, dNdx_copy, dNdξ_copy) end -getnbasefunctions(funvals::FunctionValues) = size(funvals.N_x, 1) -@propagate_inbounds shape_value(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.N_x[base_func, q_point] +getnbasefunctions(funvals::FunctionValues) = size(funvals.Nx, 1) +@propagate_inbounds shape_value(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.Nx[base_func, q_point] @propagate_inbounds shape_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = funvals.dNdx[base_func, q_point] @propagate_inbounds shape_symmetric_gradient(funvals::FunctionValues, q_point::Int, base_func::Int) = symmetric(shape_gradient(funvals, q_point, base_func)) -get_function_interpolation(funvals::FunctionValues) = funvals.ip -get_function_difforder(::FunctionValues{DiffOrder}) where DiffOrder = DiffOrder -shape_value_type(funvals::FunctionValues) = eltype(funvals.N_x) +function_interpolation(funvals::FunctionValues) = funvals.ip +function_difforder(::FunctionValues{DiffOrder}) where DiffOrder = DiffOrder +shape_value_type(funvals::FunctionValues) = eltype(funvals.Nx) shape_gradient_type(funvals::FunctionValues) = eltype(funvals.dNdx) shape_gradient_type(::FunctionValues{0}) = nothing @@ -123,7 +123,7 @@ struct ContravariantPiolaMapping end # struct DoubleCovariantPiolaMapping end # struct DoubleContravariantPiolaMapping end -get_mapping_type(fv::FunctionValues) = get_mapping_type(fv.ip) +mapping_type(fv::FunctionValues) = mapping_type(fv.ip) """ required_geo_diff_order(fun_mapping, fun_diff_order::Int) @@ -154,7 +154,7 @@ required_geo_diff_order(::CovariantPiolaMapping, fun_diff_order::Int) = 1 + # Apply mapping # ============= @inline function apply_mapping!(funvals::FunctionValues, q_point::Int, args...) - return apply_mapping!(funvals, get_mapping_type(funvals), q_point, args...) + return apply_mapping!(funvals, mapping_type(funvals), q_point, args...) end # Identity mapping @@ -176,8 +176,8 @@ end Jinv = inv(getjacobian(mapping_values)) @inbounds for j in 1:getnbasefunctions(funvals) d = get_direction(funvals.ip, j, cell) - N_ξ = funvals.N_ξ[j, q_point] - funvals.N_x[j, q_point] = d*(N_ξ ⋅ Jinv) + Nξ = funvals.Nξ[j, q_point] + funvals.Nx[j, q_point] = d*(Nξ ⋅ Jinv) end return nothing end @@ -188,9 +188,9 @@ end @inbounds for j in 1:getnbasefunctions(funvals) d = get_direction(funvals.ip, j, cell) dNdξ = funvals.dNdξ[j, q_point] - N_ξ = funvals.N_ξ[j, q_point] - funvals.N_x[j, q_point] = d*(N_ξ ⋅ Jinv) - funvals.dNdx[j, q_point] = d*(Jinv' ⋅ dNdξ ⋅ Jinv - Jinv' ⋅ (N_ξ ⋅ Jinv ⋅ H ⋅ Jinv)) + Nξ = funvals.Nξ[j, q_point] + funvals.Nx[j, q_point] = d*(Nξ ⋅ Jinv) + funvals.dNdx[j, q_point] = d*(Jinv' ⋅ dNdξ ⋅ Jinv - Jinv' ⋅ (Nξ ⋅ Jinv ⋅ H ⋅ Jinv)) end return nothing end @@ -201,8 +201,8 @@ end detJ = det(J) @inbounds for j in 1:getnbasefunctions(funvals) d = get_direction(funvals.ip, j, cell) - N_ξ = funvals.N_ξ[j, q_point] - funvals.N_x[j, q_point] = d*(J ⋅ N_ξ)/detJ + Nξ = funvals.Nξ[j, q_point] + funvals.Nx[j, q_point] = d*(J ⋅ Nξ)/detJ end return nothing end @@ -219,9 +219,9 @@ end @inbounds for j in 1:getnbasefunctions(funvals) d = get_direction(funvals.ip, j, cell) dNdξ = funvals.dNdξ[j, q_point] - N_ξ = funvals.N_ξ[j, q_point] - funvals.N_x[j, q_point] = d*(J ⋅ N_ξ)/detJ - funvals.dNdx[j, q_point] = d*(J ⋅ dNdξ ⋅ Jinv/detJ + A1 ⋅ N_ξ - (J ⋅ N_ξ) ⊗ A2) + Nξ = funvals.Nξ[j, q_point] + funvals.Nx[j, q_point] = d*(J ⋅ Nξ)/detJ + funvals.dNdx[j, q_point] = d*(J ⋅ dNdξ ⋅ Jinv/detJ + A1 ⋅ Nξ - (J ⋅ Nξ) ⊗ A2) end return nothing end diff --git a/src/FEValues/GeometryMapping.jl b/src/FEValues/GeometryMapping.jl index b3a283dfed..682d56a114 100644 --- a/src/FEValues/GeometryMapping.jl +++ b/src/FEValues/GeometryMapping.jl @@ -98,7 +98,7 @@ end getngeobasefunctions(geo_mapping::GeometryMapping) = size(geo_mapping.M, 1) @propagate_inbounds geometric_value(geo_mapping::GeometryMapping, q_point::Int, base_func::Int) = geo_mapping.M[base_func, q_point] -get_geometric_interpolation(geo_mapping::GeometryMapping) = geo_mapping.ip +geometric_interpolation(geo_mapping::GeometryMapping) = geo_mapping.ip # Hot-fixes to support embedded elements before MixedTensors are available # See https://github.com/Ferrite-FEM/Tensors.jl/pull/188 diff --git a/src/PointEval/point_values.jl b/src/PointEval/point_values.jl index 044a851afd..62107b4343 100644 --- a/src/PointEval/point_values.jl +++ b/src/PointEval/point_values.jl @@ -26,9 +26,9 @@ end function PointValues(cv::CellValues) T = typeof(getdetJdV(cv, 1)) - ip_fun = get_function_interpolation(cv) - ip_geo = get_geometric_interpolation(cv) - update_gradients = get_function_difforder(cv) == 1 + ip_fun = function_interpolation(cv) + ip_geo = geometric_interpolation(cv) + update_gradients = function_difforder(cv) == 1 return PointValues(T, ip_fun, ip_geo; update_gradients) end function PointValues(ip::Interpolation, ipg::Interpolation = default_geometric_interpolation(ip); kwargs...) diff --git a/src/interpolations.jl b/src/interpolations.jl index b2f519dd59..e394b7052c 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1559,17 +1559,17 @@ reference_coordinates(ip::VectorizedInterpolation) = reference_coordinates(ip.ip is_discontinuous(::Type{<:VectorizedInterpolation{<:Any, <:Any, <:Any, ip}}) where {ip} = is_discontinuous(ip) """ - get_mapping_type(ip::Interpolation) + mapping_type(ip::Interpolation) Get the type of mapping from the reference cell to the real cell for an interpolation `ip`. Subtypes of `ScalarInterpolation` and `VectorizedInterpolation` return `IdentityMapping()`, but other non-scalar interpolations may request different mapping types. """ -function get_mapping_type end +function mapping_type end -get_mapping_type(::ScalarInterpolation) = IdentityMapping() -get_mapping_type(::VectorizedInterpolation) = IdentityMapping() +mapping_type(::ScalarInterpolation) = IdentityMapping() +mapping_type(::VectorizedInterpolation) = IdentityMapping() ##################################### @@ -1578,7 +1578,7 @@ get_mapping_type(::VectorizedInterpolation) = IdentityMapping() # https://defelement.com/elements/raviart-thomas.html # https://defelement.com/elements/qdiv.html struct RaviartThomas{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end -get_mapping_type(::RaviartThomas) = ContravariantPiolaMapping() +mapping_type(::RaviartThomas) = ContravariantPiolaMapping() n_dbc_components(::RaviartThomas) = 1 # RefTriangle, 1st order Lagrange @@ -1606,7 +1606,7 @@ end # Nedelec (1st kind), H(curl) # ##################################### struct Nedelec{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end -get_mapping_type(::Nedelec) = CovariantPiolaMapping() +mapping_type(::Nedelec) = CovariantPiolaMapping() reference_coordinates(ip::Nedelec{vdim}) where vdim = fill(NaN*zero(Vec{vdim}), getnbasefunctions(ip)) dirichlet_facedof_indices(ip::Nedelec) = facedof_interior_indices(ip) n_dbc_components(::Nedelec) = 1 diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 851855b3a8..9f66ccbbc4 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -318,24 +318,24 @@ end cv = CellValues(qr, fun_ip) @test Ferrite.shape_value_type(cv) == value_type(Float64) @test Ferrite.shape_gradient_type(cv) == grad_type(Float64) - @test Ferrite.get_geometric_interpolation(cv) == Lagrange{RefTriangle, 1}() + @test Ferrite.geometric_interpolation(cv) == Lagrange{RefTriangle, 1}() # Numeric type + quadrature + scalar function cv = CellValues(Float32, qr, fun_ip) @test Ferrite.shape_value_type(cv) == value_type(Float32) @test Ferrite.shape_gradient_type(cv) == grad_type(Float32) - @test Ferrite.get_geometric_interpolation(cv) == Lagrange{RefTriangle, 1}() + @test Ferrite.geometric_interpolation(cv) == Lagrange{RefTriangle, 1}() for geo_ip in (Lagrange{RefTriangle, 2}(), Lagrange{RefTriangle, 2}()^2) scalar_ip(ip) = ip isa VectorizedInterpolation ? ip.ip : ip # Quadrature + scalar function + geo cv = CellValues(qr, fun_ip, geo_ip) @test Ferrite.shape_value_type(cv) == value_type(Float64) @test Ferrite.shape_gradient_type(cv) == grad_type(Float64) - @test Ferrite.get_geometric_interpolation(cv) == scalar_ip(geo_ip) + @test Ferrite.geometric_interpolation(cv) == scalar_ip(geo_ip) # Numeric type + quadrature + scalar function + scalar geo cv = CellValues(Float32, qr, fun_ip, geo_ip) @test Ferrite.shape_value_type(cv) == value_type(Float32) @test Ferrite.shape_gradient_type(cv) == grad_type(Float32) - @test Ferrite.get_geometric_interpolation(cv) == scalar_ip(geo_ip) + @test Ferrite.geometric_interpolation(cv) == scalar_ip(geo_ip) end end end diff --git a/test/test_interfacevalues.jl b/test/test_interfacevalues.jl index f69a49c227..6c99c8eeb1 100644 --- a/test/test_interfacevalues.jl +++ b/test/test_interfacevalues.jl @@ -1,7 +1,7 @@ @testset "InterfaceValues" begin function test_interfacevalues(grid::Ferrite.AbstractGrid, iv::InterfaceValues; tol = 0) - ip_here = Ferrite.get_function_interpolation(iv.here) - ip_there = Ferrite.get_function_interpolation(iv.there) + ip_here = Ferrite.function_interpolation(iv.here) + ip_there = Ferrite.function_interpolation(iv.there) ndim = Ferrite.getdim(ip_here) n_basefuncs = getnbasefunctions(ip_here) + getnbasefunctions(ip_there) From b3ce313c086023a24fd9b5d3eeaa10e68307f41a Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 6 Dec 2023 11:49:07 +0100 Subject: [PATCH 116/145] Fix type instability in point eval --- src/PointEval/PointEvalHandler.jl | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/PointEval/PointEvalHandler.jl b/src/PointEval/PointEvalHandler.jl index e8da115a07..7e27417d5a 100644 --- a/src/PointEval/PointEvalHandler.jl +++ b/src/PointEval/PointEvalHandler.jl @@ -204,12 +204,12 @@ end # values in dof-order. They must be obtained from the same DofHandler that was used for constructing the PointEvalHandler function evaluate_at_points!(out_vals::Vector{T2}, - ph::PointEvalHandler, + ph::PointEvalHandler{<:Any, <:Any, T_ph}, dh::DofHandler, dof_vals::Vector{T}, fname::Symbol, func_interpolations - ) where {T2, T} + ) where {T2, T_ph, T} # TODO: I don't think this is correct?? length(dof_vals) == ndofs(dh) || error("You must supply values for all $(ndofs(dh)) dofs.") @@ -219,35 +219,38 @@ function evaluate_at_points!(out_vals::Vector{T2}, if ip !== nothing dofrange = dof_range(sdh, fname) cellset = sdh.cellset - _evaluate_at_points!(out_vals, dof_vals, ph, dh, ip, cellset, dofrange) + ip_geo = default_interpolation(getcelltype(sdh)) + pv = PointValues(T_ph, ip, ip_geo; update_gradients = false) + _evaluate_at_points!(out_vals, dof_vals, ph, dh, pv, cellset, dofrange) end end return out_vals end -# function barrier with concrete type of interpolation +# function barrier with concrete type of PointValues function _evaluate_at_points!( out_vals::Vector{T2}, dof_vals::Vector{T}, ph::PointEvalHandler, dh::AbstractDofHandler, - ip::Interpolation, + pv::PointValues, cellset::Union{Nothing, Set{Int}}, dofrange::AbstractRange{Int}, ) where {T2,T} # extract variables local_coords = ph.local_coords + # preallocate some stuff specific to this cellset idx = findfirst(!isnothing, local_coords) idx === nothing && return out_vals - first_cell = cellset === nothing ? 1 : first(cellset) + grid = get_grid(dh) - ip_geo = default_interpolation(getcelltype(grid, first_cell)) - pv = PointValues(eltype(local_coords[idx]), ip, ip_geo; update_gradients = false) + first_cell = cellset === nothing ? 1 : first(cellset) cell_dofs = Vector{Int}(undef, ndofs_per_cell(dh, first_cell)) u_e = Vector{T}(undef, ndofs_per_cell(dh, first_cell)) x = getcoordinates(grid, first_cell) + # compute point values for pointid in eachindex(ph.cells) cellid = ph.cells[pointid] From 2cbd2b96d625e6d84f9ddcde88035a5ead5c5bf5 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 6 Dec 2023 13:29:29 +0100 Subject: [PATCH 117/145] Include cell in interface reinits --- src/FEValues/interface_values.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FEValues/interface_values.jl b/src/FEValues/interface_values.jl index dcee07d045..d7c07eff3d 100644 --- a/src/FEValues/interface_values.jl +++ b/src/FEValues/interface_values.jl @@ -124,8 +124,8 @@ function reinit!( ) where {dim, T} # reinit! the here side as normal - reinit!(iv.here, coords_here, face_here) - dim == 1 && return reinit!(iv.there, coords_there, face_there) + reinit!(iv.here, cell_here, coords_here, face_here) + dim == 1 && return reinit!(iv.there, cell_there, coords_there, face_there) # Transform the quadrature points from the here side to the there side set_current_face!(iv.there, face_there) # Includes boundscheck interface_transformation = InterfaceOrientationInfo(cell_here, cell_there, face_here, face_there) @@ -140,7 +140,7 @@ function reinit!( precompute_values!(get_geo_mapping(iv.there), quad_points_b) # reinit! the "there" side - reinit!(iv.there, coords_there, face_there) + reinit!(iv.there, cell_there, coords_there, face_there) return iv end From 3da6bf00ab40f19d5b240e58fb09f206a1a50450 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 6 Dec 2023 13:47:44 +0100 Subject: [PATCH 118/145] Add 2nd order RT ip on triangle --- src/interpolations.jl | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/interpolations.jl b/src/interpolations.jl index e394b7052c..6b1a8224fd 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1601,6 +1601,59 @@ function get_direction(::RaviartThomas{2,RefTriangle,1}, j, cell) return face_vertices[2] > face_vertices[1] ? 1 : -1 end +# RefTriangle, 2st order Lagrange +#= +----------------+-------------------- +Vertex numbers: | Vertex coordinates: + 2 | + | \ | v1: 𝛏 = (1.0, 0.0) + | \ | v2: 𝛏 = (0.0, 1.0) +ξ₂^ | \ | v3: 𝛏 = (0.0, 0.0) + | 3-------1 | + +--> ξ₁ | +----------------+-------------------- +Face numbers: | Face identifiers: + + | + | \ | f1: (v1, v2) + 2 1 | f2: (v2, v3) + | \ | f3: (v3, v1) + +---3---+ | +----------------+-------------------- +``` +""" +RefTriangle +=# +# https://defelement.com/elements/examples/triangle-raviart-thomas-lagrange-2.html +# Signs changed when needed to make positive direction outwards +function shape_value(ip::RaviartThomas{2,RefTriangle,2}, ξ::Vec{2}, i::Int) + x, y = ξ + # Face 1 (keep ordering, flip sign) + i == 1 && return Vec(4x*(2x-1), 2y*(4x-1)) + i == 2 && return Vec(2x*(4y-1), 4y*(2y-1)) + # Face 2 (flip ordering, keep signs) + i == 3 && return Vec( 8x*y - 2x - 6y + 2, 4y*(2y - 1)) + i == 4 && return Vec(-8x^2 - 8x*y + 12x + 6y - 4, 2y*(-4x - 4y + 3)) + # Face 3 (keep ordering, flip sign) + i == 5 && return Vec(2x*(3 - 4x - 4y), -8x*y + 6x - 8y^2 + 12y - 4) + i == 6 && return Vec(4x*(2x-1), 8x*y - 6x - 2y + 2) + # Cell + i == 7 && return Vec(8x*(-2x - y + 2), 8y*(-2x - y + 1)) + i == 8 && return Vec(8x*(-2y - x + 1), 8y*(-2y - x + 2)) + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::RaviartThomas{2,RefTriangle,2}) = 8 +facedof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = ((1, 2), (3, 4), (5, 6)) +celldof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = (7,8) +adjust_dofs_during_distribution(::RaviartThomas{2,RefTriangle,2}) = true + +function get_direction(::RaviartThomas{2,RefTriangle,2}, j, cell) + j>6 && return 1 + facenr = (j+1)÷2 + face_vertices = faces(cell)[facenr] + return face_vertices[2] > face_vertices[1] ? 1 : -1 +end + ##################################### # Nedelec (1st kind), H(curl) # From 2710cbb803d45b7066df159d31d3bc499e4bb39a Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 6 Dec 2023 15:06:09 +0100 Subject: [PATCH 119/145] Use old naming --- src/FEValues/{CellValues.jl => cell_values.jl} | 0 src/FEValues/{FaceValues.jl => face_values.jl} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/FEValues/{CellValues.jl => cell_values.jl} (100%) rename src/FEValues/{FaceValues.jl => face_values.jl} (100%) diff --git a/src/FEValues/CellValues.jl b/src/FEValues/cell_values.jl similarity index 100% rename from src/FEValues/CellValues.jl rename to src/FEValues/cell_values.jl diff --git a/src/FEValues/FaceValues.jl b/src/FEValues/face_values.jl similarity index 100% rename from src/FEValues/FaceValues.jl rename to src/FEValues/face_values.jl From 988f91649e910758d9b9e4612ee4f3dfefe17c67 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 6 Dec 2023 15:15:18 +0100 Subject: [PATCH 120/145] Add files forgotten to save --- src/Ferrite.jl | 5 ----- test/test_cellvalues.jl | 14 -------------- 2 files changed, 19 deletions(-) diff --git a/src/Ferrite.jl b/src/Ferrite.jl index 44e3aea7d8..78ad079feb 100644 --- a/src/Ferrite.jl +++ b/src/Ferrite.jl @@ -86,13 +86,8 @@ include("Quadrature/quadrature.jl") # FEValues include("FEValues/GeometryMapping.jl") include("FEValues/FunctionValues.jl") -<<<<<<< HEAD -include("FEValues/CellValues.jl") -include("FEValues/FaceValues.jl") -======= include("FEValues/cell_values.jl") include("FEValues/face_values.jl") ->>>>>>> master include("FEValues/interface_values.jl") include("PointEval/point_values.jl") diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 51db8e744c..9f66ccbbc4 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -145,30 +145,19 @@ end csv = CellValues(qr, ip) cvv = CellValues(qr, VectorizedInterpolation(ip)) csv_embedded = CellValues(qr, ip, ip^3) -<<<<<<< HEAD cv_nedelec = CellValues(qr, ip_nedelec, ip) fsv = FaceValues(qr_f, ip) fvv = FaceValues(qr_f, VectorizedInterpolation(ip)) fsv_embedded = FaceValues(qr_f, ip, ip^3) fv_nedelec = FaceValues(qr_f, ip_nedelec, ip) -======= - fsv = FaceValues(qr_f, ip) - fvv = FaceValues(qr_f, VectorizedInterpolation(ip)) - fsv_embedded = FaceValues(qr_f, ip, ip^3) - ->>>>>>> master x, n = valid_coordinates_and_normals(ip) reinit!(csv, x) reinit!(cvv, x) reinit!(fsv, x, 1) reinit!(fvv, x, 1) -<<<<<<< HEAD reinit!(cv_nedelec, cell, x) reinit!(fv_nedelec, cell, x, 1) -======= - ->>>>>>> master # Wrong number of coordinates xx = [x; x] @test_throws ArgumentError reinit!(csv, xx) @@ -185,13 +174,10 @@ end @test_throws ArgumentError reinit!(csv_embedded, x) @test_throws ArgumentError reinit!(fsv_embedded, x, 1) -<<<<<<< HEAD # Missing cell input when required @test_throws ArgumentError reinit!(cv_nedelec, x) @test_throws ArgumentError reinit!(fv_nedelec, x, 1) -======= ->>>>>>> master # Wrong number of (local) dofs # Scalar values, scalar dofs ue = rand(getnbasefunctions(csv) + 1) From 3a6289395de87b9feeaf6adf76c19053d1ae7bc0 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 6 Dec 2023 15:21:25 +0100 Subject: [PATCH 121/145] merge --- docs/make.jl | 2 + .../literate-tutorials/heat_equation_rt.jl | 337 ++++++++++++++++++ .../heat_equation_triangle.jl | 253 +++++++++++++ src/FEValues/FunctionValues.jl | 66 +++- src/FEValues/GeometryMapping.jl | 24 +- src/FEValues/common_values.jl | 3 - src/exports.jl | 2 + src/interpolations.jl | 215 ++++++++++- test/InterpolationTestUtils.jl | 116 ++++++ test/test_cellvalues.jl | 13 +- test/test_interpolations.jl | 43 +++ 11 files changed, 1047 insertions(+), 27 deletions(-) create mode 100644 docs/src/literate-tutorials/heat_equation_rt.jl create mode 100644 docs/src/literate-tutorials/heat_equation_triangle.jl create mode 100644 test/InterpolationTestUtils.jl diff --git a/docs/make.jl b/docs/make.jl index 13fc362d79..6a8635ea4f 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -47,6 +47,8 @@ bibtex_plugin = CitationBibliography( "Tutorials" => [ "Tutorials overview" => "tutorials/index.md", "tutorials/heat_equation.md", + "tutorials/heat_equation_rt.md", + "tutorials/heat_equation_triangle.md", "tutorials/linear_elasticity.md", "tutorials/incompressible_elasticity.md", "tutorials/hyperelasticity.md", diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl new file mode 100644 index 0000000000..25bcb5999b --- /dev/null +++ b/docs/src/literate-tutorials/heat_equation_rt.jl @@ -0,0 +1,337 @@ +# # [Heat equation (Mixed, RaviartThomas)](@id tutorial-heat-equation-rt) +# +# ## Strong form +# ```math +# \nabla \cdot \boldsymbol{q} = h \in \Omega \\ +# \boldsymbol{q} = - k\ \nabla u \in \Omega \\ +# \boldsymbol{q}\cdot \boldsymbol{n} = q_n \in \Gamma_\mathrm{N}\\ +# u = u_\mathrm{D} \in \Gamma_\mathrm{D} +# ``` +# +# ## Weak form +# ### Part 1 +# ```math +# \int_{\Omega} \delta u \nabla \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ +# \int_{\Gamma} \delta u \boldsymbol{n} \cdot \boldsymbol{q}\ \mathrm{d}\Gamma - +# \int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ +# ``` +# +# ### Part 2 +# ```math +# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega = - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega +# ``` +# where no Green-Gauss theorem is applied. +# +# ### Summary +# The weak form becomes, find $u\in H^1$ and $\boldsymbol{q} \in H\mathrm{(div)}$, such that +# ```math +# \begin{align*} +# -\int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega - +# \int_{\Gamma} \delta u\ q_\mathrm{n}\ \mathrm{d}\Gamma +# \quad +# \forall\ \delta u \in \delta H^1 \\ +# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega +# \quad \forall\ \boldsymbol{\delta q} \in \delta H\mathrm{(div)} +# \end{align*} +# ``` +# +# ## Commented Program +# +# Now we solve the problem in Ferrite. What follows is a program spliced with comments. +#md # The full program, without comments, can be found in the next [section](@ref heat_equation-plain-program). +# +# First we load Ferrite, and some other packages we need +using Ferrite, SparseArrays +# We start by generating a simple grid with 20x20 quadrilateral elements +# using `generate_grid`. The generator defaults to the unit square, +# so we don't need to specify the corners of the domain. +#grid = generate_grid(QuadraticTriangle, (20, 20)); +grid = generate_grid(Triangle, (20, 20)); + +# ### Trial and test functions +# A `CellValues` facilitates the process of evaluating values and gradients of +# test and trial functions (among other things). To define +# this we need to specify an interpolation space for the shape functions. +# We use Lagrange functions +# based on the two-dimensional reference quadrilateral. We also define a quadrature rule based on +# the same reference element. We combine the interpolation and the quadrature rule +# to a `CellValues` object. +ip_geo = Ferrite.default_interpolation(getcelltype(grid)) +ipu = Lagrange{RefTriangle, 1}() # Why does it "explode" for 2nd order ipu? +ipq = RaviartThomas{2,RefTriangle,1}() +qr = QuadratureRule{RefTriangle}(2) +cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) + +# ### Degrees of freedom +# Next we need to define a `DofHandler`, which will take care of numbering +# and distribution of degrees of freedom for our approximated fields. +# We create the `DofHandler` and then add a single scalar field called `:u` based on +# our interpolation `ip` defined above. +# Lastly we `close!` the `DofHandler`, it is now that the dofs are distributed +# for all the elements. +dh = DofHandler(grid) +add!(dh, :u, ipu) +add!(dh, :q, ipq) +close!(dh); + +# Now that we have distributed all our dofs we can create our tangent matrix, +# using `create_sparsity_pattern`. This function returns a sparse matrix +# with the correct entries stored. +K = create_sparsity_pattern(dh) + +# ### Boundary conditions +# In Ferrite constraints like Dirichlet boundary conditions +# are handled by a `ConstraintHandler`. +ch = ConstraintHandler(dh); + +# Next we need to add constraints to `ch`. For this problem we define +# homogeneous Dirichlet boundary conditions on the whole boundary, i.e. +# the `union` of all the face sets on the boundary. +∂Ω = union( + getfaceset(grid, "left"), + getfaceset(grid, "right"), + getfaceset(grid, "top"), + getfaceset(grid, "bottom"), +); + +# Now we are set up to define our constraint. We specify which field +# the condition is for, and our combined face set `∂Ω`. The last +# argument is a function of the form $f(\textbf{x})$ or $f(\textbf{x}, t)$, +# where $\textbf{x}$ is the spatial coordinate and +# $t$ the current time, and returns the prescribed value. Since the boundary condition in +# this case do not depend on time we define our function as $f(\textbf{x}) = 0$, i.e. +# no matter what $\textbf{x}$ we return $0$. When we have +# specified our constraint we `add!` it to `ch`. +dbc = Dirichlet(:u, ∂Ω, (x, t) -> 0) +add!(ch, dbc); + +# Finally we also need to `close!` our constraint handler. When we call `close!` +# the dofs corresponding to our constraints are calculated and stored +# in our `ch` object. +close!(ch) + +# Note that if one or more of the constraints are time dependent we would use +# [`update!`](@ref) to recompute prescribed values in each new timestep. + +# ### Assembling the linear system +# +# Now we have all the pieces needed to assemble the linear system, $K u = f$. +# Assembling of the global system is done by looping over all the elements in order to +# compute the element contributions ``K_e`` and ``f_e``, which are then assembled to the +# appropriate place in the global ``K`` and ``f``. +# +# #### Element assembly +# We define the function `assemble_element!` (see below) which computes the contribution for +# an element. The function takes pre-allocated `ke` and `fe` (they are allocated once and +# then reused for all elements) so we first need to make sure that they are all zeroes at +# the start of the function by using `fill!`. Then we loop over all the quadrature points, +# and for each quadrature point we loop over all the (local) shape functions. We need the +# value and gradient of the test function, `δu` and also the gradient of the trial function +# `u`. We get all of these from `cellvalues`. +# +# !!! note "Notation" +# Comparing with the brief finite element introduction in [Introduction to FEM](@ref), +# the variables `δu`, `∇δu` and `∇u` are actually $\phi_i(\textbf{x}_q)$, $\nabla +# \phi_i(\textbf{x}_q)$ and $\nabla \phi_j(\textbf{x}_q)$, i.e. the evaluation of the +# trial and test functions in the quadrature point ``\textbf{x}_q``. However, to +# underline the strong parallel between the weak form and the implementation, this +# example uses the symbols appearing in the weak form. + +function assemble_element!(Ke::Matrix, fe::Vector, cv::NamedTuple, dr::NamedTuple) + cvu = cv[:u] + cvq = cv[:q] + dru = dr[:u] + drq = dr[:q] + ## Loop over quadrature points + for q_point in 1:getnquadpoints(cvu) + ## Get the quadrature weight + dΩ = getdetJdV(cvu, q_point) + ## Loop over test shape functions + for (iu, Iu) in pairs(dru) + δu = shape_value(cvu, q_point, iu) + ∇δu = shape_gradient(cvu, q_point, iu) + ## Add contribution to fe + fe[Iu] -= δu * dΩ + ## Loop over trial shape functions + for (jq, Jq) in pairs(drq) + q = shape_value(cvq, q_point, jq) + ## Add contribution to Ke + Ke[Iu, Jq] += (∇δu ⋅ q) * dΩ + end + end + for (iq, Iq) in pairs(drq) + δq = shape_value(cvq, q_point, iq) + for (ju, Ju) in pairs(dru) + ∇u = shape_gradient(cvu, q_point, ju) + Ke[Iq, Ju] += (δq ⋅ ∇u) * dΩ + end + for (jq, Jq) in pairs(drq) + q = shape_value(cvq, q_point, jq) + Ke[Iq, Jq] += (δq ⋅ q) * dΩ + end + end + end + return Ke, fe +end +#md nothing # hide + +# #### Global assembly +# We define the function `assemble_global` to loop over the elements and do the global +# assembly. The function takes our `cellvalues`, the sparse matrix `K`, and our DofHandler +# as input arguments and returns the assembled global stiffness matrix, and the assembled +# global force vector. We start by allocating `Ke`, `fe`, and the global force vector `f`. +# We also create an assembler by using `start_assemble`. The assembler lets us assemble into +# `K` and `f` efficiently. We then start the loop over all the elements. In each loop +# iteration we reinitialize `cellvalues` (to update derivatives of shape functions etc.), +# compute the element contribution with `assemble_element!`, and then assemble into the +# global `K` and `f` with `assemble!`. +# +# !!! note "Notation" +# Comparing again with [Introduction to FEM](@ref), `f` and `u` correspond to +# $\underline{\hat{f}}$ and $\underline{\hat{u}}$, since they represent the discretized +# versions. However, through the code we use `f` and `u` instead to reflect the strong +# connection between the weak form and the Ferrite implementation. + +function assemble_global(cellvalues, K::SparseMatrixCSC, dh::DofHandler) + grid = dh.grid + ## Allocate the element stiffness matrix and element force vector + dofranges = (u = dof_range(dh, :u), q = dof_range(dh, :q)) + ncelldofs = ndofs_per_cell(dh) + Ke = zeros(ncelldofs, ncelldofs) + fe = zeros(ncelldofs) + ## Allocate global force vector f + f = zeros(ndofs(dh)) + ## Create an assembler + assembler = start_assemble(K, f) + x = copy(getcoordinates(grid, 1)) + dofs = copy(celldofs(dh, 1)) + ## Loop over all cels + for cellnr in 1:getncells(grid) + ## Reinitialize cellvalues for this cell + cell = getcells(grid, cellnr) + getcoordinates!(x, grid, cell) + celldofs!(dofs, dh, cellnr) + reinit!(cellvalues[:u], cell, x) + reinit!(cellvalues[:q], cell, x) + ## Reset to 0 + fill!(Ke, 0) + fill!(fe, 0) + ## Compute element contribution + assemble_element!(Ke, fe, cellvalues, dofranges) + ## Assemble Ke and fe into K and f + assemble!(assembler, dofs, Ke, fe) + end + return K, f +end +#md nothing # hide + +# ### Solution of the system +# The last step is to solve the system. First we call `assemble_global` +# to obtain the global stiffness matrix `K` and force vector `f`. +K, f = assemble_global(cellvalues, K, dh); + +# To account for the boundary conditions we use the `apply!` function. +# This modifies elements in `K` and `f` respectively, such that +# we can get the correct solution vector `u` by using `\`. +apply!(K, f, ch) +u = K \ f; + +# ### Exporting to VTK +# To visualize the result we export the grid and our field `u` +# to a VTK-file, which can be viewed in e.g. [ParaView](https://www.paraview.org/). +u_nodes = evaluate_at_grid_nodes(dh, u, :u) +∂Ω_cells = zeros(Int, getncells(grid)) +for (cellnr, facenr) in ∂Ω + ∂Ω_cells[cellnr] = 1 +end +vtk_grid("heat_equation_rt", dh) do vtk + vtk_point_data(vtk, u_nodes, "u") + vtk_cell_data(vtk, ∂Ω_cells, "dO") +end + +@show norm(u_nodes)/length(u_nodes) + +# ## Postprocess the total flux +function calculate_flux(dh, dΩ, ip, a) + grid = dh.grid + qr = FaceQuadratureRule{RefTriangle}(4) + ip_geo = Ferrite.default_interpolation(getcelltype(grid)) + fv = FaceValues(qr, ip, ip_geo) + + dofrange = dof_range(dh, :q) + flux = 0.0 + dofs = celldofs(dh, 1) + ae = zeros(length(dofs)) + x = getcoordinates(grid, 1) + for (cellnr, facenr) in dΩ + getcoordinates!(x, grid, cellnr) + cell = getcells(grid, cellnr) + celldofs!(dofs, dh, cellnr) + map!(i->a[i], ae, dofs) + reinit!(fv, cell, x, facenr) + for q_point in 1:getnquadpoints(fv) + dΓ = getdetJdV(fv, q_point) + n = getnormal(fv, q_point) + q = function_value(fv, q_point, ae, dofrange) + flux += (q ⋅ n)*dΓ + end + end + return flux +end + +function calculate_flux_lag(dh, dΩ, ip, a) + grid = dh.grid + qr = FaceQuadratureRule{RefTriangle}(4) + ip_geo = Ferrite.default_interpolation(getcelltype(grid)) + fv = FaceValues(qr, ip, ip_geo) + dofrange = dof_range(dh, :u) + flux = 0.0 + dofs = celldofs(dh, 1) + ae = zeros(length(dofs)) + x = getcoordinates(grid, 1) + for (cellnr, facenr) in dΩ + getcoordinates!(x, grid, cellnr) + cell = getcells(grid, cellnr) + celldofs!(dofs, dh, cellnr) + map!(i->a[i], ae, dofs) + reinit!(fv, cell, x, facenr) + for q_point in 1:getnquadpoints(fv) + dΓ = getdetJdV(fv, q_point) + n = getnormal(fv, q_point) + q = function_gradient(fv, q_point, ae, dofrange) + flux -= (q ⋅ n)*dΓ + end + end + return flux +end + +flux = calculate_flux(dh, ∂Ω, ipq, u) +flux_lag = calculate_flux_lag(dh, ∂Ω, ipu, u) +@show flux, flux_lag + + +function get_Ke(dh, cellvalues; cellnr=1) + dofranges = (u = dof_range(dh, :u), q = dof_range(dh, :q)) + ncelldofs = ndofs_per_cell(dh) + Ke = zeros(ncelldofs, ncelldofs) + fe = zeros(ncelldofs) + x = getcoordinates(grid, cellnr) + cell = getcells(grid, cellnr) + reinit!(cellvalues[:u], cell, x) + reinit!(cellvalues[:q], cell, x) + + ## Reset to 0 + fill!(Ke, 0) + fill!(fe, 0) + ## Compute element contribution + assemble_element!(Ke, fe, cellvalues, dofranges) + return Ke +end +#md # ## [Plain program](@id heat_equation-plain-program) +#md # +#md # Here follows a version of the program without any comments. +#md # The file is also available here: [`heat_equation.jl`](heat_equation.jl). +#md # +#md # ```julia +#md # @__CODE__ +#md # ``` diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl new file mode 100644 index 0000000000..414a7f9195 --- /dev/null +++ b/docs/src/literate-tutorials/heat_equation_triangle.jl @@ -0,0 +1,253 @@ +# # [Heat equation (Triangle)](@id tutorial-heat-equation-triangle) +# +# ![](heat_square.png) +# +# *Figure 1*: Temperature field on the unit square with an internal uniform heat source +# solved with homogeneous Dirichlet boundary conditions on the boundary. +# +# ## Introduction +# +# The heat equation is the "Hello, world!" equation of finite elements. +# Here we solve the equation on a unit square, with a uniform internal source. +# The strong form of the (linear) heat equation is given by +# +# ```math +# -\nabla \cdot (k \nabla u) = f \quad \textbf{x} \in \Omega, +# ``` +# +# where $u$ is the unknown temperature field, $k$ the heat conductivity, +# $f$ the heat source and $\Omega$ the domain. For simplicity we set $f = 1$ +# and $k = 1$. We will consider homogeneous Dirichlet boundary conditions such that +# ```math +# u(\textbf{x}) = 0 \quad \textbf{x} \in \partial \Omega, +# ``` +# where $\partial \Omega$ denotes the boundary of $\Omega$. +# The resulting weak form is given given as follows: Find ``u \in \mathbb{U}`` such that +# ```math +# \int_{\Omega} \nabla \delta u \cdot \nabla u \ d\Omega = \int_{\Omega} \delta u \ d\Omega \quad \forall \delta u \in \mathbb{T}, +# ``` +# where $\delta u$ is a test function, and where $\mathbb{U}$ and $\mathbb{T}$ are suitable +# trial and test function sets, respectively. +#- +# ## Commented Program +# +# Now we solve the problem in Ferrite. What follows is a program spliced with comments. +#md # The full program, without comments, can be found in the next [section](@ref heat_equation-plain-program). +# +# First we load Ferrite, and some other packages we need +using Ferrite, SparseArrays +# We start by generating a simple grid with 20x20 quadrilateral elements +# using `generate_grid`. The generator defaults to the unit square, +# so we don't need to specify the corners of the domain. +grid = generate_grid(Triangle, (20, 20)); + +# ### Trial and test functions +# A `CellValues` facilitates the process of evaluating values and gradients of +# test and trial functions (among other things). To define +# this we need to specify an interpolation space for the shape functions. +# We use Lagrange functions +# based on the two-dimensional reference quadrilateral. We also define a quadrature rule based on +# the same reference element. We combine the interpolation and the quadrature rule +# to a `CellValues` object. +ip = Lagrange{RefTriangle, 1}() +qr = QuadratureRule{RefTriangle}(2) +cellvalues = CellValues(qr, ip); + +# ### Degrees of freedom +# Next we need to define a `DofHandler`, which will take care of numbering +# and distribution of degrees of freedom for our approximated fields. +# We create the `DofHandler` and then add a single scalar field called `:u` based on +# our interpolation `ip` defined above. +# Lastly we `close!` the `DofHandler`, it is now that the dofs are distributed +# for all the elements. +dh = DofHandler(grid) +add!(dh, :u, ip) +close!(dh); + +# Now that we have distributed all our dofs we can create our tangent matrix, +# using `create_sparsity_pattern`. This function returns a sparse matrix +# with the correct entries stored. +K = create_sparsity_pattern(dh) + +# ### Boundary conditions +# In Ferrite constraints like Dirichlet boundary conditions +# are handled by a `ConstraintHandler`. +ch = ConstraintHandler(dh); + +# Next we need to add constraints to `ch`. For this problem we define +# homogeneous Dirichlet boundary conditions on the whole boundary, i.e. +# the `union` of all the face sets on the boundary. +∂Ω = union( + getfaceset(grid, "left"), + getfaceset(grid, "right"), + getfaceset(grid, "top"), + getfaceset(grid, "bottom"), +); + +# Now we are set up to define our constraint. We specify which field +# the condition is for, and our combined face set `∂Ω`. The last +# argument is a function of the form $f(\textbf{x})$ or $f(\textbf{x}, t)$, +# where $\textbf{x}$ is the spatial coordinate and +# $t$ the current time, and returns the prescribed value. Since the boundary condition in +# this case do not depend on time we define our function as $f(\textbf{x}) = 0$, i.e. +# no matter what $\textbf{x}$ we return $0$. When we have +# specified our constraint we `add!` it to `ch`. +dbc = Dirichlet(:u, ∂Ω, (x, t) -> 0) +add!(ch, dbc); + +# Finally we also need to `close!` our constraint handler. When we call `close!` +# the dofs corresponding to our constraints are calculated and stored +# in our `ch` object. +close!(ch) + +# Note that if one or more of the constraints are time dependent we would use +# [`update!`](@ref) to recompute prescribed values in each new timestep. + +# ### Assembling the linear system +# +# Now we have all the pieces needed to assemble the linear system, $K u = f$. +# Assembling of the global system is done by looping over all the elements in order to +# compute the element contributions ``K_e`` and ``f_e``, which are then assembled to the +# appropriate place in the global ``K`` and ``f``. +# +# #### Element assembly +# We define the function `assemble_element!` (see below) which computes the contribution for +# an element. The function takes pre-allocated `ke` and `fe` (they are allocated once and +# then reused for all elements) so we first need to make sure that they are all zeroes at +# the start of the function by using `fill!`. Then we loop over all the quadrature points, +# and for each quadrature point we loop over all the (local) shape functions. We need the +# value and gradient of the test function, `δu` and also the gradient of the trial function +# `u`. We get all of these from `cellvalues`. +# +# !!! note "Notation" +# Comparing with the brief finite element introduction in [Introduction to FEM](@ref), +# the variables `δu`, `∇δu` and `∇u` are actually $\phi_i(\textbf{x}_q)$, $\nabla +# \phi_i(\textbf{x}_q)$ and $\nabla \phi_j(\textbf{x}_q)$, i.e. the evaluation of the +# trial and test functions in the quadrature point ``\textbf{x}_q``. However, to +# underline the strong parallel between the weak form and the implementation, this +# example uses the symbols appearing in the weak form. + +function assemble_element!(Ke::Matrix, fe::Vector, cellvalues::CellValues) + n_basefuncs = getnbasefunctions(cellvalues) + ## Reset to 0 + fill!(Ke, 0) + fill!(fe, 0) + ## Loop over quadrature points + for q_point in 1:getnquadpoints(cellvalues) + ## Get the quadrature weight + dΩ = getdetJdV(cellvalues, q_point) + ## Loop over test shape functions + for i in 1:n_basefuncs + δu = shape_value(cellvalues, q_point, i) + ∇δu = shape_gradient(cellvalues, q_point, i) + ## Add contribution to fe + fe[i] += δu * dΩ + ## Loop over trial shape functions + for j in 1:n_basefuncs + ∇u = shape_gradient(cellvalues, q_point, j) + ## Add contribution to Ke + Ke[i, j] += (∇δu ⋅ ∇u) * dΩ + end + end + end + return Ke, fe +end +#md nothing # hide + +# #### Global assembly +# We define the function `assemble_global` to loop over the elements and do the global +# assembly. The function takes our `cellvalues`, the sparse matrix `K`, and our DofHandler +# as input arguments and returns the assembled global stiffness matrix, and the assembled +# global force vector. We start by allocating `Ke`, `fe`, and the global force vector `f`. +# We also create an assembler by using `start_assemble`. The assembler lets us assemble into +# `K` and `f` efficiently. We then start the loop over all the elements. In each loop +# iteration we reinitialize `cellvalues` (to update derivatives of shape functions etc.), +# compute the element contribution with `assemble_element!`, and then assemble into the +# global `K` and `f` with `assemble!`. +# +# !!! note "Notation" +# Comparing again with [Introduction to FEM](@ref), `f` and `u` correspond to +# $\underline{\hat{f}}$ and $\underline{\hat{u}}$, since they represent the discretized +# versions. However, through the code we use `f` and `u` instead to reflect the strong +# connection between the weak form and the Ferrite implementation. + +function assemble_global(cellvalues::CellValues, K::SparseMatrixCSC, dh::DofHandler) + ## Allocate the element stiffness matrix and element force vector + n_basefuncs = getnbasefunctions(cellvalues) + Ke = zeros(n_basefuncs, n_basefuncs) + fe = zeros(n_basefuncs) + ## Allocate global force vector f + f = zeros(ndofs(dh)) + ## Create an assembler + assembler = start_assemble(K, f) + ## Loop over all cels + for cell in CellIterator(dh) + ## Reinitialize cellvalues for this cell + reinit!(cellvalues, cell) + ## Compute element contribution + assemble_element!(Ke, fe, cellvalues) + ## Assemble Ke and fe into K and f + assemble!(assembler, celldofs(cell), Ke, fe) + end + return K, f +end +#md nothing # hide + +# ### Solution of the system +# The last step is to solve the system. First we call `assemble_global` +# to obtain the global stiffness matrix `K` and force vector `f`. +K, f = assemble_global(cellvalues, K, dh); + +# To account for the boundary conditions we use the `apply!` function. +# This modifies elements in `K` and `f` respectively, such that +# we can get the correct solution vector `u` by using `\`. +apply!(K, f, ch) +u = K \ f; + +# ### Exporting to VTK +# To visualize the result we export the grid and our field `u` +# to a VTK-file, which can be viewed in e.g. [ParaView](https://www.paraview.org/). +vtk_grid("heat_equation", dh) do vtk + vtk_point_data(vtk, dh, u) +end + +@show norm(u)/length(u) + +# ### Postprocessing the total flux + +function calculate_flux_lag(dh, dΩ, ip, a) + qr = FaceQuadratureRule{RefTriangle}(2) + fv = FaceValues(qr, ip, Lagrange{RefTriangle,1}()) + grid = dh.grid + dofrange = dof_range(dh, :u) + flux = 0.0 + dofs = celldofs(dh, 1) + ae = zeros(length(dofs)) + x = getcoordinates(grid, 1) + for (cellnr, facenr) in dΩ + getcoordinates!(x, grid, cellnr) + cell = getcells(grid, cellnr) + celldofs!(dofs, dh, cellnr) + map!(i->a[i], ae, dofs) + reinit!(fv, cell, x, facenr) + for q_point in 1:getnquadpoints(fv) + dΓ = getdetJdV(fv, q_point) + n = getnormal(fv, q_point) + q = function_gradient(fv, q_point, ae, dofrange) + flux -= (q ⋅ n)*dΓ + end + end + return flux +end + +flux = calculate_flux_lag(dh, ∂Ω, ip, u) +@show flux + +#md # ## [Plain program](@id heat_equation-plain-program) +#md # +#md # Here follows a version of the program without any comments. +#md # The file is also available here: [`heat_equation.jl`](heat_equation.jl). +#md # +#md # ```julia +#md # @__CODE__ +#md # ``` diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index 7250116892..c45a50df61 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -117,9 +117,9 @@ end # Mapping types struct IdentityMapping end +struct CovariantPiolaMapping end +struct ContravariantPiolaMapping end # Not yet implemented: -# struct CovariantPiolaMapping end # PR798 -# struct ContravariantPiolaMapping end # PR798 # struct DoubleCovariantPiolaMapping end # struct DoubleContravariantPiolaMapping end @@ -133,9 +133,8 @@ the function values and gradients from the reference cell to the physical cell geometry. """ required_geo_diff_order(::IdentityMapping, fun_diff_order::Int) = fun_diff_order -#required_geo_diff_order(::ContravariantPiolaMapping, fun_diff_order::Int) = 1 + fun_diff_order # PR798 -#required_geo_diff_order(::CovariantPiolaMapping, fun_diff_order::Int) = 1 + fun_diff_order # PR798 - +required_geo_diff_order(::ContravariantPiolaMapping, fun_diff_order::Int) = 1 + fun_diff_order +required_geo_diff_order(::CovariantPiolaMapping, fun_diff_order::Int) = 1 + fun_diff_order # Support for embedded elements @inline calculate_Jinv(J::Tensor{2}) = inv(J) @@ -172,6 +171,57 @@ end return nothing end -# TODO in PR798, apply_mapping! for -# * CovariantPiolaMapping -# * ContravariantPiolaMapping +# Covariant Piola Mapping +@inline function apply_mapping!(funvals::FunctionValues{0}, ::CovariantPiolaMapping, q_point::Int, mapping_values, cell) + Jinv = inv(getjacobian(mapping_values)) + @inbounds for j in 1:getnbasefunctions(funvals) + d = get_direction(funvals.ip, j, cell) + Nξ = funvals.Nξ[j, q_point] + funvals.Nx[j, q_point] = d*(Nξ ⋅ Jinv) + end + return nothing +end + +@inline function apply_mapping!(funvals::FunctionValues{1}, ::CovariantPiolaMapping, q_point::Int, mapping_values, cell) + H = gethessian(mapping_values) + Jinv = inv(getjacobian(mapping_values)) + @inbounds for j in 1:getnbasefunctions(funvals) + d = get_direction(funvals.ip, j, cell) + dNdξ = funvals.dNdξ[j, q_point] + Nξ = funvals.Nξ[j, q_point] + funvals.Nx[j, q_point] = d*(Nξ ⋅ Jinv) + funvals.dNdx[j, q_point] = d*(Jinv' ⋅ dNdξ ⋅ Jinv - Jinv' ⋅ (Nξ ⋅ Jinv ⋅ H ⋅ Jinv)) + end + return nothing +end + +# Contravariant Piola Mapping +@inline function apply_mapping!(funvals::FunctionValues{0}, ::ContravariantPiolaMapping, q_point::Int, mapping_values, cell) + J = getjacobian(mapping_values) + detJ = det(J) + @inbounds for j in 1:getnbasefunctions(funvals) + d = get_direction(funvals.ip, j, cell) + Nξ = funvals.Nξ[j, q_point] + funvals.Nx[j, q_point] = d*(J ⋅ Nξ)/detJ + end + return nothing +end + +@inline function apply_mapping!(funvals::FunctionValues{1}, ::ContravariantPiolaMapping, q_point::Int, mapping_values, cell) + H = gethessian(mapping_values) + J = getjacobian(mapping_values) + Jinv = inv(J) + detJ = det(J) + I2 = one(J) + H_Jinv = H⋅Jinv + A1 = (H_Jinv ⊡ (otimesl(I2,I2))) / detJ + A2 = (Jinv' ⊡ H_Jinv) / detJ + @inbounds for j in 1:getnbasefunctions(funvals) + d = get_direction(funvals.ip, j, cell) + dNdξ = funvals.dNdξ[j, q_point] + Nξ = funvals.Nξ[j, q_point] + funvals.Nx[j, q_point] = d*(J ⋅ Nξ)/detJ + funvals.dNdx[j, q_point] = d*(J ⋅ dNdξ ⋅ Jinv/detJ + A1 ⋅ Nξ - (J ⋅ Nξ) ⊗ A2) + end + return nothing +end diff --git a/src/FEValues/GeometryMapping.jl b/src/FEValues/GeometryMapping.jl index b6346b7550..682d56a114 100644 --- a/src/FEValues/GeometryMapping.jl +++ b/src/FEValues/GeometryMapping.jl @@ -12,10 +12,8 @@ struct MappingValues{JT, HT} J::JT # dx/dξ # Jacobian H::HT # dJ/dξ # Hessian end - @inline getjacobian(mv::MappingValues{<:Union{AbstractTensor, SMatrix}}) = mv.J -# @inline gethessian(mv::MappingValues{<:Any,<:AbstractTensor}) = mv.H # PR798 - +@inline gethessian(mv::MappingValues{<:Any,<:AbstractTensor}) = mv.H """ GeometryMapping{DiffOrder}(::Type{T}, ip_geo, qr::QuadratureRule) @@ -46,12 +44,12 @@ struct GeometryMapping{DiffOrder, IP, M_t, dMdξ_t, d2Mdξ2_t} ) where {IP <: ScalarInterpolation, M_t<:AbstractMatrix{<:Number}, dMdξ_t <: AbstractMatrix{<:Vec}} return new{1, IP, M_t, dMdξ_t, Nothing}(ip, M, dMdξ, nothing) end -#= function GeometryMapping( + function GeometryMapping( ip::IP, M::M_t, dMdξ::dMdξ_t, d2Mdξ2::d2Mdξ2_t) where {IP <: ScalarInterpolation, M_t<:AbstractMatrix{<:Number}, dMdξ_t <: AbstractMatrix{<:Vec}, d2Mdξ2_t <: AbstractMatrix{<:Tensor{2}}} return new{2, IP, M_t, dMdξ_t, d2Mdξ2_t}(ip, M, dMdξ, d2Mdξ2) - end =# # PR798 + end end function GeometryMapping{0}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T n_shape = getnbasefunctions(ip) @@ -71,7 +69,7 @@ function GeometryMapping{1}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRu precompute_values!(gm, getpoints(qr)) return gm end -#= function GeometryMapping{2}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T +function GeometryMapping{2}(::Type{T}, ip::ScalarInterpolation, qr::QuadratureRule) where T n_shape = getnbasefunctions(ip) n_qpoints = getnquadpoints(qr) @@ -82,7 +80,7 @@ end gm = GeometryMapping(ip, M, dMdξ, d2Mdξ2) precompute_values!(gm, getpoints(qr)) return gm -end =# # PR798 +end function precompute_values!(gm::GeometryMapping{0}, qr_points::Vector{<:Vec}) shape_values!(gm.M, gm.ip, qr_points) @@ -90,9 +88,9 @@ end function precompute_values!(gm::GeometryMapping{1}, qr_points::Vector{<:Vec}) shape_gradients_and_values!(gm.dMdξ, gm.M, gm.ip, qr_points) end -#= function precompute_values!(gm::GeometryMapping{2}, qr_points::Vector{<:Vec}) +function precompute_values!(gm::GeometryMapping{2}, qr_points::Vector{<:Vec}) shape_hessians_gradients_and_values!(gm.d2Mdξ2, gm.dMdξ, gm.M, gm.ip, qr_points) -end =# # PR798 +end function Base.copy(v::GeometryMapping) return GeometryMapping(copy(v.ip), copy(v.M), _copy_or_nothing(v.dMdξ), _copy_or_nothing(v.d2Mdξ2)) @@ -117,9 +115,9 @@ end function otimes_returntype(#=typeof(x)=#::Type{<:Vec{dim,Tx}}, #=typeof(dMdξ)=#::Type{<:Vec{dim,TM}}) where {dim, Tx, TM} return Tensor{2,dim,promote_type(Tx,TM)} end -#= function otimes_returntype(#=typeof(x)=#::Type{<:Vec{dim,Tx}}, #=typeof(d2Mdξ2)=#::Type{<:Tensor{2,dim,TM}}) where {dim, Tx, TM} +function otimes_returntype(#=typeof(x)=#::Type{<:Vec{dim,Tx}}, #=typeof(d2Mdξ2)=#::Type{<:Tensor{2,dim,TM}}) where {dim, Tx, TM} return Tensor{3,dim,promote_type(Tx,TM)} -end =# # PR798 +end @inline function calculate_mapping(::GeometryMapping{0}, q_point, x) return MappingValues(nothing, nothing) @@ -134,7 +132,7 @@ end return MappingValues(fecv_J, nothing) end -#= @inline function calculate_mapping(geo_mapping::GeometryMapping{2}, q_point, x) +@inline function calculate_mapping(geo_mapping::GeometryMapping{2}, q_point, x) J = zero(otimes_returntype(eltype(x), eltype(geo_mapping.dMdξ))) H = zero(otimes_returntype(eltype(x), eltype(geo_mapping.d2Mdξ2))) @inbounds for j in 1:getngeobasefunctions(geo_mapping) @@ -142,7 +140,7 @@ end H += x[j] ⊗ geo_mapping.d2Mdξ2[j, q_point] end return MappingValues(J, H) -end =# # PR798 +end calculate_detJ(J::Tensor{2}) = det(J) calculate_detJ(J::SMatrix) = embedding_det(J) diff --git a/src/FEValues/common_values.jl b/src/FEValues/common_values.jl index 181e54b03c..dad7f8b50c 100644 --- a/src/FEValues/common_values.jl +++ b/src/FEValues/common_values.jl @@ -302,11 +302,8 @@ function shape_gradients_and_values!(gradients::AbstractMatrix, values::Abstract end end -#= PR798 function shape_hessians_gradients_and_values!(hessians::AbstractMatrix, gradients::AbstractMatrix, values::AbstractMatrix, ip, qr_points::Vector{<:Vec}) for (qp, ξ) in pairs(qr_points) shape_hessians_gradients_and_values!(@view(hessians[:, qp]), @view(gradients[:, qp]), @view(values[:, qp]), ip, ξ) end end -=# - diff --git a/src/exports.jl b/src/exports.jl index dab7e368fb..ae96f39c71 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -16,6 +16,8 @@ export Lagrange, DiscontinuousLagrange, Serendipity, + Nedelec, + RaviartThomas, getnbasefunctions, getrefshape, diff --git a/src/interpolations.jl b/src/interpolations.jl index 0d74256e44..2e4893848c 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -246,6 +246,21 @@ and store them in `hessians`, `gradients`, and `values`. end =# +""" + shape_hessians_gradients_and_values!(hessians::AbstractVector, gradients::AbstractVector, values::AbstractVector, ip::Interpolation, ξ::Vec) + +Evaluate all shape function hessians, gradients and values of `ip` at once at the reference point `ξ` +and store them in `hessians`, `gradients`, and `values`. +""" +@propagate_inbounds function shape_hessians_gradients_and_values!(hessians::AbstractVector, gradients::AbstractVector, values::AbstractVector, ip::Interpolation, ξ::Vec) + @boundscheck checkbounds(hessians, 1:getnbasefunctions(ip)) + @boundscheck checkbounds(gradients, 1:getnbasefunctions(ip)) + @boundscheck checkbounds(values, 1:getnbasefunctions(ip)) + @inbounds for i in 1:getnbasefunctions(ip) + hessians[i], gradients[i], values[i] = shape_hessian_gradient_and_value(ip, ξ, i) + end +end + """ shape_value(ip::Interpolation, ξ::Vec, i::Int) @@ -291,6 +306,16 @@ function shape_hessian_gradient_and_value(ip::Interpolation, ξ::Vec, i::Int) end =# +""" + shape_hessian_gradient_and_value(ip::Interpolation, ξ::Vec, i::Int) + +Optimized version combining the evaluation [`Ferrite.shape_value(::Interpolation)`](@ref), +[`Ferrite.shape_gradient(::Interpolation)`](@ref), and the gradient of the latter. +""" +function shape_hessian_gradient_and_value(ip::Interpolation, ξ::Vec, i::Int) + return hessian(x -> shape_value(ip, x, i), ξ, :all) +end + """ reference_coordinates(ip::Interpolation) @@ -1560,7 +1585,6 @@ function shape_gradient_and_value(ipv::VectorizedInterpolation{vdim, shape}, ξ: end reference_coordinates(ip::VectorizedInterpolation) = reference_coordinates(ip.ip) - is_discontinuous(::Type{<:VectorizedInterpolation{<:Any, <:Any, <:Any, ip}}) where {ip} = is_discontinuous(ip) """ @@ -1575,3 +1599,192 @@ function mapping_type end mapping_type(::ScalarInterpolation) = IdentityMapping() mapping_type(::VectorizedInterpolation) = IdentityMapping() + + +##################################### +# RaviartThomas (1st kind), H(div) # +##################################### +# https://defelement.com/elements/raviart-thomas.html +# https://defelement.com/elements/qdiv.html +struct RaviartThomas{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end +mapping_type(::RaviartThomas) = ContravariantPiolaMapping() +n_dbc_components(::RaviartThomas) = 1 + +# RefTriangle, 1st order Lagrange +# https://defelement.com/elements/examples/triangle-raviart-thomas-lagrange-1.html +# Signs changed when needed to make positive direction outwards +function shape_value(ip::RaviartThomas{2,RefTriangle,1}, ξ::Vec{2}, i::Int) + x, y = ξ + i == 1 && return ξ # Flip sign + i == 2 && return Vec(x-1, y) # Keep sign + i == 3 && return Vec(x, y - 1) # Flip sign + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::RaviartThomas{2,RefTriangle,1}) = 3 +facedof_interior_indices(::RaviartThomas{2,RefTriangle,1}) = ((1,), (2,), (3,)) +adjust_dofs_during_distribution(::RaviartThomas) = false + +function get_direction(::RaviartThomas{2,RefTriangle,1}, j, cell) + face_vertices = faces(cell)[j] + return face_vertices[2] > face_vertices[1] ? 1 : -1 +end + +# RefTriangle, 2st order Lagrange +#= +----------------+-------------------- +Vertex numbers: | Vertex coordinates: + 2 | + | \ | v1: 𝛏 = (1.0, 0.0) + | \ | v2: 𝛏 = (0.0, 1.0) +ξ₂^ | \ | v3: 𝛏 = (0.0, 0.0) + | 3-------1 | + +--> ξ₁ | +----------------+-------------------- +Face numbers: | Face identifiers: + + | + | \ | f1: (v1, v2) + 2 1 | f2: (v2, v3) + | \ | f3: (v3, v1) + +---3---+ | +----------------+-------------------- +``` +""" +RefTriangle +=# +# https://defelement.com/elements/examples/triangle-raviart-thomas-lagrange-2.html +# Signs changed when needed to make positive direction outwards +function shape_value(ip::RaviartThomas{2,RefTriangle,2}, ξ::Vec{2}, i::Int) + x, y = ξ + # Face 1 (keep ordering, flip sign) + i == 1 && return Vec(4x*(2x-1), 2y*(4x-1)) + i == 2 && return Vec(2x*(4y-1), 4y*(2y-1)) + # Face 2 (flip ordering, keep signs) + i == 3 && return Vec( 8x*y - 2x - 6y + 2, 4y*(2y - 1)) + i == 4 && return Vec(-8x^2 - 8x*y + 12x + 6y - 4, 2y*(-4x - 4y + 3)) + # Face 3 (keep ordering, flip sign) + i == 5 && return Vec(2x*(3 - 4x - 4y), -8x*y + 6x - 8y^2 + 12y - 4) + i == 6 && return Vec(4x*(2x-1), 8x*y - 6x - 2y + 2) + # Cell + i == 7 && return Vec(8x*(-2x - y + 2), 8y*(-2x - y + 1)) + i == 8 && return Vec(8x*(-2y - x + 1), 8y*(-2y - x + 2)) + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::RaviartThomas{2,RefTriangle,2}) = 8 +facedof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = ((1, 2), (3, 4), (5, 6)) +celldof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = (7,8) +adjust_dofs_during_distribution(::RaviartThomas{2,RefTriangle,2}) = true + +function get_direction(::RaviartThomas{2,RefTriangle,2}, j, cell) + j>6 && return 1 + facenr = (j+1)÷2 + face_vertices = faces(cell)[facenr] + return face_vertices[2] > face_vertices[1] ? 1 : -1 +end + + +##################################### +# Nedelec (1st kind), H(curl) # +##################################### +struct Nedelec{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end +mapping_type(::Nedelec) = CovariantPiolaMapping() +reference_coordinates(ip::Nedelec{vdim}) where vdim = fill(NaN*zero(Vec{vdim}), getnbasefunctions(ip)) +dirichlet_facedof_indices(ip::Nedelec) = facedof_interior_indices(ip) +n_dbc_components(::Nedelec) = 1 +# RefTriangle, 1st order Lagrange +# https://defelement.com/elements/examples/triangle-nedelec1-lagrange-1.html +function shape_value(ip::Nedelec{2,RefTriangle,1}, ξ::Vec{2}, i::Int) + x, y = ξ + i == 1 && return Vec( - y, x) + i == 2 && return Vec( - y, x - 1) # Changed signed, follow Ferrite's sign convention + i == 3 && return Vec(1 - y, x) + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::Nedelec{2,RefTriangle,1}) = 3 +facedof_interior_indices(::Nedelec{2,RefTriangle,1}) = ((1,), (2,), (3,)) +adjust_dofs_during_distribution(::Nedelec{2,RefTriangle,1}) = false + +function get_direction(::Nedelec{2,RefTriangle,1}, j, cell) + face_vertices = faces(cell)[j] + return face_vertices[2] > face_vertices[1] ? 1 : -1 +end + +# RefTriangle, 2nd order Lagrange +# https://defelement.com/elements/examples/triangle-nedelec1-lagrange-2.html +function shape_value(ip::Nedelec{2,RefTriangle,2}, ξ::Vec{2}, i::Int) + x, y = ξ + # Face 1 + i == 1 && return Vec( 2*y*(1 - 4*x), + 4*x*(2*x - 1)) + i == 2 && return Vec( 4*y*(1 - 2*y), + 2*x*(4*y - 1)) + # Face 2 (flip order and sign compared to defelement) + i == 3 && return Vec( 4*y*(1 - 2*y), + 8*x*y - 2*x - 6*y + 2) + i == 4 && return Vec( 2*y*(4*x + 4*y - 3), + -8*x^2 - 8*x*y + 12*x + 6*y - 4) + # Face 3 + i == 5 && return Vec( 8*x*y - 6*x + 8*y^2 - 12*y + 4, + 2*x*(-4*x - 4*y + 3)) + i == 6 && return Vec(-8*x*y + 6*x + 2*y - 2, + 4*x*(2*x - 1)) + # Cell + i == 7 && return Vec( 8*y*(-x - 2*y + 2), + 8*x*( x + 2*y - 1)) + i == 8 && return Vec( 8*y*( 2*x + y - 1), + 8*x*(-2*x - y + 2)) + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::Nedelec{2,RefTriangle,2}) = 8 +facedof_interior_indices(::Nedelec{2,RefTriangle,2}) = ((1,2), (3,4), (5,6)) +celldof_interior_indices(::Nedelec{2,RefTriangle,2}) = (7,8) +adjust_dofs_during_distribution(::Nedelec{2,RefTriangle,2}) = true + +function get_direction(::Nedelec{2,RefTriangle,2}, j, cell) + j>6 && return 1 + facenr = (j+1)÷2 + face_vertices = faces(cell)[facenr] + return face_vertices[2] > face_vertices[1] ? 1 : -1 +end + +# RefTetrahedron, 1st order Lagrange - 𝐍𝐎𝐓 𝐓𝐄𝐒𝐓𝐄𝐃 +# https://defelement.com/elements/examples/tetrahedron-nedelec1-lagrange-1.html +function shape_value(ip::Nedelec{3,RefTetrahedron,1}, ξ::Vec{3,T}, i::Int) where T + x, y, z = ξ + # Edge 1 (defelement 5, positive) + i == 1 && return Vec(- y - z + 1, x, x) + # Edge 2 (defelement 2, positive) + i == 2 && return Vec(-y, x, zero(T)) + # Edge 3 (defelement 4, negative) + i == 3 && return Vec(-y, x + z - 1, -y) + # Edge 4 (defelement 3, positive) + i == 4 && return Vec(z, z, -x - y + 1) + # Edge 5 (defelement 1, positive) + i == 5 && return Vec(-z, zero(T), x) + # Edge 6 (defelement 0, positive) + i == 6 && return Vec(zero(T), -z, y) + + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::Nedelec{3,RefTetrahedron,1}) = 6 +edgedof_interior_indices(::Nedelec{3,RefTetrahedron,1}) = ntuple(i->(i,), 6) +adjust_dofs_during_distribution(::Nedelec{3,RefTetrahedron,1}) = false + +function get_direction(::Nedelec{3,RefTetrahedron,1}, j, cell) + edge_vertices = edges(cell)[j] + return edge_vertices[2] > edge_vertices[1] ? 1 : -1 +end + +# RefTetrahedron, 2nd order Lagrange +# https://defelement.com/elements/examples/tetrahedron-nedelec1-lagrange-2.html +#= Notes +The dofs belong to faces seem to require extra consideration, but not sure. +Basically, we need to make sure they are aligned with the same edges that they refer to. +It might be that this works automatically, following `adjust_dofs_during_distribution`, +but test cases need to be developed first to make sure. +No point in implementing guesses that cannot be verified... +=# diff --git a/test/InterpolationTestUtils.jl b/test/InterpolationTestUtils.jl new file mode 100644 index 0000000000..563241e042 --- /dev/null +++ b/test/InterpolationTestUtils.jl @@ -0,0 +1,116 @@ +module InterpolationTestUtils + using Ferrite + using Test + import LinearAlgebra: normalize + import Random: randperm + + function find_matching_face(grid, face::FaceIndex) + cell, facenr = face + face_vertices = Set(Ferrite.faces(getcells(grid, cell))[facenr]) + for cnr in 1:getncells(grid) + cnr == cell && continue + for (i, f_vert) in enumerate(Ferrite.faces(getcells(grid, cnr))) + face_vertices == Set(f_vert) && return FaceIndex(cnr, i) + end + end + return nothing + end + + function test_continuity(dh::DofHandler, face::FaceIndex; + transformation_function::Function=identity, + value_function::Function=function_value) + # transformation_function: (v,n) -> z + # Examples + # * Tangential continuity: fun(v, n) = v - (v ⋅ n)*n + # * Normal continuity: fun(v, n) = v ⋅ n + # value_function: (fe_v, q_point, ue) -> z + + # Check validity of input + @assert length(dh.subdofhandlers) == 1 + @assert length(Ferrite.getfieldnames(dh)) == 1 + + # Find the matching FaceIndex + cellnr, facenr = face + face2 = find_matching_face(dh.grid, face) + face2 === nothing && return false + + # Pick "random" points on the face + cell = getcells(dh.grid, cellnr) + RefShape = Ferrite.getrefshape(getcells(dh.grid, cellnr)) + ip_geo = Ferrite.default_interpolation(typeof(cell)) + ip_fun = Ferrite.getfieldinterpolation(dh, (1,1)) + fqr = FaceQuadratureRule{RefShape}(10) + fv = FaceValues(fqr, ip_fun, ip_geo) + cell_coords = getcoordinates(dh.grid, cellnr) + inds = randperm(getnquadpoints(fv))[1:min(4, getnquadpoints(fv))] + + # Random dof vector to test continuity + u = rand(ndofs(dh)) + + # Calculate coordinates and function values for these + point_coords = zeros(eltype(cell_coords), length(inds)) + point_normal = similar(point_coords) + fun_vals = zeros(typeof(shape_value(fv, 1, 1)), length(inds)) + reinit!(fv, cell, cell_coords, facenr) + ue = u[celldofs(dh, cellnr)] + for (i, q_point) in enumerate(inds) + point_coords[i] = spatial_coordinate(fv, q_point, cell_coords) + point_normal[i] = getnormal(fv, q_point) + fun_vals[i] = value_function(fv, q_point, ue) + end + + # Calculate function values on the other cell + cell2 = getcells(dh.grid, face2[1]) + cell_coords2 = getcoordinates(dh.grid, face2[1]) + local_coords = map(x->Ferrite.find_local_coordinate(ip_geo, cell_coords2, x), point_coords) + @assert all(first.(local_coords)) # check that find_local_coordinate converged + ξs = collect(last.(local_coords)) # Extract the local coordinates + qr = QuadratureRule{RefShape}(zeros(length(ξs)), ξs) + cv = CellValues(qr, ip_fun, ip_geo) + reinit!(cv, cell2, cell_coords2) + fun_vals2 = similar(fun_vals) + ue2 = u[celldofs(dh, face2[1])] + for q_point in 1:getnquadpoints(cv) + @assert spatial_coordinate(cv, q_point, cell_coords2) ≈ point_coords[q_point] + fun_vals2[q_point] = value_function(cv, q_point, ue2) + end + + d1 = map((v,n)->transformation_function(v,n), fun_vals, point_normal) + d2 = map((v,n)->transformation_function(v,n), fun_vals2, point_normal) + @test isapprox(d1, d2; rtol=1e-6) # Approximate points can contribute to the inexactness + return true + end + + function create_gradcheck_qr(ip_geo::Interpolation{RefShape}, ΔL) where RefShape + dim = Ferrite.getdim(ip_geo) + xref = Ferrite.reference_coordinates(ip_geo) + xc = sum(xref)/length(xref) + ws = rand(length(xref))*((1-ΔL)/length(xref)) + xp = xc + sum(map((x,w) -> w*(x - xc), xref, ws)) + v = normalize(rand(Vec{dim}) - ones(Vec{dim})/2) + x1 = xp + ΔL*v + qr_w = [NaN, NaN] + qr_x = [xp, x1] + return QuadratureRule{RefShape}(qr_w, qr_x) + end + + function test_gradient(dh, cellnr; ΔL=1e-6) + ue = rand(ndofs_per_cell(dh, cellnr)) + x = getcoordinates(dh.grid, cellnr) + cell = getcells(dh.grid, cellnr) + ip_geo = Ferrite.default_interpolation(typeof(cell)) + ip_fun = Ferrite.getfieldinterpolation(dh, (1,1)) + qr = create_gradcheck_qr(ip_geo, ΔL) + cv = CellValues(qr, ip_fun, ip_geo) + reinit!(cv, cell, x) + Δu_num = function_value(cv, 2, ue) - function_value(cv, 1, ue) + Δx = spatial_coordinate(cv, 2, x) - spatial_coordinate(cv, 1, x) + ∇u1 = function_gradient(cv, 1, ue) + ∇u2 = function_gradient(cv, 2, ue) + Δu_ana = 0.5*(∇u1+∇u2) ⋅ Δx + # Δu_ana_var = 0.5*(∇u2-∇u1) ⋅ Δx # Relevant to compare magnitude if test fails + @test isapprox(Δu_num, Δu_ana; rtol=1e-6) + return nothing + end + +end \ No newline at end of file diff --git a/test/test_cellvalues.jl b/test/test_cellvalues.jl index 052251c1f7..9f66ccbbc4 100644 --- a/test/test_cellvalues.jl +++ b/test/test_cellvalues.jl @@ -137,22 +137,27 @@ end @testset "error paths in function_* and reinit!" begin dim = 2 qp = 1 + cell = Triangle((1,2,3)) ip = Lagrange{RefTriangle,1}() + ip_nedelec = Nedelec{2,RefTriangle,1}() qr = QuadratureRule{RefTriangle}(1) qr_f = FaceQuadratureRule{RefTriangle}(1) csv = CellValues(qr, ip) cvv = CellValues(qr, VectorizedInterpolation(ip)) csv_embedded = CellValues(qr, ip, ip^3) + cv_nedelec = CellValues(qr, ip_nedelec, ip) fsv = FaceValues(qr_f, ip) fvv = FaceValues(qr_f, VectorizedInterpolation(ip)) fsv_embedded = FaceValues(qr_f, ip, ip^3) - + fv_nedelec = FaceValues(qr_f, ip_nedelec, ip) x, n = valid_coordinates_and_normals(ip) reinit!(csv, x) reinit!(cvv, x) reinit!(fsv, x, 1) reinit!(fvv, x, 1) - + reinit!(cv_nedelec, cell, x) + reinit!(fv_nedelec, cell, x, 1) + # Wrong number of coordinates xx = [x; x] @test_throws ArgumentError reinit!(csv, xx) @@ -169,6 +174,10 @@ end @test_throws ArgumentError reinit!(csv_embedded, x) @test_throws ArgumentError reinit!(fsv_embedded, x, 1) + # Missing cell input when required + @test_throws ArgumentError reinit!(cv_nedelec, x) + @test_throws ArgumentError reinit!(fv_nedelec, x, 1) + # Wrong number of (local) dofs # Scalar values, scalar dofs ue = rand(getnbasefunctions(csv) + 1) diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index b67e0599a1..061e0b96bd 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -1,3 +1,4 @@ + @testset "interpolations" begin @testset "$interpolation" for interpolation in ( @@ -208,4 +209,46 @@ end @test Ferrite.is_discontinuous(ip_t) == false @test Ferrite.is_discontinuous(d_ip) == true @test Ferrite.is_discontinuous(d_ip_t) == true + +@testset "Hcurl and Hdiv" begin + include(joinpath(@__DIR__, "InterpolationTestUtils.jl")) + import .InterpolationTestUtils as ITU + nel = 3 + transformation_functions = Dict( + Nedelec=>(v,n)-> v - n*(v⋅n), # Hcurl (tangent continuity) + RaviartThomas=>(v,n) -> v ⋅ n) # Hdiv (normal continuity) + for CT in (Triangle, QuadraticTriangle, Tetrahedron) + dim = Ferrite.getdim(CT) + p1, p2 = (rand(Vec{dim}), ones(Vec{dim})+rand(Vec{dim})) + grid = generate_grid(CT, ntuple(_->nel, dim), p1, p2) + # Smoothly distort grid (to avoid spuriously badly deformed elements). + # A distorted grid is important to properly test the geometry mapping + # for 2nd order elements. + transfun(x) = typeof(x)(i->sinpi(x[mod(i, length(x))+1]+i/3))/10 + transform_coordinates!(grid, x->(x + transfun(x))) + RefShape = Ferrite.getrefshape(getcells(grid, 1)) + for order in (1, 2) + for IPT in (Nedelec, RaviartThomas) + dim == 3 && order > 1 && continue + IPT == RaviartThomas && (dim == 3 || order > 1) && continue + transformation_function=transformation_functions[IPT] + ip = IPT{dim,RefShape,order}() + @testset "$CT, $ip" begin + dh = DofHandler(grid) + add!(dh, :u, ip) + close!(dh) + cellnr = getncells(grid)÷2 # Should be a cell in the center + for facenr in 1:nfaces(RefShape) + fi = FaceIndex(cellnr, facenr) + # Check continuity of tangential function value + ITU.test_continuity(dh, fi; transformation_function) + end + # Check gradient calculation + ITU.test_gradient(dh, cellnr) + end + end + end + end end +end + From 3f5721e8c7c0afba463668e4808c86fe7ded323e Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 28 Feb 2024 18:34:36 +0100 Subject: [PATCH 122/145] Fix after merge --- test/test_facevalues.jl | 2 +- test/test_interpolations.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test_facevalues.jl b/test/test_facevalues.jl index 056cc542e2..e7ed791257 100644 --- a/test/test_facevalues.jl +++ b/test/test_facevalues.jl @@ -17,7 +17,7 @@ for (scalar_interpol, quad_rule) in ( for func_interpol in (scalar_interpol, VectorizedInterpolation(scalar_interpol)) geom_interpol = scalar_interpol # Tests below assume this n_basefunc_base = getnbasefunctions(scalar_interpol) - fv = if VERSION ≥ v"1.9" + fv = if false # VERSION ≥ v"1.9" # TODO: Lost type stability again... @inferred FaceValues(quad_rule, func_interpol, geom_interpol) else # Type unstable on 1.6, but works at least for 1.9 and later. PR882 FaceValues(quad_rule, func_interpol, geom_interpol) diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index ed1a6155b2..99e352af06 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -224,6 +224,7 @@ @test Ferrite.is_discontinuous(ip_t) == false @test Ferrite.is_discontinuous(d_ip) == true @test Ferrite.is_discontinuous(d_ip_t) == true +end @testset "Hcurl and Hdiv" begin include(joinpath(@__DIR__, "InterpolationTestUtils.jl")) From 90dbf686b1592119be4f080e4aa53b1b507683d9 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Thu, 21 Mar 2024 11:43:27 +0100 Subject: [PATCH 123/145] Make CellCache reinit work --- src/iterators.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/iterators.jl b/src/iterators.jl index e1431de711..70793d45ab 100644 --- a/src/iterators.jl +++ b/src/iterators.jl @@ -89,9 +89,12 @@ function reinit!(cc::CellCache, i::Int) end # reinit! FEValues with CellCache -reinit!(cv::CellValues, cc::CellCache) = reinit!(cv, cc.coords) +# TODO: Should we provide a fast path if the cell is not required for reinit? +#reinit!(cv::CellValues, cc::CellCache) = reinit!(cv, cc.coords) +reinit!(cv::CellValues, cc::CellCache) = reinit!(cv, getcells(cc.grid, cellid(cc)), cc.coords) reinit!(fv::FaceValues, cc::CellCache, f::Int) = reinit!(fv, cc.coords, f) # TODO: Deprecate? + # Accessor functions (TODO: Deprecate? We are so inconsistent with `getxx` vs `xx`...) getnodes(cc::CellCache) = cc.nodes getcoordinates(cc::CellCache) = cc.coords From 10b2dfd2a651c97487b86ffce3aa91b5e77dc23b Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Thu, 21 Mar 2024 17:28:41 +0100 Subject: [PATCH 124/145] Nonworking Nedelec on Hexahedron --- src/interpolations.jl | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/interpolations.jl b/src/interpolations.jl index 0670aee199..2ffe98624f 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1751,7 +1751,6 @@ function get_direction(::Nedelec{2,RefTriangle,2}, j, cell) return face_vertices[2] > face_vertices[1] ? 1 : -1 end -# RefTetrahedron, 1st order Lagrange - 𝐍𝐎𝐓 𝐓𝐄𝐒𝐓𝐄𝐃 # https://defelement.com/elements/examples/tetrahedron-nedelec1-lagrange-1.html function shape_value(ip::Nedelec{3,RefTetrahedron,1}, ξ::Vec{3,T}, i::Int) where T x, y, z = ξ @@ -1789,3 +1788,43 @@ It might be that this works automatically, following `adjust_dofs_during_distrib but test cases need to be developed first to make sure. No point in implementing guesses that cannot be verified... =# + +# https://defelement.com/elements/examples/hexahedron-nedelec1-lagrange-1.html +function shape_value(ip::Nedelec{3,RefHexahedron,1}, ξ::Vec{3,T}, i::Int) where T + x, y, z = 2ξ - ones(ξ) + # Edge 1 (defelement 0, positive) + i == 1 && return Vec(- y*z - y - z + 1, zero(T), zero(T)) + # Edge 2 (defelement 3, positive) + i == 2 && return Vec(zero(T), x * (1 - z), zero(T)) + # Edge 3 (defelement 5, negative) + i == 3 && return Vec(-y*(1-z), zero(T), zero(T)) + # Edge 4 (defelement 1, negative) + i == 4 && return Vec(zero(T), - x*z + x + z - 1, zero(T)) + # Edge 5 (defelement 8, positive) + i == 5 && return Vec(z*(1-y), zero(T), zero(T)) + # Edge 6 (defelement 10, positive) + i == 6 && return Vec(zero(T), z * z, zero(T)) + # Edge 7 (defelement 11, negative) + i == 7 && return Vec(- y*z, zero(T), zero(T)) + # Edge 8 (defelement 9, negative) + i == 8 && return Vec(zero(T), - z * (1 - x), zero(T)) + # Edge 9 (defelement 2, positive) + i == 9 && return Vec(zero(T), zero(T), x*y - x - y + 1) + # Edge 10 (defelement 4, positive) + i == 10 && return Vec(zero(T), zero(T), x * (1 - y)) + # Edge 11 (defelement 7, positive) + i == 11 && return Vec(zero(T), zero(T), x * y) + # Edge 12 (defelement 6, positive) + i == 12 && return Vec(zero(T), zero(T), y * (1 - x)) + + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::Nedelec{3,RefHexahedron,1}) = 12 +edgedof_interior_indices(::Nedelec{3,RefHexahedron,1}) = ntuple(i->(i,), 12) +adjust_dofs_during_distribution(::Nedelec{3,RefHexahedron,1}) = false + +function get_direction(::Nedelec{3,RefHexahedron,1}, j, cell) + edge_vertices = edges(cell)[j] + return edge_vertices[2] > edge_vertices[1] ? 1 : -1 +end From fc38951b0c3867ab659bfa8c01deafa36920453e Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 22 Mar 2024 14:30:10 +0100 Subject: [PATCH 125/145] Fix Nedelec{3,RefHexahedron} --- src/interpolations.jl | 10 +++++++--- test/test_interpolations.jl | 5 +++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/interpolations.jl b/src/interpolations.jl index 2ffe98624f..087b1dcf1b 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1790,10 +1790,14 @@ No point in implementing guesses that cannot be verified... =# # https://defelement.com/elements/examples/hexahedron-nedelec1-lagrange-1.html +# TODO: Need to "map" from defelement [0,1] refcell to Ferrite [-1,1], which +# for Nedelec should be scaling with J^-T where J=2I, i.e. divide by 2 +# For RT elements with Hdiv, this should instead be J/det(J) => 2/2^dim, +# i.e. also divide by 2 in 3d, no scaling in 2d, and multiply by 2 in 1d. function shape_value(ip::Nedelec{3,RefHexahedron,1}, ξ::Vec{3,T}, i::Int) where T - x, y, z = 2ξ - ones(ξ) + x, y, z = (ξ + ones(ξ))/2 # Edge 1 (defelement 0, positive) - i == 1 && return Vec(- y*z - y - z + 1, zero(T), zero(T)) + i == 1 && return Vec(y*z - y - z + 1, zero(T), zero(T)) # Edge 2 (defelement 3, positive) i == 2 && return Vec(zero(T), x * (1 - z), zero(T)) # Edge 3 (defelement 5, negative) @@ -1803,7 +1807,7 @@ function shape_value(ip::Nedelec{3,RefHexahedron,1}, ξ::Vec{3,T}, i::Int) where # Edge 5 (defelement 8, positive) i == 5 && return Vec(z*(1-y), zero(T), zero(T)) # Edge 6 (defelement 10, positive) - i == 6 && return Vec(zero(T), z * z, zero(T)) + i == 6 && return Vec(zero(T), x * z, zero(T)) # Edge 7 (defelement 11, negative) i == 7 && return Vec(- y*z, zero(T), zero(T)) # Edge 8 (defelement 9, negative) diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index 99e352af06..d470084e8d 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -233,7 +233,7 @@ end transformation_functions = Dict( Nedelec=>(v,n)-> v - n*(v⋅n), # Hcurl (tangent continuity) RaviartThomas=>(v,n) -> v ⋅ n) # Hdiv (normal continuity) - for CT in (Triangle, QuadraticTriangle, Tetrahedron) + for CT in (Triangle, QuadraticTriangle, Tetrahedron, Hexahedron) dim = Ferrite.getdim(CT) p1, p2 = (rand(Vec{dim}), ones(Vec{dim})+rand(Vec{dim})) grid = generate_grid(CT, ntuple(_->nel, dim), p1, p2) @@ -247,13 +247,14 @@ end for IPT in (Nedelec, RaviartThomas) dim == 3 && order > 1 && continue IPT == RaviartThomas && (dim == 3 || order > 1) && continue + IPT == RaviartThomas && (CT == Hexahedron) && continue transformation_function=transformation_functions[IPT] ip = IPT{dim,RefShape,order}() @testset "$CT, $ip" begin dh = DofHandler(grid) add!(dh, :u, ip) close!(dh) - cellnr = getncells(grid)÷2 # Should be a cell in the center + cellnr = getncells(grid)÷2 + 1 # Should be a cell in the center for facenr in 1:nfaces(RefShape) fi = FaceIndex(cellnr, facenr) # Check continuity of tangential function value From d356a429728596a6198ecca046e9bd7304925c1a Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 22 Mar 2024 14:30:40 +0100 Subject: [PATCH 126/145] Add temporary visualization script and project --- visualization/Manifest.toml | 1690 ++++++++++++++++++++++++++++ visualization/Project.toml | 4 + visualization/reference_cell_ip.jl | 85 ++ 3 files changed, 1779 insertions(+) create mode 100644 visualization/Manifest.toml create mode 100644 visualization/Project.toml create mode 100644 visualization/reference_cell_ip.jl diff --git a/visualization/Manifest.toml b/visualization/Manifest.toml new file mode 100644 index 0000000000..ec88abc416 --- /dev/null +++ b/visualization/Manifest.toml @@ -0,0 +1,1690 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.2" +manifest_format = "2.0" +project_hash = "9dc2d1ce07b87cc5107b7fa3d34838a5e8d48de1" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.3.0" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.0.4" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.9.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Automa]] +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "1.0.3" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "a4c43f59baa34011e303e76f5c8c91bf58415aaf" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.23.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.14.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.0+0" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.5" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.2" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "0f4b5d62a88d8f59003e43c25a8a90de9eb76317" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.18" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "d4e9dc4c6106b8d44e40cd4faf8261a678552c7c" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.12" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.107" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArrays"] +git-tree-sha1 = "b3f2ff58735b5f024c392fde763f29b057e4b025" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.8" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.Extents]] +git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.2" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "ab3f7e1819dba9434a3a5126510c8fda3a4e7000" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "6.1.1+0" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.8.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + +[[deps.Ferrite]] +deps = ["EnumX", "LinearAlgebra", "NearestNeighbors", "Preferences", "Reexport", "SparseArrays", "StaticArrays", "Tensors", "WriteVTK"] +path = ".." +uuid = "c061ca5d-56c9-439f-9c0e-210fe06d3992" +version = "0.3.14" + + [deps.Ferrite.extensions] + FerriteBlockArrays = "BlockArrays" + FerriteMetis = "Metis" + + [deps.Ferrite.weakdeps] + BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" + Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b" + +[[deps.FerriteViz]] +deps = ["Ferrite", "GeometryBasics", "LinearAlgebra", "Makie", "Reexport", "ShaderAbstractions", "StaticArrays", "Tensors"] +path = "C:\\Users\\meyer\\.julia\\dev\\FerriteViz" +uuid = "59d0093e-b1f1-4fb7-ac85-ab57e45f39d9" +version = "0.2.1" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.3" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra", "Random"] +git-tree-sha1 = "5b93957f6dcd33fc343044af3d48c215be2562f1" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.9.3" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "bc0c5092d6caaea112d3c8e3b238d61563c58d5f" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.23.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Formatting]] +deps = ["Logging", "Printf"] +git-tree-sha1 = "fb409abab2caf118986fc597ba84b50cbaf00b87" +uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" +version = "0.4.3" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.1" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.1" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GLFW]] +deps = ["GLFW_jll"] +git-tree-sha1 = "35dbc482f0967d8dceaa7ce007d16f9064072166" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "3.4.1" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.3.9+0" + +[[deps.GLMakie]] +deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] +git-tree-sha1 = "8236ce4eda9837d15bab49573bba16ba0652b486" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.8.12" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.3" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "5694b56ccf9d15addedc35e9a4ba9c317721b788" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.10" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.0+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.9.2" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.7" + +[[deps.ImageCore]] +deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "b2a7eaa169c13f5bcae8131a83bc30eff8f71be0" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.2" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.0.2+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.15.1" + + [deps.Interpolations.extensions] + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm_jll", "RoundingEmulator"] +git-tree-sha1 = "552505ed27d2a90ff04c15b0ecf4634e0ab5547b" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.22.9" +weakdeps = ["DiffRules", "ForwardDiff", "RecipesBase"] + + [deps.IntervalArithmetic.extensions] + IntervalArithmeticDiffRulesExt = "DiffRules" + IntervalArithmeticForwardDiffExt = "ForwardDiff" + IntervalArithmeticRecipesBaseExt = "RecipesBase" + +[[deps.IntervalSets]] +git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.10" +weakdeps = ["Random", "RecipesBase", "Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.10.0" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.5" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3336abae9a713d2210bb57ab484b1e065edd7d23" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.2+0" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.8" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.7+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.6.0+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.39.3+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.39.3+1" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.1" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] +git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.2.7" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.27" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.0.0+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "35fa3c150cd96fd77417a23965b7037b90d6ffc9" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.19.12" + +[[deps.MakieCore]] +deps = ["Observables", "REPL"] +git-tree-sha1 = "9b11acd07f21c4d035bd4156e789532e8ee2cc70" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.6.9" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] +git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.7" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] +git-tree-sha1 = "8c26ab950860dfca6767f2bbd90fdf1e8ddc678b" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.4.11" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "b76ea40b5c0f45790ae09492712dd326208c28b2" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.1.7" + +[[deps.Mods]] +git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "2.2.4" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NearestNeighbors]] +deps = ["Distances", "StaticArrays"] +git-tree-sha1 = "ded64ff6d4fdd1cb68dfcbb818c69e144a5b2e4c" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.16" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.OffsetArrays]] +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+4" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+2" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "60e3045590bd104a16fefb12836c00c0ef8c7f8c" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.13+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.Optim]] +deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "PackageExtensionCompat", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "d1223e69af90b6d26cea5b6f3b289b3148ba702c" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.9.3" + + [deps.Optim.extensions] + OptimMOIExt = "MathOptInterface" + + [deps.Optim.weakdeps] + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.31" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.3" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.20" + +[[deps.PikaParser]] +deps = ["DocStringExtensions"] +git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" +uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" +version = "0.6.1" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "7b1a9df27f072ac4c9c7cbe5efb198489258d1f5" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.1" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.6" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "cb420f77dc474d23ee47ca8d14c90810cafe69e7" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.6" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "763a8ceb07833dd51bb9e3bbca372de32c0605ad" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.10.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.4" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SIMD]] +deps = ["PrecompileTools"] +git-tree-sha1 = "d8911cc125da009051fb35322415641d02d9e37f" +uuid = "fdea26ae-647d-5447-a871-4b548cad5224" +version = "3.4.6" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "79123bc60c5507f035e6d1d9e563bb2971954ec8" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.4.1" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.6" + +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "e182b9e5afb194142d4668536345a365ea19363a" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.2" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.17" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableHashTraits]] +deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "10dc702932fe05a0e09b8e5955f00794ea1e8b12" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.1.8" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.3" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.2" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.1" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.18" + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = "GPUArraysCore" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + + [deps.StructArrays.weakdeps] + Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Tensors]] +deps = ["ForwardDiff", "LinearAlgebra", "PrecompileTools", "SIMD", "StaticArrays", "Statistics"] +git-tree-sha1 = "957f256fb380cad64cae4da39e562ecfb5c3fec9" +uuid = "48a634ad-e948-5137-8d70-aa71f2a747f4" +version = "1.16.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.8" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "a09c933bebed12501890d8e92946bbab6a1690f1" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.5" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + +[[deps.TupleTools]] +git-tree-sha1 = "41d61b1c545b06279871ef1a4b5fcb2cac2191cd" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.5.0" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.VTKBase]] +git-tree-sha1 = "c2d0db3ef09f1942d08ea455a9e252594be5f3b6" +uuid = "4004b06d-e244-455f-a6ce-a5f9919cc534" +version = "1.0.1" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.WriteVTK]] +deps = ["Base64", "CodecZlib", "FillArrays", "LightXML", "TranscodingStreams", "VTKBase"] +git-tree-sha1 = "17877c404fd20090e3998a66f6f44cf01e2b1e60" +uuid = "64499a7a-5c06-52f2-abe2-ccb03c286192" +version = "1.18.3" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "07e470dabc5a6a4254ffebc29a1b3fc01464e105" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.5+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.0+4" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "5.0.3+4" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.7.10+4" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] +git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.4+4" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.2+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.43+1" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" diff --git a/visualization/Project.toml b/visualization/Project.toml new file mode 100644 index 0000000000..c5b64e5103 --- /dev/null +++ b/visualization/Project.toml @@ -0,0 +1,4 @@ +[deps] +Ferrite = "c061ca5d-56c9-439f-9c0e-210fe06d3992" +FerriteViz = "59d0093e-b1f1-4fb7-ac85-ab57e45f39d9" +GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" diff --git a/visualization/reference_cell_ip.jl b/visualization/reference_cell_ip.jl new file mode 100644 index 0000000000..b43cc6a8a0 --- /dev/null +++ b/visualization/reference_cell_ip.jl @@ -0,0 +1,85 @@ +using Ferrite +import FerriteViz as Viz +import GLMakie as Plt + + +function refshape_shapevalues(ip::VectorInterpolation{3, RefHexahedron}, shape_nr; npoints = 5) + x, y, z, u, v, w = (zeros(npoints^3) for _ in 1:6) + idx = 1 + for i in 1:npoints + for j in 1:npoints + for k in 1:npoints + x[idx], y[idx], z[idx] = (i-1, j-1, k-1) .* (2/(npoints-1)) .- 1 + u[idx], v[idx], w[idx] = shape_value(ip, Vec((x[idx], y[idx], z[idx])), shape_nr) + idx += 1 + end + end + end + return x, y, z, u, v, w +end + +refcell(::Type{RefHexahedron}) = Hexahedron(ntuple(i->i, 8)) +refcell(::Type{RefTetrahedron}) = Tetrahedron(ntuple(i->i, 4)) +refip(::Type{RefShape}) where {RefShape <: Ferrite.AbstractRefShape} = Lagrange{RefShape,1}() + + +function plot_refcell(::Type{RefShape}; kwargs...) where {RefShape <: Ferrite.AbstractRefShape{3}} + fig = Plt.Figure() + ax = Plt.Axis3(fig[1,1]; xlabel="ξ₁", ylabel="ξ₂", zlabel="ξ₃") + plot_refcell!(ax, RefShape; kwargs...) + return fig, ax +end + +function plot_refcell!(ax, ::Type{RefShape}; vertices=true, edges=true, faces=true) where {RefShape <: Ferrite.AbstractRefShape{3}} + plot_vertices!(ax, RefShape; label=vertices) + plot_edges!(ax, RefShape; label=edges) + plot_faces!(ax, RefShape; label=faces) + return ax +end + +function plot_vertices!(ax, ::Type{RefShape}; label) where {RefShape <: Ferrite.AbstractRefShape{3}} + ξ = Ferrite.reference_coordinates(refip(RefShape)) + ξ1, ξ2, ξ3 = (getindex.(ξ, i) for i in 1:3) + Plt.scatter!(ax, ξ1, ξ2, ξ3) + if label + Plt.text!(ax, ξ1, ξ2, ξ3; text=[string(i) for i in 1:length(ξ)]) + end + return ax +end + +function plot_edges!(ax, ::Type{RefShape}; label) where {RefShape <: Ferrite.AbstractRefShape{3}} + arrowheadpos = 2/3 + cell = refcell(RefShape) + ξ = Ferrite.reference_coordinates(refip(RefShape)) + x, y, z, u, v, w = (zeros(length(Ferrite.edges(cell))) for _ in 1:6) + for (k, e) in enumerate(Ferrite.edges(cell)) + ξa, ξb = getindex.((ξ,), e) + Plt.lines!(ax, ([ξa[i], ξb[i]] for i in 1:3)...) + x[k], y[k], z[k] = ξa + u[k], v[k], w[k] = ξb - ξa + end + Plt.arrows!(ax, x, y, z, u * arrowheadpos, v * arrowheadpos, w * arrowheadpos; linewidth=0.05, arrowsize=0.1) + if label + s = arrowheadpos + (1-arrowheadpos)/6 + Plt.text!(ax, x + u*s, y + v*s, z + w*s; text=[string(i) for i in 1:length(x)]) + end +end + +plot_faces!(ax, RefShape; label) = nothing + +function testit(nshape=1) + ip = Nedelec{3,RefHexahedron,1}(); + + fig, ax = plot_refcell(RefHexahedron; vertices=true, edges=true); + vals = refshape_shapevalues(ip, nshape) + lengths = sqrt.(vals[4].^2 + vals[5].^2 + vals[6].^2) + Plt.arrows!(ax, vals...; lengthscale=0.1, arrowsize=0.1, color=lengths) + return fig +end + +# Possible tests +#= +1) Check shape_value(ip, ξ, i) ⋅ v_edge[i] = |shape_value(ip, ξ, i)| (checks alignment) +2) Check ∫ Ni ⋅ v dL = 1 on each edge +3) Check shape_value(ip, ξ, i) ⋅ v_edge[j] = 0 for i≠j +=# \ No newline at end of file From 876bea96747685138e9011f4dafe2176914461ed Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 22 Mar 2024 15:03:05 +0100 Subject: [PATCH 127/145] Disable JET testing on nightly --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 72f7d71e53..b8aadba69c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -17,7 +17,7 @@ if HAS_EXTENSIONS && MODULE_CAN_BE_TYPE_PARAMETER import Metis end -const RUN_JET_TESTS = VERSION >= v"1.9" +const RUN_JET_TESTS = (VERSION >= v"1.9" && isempty(VERSION.prerelease)) # Temporarily disable on nightly since JET fails if RUN_JET_TESTS using JET: @test_call From a2819946ec4675ce6b0428c0f21edb963fc196e4 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 22 Mar 2024 20:02:03 +0100 Subject: [PATCH 128/145] Reenable JET, doesn't help anyways --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index b8aadba69c..72f7d71e53 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -17,7 +17,7 @@ if HAS_EXTENSIONS && MODULE_CAN_BE_TYPE_PARAMETER import Metis end -const RUN_JET_TESTS = (VERSION >= v"1.9" && isempty(VERSION.prerelease)) # Temporarily disable on nightly since JET fails +const RUN_JET_TESTS = VERSION >= v"1.9" if RUN_JET_TESTS using JET: @test_call From 230864ae6b26afd802251ea4bb629b2cff0c7737 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Fri, 22 Mar 2024 21:35:23 +0100 Subject: [PATCH 129/145] Add grid pertubations to interpolation tests --- test/test_interpolations.jl | 59 +++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index d470084e8d..718b99a9a6 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -226,6 +226,37 @@ @test Ferrite.is_discontinuous(d_ip_t) == true end + +tupleshift(t::NTuple{N}, shift::Int) where N = ntuple(i -> t[mod(i - 1 - shift, N) + 1], N) +#tupleshift(t::NTuple, shift::Int) = tuple(circshift(SVector(t), shift)...) +cell_permutations(cell::Quadrilateral) = (Quadrilateral(tupleshift(cell.nodes, shift)) for shift in 0:3) +cell_permutations(cell::Triangle) = ( Triangle(tupleshift(cell.nodes, shift)) for shift in 0:2) +cell_permutations(cell::QuadraticTriangle) = (QuadraticTriangle((tupleshift(cell.nodes[1:3], shift)..., tupleshift(cell.nodes[4:6], shift)...)) for shift in 0:3) + +function cell_permutations(cell::Hexahedron) + idx = ( #Logic on refshape: Select 1st and 2nd vertex (must be neighbours) + # The next follows to create inward vector with RHR, and then 4th is in same plane. + # The last four must be the neighbours on the other plane to the first four (same order) + (1,2,3,4,5,6,7,8), (1,4,8,5,2,3,7,6), (1,5,6,2,4,8,7,3), + (2,1,5,6,3,4,8,7), (2,3,4,1,6,7,8,5), (2,6,7,3,1,5,8,4), + (3,2,6,7,4,1,5,8), (3,4,1,2,7,8,5,6), (3,7,8,4,2,6,5,1), + (4,1,2,3,8,5,6,7), (4,3,7,8,1,2,6,5), (4,8,5,1,3,7,6,1), + (5,1,4,8,6,2,3,7), (5,6,2,1,8,7,3,4), (5,8,7,6,1,4,3,2), + (6,2,1,5,7,3,4,8), (6,5,8,7,2,1,4,3), (6,7,3,2,5,8,4,1), + (7,3,2,6,8,4,1,5), (7,6,5,8,3,2,1,4), (7,8,4,3,6,5,1,2), + (8,4,3,7,5,1,2,6), (8,5,1,4,7,6,2,3), (8,7,6,5,4,3,2,1), + ) + return (Hexahedron(ntuple(i -> cell.nodes[perm[i]], 8)) for perm in idx) +end + +function cell_permutations(cell::Tetrahedron) + idx = ( (1,2,3,4), (1,3,4,2), (1,4,2,3), + (2,1,4,3), (2,3,1,4), (2,4,3,1), + (3,1,2,4), (3,2,4,1), (3,4,1,2), + (4,1,3,2), (4,3,2,1), (4,2,1,3)) + return (Tetrahedron(ntuple(i -> cell.nodes[perm[i]], 4)) for perm in idx) +end + @testset "Hcurl and Hdiv" begin include(joinpath(@__DIR__, "InterpolationTestUtils.jl")) import .InterpolationTestUtils as ITU @@ -242,26 +273,30 @@ end # for 2nd order elements. transfun(x) = typeof(x)(i->sinpi(x[mod(i, length(x))+1]+i/3))/10 transform_coordinates!(grid, x->(x + transfun(x))) - RefShape = Ferrite.getrefshape(getcells(grid, 1)) + cellnr = getncells(grid)÷2 + 1 # Should be a cell in the center + basecell = getcells(grid, cellnr) + RefShape = Ferrite.getrefshape(basecell) for order in (1, 2) for IPT in (Nedelec, RaviartThomas) dim == 3 && order > 1 && continue IPT == RaviartThomas && (dim == 3 || order > 1) && continue - IPT == RaviartThomas && (CT == Hexahedron) && continue + IPT == RaviartThomas && (RefShape == RefHexahedron) && continue transformation_function=transformation_functions[IPT] ip = IPT{dim,RefShape,order}() @testset "$CT, $ip" begin - dh = DofHandler(grid) - add!(dh, :u, ip) - close!(dh) - cellnr = getncells(grid)÷2 + 1 # Should be a cell in the center - for facenr in 1:nfaces(RefShape) - fi = FaceIndex(cellnr, facenr) - # Check continuity of tangential function value - ITU.test_continuity(dh, fi; transformation_function) + for testcell in cell_permutations(basecell) + grid.cells[cellnr] = testcell + dh = DofHandler(grid) + add!(dh, :u, ip) + close!(dh) + for facenr in 1:nfaces(RefShape) + fi = FaceIndex(cellnr, facenr) + # Check continuity of tangential function value + ITU.test_continuity(dh, fi; transformation_function) + end + # Check gradient calculation + ITU.test_gradient(dh, cellnr) end - # Check gradient calculation - ITU.test_gradient(dh, cellnr) end end end From f2278e0f3eb3e226ebca88ca0573777bfa9755fa Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Sat, 23 Mar 2024 00:07:56 +0100 Subject: [PATCH 130/145] Add tests for basic properties and fullfill them --- src/interpolations.jl | 31 +++++++++++------------ test/test_interpolations.jl | 50 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/interpolations.jl b/src/interpolations.jl index 087b1dcf1b..04236b2fa6 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1789,37 +1789,34 @@ but test cases need to be developed first to make sure. No point in implementing guesses that cannot be verified... =# -# https://defelement.com/elements/examples/hexahedron-nedelec1-lagrange-1.html -# TODO: Need to "map" from defelement [0,1] refcell to Ferrite [-1,1], which -# for Nedelec should be scaling with J^-T where J=2I, i.e. divide by 2 -# For RT elements with Hdiv, this should instead be J/det(J) => 2/2^dim, -# i.e. also divide by 2 in 3d, no scaling in 2d, and multiply by 2 in 1d. +# https://defelement.com/elements/examples/hexahedron-nedelec1-lagrange-1.html +# Note: Divide by 2 since J=2I compared to DefElement's reference shape, and mapping is N ⋅ J^-T function shape_value(ip::Nedelec{3,RefHexahedron,1}, ξ::Vec{3,T}, i::Int) where T x, y, z = (ξ + ones(ξ))/2 # Edge 1 (defelement 0, positive) - i == 1 && return Vec(y*z - y - z + 1, zero(T), zero(T)) + i == 1 && return Vec(y*z - y - z + 1, zero(T), zero(T))/2 # Edge 2 (defelement 3, positive) - i == 2 && return Vec(zero(T), x * (1 - z), zero(T)) + i == 2 && return Vec(zero(T), x * (1 - z), zero(T))/2 # Edge 3 (defelement 5, negative) - i == 3 && return Vec(-y*(1-z), zero(T), zero(T)) + i == 3 && return Vec(-y*(1-z), zero(T), zero(T))/2 # Edge 4 (defelement 1, negative) - i == 4 && return Vec(zero(T), - x*z + x + z - 1, zero(T)) + i == 4 && return Vec(zero(T), - x*z + x + z - 1, zero(T))/2 # Edge 5 (defelement 8, positive) - i == 5 && return Vec(z*(1-y), zero(T), zero(T)) + i == 5 && return Vec(z*(1-y), zero(T), zero(T))/2 # Edge 6 (defelement 10, positive) - i == 6 && return Vec(zero(T), x * z, zero(T)) + i == 6 && return Vec(zero(T), x * z, zero(T))/2 # Edge 7 (defelement 11, negative) - i == 7 && return Vec(- y*z, zero(T), zero(T)) + i == 7 && return Vec(- y*z, zero(T), zero(T))/2 # Edge 8 (defelement 9, negative) - i == 8 && return Vec(zero(T), - z * (1 - x), zero(T)) + i == 8 && return Vec(zero(T), - z * (1 - x), zero(T))/2 # Edge 9 (defelement 2, positive) - i == 9 && return Vec(zero(T), zero(T), x*y - x - y + 1) + i == 9 && return Vec(zero(T), zero(T), x*y - x - y + 1)/2 # Edge 10 (defelement 4, positive) - i == 10 && return Vec(zero(T), zero(T), x * (1 - y)) + i == 10 && return Vec(zero(T), zero(T), x * (1 - y))/2 # Edge 11 (defelement 7, positive) - i == 11 && return Vec(zero(T), zero(T), x * y) + i == 11 && return Vec(zero(T), zero(T), x * y)/2 # Edge 12 (defelement 6, positive) - i == 12 && return Vec(zero(T), zero(T), y * (1 - x)) + i == 12 && return Vec(zero(T), zero(T), y * (1 - x))/2 throw(ArgumentError("no shape function $i for interpolation $ip")) end diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index 718b99a9a6..6581649668 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -226,6 +226,56 @@ @test Ferrite.is_discontinuous(d_ip_t) == true end +reference_cell(::Type{RefTriangle}) = Triangle((1,2,3)) +reference_cell(::Type{RefQuadrilateral}) = Quadrilateral((1,2,3,4)) +reference_cell(::Type{RefTetrahedron}) = Tetrahedron((1,2,3,4)) +reference_cell(::Type{RefHexahedron}) = Hexahedron((ntuple(identity, 8))) + +function line_integral(qr::QuadratureRule{RefLine, T}, ip, shape_nr, x0, Δx, L, v, f) where T + s = zero(T) + for (ξ1d, w) in zip(Ferrite.getpoints(qr), Ferrite.getweights(qr)) + ξ = x0 + (ξ1d[1]/2) * Δx + s += (shape_value(ip, ξ, shape_nr) ⋅ v) * (w*L/2) * f((ξ1d[1]+1)/2) + end + return s +end + +# Required properties of shape value Nⱼ of an edge-elements (Hcurl) on an edge with direction v, length L, and dofs ∈ 𝔇 +# 1) Unit property: ∑_{j∈𝔇} ∫(Nⱼ ⋅ v f(s) dS) = 1 +# Where f(s) = 1 for linear interpolation and f(s)=1-s and f(s)=s for 2nd order interpolation (first and second shape function) +# And s is the path parameter ∈[0,1] along the positive direction of the path. +# 2) Zero along other edges: Nⱼ ⋅ v = 0 if j∉𝔇 +@testset "Nedelec" begin + lineqr = QuadratureRule{RefLine}(20) + for ip in (Nedelec{2,RefTriangle,1}(), Nedelec{2,RefTriangle,2}(), Nedelec{3,RefTetrahedron,1}(), Nedelec{3,RefHexahedron,1}()) + cell = reference_cell(getrefshape(ip)) + edges = Ferrite.getdim(ip) == 2 ? Ferrite.faces(cell) : Ferrite.edges(cell) + dofs = Ferrite.getdim(ip) == 2 ? Ferrite.facedof_interior_indices(ip) : Ferrite.edgedof_interior_indices(ip) + x = Ferrite.reference_coordinates(Ferrite.default_interpolation(typeof(cell))) + @testset "$(getrefshape(ip)), order=$(Ferrite.getorder(ip))" begin + for (edge_nr, (i1, i2)) in enumerate(edges) + Δx = x[i2]-x[i1] + x0 = (x[i1]+x[i2])/2 + L = norm(Δx) + v = Δx/L + for (idof, shape_nr) in enumerate(dofs[edge_nr]) + nedgedofs = length(dofs[edge_nr]) + f(x) = nedgedofs == 1 ? 1.0 : (idof == 1 ? 1-x : x) + s = line_integral(lineqr, ip, shape_nr, x0, Δx, L, v, f) + @test s ≈ one(s) + end + for (j_edge, shape_nrs) in enumerate(dofs) + j_edge == edge_nr && continue + for shape_nr in shape_nrs + for ξ in (x[i1] + r*Δx for r in [0.0, rand(3)..., 1.0]) + @test abs(shape_value(ip, ξ, shape_nr) ⋅ v) < eps()*100 + end + end + end + end + end + end +end tupleshift(t::NTuple{N}, shift::Int) where N = ntuple(i -> t[mod(i - 1 - shift, N) + 1], N) #tupleshift(t::NTuple, shift::Int) = tuple(circshift(SVector(t), shift)...) From 4567f0c2e6eeb6a68ad7bc79b0ec073fc280bac5 Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Mon, 19 Aug 2024 12:26:47 +0200 Subject: [PATCH 131/145] Fix merge errors --- .../literate-tutorials/heat_equation_rt.jl | 48 ++++----- .../heat_equation_triangle.jl | 4 +- src/interpolations.jl | 97 +++++++++---------- src/iterators.jl | 2 +- test/InterpolationTestUtils.jl | 70 ++++++------- test/test_interpolations.jl | 22 ++--- 6 files changed, 120 insertions(+), 123 deletions(-) diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl index 25bcb5999b..3d6fb2cacf 100644 --- a/docs/src/literate-tutorials/heat_equation_rt.jl +++ b/docs/src/literate-tutorials/heat_equation_rt.jl @@ -7,7 +7,7 @@ # \boldsymbol{q}\cdot \boldsymbol{n} = q_n \in \Gamma_\mathrm{N}\\ # u = u_\mathrm{D} \in \Gamma_\mathrm{D} # ``` -# +# # ## Weak form # ### Part 1 # ```math @@ -15,13 +15,13 @@ # \int_{\Gamma} \delta u \boldsymbol{n} \cdot \boldsymbol{q}\ \mathrm{d}\Gamma - # \int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ # ``` -# +# # ### Part 2 # ```math # \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega = - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega # ``` -# where no Green-Gauss theorem is applied. -# +# where no Green-Gauss theorem is applied. +# # ### Summary # The weak form becomes, find $u\in H^1$ and $\boldsymbol{q} \in H\mathrm{(div)}$, such that # ```math @@ -34,7 +34,7 @@ # \quad \forall\ \boldsymbol{\delta q} \in \delta H\mathrm{(div)} # \end{align*} # ``` -# +# # ## Commented Program # # Now we solve the problem in Ferrite. What follows is a program spliced with comments. @@ -56,11 +56,11 @@ grid = generate_grid(Triangle, (20, 20)); # based on the two-dimensional reference quadrilateral. We also define a quadrature rule based on # the same reference element. We combine the interpolation and the quadrature rule # to a `CellValues` object. -ip_geo = Ferrite.default_interpolation(getcelltype(grid)) +ip_geo = geometric_interpolation(getcelltype(grid)) ipu = Lagrange{RefTriangle, 1}() # Why does it "explode" for 2nd order ipu? ipq = RaviartThomas{2,RefTriangle,1}() qr = QuadratureRule{RefTriangle}(2) -cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) +cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) # ### Degrees of freedom # Next we need to define a `DofHandler`, which will take care of numbering @@ -77,7 +77,7 @@ close!(dh); # Now that we have distributed all our dofs we can create our tangent matrix, # using `create_sparsity_pattern`. This function returns a sparse matrix # with the correct entries stored. -K = create_sparsity_pattern(dh) +K = allocate_matrix(dh) # ### Boundary conditions # In Ferrite constraints like Dirichlet boundary conditions @@ -86,12 +86,12 @@ ch = ConstraintHandler(dh); # Next we need to add constraints to `ch`. For this problem we define # homogeneous Dirichlet boundary conditions on the whole boundary, i.e. -# the `union` of all the face sets on the boundary. +# the `union` of all the boundary facet sets. ∂Ω = union( - getfaceset(grid, "left"), - getfaceset(grid, "right"), - getfaceset(grid, "top"), - getfaceset(grid, "bottom"), + getfacetset(grid, "left"), + getfacetset(grid, "right"), + getfacetset(grid, "top"), + getfacetset(grid, "bottom"), ); # Now we are set up to define our constraint. We specify which field @@ -241,12 +241,12 @@ u = K \ f; # to a VTK-file, which can be viewed in e.g. [ParaView](https://www.paraview.org/). u_nodes = evaluate_at_grid_nodes(dh, u, :u) ∂Ω_cells = zeros(Int, getncells(grid)) -for (cellnr, facenr) in ∂Ω +for (cellnr, _) in ∂Ω ∂Ω_cells[cellnr] = 1 end -vtk_grid("heat_equation_rt", dh) do vtk - vtk_point_data(vtk, u_nodes, "u") - vtk_cell_data(vtk, ∂Ω_cells, "dO") +VTKGridFile("heat_equation_rt", dh) do vtk + write_node_data(vtk, u_nodes, "u") + write_cell_data(vtk, ∂Ω_cells, "dO") end @show norm(u_nodes)/length(u_nodes) @@ -254,10 +254,10 @@ end # ## Postprocess the total flux function calculate_flux(dh, dΩ, ip, a) grid = dh.grid - qr = FaceQuadratureRule{RefTriangle}(4) - ip_geo = Ferrite.default_interpolation(getcelltype(grid)) - fv = FaceValues(qr, ip, ip_geo) - + qr = FacetQuadratureRule{RefTriangle}(4) + ip_geo = geometric_interpolation(getcelltype(grid)) + fv = FacetValues(qr, ip, ip_geo) + dofrange = dof_range(dh, :q) flux = 0.0 dofs = celldofs(dh, 1) @@ -281,9 +281,9 @@ end function calculate_flux_lag(dh, dΩ, ip, a) grid = dh.grid - qr = FaceQuadratureRule{RefTriangle}(4) - ip_geo = Ferrite.default_interpolation(getcelltype(grid)) - fv = FaceValues(qr, ip, ip_geo) + qr = FacetQuadratureRule{RefTriangle}(4) + ip_geo = geometric_interpolation(getcelltype(grid)) + fv = FacetValues(qr, ip, ip_geo) dofrange = dof_range(dh, :u) flux = 0.0 dofs = celldofs(dh, 1) diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl index 414a7f9195..28234d4ade 100644 --- a/docs/src/literate-tutorials/heat_equation_triangle.jl +++ b/docs/src/literate-tutorials/heat_equation_triangle.jl @@ -216,8 +216,8 @@ end # ### Postprocessing the total flux function calculate_flux_lag(dh, dΩ, ip, a) - qr = FaceQuadratureRule{RefTriangle}(2) - fv = FaceValues(qr, ip, Lagrange{RefTriangle,1}()) + qr = FacetQuadratureRule{RefTriangle}(2) + fv = FacetValues(qr, ip, Lagrange{RefTriangle,1}()) grid = dh.grid dofrange = dof_range(dh, :u) flux = 0.0 diff --git a/src/interpolations.jl b/src/interpolations.jl index a29f4e0ba7..4086ef8b66 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -253,7 +253,7 @@ Optimized version combining the evaluation [`Ferrite.shape_value(::Interpolation [`Ferrite.shape_gradient(::Interpolation)`](@ref), and the gradient of the latter. """ function shape_hessian_gradient_and_value(ip::Interpolation, ξ::Vec, i::Int) - return hessian(x -> shape_value(ip, x, i), ξ, :all) + return hessian(x -> reference_shape_value(ip, x, i), ξ, :all) end """ @@ -1739,7 +1739,7 @@ n_dbc_components(::RaviartThomas) = 1 # RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-raviart-thomas-lagrange-1.html # Signs changed when needed to make positive direction outwards -function shape_value(ip::RaviartThomas{2,RefTriangle,1}, ξ::Vec{2}, i::Int) +function reference_shape_value(ip::RaviartThomas{2, RefTriangle, 1}, ξ::Vec{2}, i::Int) x, y = ξ i == 1 && return ξ # Flip sign i == 2 && return Vec(x-1, y) # Keep sign @@ -1747,13 +1747,13 @@ function shape_value(ip::RaviartThomas{2,RefTriangle,1}, ξ::Vec{2}, i::Int) throw(ArgumentError("no shape function $i for interpolation $ip")) end -getnbasefunctions(::RaviartThomas{2,RefTriangle,1}) = 3 -facedof_interior_indices(::RaviartThomas{2,RefTriangle,1}) = ((1,), (2,), (3,)) +getnbasefunctions(::RaviartThomas{2, RefTriangle, 1}) = 3 +edgedof_interior_indices(::RaviartThomas{2, RefTriangle, 1}) = ((1,), (2,), (3,)) adjust_dofs_during_distribution(::RaviartThomas) = false function get_direction(::RaviartThomas{2,RefTriangle,1}, j, cell) - face_vertices = faces(cell)[j] - return face_vertices[2] > face_vertices[1] ? 1 : -1 + edge = edges(cell)[j] + return ifelse(edge[2] > edge[1], 1, -1) end # RefTriangle, 2st order Lagrange @@ -1767,11 +1767,11 @@ Vertex numbers: | Vertex coordinates: | 3-------1 | +--> ξ₁ | ----------------+-------------------- -Face numbers: | Face identifiers: +Edge numbers: | Edge identifiers: + | - | \ | f1: (v1, v2) - 2 1 | f2: (v2, v3) - | \ | f3: (v3, v1) + | \ | e1: (v1, v2) + 2 1 | e2: (v2, v3) + | \ | e3: (v3, v1) +---3---+ | ----------------+-------------------- ``` @@ -1780,7 +1780,7 @@ RefTriangle =# # https://defelement.com/elements/examples/triangle-raviart-thomas-lagrange-2.html # Signs changed when needed to make positive direction outwards -function shape_value(ip::RaviartThomas{2,RefTriangle,2}, ξ::Vec{2}, i::Int) +function reference_shape_value(ip::RaviartThomas{2, RefTriangle, 2}, ξ::Vec{2}, i::Int) x, y = ξ # Face 1 (keep ordering, flip sign) i == 1 && return Vec(4x*(2x-1), 2y*(4x-1)) @@ -1798,18 +1798,16 @@ function shape_value(ip::RaviartThomas{2,RefTriangle,2}, ξ::Vec{2}, i::Int) end getnbasefunctions(::RaviartThomas{2,RefTriangle,2}) = 8 -facedof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = ((1, 2), (3, 4), (5, 6)) -celldof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = (7,8) +edgedof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = ((1, 2), (3, 4), (5, 6)) +volumedof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = (7,8) adjust_dofs_during_distribution(::RaviartThomas{2,RefTriangle,2}) = true -function get_direction(::RaviartThomas{2,RefTriangle,2}, j, cell) - j>6 && return 1 - facenr = (j+1)÷2 - face_vertices = faces(cell)[facenr] - return face_vertices[2] > face_vertices[1] ? 1 : -1 +function get_direction(::RaviartThomas{2, RefTriangle, 2}, j, cell) + j > 6 && return 1 + edge = edges(cell)[(j + 1) ÷ 2] + return ifelse(edge[2] > edge[1], 1, -1) end - ##################################### # Nedelec (1st kind), H(curl) # ##################################### @@ -1820,7 +1818,7 @@ dirichlet_facedof_indices(ip::Nedelec) = facedof_interior_indices(ip) n_dbc_components(::Nedelec) = 1 # RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-1.html -function shape_value(ip::Nedelec{2,RefTriangle,1}, ξ::Vec{2}, i::Int) +function reference_shape_value(ip::Nedelec{2,RefTriangle,1}, ξ::Vec{2}, i::Int) x, y = ξ i == 1 && return Vec( - y, x) i == 2 && return Vec( - y, x - 1) # Changed signed, follow Ferrite's sign convention @@ -1828,18 +1826,18 @@ function shape_value(ip::Nedelec{2,RefTriangle,1}, ξ::Vec{2}, i::Int) throw(ArgumentError("no shape function $i for interpolation $ip")) end -getnbasefunctions(::Nedelec{2,RefTriangle,1}) = 3 -facedof_interior_indices(::Nedelec{2,RefTriangle,1}) = ((1,), (2,), (3,)) -adjust_dofs_during_distribution(::Nedelec{2,RefTriangle,1}) = false +getnbasefunctions(::Nedelec{2, RefTriangle, 1}) = 3 +edgedof_interior_indices(::Nedelec{2, RefTriangle, 1}) = ((1,), (2,), (3,)) +adjust_dofs_during_distribution(::Nedelec{2, RefTriangle, 1}) = false -function get_direction(::Nedelec{2,RefTriangle,1}, j, cell) - face_vertices = faces(cell)[j] - return face_vertices[2] > face_vertices[1] ? 1 : -1 +function get_direction(::Nedelec{2, RefTriangle, 1}, j, cell) + edge = edges(cell)[j] + return ifelse(edge[2] > edge[1], 1, -1) end # RefTriangle, 2nd order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-2.html -function shape_value(ip::Nedelec{2,RefTriangle,2}, ξ::Vec{2}, i::Int) +function reference_shape_value(ip::Nedelec{2,RefTriangle,2}, ξ::Vec{2}, i::Int) x, y = ξ # Face 1 i == 1 && return Vec( 2*y*(1 - 4*x), @@ -1864,20 +1862,19 @@ function shape_value(ip::Nedelec{2,RefTriangle,2}, ξ::Vec{2}, i::Int) throw(ArgumentError("no shape function $i for interpolation $ip")) end -getnbasefunctions(::Nedelec{2,RefTriangle,2}) = 8 -facedof_interior_indices(::Nedelec{2,RefTriangle,2}) = ((1,2), (3,4), (5,6)) -celldof_interior_indices(::Nedelec{2,RefTriangle,2}) = (7,8) -adjust_dofs_during_distribution(::Nedelec{2,RefTriangle,2}) = true +getnbasefunctions(::Nedelec{2, RefTriangle, 2}) = 8 +edgedof_interior_indices(::Nedelec{2, RefTriangle, 2}) = ((1,2), (3,4), (5,6)) +volumedof_interior_indices(::Nedelec{2, RefTriangle, 2}) = (7,8) +adjust_dofs_during_distribution(::Nedelec{2, RefTriangle, 2}) = true -function get_direction(::Nedelec{2,RefTriangle,2}, j, cell) - j>6 && return 1 - facenr = (j+1)÷2 - face_vertices = faces(cell)[facenr] - return face_vertices[2] > face_vertices[1] ? 1 : -1 +function get_direction(::Nedelec{2, RefTriangle, 2}, j, cell) + j > 6 && return 1 + edge = edges(cell)[(j + 1) ÷ 2] + return ifelse(edge[2] > edge[1], 1, -1) end # https://defelement.com/elements/examples/tetrahedron-nedelec1-lagrange-1.html -function shape_value(ip::Nedelec{3,RefTetrahedron,1}, ξ::Vec{3,T}, i::Int) where T +function reference_shape_value(ip::Nedelec{3, RefTetrahedron, 1}, ξ::Vec{3, T}, i::Int) where T x, y, z = ξ # Edge 1 (defelement 5, positive) i == 1 && return Vec(- y - z + 1, x, x) @@ -1895,13 +1892,13 @@ function shape_value(ip::Nedelec{3,RefTetrahedron,1}, ξ::Vec{3,T}, i::Int) wher throw(ArgumentError("no shape function $i for interpolation $ip")) end -getnbasefunctions(::Nedelec{3,RefTetrahedron,1}) = 6 -edgedof_interior_indices(::Nedelec{3,RefTetrahedron,1}) = ntuple(i->(i,), 6) -adjust_dofs_during_distribution(::Nedelec{3,RefTetrahedron,1}) = false +getnbasefunctions(::Nedelec{3, RefTetrahedron, 1}) = 6 +edgedof_interior_indices(::Nedelec{3, RefTetrahedron, 1}) = ntuple(i->(i,), 6) +adjust_dofs_during_distribution(::Nedelec{3, RefTetrahedron, 1}) = false -function get_direction(::Nedelec{3,RefTetrahedron,1}, j, cell) - edge_vertices = edges(cell)[j] - return edge_vertices[2] > edge_vertices[1] ? 1 : -1 +function get_direction(::Nedelec{3, RefTetrahedron, 1}, j, cell) + edge = edges(cell)[j] + return ifelse(edge[2] > edge[1], 1, -1) end # RefTetrahedron, 2nd order Lagrange @@ -1916,7 +1913,7 @@ No point in implementing guesses that cannot be verified... # https://defelement.com/elements/examples/hexahedron-nedelec1-lagrange-1.html # Note: Divide by 2 since J=2I compared to DefElement's reference shape, and mapping is N ⋅ J^-T -function shape_value(ip::Nedelec{3,RefHexahedron,1}, ξ::Vec{3,T}, i::Int) where T +function reference_shape_value(ip::Nedelec{3, RefHexahedron, 1}, ξ::Vec{3, T}, i::Int) where T x, y, z = (ξ + ones(ξ))/2 # Edge 1 (defelement 0, positive) i == 1 && return Vec(y*z - y - z + 1, zero(T), zero(T))/2 @@ -1946,11 +1943,11 @@ function shape_value(ip::Nedelec{3,RefHexahedron,1}, ξ::Vec{3,T}, i::Int) where throw(ArgumentError("no shape function $i for interpolation $ip")) end -getnbasefunctions(::Nedelec{3,RefHexahedron,1}) = 12 -edgedof_interior_indices(::Nedelec{3,RefHexahedron,1}) = ntuple(i->(i,), 12) -adjust_dofs_during_distribution(::Nedelec{3,RefHexahedron,1}) = false +getnbasefunctions(::Nedelec{3, RefHexahedron, 1}) = 12 +edgedof_interior_indices(::Nedelec{3, RefHexahedron, 1}) = ntuple(i->(i,), 12) +adjust_dofs_during_distribution(::Nedelec{3, RefHexahedron, 1}) = false -function get_direction(::Nedelec{3,RefHexahedron,1}, j, cell) - edge_vertices = edges(cell)[j] - return edge_vertices[2] > edge_vertices[1] ? 1 : -1 +function get_direction(::Nedelec{3, RefHexahedron, 1}, j, cell) + edge = edges(cell)[j] + return ifelse(edge[2] > edge[1], 1, -1) end diff --git a/src/iterators.jl b/src/iterators.jl index 0a05e0da5d..570a247c7e 100644 --- a/src/iterators.jl +++ b/src/iterators.jl @@ -92,7 +92,7 @@ end # TODO: Should we provide a fast path if the cell is not required for reinit? #reinit!(cv::CellValues, cc::CellCache) = reinit!(cv, cc.coords) reinit!(cv::CellValues, cc::CellCache) = reinit!(cv, getcells(cc.grid, cellid(cc)), cc.coords) -reinit!(fv::FaceValues, cc::CellCache, f::Int) = reinit!(fv, cc.coords, f) # TODO: Deprecate? +reinit!(fv::FacetValues, cc::CellCache, f::Int) = reinit!(fv, cc.coords, f) # TODO: Deprecate? # Accessor functions (TODO: Deprecate? We are so inconsistent with `getxx` vs `xx`...) diff --git a/test/InterpolationTestUtils.jl b/test/InterpolationTestUtils.jl index 563241e042..a983edacc9 100644 --- a/test/InterpolationTestUtils.jl +++ b/test/InterpolationTestUtils.jl @@ -4,85 +4,85 @@ module InterpolationTestUtils import LinearAlgebra: normalize import Random: randperm - function find_matching_face(grid, face::FaceIndex) - cell, facenr = face - face_vertices = Set(Ferrite.faces(getcells(grid, cell))[facenr]) + function find_matching_facet(grid, facet::FacetIndex) + cell, facetnr = facet + facet_vertices = Set(Ferrite.facets(getcells(grid, cell))[facetnr]) for cnr in 1:getncells(grid) cnr == cell && continue - for (i, f_vert) in enumerate(Ferrite.faces(getcells(grid, cnr))) - face_vertices == Set(f_vert) && return FaceIndex(cnr, i) + for (i, f_vert) in enumerate(Ferrite.facets(getcells(grid, cnr))) + facet_vertices == Set(f_vert) && return FacetIndex(cnr, i) end end return nothing end - - function test_continuity(dh::DofHandler, face::FaceIndex; + + function test_continuity(dh::DofHandler, facet::FacetIndex; transformation_function::Function=identity, value_function::Function=function_value) # transformation_function: (v,n) -> z - # Examples + # Examples # * Tangential continuity: fun(v, n) = v - (v ⋅ n)*n # * Normal continuity: fun(v, n) = v ⋅ n # value_function: (fe_v, q_point, ue) -> z - + # Check validity of input @assert length(dh.subdofhandlers) == 1 @assert length(Ferrite.getfieldnames(dh)) == 1 - + # Find the matching FaceIndex - cellnr, facenr = face - face2 = find_matching_face(dh.grid, face) - face2 === nothing && return false - - # Pick "random" points on the face + cellnr, facetnr = facet + facet2 = find_matching_facet(dh.grid, facet) + facet2 === nothing && return false + + # Pick "random" points on the facet cell = getcells(dh.grid, cellnr) RefShape = Ferrite.getrefshape(getcells(dh.grid, cellnr)) - ip_geo = Ferrite.default_interpolation(typeof(cell)) + ip_geo = geometric_interpolation(typeof(cell)) ip_fun = Ferrite.getfieldinterpolation(dh, (1,1)) - fqr = FaceQuadratureRule{RefShape}(10) - fv = FaceValues(fqr, ip_fun, ip_geo) + fqr = FacetQuadratureRule{RefShape}(8) + fv = FacetValues(fqr, ip_fun, ip_geo) cell_coords = getcoordinates(dh.grid, cellnr) inds = randperm(getnquadpoints(fv))[1:min(4, getnquadpoints(fv))] - - # Random dof vector to test continuity + + # Random dof vector to test continuity u = rand(ndofs(dh)) - + # Calculate coordinates and function values for these point_coords = zeros(eltype(cell_coords), length(inds)) point_normal = similar(point_coords) fun_vals = zeros(typeof(shape_value(fv, 1, 1)), length(inds)) - reinit!(fv, cell, cell_coords, facenr) + reinit!(fv, cell, cell_coords, facetnr) ue = u[celldofs(dh, cellnr)] for (i, q_point) in enumerate(inds) point_coords[i] = spatial_coordinate(fv, q_point, cell_coords) point_normal[i] = getnormal(fv, q_point) fun_vals[i] = value_function(fv, q_point, ue) end - + # Calculate function values on the other cell - cell2 = getcells(dh.grid, face2[1]) - cell_coords2 = getcoordinates(dh.grid, face2[1]) - local_coords = map(x->Ferrite.find_local_coordinate(ip_geo, cell_coords2, x), point_coords) + cell2 = getcells(dh.grid, facet2[1]) + cell_coords2 = getcoordinates(dh.grid, facet2[1]) + local_coords = map(x->Ferrite.find_local_coordinate(ip_geo, cell_coords2, x, Ferrite.NewtonLineSearchPointFinder()), point_coords) @assert all(first.(local_coords)) # check that find_local_coordinate converged ξs = collect(last.(local_coords)) # Extract the local coordinates qr = QuadratureRule{RefShape}(zeros(length(ξs)), ξs) cv = CellValues(qr, ip_fun, ip_geo) reinit!(cv, cell2, cell_coords2) fun_vals2 = similar(fun_vals) - ue2 = u[celldofs(dh, face2[1])] + ue2 = u[celldofs(dh, facet2[1])] for q_point in 1:getnquadpoints(cv) @assert spatial_coordinate(cv, q_point, cell_coords2) ≈ point_coords[q_point] fun_vals2[q_point] = value_function(cv, q_point, ue2) end - - d1 = map((v,n)->transformation_function(v,n), fun_vals, point_normal) + + d1 = map((v,n)->transformation_function(v,n), fun_vals, point_normal) d2 = map((v,n)->transformation_function(v,n), fun_vals2, point_normal) - @test isapprox(d1, d2; rtol=1e-6) # Approximate points can contribute to the inexactness + @test isapprox(d1, d2; rtol=1e-6) # Approximate points can contribute to the inexactness return true end - + function create_gradcheck_qr(ip_geo::Interpolation{RefShape}, ΔL) where RefShape - dim = Ferrite.getdim(ip_geo) + dim = Ferrite.getrefdim(ip_geo) xref = Ferrite.reference_coordinates(ip_geo) xc = sum(xref)/length(xref) ws = rand(length(xref))*((1-ΔL)/length(xref)) @@ -93,12 +93,12 @@ module InterpolationTestUtils qr_x = [xp, x1] return QuadratureRule{RefShape}(qr_w, qr_x) end - + function test_gradient(dh, cellnr; ΔL=1e-6) ue = rand(ndofs_per_cell(dh, cellnr)) x = getcoordinates(dh.grid, cellnr) cell = getcells(dh.grid, cellnr) - ip_geo = Ferrite.default_interpolation(typeof(cell)) + ip_geo = geometric_interpolation(typeof(cell)) ip_fun = Ferrite.getfieldinterpolation(dh, (1,1)) qr = create_gradcheck_qr(ip_geo, ΔL) cv = CellValues(qr, ip_fun, ip_geo) @@ -113,4 +113,4 @@ module InterpolationTestUtils return nothing end -end \ No newline at end of file +end diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index d22a1c9f28..0ef4483c50 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -229,11 +229,11 @@ reference_cell(::Type{RefQuadrilateral}) = Quadrilateral((1,2,3,4)) reference_cell(::Type{RefTetrahedron}) = Tetrahedron((1,2,3,4)) reference_cell(::Type{RefHexahedron}) = Hexahedron((ntuple(identity, 8))) -function line_integral(qr::QuadratureRule{RefLine, T}, ip, shape_nr, x0, Δx, L, v, f) where T - s = zero(T) +function line_integral(qr::QuadratureRule{RefLine}, ip, shape_nr, x0, Δx, L, v, f) + s = 0.0 for (ξ1d, w) in zip(Ferrite.getpoints(qr), Ferrite.getweights(qr)) ξ = x0 + (ξ1d[1]/2) * Δx - s += (shape_value(ip, ξ, shape_nr) ⋅ v) * (w*L/2) * f((ξ1d[1]+1)/2) + s += (reference_shape_value(ip, ξ, shape_nr) ⋅ v) * (w*L/2) * f((ξ1d[1]+1)/2) end return s end @@ -247,9 +247,9 @@ end lineqr = QuadratureRule{RefLine}(20) for ip in (Nedelec{2,RefTriangle,1}(), Nedelec{2,RefTriangle,2}(), Nedelec{3,RefTetrahedron,1}(), Nedelec{3,RefHexahedron,1}()) cell = reference_cell(getrefshape(ip)) - edges = Ferrite.getdim(ip) == 2 ? Ferrite.faces(cell) : Ferrite.edges(cell) - dofs = Ferrite.getdim(ip) == 2 ? Ferrite.facedof_interior_indices(ip) : Ferrite.edgedof_interior_indices(ip) - x = Ferrite.reference_coordinates(Ferrite.default_interpolation(typeof(cell))) + edges = Ferrite.edges(cell) + dofs = Ferrite.edgedof_interior_indices(ip) + x = Ferrite.reference_coordinates(geometric_interpolation(typeof(cell))) @testset "$(getrefshape(ip)), order=$(Ferrite.getorder(ip))" begin for (edge_nr, (i1, i2)) in enumerate(edges) Δx = x[i2]-x[i1] @@ -266,7 +266,7 @@ end j_edge == edge_nr && continue for shape_nr in shape_nrs for ξ in (x[i1] + r*Δx for r in [0.0, rand(3)..., 1.0]) - @test abs(shape_value(ip, ξ, shape_nr) ⋅ v) < eps()*100 + @test abs(reference_shape_value(ip, ξ, shape_nr) ⋅ v) < eps()*100 end end end @@ -313,7 +313,7 @@ end Nedelec=>(v,n)-> v - n*(v⋅n), # Hcurl (tangent continuity) RaviartThomas=>(v,n) -> v ⋅ n) # Hdiv (normal continuity) for CT in (Triangle, QuadraticTriangle, Tetrahedron, Hexahedron) - dim = Ferrite.getdim(CT) + dim = Ferrite.getrefdim(CT) # dim = sdim = rdim p1, p2 = (rand(Vec{dim}), ones(Vec{dim})+rand(Vec{dim})) grid = generate_grid(CT, ntuple(_->nel, dim), p1, p2) # Smoothly distort grid (to avoid spuriously badly deformed elements). @@ -330,15 +330,15 @@ end IPT == RaviartThomas && (dim == 3 || order > 1) && continue IPT == RaviartThomas && (RefShape == RefHexahedron) && continue transformation_function=transformation_functions[IPT] - ip = IPT{dim,RefShape,order}() + ip = IPT{dim, RefShape, order}() @testset "$CT, $ip" begin for testcell in cell_permutations(basecell) grid.cells[cellnr] = testcell dh = DofHandler(grid) add!(dh, :u, ip) close!(dh) - for facenr in 1:nfaces(RefShape) - fi = FaceIndex(cellnr, facenr) + for facetnr in 1:nfacets(RefShape) + fi = FacetIndex(cellnr, facetnr) # Check continuity of tangential function value ITU.test_continuity(dh, fi; transformation_function) end From d2a9699635c9b482cce15ca98f0f631a493392c1 Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Tue, 29 Oct 2024 21:27:07 +0100 Subject: [PATCH 132/145] Add some refs --- .../literate-tutorials/heat_equation_rt.jl | 27 ++++++++++++++++++- .../heat_equation_triangle.jl | 14 +++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl index 3d6fb2cacf..48f6fee6f4 100644 --- a/docs/src/literate-tutorials/heat_equation_rt.jl +++ b/docs/src/literate-tutorials/heat_equation_rt.jl @@ -1,4 +1,29 @@ # # [Heat equation (Mixed, RaviartThomas)](@id tutorial-heat-equation-rt) +# Note, there are a lot to consider here it seems like. Good ref, +# @book{Gatica2014, +# title = {A Simple Introduction to the Mixed Finite Element Method: Theory and Applications}, +# ISBN = {9783319036953}, +# ISSN = {2191-8201}, +# url = {http://dx.doi.org/10.1007/978-3-319-03695-3}, +# DOI = {10.1007/978-3-319-03695-3}, +# journal = {SpringerBriefs in Mathematics}, +# publisher = {Springer International Publishing}, +# author = {Gatica, Gabriel N.}, +# year = {2014} +# } +# See also, +# @book{Boffi2013, +# title = {Mixed Finite Element Methods and Applications}, +# ISBN = {9783642365195}, +# ISSN = {0179-3632}, +# url = {http://dx.doi.org/10.1007/978-3-642-36519-5}, +# DOI = {10.1007/978-3-642-36519-5}, +# journal = {Springer Series in Computational Mathematics}, +# publisher = {Springer Berlin Heidelberg}, +# author = {Boffi, Daniele and Brezzi, Franco and Fortin, Michel}, +# year = {2013} +# } +# for a(n even) more comprehensive book. # # ## Strong form # ```math @@ -58,7 +83,7 @@ grid = generate_grid(Triangle, (20, 20)); # to a `CellValues` object. ip_geo = geometric_interpolation(getcelltype(grid)) ipu = Lagrange{RefTriangle, 1}() # Why does it "explode" for 2nd order ipu? -ipq = RaviartThomas{2,RefTriangle,1}() +ipq = RaviartThomas{2,RefTriangle, 1}() qr = QuadratureRule{RefTriangle}(2) cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl index 28234d4ade..52d463b108 100644 --- a/docs/src/literate-tutorials/heat_equation_triangle.jl +++ b/docs/src/literate-tutorials/heat_equation_triangle.jl @@ -67,7 +67,7 @@ close!(dh); # Now that we have distributed all our dofs we can create our tangent matrix, # using `create_sparsity_pattern`. This function returns a sparse matrix # with the correct entries stored. -K = create_sparsity_pattern(dh) +K = allocate_matrix(dh) # ### Boundary conditions # In Ferrite constraints like Dirichlet boundary conditions @@ -78,10 +78,10 @@ ch = ConstraintHandler(dh); # homogeneous Dirichlet boundary conditions on the whole boundary, i.e. # the `union` of all the face sets on the boundary. ∂Ω = union( - getfaceset(grid, "left"), - getfaceset(grid, "right"), - getfaceset(grid, "top"), - getfaceset(grid, "bottom"), + getfacetset(grid, "left"), + getfacetset(grid, "right"), + getfacetset(grid, "top"), + getfacetset(grid, "bottom"), ); # Now we are set up to define our constraint. We specify which field @@ -207,8 +207,8 @@ u = K \ f; # ### Exporting to VTK # To visualize the result we export the grid and our field `u` # to a VTK-file, which can be viewed in e.g. [ParaView](https://www.paraview.org/). -vtk_grid("heat_equation", dh) do vtk - vtk_point_data(vtk, dh, u) +VTKGridFile("heat_equation", dh) do vtk + write_solution(vtk, dh, u) end @show norm(u)/length(u) From 35529ec242e0ef0d9239ab17be6e50e0b211e3f1 Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Thu, 31 Oct 2024 18:47:19 +0100 Subject: [PATCH 133/145] Fix formatting using pre-commit --- visualization/reference_cell_ip.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/visualization/reference_cell_ip.jl b/visualization/reference_cell_ip.jl index b43cc6a8a0..d60e354674 100644 --- a/visualization/reference_cell_ip.jl +++ b/visualization/reference_cell_ip.jl @@ -77,9 +77,9 @@ function testit(nshape=1) return fig end -# Possible tests -#= +# Possible tests +#= 1) Check shape_value(ip, ξ, i) ⋅ v_edge[i] = |shape_value(ip, ξ, i)| (checks alignment) -2) Check ∫ Ni ⋅ v dL = 1 on each edge -3) Check shape_value(ip, ξ, i) ⋅ v_edge[j] = 0 for i≠j -=# \ No newline at end of file +2) Check ∫ Ni ⋅ v dL = 1 on each edge +3) Check shape_value(ip, ξ, i) ⋅ v_edge[j] = 0 for i≠j +=# From fa2a3176fa871617a82429ef80bdba77301e546f Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Fri, 1 Nov 2024 19:52:50 +0100 Subject: [PATCH 134/145] Started adding BrezziDouglasMarini --- docs/liveserver.jl | 2 +- .../literate-tutorials/heat_equation_rt.jl | 82 +- .../heat_equation_triangle.jl | 1 - src/interpolations.jl | 53 +- test/test_interpolations.jl | 53 +- .../2d_vector_interpolation_checkplots.jl | 23 + visualization/Manifest.toml | 978 ++++++++---------- visualization/Project.toml | 3 +- 8 files changed, 603 insertions(+), 592 deletions(-) create mode 100644 visualization/2d_vector_interpolation_checkplots.jl diff --git a/docs/liveserver.jl b/docs/liveserver.jl index a589e910c1..c1e83b4de9 100755 --- a/docs/liveserver.jl +++ b/docs/liveserver.jl @@ -14,7 +14,7 @@ push!(ARGS, "liveserver") # Run LiveServer.servedocs(...) import LiveServer LiveServer.servedocs(; - host = "0.0.0.0", + # host = "0.0.0.0", # Documentation root where make.jl and src/ are located foldername = joinpath(repo_root, "docs"), # Extra source folder to watch for changes diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl index 48f6fee6f4..2d22955038 100644 --- a/docs/src/literate-tutorials/heat_equation_rt.jl +++ b/docs/src/literate-tutorials/heat_equation_rt.jl @@ -1,5 +1,6 @@ # # [Heat equation (Mixed, RaviartThomas)](@id tutorial-heat-equation-rt) -# Note, there are a lot to consider here it seems like. Good ref, +# Note, there are a lot to consider here it seems like. Good refs, +# ``` # @book{Gatica2014, # title = {A Simple Introduction to the Mixed Finite Element Method: Theory and Applications}, # ISBN = {9783319036953}, @@ -24,54 +25,63 @@ # year = {2013} # } # for a(n even) more comprehensive book. -# -# ## Strong form -# ```math -# \nabla \cdot \boldsymbol{q} = h \in \Omega \\ -# \boldsymbol{q} = - k\ \nabla u \in \Omega \\ -# \boldsymbol{q}\cdot \boldsymbol{n} = q_n \in \Gamma_\mathrm{N}\\ -# u = u_\mathrm{D} \in \Gamma_\mathrm{D} -# ``` -# -# ## Weak form -# ### Part 1 -# ```math -# \int_{\Omega} \delta u \nabla \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ -# \int_{\Gamma} \delta u \boldsymbol{n} \cdot \boldsymbol{q}\ \mathrm{d}\Gamma - -# \int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega = \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega \\ # ``` # -# ### Part 2 +# ## Theory +# We start with the strong form of the heat equation: Find the temperature, $u(\boldsymbol{x})$, and heat flux, $\boldsymbol{q}(x)$, +# such that # ```math -# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega = - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega +# \begin{align*} +# \boldsymbol{\nabla}\cdot \boldsymbol{q} &= h(\boldsymbol{x}), \quad \forall \boldsymbol{x} \in \Omega \\ +# \boldsymbol{q}(\boldsymbol{x}) &= - k\ \boldsymbol{\nabla} u(\boldsymbol{x}), \quad \forall \boldsymbol{x} \in \Omega \\ +# \boldsymbol{q}(\boldsymbol{x})\cdot \boldsymbol{n}(\boldsymbol{x}) &= q_n, \quad \forall \boldsymbol{x} \in \Gamma_\mathrm{N}\\ +# u(\boldsymbol{x}) &= u_\mathrm{D}, \quad \forall \boldsymbol{x} \in \Gamma_\mathrm{D} +# \end{align*} # ``` -# where no Green-Gauss theorem is applied. # -# ### Summary -# The weak form becomes, find $u\in H^1$ and $\boldsymbol{q} \in H\mathrm{(div)}$, such that +# From this strong form, we can formulate the weak form as a mixed formulation. +# Find $u \in \mathbb{U}$ and $\boldsymbol{q}\in\mathbb{Q}$ such that # ```math # \begin{align*} -# -\int_{\Omega} \nabla (\delta u) \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= \int_{\Omega} \delta u\ h\ \mathrm{d}\Omega - -# \int_{\Gamma} \delta u\ q_\mathrm{n}\ \mathrm{d}\Gamma -# \quad -# \forall\ \delta u \in \delta H^1 \\ -# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= - \int_{\Omega} \boldsymbol{\delta q} \cdot \left[k\ \nabla u\right]\ \mathrm{d}\Omega -# \quad \forall\ \boldsymbol{\delta q} \in \delta H\mathrm{(div)} +# \int_{\Omega} \delta u [\boldsymbol{\nabla} \cdot \boldsymbol{q}]\ \mathrm{d}\Omega &= - \int_\Omega \delta u h\ \mathrm{d}\Omega, \quad \forall\ \delta u \in \delta\mathbb{U} \\ +# %\int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= \int_\Omega \boldsymbol{\delta q} \cdot [k\ \boldsymbol{\nabla} u]\ \mathrm{d}\Omega \\ +# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega + \int_{\Omega} [\boldsymbol{\nabla} \cdot \boldsymbol{\delta q}] k u \ \mathrm{d}\Omega &= +# \int_\Gamma \boldsymbol{\delta q} \cdot \boldsymbol{n} k\ u\ \mathrm{d}\Omega, \quad \forall\ \boldsymbol{\delta q} \in \delta\mathbb{Q} # \end{align*} # ``` +# where we have the function spaces +# * $\mathbb{U} = \delta\mathbb{U} = L^2$ +# * $\mathbb{Q} = \lbrace \boldsymbol{q} \in H(\mathrm{div}) \text{such that} \boldsymbol{q}\cdot\boldsymbol{n} = q_\mathrm{n} \text{ on } \Gamma_\mathrm{D}\rbrace$ +# * $\mathbb{Q} = \lbrace \boldsymbol{q} \in H(\mathrm{div}) \text{such that} \boldsymbol{q}\cdot\boldsymbol{n} = 0 \text{ on } \Gamma_\mathrm{D}\rbrace$ +# +# A stable choice of finite element spaces for this problem on grid with triangles is using +# * `DiscontinuousLagrange{RefTriangle, k-1}` for approximating $L^2$ +# * `BrezziDouglasMarini{RefTriangle, k}` for approximating $H(\mathrm{div})$ +# following [fenics](https://fenicsproject.org/olddocs/dolfin/1.4.0/python/demo/documented/mixed-poisson/python/documentation.html). +# For further details, see Boffi2013. +# We will also see what happens if we instead use `Lagrange` elements which are a subspace of $H^1$ instead of $H(\mathrm{div})$ elements. # # ## Commented Program # # Now we solve the problem in Ferrite. What follows is a program spliced with comments. -#md # The full program, without comments, can be found in the next [section](@ref heat_equation-plain-program). # -# First we load Ferrite, and some other packages we need -using Ferrite, SparseArrays -# We start by generating a simple grid with 20x20 quadrilateral elements -# using `generate_grid`. The generator defaults to the unit square, -# so we don't need to specify the corners of the domain. -#grid = generate_grid(QuadraticTriangle, (20, 20)); -grid = generate_grid(Triangle, (20, 20)); +# First we load Ferrite, +using Ferrite +# And define our grid, representing a channel with a central part having a lower +# conductivity, $k$, than the surrounding. +function create_grid(ny::Int) + width = 10.0 + length = 40.0 + center_width = 5.0 + center_length = 20.0 + upper_right = Vec((length / 2, width / 2)) + grid = generate_grid(Triangle, (round(Int, ny * length / width), ny), -upper_right, upper_right); + addcellset!(grid, "center", x -> abs(x[1]) < center_width/2 && abs(x[2]) < center_length / 2) + addcellset!(grid, "around", setdiff(1:getncells(grid), getcellset(grid, "center"))) + return grid +end + +grid = create_grid(10) # ### Trial and test functions # A `CellValues` facilitates the process of evaluating values and gradients of @@ -82,7 +92,7 @@ grid = generate_grid(Triangle, (20, 20)); # the same reference element. We combine the interpolation and the quadrature rule # to a `CellValues` object. ip_geo = geometric_interpolation(getcelltype(grid)) -ipu = Lagrange{RefTriangle, 1}() # Why does it "explode" for 2nd order ipu? +ipu = DiscontinuousLagrange{RefTriangle, 1}() # Why does it "explode" for 2nd order ipu? ipq = RaviartThomas{2,RefTriangle, 1}() qr = QuadratureRule{RefTriangle}(2) cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl index 52d463b108..c5505ef026 100644 --- a/docs/src/literate-tutorials/heat_equation_triangle.jl +++ b/docs/src/literate-tutorials/heat_equation_triangle.jl @@ -32,7 +32,6 @@ # ## Commented Program # # Now we solve the problem in Ferrite. What follows is a program spliced with comments. -#md # The full program, without comments, can be found in the next [section](@ref heat_equation-plain-program). # # First we load Ferrite, and some other packages we need using Ferrite, SparseArrays diff --git a/src/interpolations.jl b/src/interpolations.jl index 9c5a0f9037..b6fc6c4f9b 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1855,13 +1855,64 @@ function get_direction(::RaviartThomas{2, RefTriangle, 2}, j, cell) return ifelse(edge[2] > edge[1], 1, -1) end +##################################### +# Brezzi-Douglas–Marini, H(div) # +##################################### +struct BrezziDouglasMarini{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end +mapping_type(::BrezziDouglasMarini) = ContravariantPiolaMapping() +reference_coordinates(ip::BrezziDouglasMarini{vdim}) where vdim = fill(NaN*zero(Vec{vdim}), getnbasefunctions(ip)) +dirichlet_facedof_indices(ip::BrezziDouglasMarini) = facetdof_interior_indices(ip) +n_dbc_components(::BrezziDouglasMarini) = 1 +#= +----------------+-------------------- +Vertex numbers: | Vertex coordinates: + 2 | + | \ | v1: 𝛏 = (1.0, 0.0) + | \ | v2: 𝛏 = (0.0, 1.0) +ξ₂^ | \ | v3: 𝛏 = (0.0, 0.0) + | 3-------1 | + +--> ξ₁ | +----------------+-------------------- +Edge numbers: | Edge identifiers: + + | + | \ | e1: (v1, v2) + 2 1 | e2: (v2, v3) + | \ | e3: (v3, v1) + +---3---+ | +----------------+-------------------- +=# + +# RefTriangle, 1st order Lagrange +function reference_shape_value(ip::BrezziDouglasMarini{2, RefTriangle, 1}, ξ::Vec{2}, i::Int) + x, y = ξ + # Edge 1 + i == 1 && return Vec(4x, -2y) # Changed sign to make positive outwards + i == 2 && return Vec(-2x, 4y) # Changed sign to make positive outwards + # Edge 2 (reverse order to follow Ferrite convention) + i == 3 && return Vec(-2x - 6y + 2, 4y) + i == 4 && return Vec(4x + 6y - 4, -2y) + # Edge 3 + i == 5 && return Vec(-2x, 6x + 4y - 4) # Changed sign to make positive outwards + i == 6 && return Vec(4x, -6x - 2y + 2) # Changed sign to make positive outwards + throw(ArgumentError("no shape function $i for interpolation $ip")) +end + +getnbasefunctions(::BrezziDouglasMarini{2, RefTriangle, 1}) = 6 +edgedof_interior_indices(::BrezziDouglasMarini{2, RefTriangle, 1}) = ((1, 2), (3, 4), (5, 6)) +adjust_dofs_during_distribution(::BrezziDouglasMarini{2, RefTriangle, 1}) = false + +function get_direction(::BrezziDouglasMarini{2, RefTriangle, 1}, j, cell) + edge = edges(cell)[(j + 1) ÷ 2] + return ifelse(edge[2] > edge[1], 1, -1) +end + ##################################### # Nedelec (1st kind), H(curl) # ##################################### struct Nedelec{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end mapping_type(::Nedelec) = CovariantPiolaMapping() reference_coordinates(ip::Nedelec{vdim}) where vdim = fill(NaN*zero(Vec{vdim}), getnbasefunctions(ip)) -dirichlet_facedof_indices(ip::Nedelec) = facedof_interior_indices(ip) +dirichlet_facedof_indices(ip::Nedelec) = facetdof_interior_indices(ip) n_dbc_components(::Nedelec) = 1 # RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-1.html diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index 1610b1d8f4..6ca757869f 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -270,7 +270,7 @@ end # Where f(s) = 1 for linear interpolation and f(s)=1-s and f(s)=s for 2nd order interpolation (first and second shape function) # And s is the path parameter ∈[0,1] along the positive direction of the path. # 2) Zero along other edges: Nⱼ ⋅ v = 0 if j∉𝔇 -@testset "Nedelec" begin +@testset "H(curl) on RefCell" begin lineqr = QuadratureRule{RefLine}(20) for ip in (Nedelec{2,RefTriangle,1}(), Nedelec{2,RefTriangle,2}(), Nedelec{3,RefTetrahedron,1}(), Nedelec{3,RefHexahedron,1}()) cell = reference_cell(getrefshape(ip)) @@ -302,6 +302,46 @@ end end end +# Required properties of shape value Nⱼ of an edge-elements (Hdiv) on an edge with normal n, length L, and dofs ∈ 𝔇 +# 1) Unit property: ∫(Nⱼ ⋅ n f(s) dS) = 1 +# Where f(s) = 1 for single shape function on edge, and f(s)=1-s and f(s)=s for two shape functions on edge +# s is the path parameter ∈[0,1] along the positive direction of the path. +# 2) Zero normal component on other edges: Nⱼ ⋅ n = 0 if j∉𝔇 +@testset "H(div) on RefCell" begin + lineqr = QuadratureRule{RefLine}(20) + for ip in (RaviartThomas{2, RefTriangle, 1}(), Ferrite.BrezziDouglasMarini{2, RefTriangle, 1}(), ) + cell = reference_cell(getrefshape(ip)) + cell_facets = Ferrite.facets(cell) + dofs = Ferrite.facetdof_interior_indices(ip) + x = Ferrite.reference_coordinates(geometric_interpolation(typeof(cell))) + normals = reference_normals(geometric_interpolation(typeof(cell))) + @testset "$ip" begin + for (facet_nr, (i1, i2)) in enumerate(cell_facets) + @testset "Facet $facet_nr" begin + Δx = x[i2]-x[i1] + x0 = (x[i1]+x[i2])/2 + L = norm(Δx) + n = normals[facet_nr] + for (idof, shape_nr) in enumerate(dofs[facet_nr]) + nfacetdofs = length(dofs[facet_nr]) + f(x) = nfacetdofs == 1 ? 1.0 : (idof == 1 ? 1-x : x) + s = line_integral(lineqr, ip, shape_nr, x0, Δx, L, n, f) + @test s ≈ one(s) + end + for (j_facet, shape_nrs) in enumerate(dofs) + j_facet == facet_nr && continue + for shape_nr in shape_nrs + for ξ in (x[i1] + r*Δx for r in [0.0, rand(3)..., 1.0]) + @test abs(reference_shape_value(ip, ξ, shape_nr) ⋅ n) < eps()*100 + end + end + end + end + end + end + end +end + tupleshift(t::NTuple{N}, shift::Int) where N = ntuple(i -> t[mod(i - 1 - shift, N) + 1], N) #tupleshift(t::NTuple, shift::Int) = tuple(circshift(SVector(t), shift)...) cell_permutations(cell::Quadrilateral) = (Quadrilateral(tupleshift(cell.nodes, shift)) for shift in 0:3) @@ -336,9 +376,10 @@ end include(joinpath(@__DIR__, "InterpolationTestUtils.jl")) import .InterpolationTestUtils as ITU nel = 3 - transformation_functions = Dict( - Nedelec=>(v,n)-> v - n*(v⋅n), # Hcurl (tangent continuity) - RaviartThomas=>(v,n) -> v ⋅ n) # Hdiv (normal continuity) + hdiv_check(v, n) = v ⋅ n # Hdiv (normal continuity) + hcurl_check(v, n) = v - n*(v⋅n) # Hcurl (tangent continuity) + transformation_functions = ((Nedelec, hcurl_check), (RaviartThomas, hdiv_check), (Ferrite.BrezziDouglasMarini, hdiv_check)) + for CT in (Triangle, QuadraticTriangle, Tetrahedron, Hexahedron) dim = Ferrite.getrefdim(CT) # dim = sdim = rdim p1, p2 = (rand(Vec{dim}), ones(Vec{dim})+rand(Vec{dim})) @@ -352,11 +393,11 @@ end basecell = getcells(grid, cellnr) RefShape = Ferrite.getrefshape(basecell) for order in (1, 2) - for IPT in (Nedelec, RaviartThomas) + for (IPT, transformation_function) in transformation_functions dim == 3 && order > 1 && continue IPT == RaviartThomas && (dim == 3 || order > 1) && continue IPT == RaviartThomas && (RefShape == RefHexahedron) && continue - transformation_function=transformation_functions[IPT] + IPT == Ferrite.BrezziDouglasMarini && !(RefShape == RefTriangle && order == 1) && continue ip = IPT{dim, RefShape, order}() @testset "$CT, $ip" begin for testcell in cell_permutations(basecell) diff --git a/visualization/2d_vector_interpolation_checkplots.jl b/visualization/2d_vector_interpolation_checkplots.jl new file mode 100644 index 0000000000..d51487bbc3 --- /dev/null +++ b/visualization/2d_vector_interpolation_checkplots.jl @@ -0,0 +1,23 @@ +using Ferrite +import CairoMakie as Plt + +function plot_shape_function(ip::VectorInterpolation{2, RefShape}, qr::Int, i::Int) where {RefShape<:Ferrite.AbstractRefShape{2}} + return plot_shape_function(ip, QuadratureRule{RefShape}(qr), i) +end + +function plot_shape_function(ip::VectorInterpolation{2, RefShape}, qr::QuadratureRule{RefShape}, i::Int) where {RefShape<:Ferrite.AbstractRefShape{2}} + points = Ferrite.getpoints(qr) + N = map(ξ -> Ferrite.reference_shape_value(ip, ξ, i), points) + vertices = Ferrite.reference_coordinates(Lagrange{RefShape, 1}()) + push!(vertices, first(vertices)) + + fig = Plt.Figure() + ax = Plt.Axis(fig[1,1]) + Plt.lines!(ax, first.(vertices), last.(vertices)) + Plt.arrows!(ax, first.(points), last.(points), first.(N), last.(N); lengthscale = 0.3) + return fig +end + +function plot_global_shape_function(ip, qr, nx, ny, i) + #TODO: Plot a single global shape function to investigate continuity +end diff --git a/visualization/Manifest.toml b/visualization/Manifest.toml index ec88abc416..96331314ab 100644 --- a/visualization/Manifest.toml +++ b/visualization/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.2" +julia_version = "1.11.1" manifest_format = "2.0" -project_hash = "9dc2d1ce07b87cc5107b7fa3d34838a5e8d48de1" +project_hash = "f8140ea440af404cde81e65338add89dc118d0fc" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -15,11 +15,6 @@ weakdeps = ["ChainRulesCore", "Test"] AbstractFFTsChainRulesCoreExt = "ChainRulesCore" AbstractFFTsTestExt = "Test" -[[deps.AbstractLattices]] -git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" -uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" -version = "0.3.0" - [[deps.AbstractTrees]] git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" @@ -27,14 +22,25 @@ version = "0.4.5" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" +git-tree-sha1 = "50c3c56a52972d78e8be9fd135bfb91c9574c140" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.0.4" +version = "4.1.1" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] AdaptStaticArraysExt = "StaticArrays" +[[deps.AdaptivePredicates]] +git-tree-sha1 = "7e651ea8d262d2d74ce75fdf47c4d63c07dba7a6" +uuid = "35492f91-a3bd-45ad-95db-fcad7dcfedb7" +version = "1.2.0" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + [[deps.Animations]] deps = ["Colors"] git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" @@ -43,42 +49,17 @@ version = "0.4.1" [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.9.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" +version = "1.1.2" [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" [[deps.Automa]] -deps = ["PrecompileTools", "TranscodingStreams"] -git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" +deps = ["PrecompileTools", "SIMD", "TranscodingStreams"] +git-tree-sha1 = "a8f503e8e1a5f583fbef15a8440c8c7e32185df2" uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "1.0.3" +version = "1.1.0" [[deps.AxisAlgorithms]] deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] @@ -94,12 +75,13 @@ version = "0.4.7" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +git-tree-sha1 = "8873e196c2eb87962a2048b3b8e08946535864a1" uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.8+1" +version = "1.0.8+2" [[deps.CEnum]] git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" @@ -108,6 +90,7 @@ version = "0.5.0" [[deps.CRC32c]] uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" +version = "1.11.0" [[deps.CRlibm_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -115,23 +98,29 @@ git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" version = "1.0.1+0" +[[deps.Cairo]] +deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] +git-tree-sha1 = "7b6ad8c35f4bc3bca8eb78127c8b99719506a5fb" +uuid = "159f3aea-2a34-519c-b102-8c37f9878175" +version = "1.1.0" + +[[deps.CairoMakie]] +deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] +git-tree-sha1 = "fbfdb7cbe17bd14b60646c14c27a16e5038cde54" +uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +version = "0.12.15" + [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "a4c43f59baa34011e303e76f5c8c91bf58415aaf" +git-tree-sha1 = "009060c9a6168704143100f36ab08f06c2af4642" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.0+1" - -[[deps.Calculus]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.5.1" +version = "1.18.2+1" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +git-tree-sha1 = "3e4b134270b372f2ed4d4d0e936aabaefc1802bc" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.23.0" +version = "1.25.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -139,9 +128,9 @@ weakdeps = ["SparseArrays"] [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +git-tree-sha1 = "bce6804e5e6044c6daab27bb533d1295e4a2e759" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.4" +version = "0.7.6" [[deps.ColorBrewer]] deps = ["Colors", "JSON", "Test"] @@ -151,15 +140,15 @@ version = "0.4.0" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +git-tree-sha1 = "13951eb68769ad1cd460cdb2e64e5e95f1bf123d" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.24.0" +version = "3.27.0" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.4" +version = "0.11.5" [[deps.ColorVectorSpace]] deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] @@ -173,26 +162,21 @@ weakdeps = ["SpecialFunctions"] [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.10" - -[[deps.Combinatorics]] -git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "1.0.2" +version = "0.12.11" [[deps.CommonSubexpressions]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.0" +version = "0.3.1" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.14.0" +version = "4.16.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -201,23 +185,23 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.0+0" +version = "1.1.1+0" [[deps.ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +git-tree-sha1 = "76219f1ed5771adbb096743bff43fb5fdd4c1157" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.5" -weakdeps = ["IntervalSets", "StaticArrays"] +version = "1.5.8" +weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" ConstructionBaseStaticArraysExt = "StaticArrays" [[deps.Contour]] -git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.6.2" +version = "0.6.3" [[deps.DataAPI]] git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" @@ -226,9 +210,9 @@ version = "1.16.0" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "0f4b5d62a88d8f59003e43c25a8a90de9eb76317" +git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.18" +version = "0.18.20" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -238,12 +222,13 @@ version = "1.0.0" [[deps.Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" [[deps.DelaunayTriangulation]] -deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] -git-tree-sha1 = "d4e9dc4c6106b8d44e40cd4faf8261a678552c7c" +deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "PrecompileTools", "Random"] +git-tree-sha1 = "89df54fbe66e5872d91d8c2cd3a375f660c3fd64" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "0.8.12" +version = "1.6.1" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -259,9 +244,9 @@ version = "1.15.1" [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.11" +version = "0.10.12" weakdeps = ["ChainRulesCore", "SparseArrays"] [deps.Distances.extensions] @@ -271,12 +256,13 @@ weakdeps = ["ChainRulesCore", "SparseArrays"] [[deps.Distributed]] deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" [[deps.Distributions]] -deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "d7477ecdafb813ddee2ae727afa94e9dcb5f3fb0" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.107" +version = "0.25.112" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" @@ -299,12 +285,6 @@ deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" -[[deps.DualNumbers]] -deps = ["Calculus", "NaNMath", "SpecialFunctions"] -git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" -uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" -version = "0.6.8" - [[deps.EarCut_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" @@ -324,20 +304,20 @@ version = "2.2.8" [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +git-tree-sha1 = "1c6317308b9dc757616f0b5cb379db10494443a7" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.5.0+0" +version = "2.6.2+0" [[deps.Extents]] -git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" +git-tree-sha1 = "81023caa0021a41712685887db1fc03db26f41f5" uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.2" +version = "0.1.4" [[deps.FFMPEG_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "ab3f7e1819dba9434a3a5126510c8fda3a4e7000" +git-tree-sha1 = "8cc47f299902e13f90405ddb5bf87e5d474c0d38" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "6.1.1+0" +version = "6.1.2+0" [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] @@ -347,15 +327,15 @@ version = "1.8.0" [[deps.FFTW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +git-tree-sha1 = "4d81ed14783ec49ce9f2e168208a12ce1815aa25" uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.10+0" +version = "3.3.10+1" [[deps.Ferrite]] -deps = ["EnumX", "LinearAlgebra", "NearestNeighbors", "Preferences", "Reexport", "SparseArrays", "StaticArrays", "Tensors", "WriteVTK"] +deps = ["EnumX", "ForwardDiff", "LinearAlgebra", "NearestNeighbors", "OrderedCollections", "Preferences", "Reexport", "SparseArrays", "StaticArrays", "Tensors", "WriteVTK"] path = ".." uuid = "c061ca5d-56c9-439f-9c0e-210fe06d3992" -version = "0.3.14" +version = "1.0.0" [deps.Ferrite.extensions] FerriteBlockArrays = "BlockArrays" @@ -365,26 +345,38 @@ version = "0.3.14" BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b" -[[deps.FerriteViz]] -deps = ["Ferrite", "GeometryBasics", "LinearAlgebra", "Makie", "Reexport", "ShaderAbstractions", "StaticArrays", "Tensors"] -path = "C:\\Users\\meyer\\.julia\\dev\\FerriteViz" -uuid = "59d0093e-b1f1-4fb7-ac85-ab57e45f39d9" -version = "0.2.1" - [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" +git-tree-sha1 = "62ca0547a14c57e98154423419d8a342dca75ca9" uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.3" +version = "1.16.4" + +[[deps.FilePaths]] +deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] +git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" +uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" +version = "0.8.3" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates"] +git-tree-sha1 = "7878ff7172a8e6beedd1dea14bd27c3c6340d361" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.22" +weakdeps = ["Mmap", "Test"] + + [deps.FilePathsBase.extensions] + FilePathsBaseMmapExt = "Mmap" + FilePathsBaseTestExt = "Test" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" [[deps.FillArrays]] -deps = ["LinearAlgebra", "Random"] -git-tree-sha1 = "5b93957f6dcd33fc343044af3d48c215be2562f1" +deps = ["LinearAlgebra"] +git-tree-sha1 = "6a70198746448456524cb442b8af316927ff3e1a" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.9.3" +version = "1.13.0" weakdeps = ["PDMats", "SparseArrays", "Statistics"] [deps.FillArrays.extensions] @@ -392,45 +384,28 @@ weakdeps = ["PDMats", "SparseArrays", "Statistics"] FillArraysSparseArraysExt = "SparseArrays" FillArraysStatisticsExt = "Statistics" -[[deps.FiniteDiff]] -deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "bc0c5092d6caaea112d3c8e3b238d61563c58d5f" -uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.23.0" - - [deps.FiniteDiff.extensions] - FiniteDiffBandedMatricesExt = "BandedMatrices" - FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" - FiniteDiffStaticArraysExt = "StaticArrays" - - [deps.FiniteDiff.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - [[deps.FixedPointNumbers]] deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" +version = "0.8.5" [[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.93+0" +version = "2.13.96+0" -[[deps.Formatting]] -deps = ["Logging", "Printf"] -git-tree-sha1 = "fb409abab2caf118986fc597ba84b50cbaf00b87" -uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" -version = "0.4.3" +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +git-tree-sha1 = "a9ce73d3c827adab2d70bf168aaece8cce196898" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.36" +version = "0.10.37" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] @@ -444,55 +419,38 @@ version = "4.1.1" [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +git-tree-sha1 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.1+0" +version = "2.13.2+0" [[deps.FreeTypeAbstraction]] deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] -git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" +git-tree-sha1 = "84dfe824bd6fdf2a5d73bb187ff31b5549b2a79c" uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.1" +version = "0.10.4" [[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.10+0" +version = "1.0.14+0" -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[deps.GLFW]] -deps = ["GLFW_jll"] -git-tree-sha1 = "35dbc482f0967d8dceaa7ce007d16f9064072166" -uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -version = "3.4.1" - -[[deps.GLFW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] -git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" -uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" -version = "3.3.9+0" - -[[deps.GLMakie]] -deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "8236ce4eda9837d15bab49573bba16ba0652b486" -uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.8.12" +[[deps.GeoFormatTypes]] +git-tree-sha1 = "59107c179a586f0fe667024c5eb7033e81333271" +uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f" +version = "0.4.2" [[deps.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" +deps = ["Extents", "GeoFormatTypes"] +git-tree-sha1 = "2f6fce56cdb8373637a6614e14a5768a88450de2" uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.3" +version = "1.3.7" [[deps.GeometryBasics]] deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "5694b56ccf9d15addedc35e9a4ba9c317721b788" +git-tree-sha1 = "b62f2b2d76cee0d61a2ef2b3118cd2a3215d3134" uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.4.10" +version = "0.4.11" [[deps.Gettext_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] @@ -500,11 +458,23 @@ git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" version = "0.21.0+0" +[[deps.Giflib_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0224cce99284d997f6880a42ef715a37c99338d1" +uuid = "59f7168a-df46-5410-90c8-f2779963d0ec" +version = "5.2.2+0" + [[deps.Glib_jll]] deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" +git-tree-sha1 = "674ff0db93fffcd11a3573986e550d66cd4fd71f" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.0+0" +version = "2.80.5+0" + +[[deps.Graphics]] +deps = ["Colors", "LinearAlgebra", "NaNMath"] +git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "1.1.2" [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -514,9 +484,9 @@ version = "1.3.14+0" [[deps.GridLayoutBase]] deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" +git-tree-sha1 = "fc713f007cff99ff9e50accba6373624ddd33588" uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.9.2" +version = "0.11.0" [[deps.Grisu]] git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" @@ -524,16 +494,16 @@ uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" version = "1.0.2" [[deps.HarfBuzz_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] -git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "401e4f3f30f43af2c8478fc008da50096ea5240f" uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" -version = "2.8.1+1" +version = "8.3.1+0" [[deps.HypergeometricFunctions]] -deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "7c4195be1649ae622304031ed46a2f4df989f1eb" uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.23" +version = "0.3.24" [[deps.ImageAxes]] deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] @@ -554,10 +524,10 @@ uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" version = "0.10.2" [[deps.ImageIO]] -deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] -git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs", "WebP"] +git-tree-sha1 = "696144904b76e1ca433b886b4e7edd067d76cbf7" uuid = "82e4d734-157c-48bb-816b-45c225c6df19" -version = "0.6.7" +version = "0.6.9" [[deps.ImageMetadata]] deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] @@ -567,9 +537,9 @@ version = "0.9.9" [[deps.Imath_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +git-tree-sha1 = "0936ba688c6d201805a83da835b55c61a180db52" uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" -version = "3.1.7+0" +version = "3.1.11+0" [[deps.IndirectArrays]] git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" @@ -577,60 +547,74 @@ uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" version = "1.0.0" [[deps.Inflate]] -git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.4" - -[[deps.IntegerMathUtils]] -git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" -uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" -version = "0.1.2" +version = "0.1.5" [[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "10bd689145d2c3b2a9844005d01087cc1194e79e" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.0.2+0" +version = "2024.2.1+0" [[deps.InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" [[deps.Interpolations]] deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" version = "0.15.1" +weakdeps = ["Unitful"] [deps.Interpolations.extensions] InterpolationsUnitfulExt = "Unitful" - [deps.Interpolations.weakdeps] - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - [[deps.IntervalArithmetic]] -deps = ["CRlibm_jll", "RoundingEmulator"] -git-tree-sha1 = "552505ed27d2a90ff04c15b0ecf4634e0ab5547b" +deps = ["CRlibm_jll", "LinearAlgebra", "MacroTools", "RoundingEmulator"] +git-tree-sha1 = "c59c57c36683aa17c563be6edaac888163f35285" uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.9" -weakdeps = ["DiffRules", "ForwardDiff", "RecipesBase"] +version = "0.22.18" [deps.IntervalArithmetic.extensions] IntervalArithmeticDiffRulesExt = "DiffRules" IntervalArithmeticForwardDiffExt = "ForwardDiff" + IntervalArithmeticIntervalSetsExt = "IntervalSets" IntervalArithmeticRecipesBaseExt = "RecipesBase" + [deps.IntervalArithmetic.weakdeps] + DiffRules = "b552c78f-8df3-52c6-915a-8e097449b14b" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" + [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" uuid = "8197267c-284f-5f27-9208-e0e47529a953" version = "0.7.10" -weakdeps = ["Random", "RecipesBase", "Statistics"] [deps.IntervalSets.extensions] IntervalSetsRandomExt = "Random" IntervalSetsRecipesBaseExt = "RecipesBase" IntervalSetsStatisticsExt = "Statistics" + [deps.IntervalSets.weakdeps] + Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.InverseFunctions]] +git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.17" +weakdeps = ["Dates", "Test"] + + [deps.InverseFunctions.extensions] + InverseFunctionsDatesExt = "Dates" + InverseFunctionsTestExt = "Test" + [[deps.IrrationalConstants]] git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" @@ -654,9 +638,9 @@ version = "1.0.0" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +git-tree-sha1 = "be3dc50a92e5a386872a493a10050136d4703f9b" uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.5.0" +version = "1.6.1" [[deps.JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] @@ -672,42 +656,49 @@ version = "0.1.5" [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3336abae9a713d2210bb57ab484b1e065edd7d23" +git-tree-sha1 = "25ee0be4d43d0269027024d75a24c24d6c6e590c" uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.0.2+0" +version = "3.0.4+0" [[deps.KernelDensity]] deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" +git-tree-sha1 = "7d703202e65efa1369de1279c162b915e245eed1" uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.8" +version = "0.6.9" [[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.1+0" +version = "3.100.2+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "36bdbc52f13a7d1dcb0f3cd694e01677a515655b" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.0+0" [[deps.LLVMOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +git-tree-sha1 = "78211fb6cbc872f77cad3fc0b6cf647d923f4929" uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "15.0.7+0" +version = "18.1.7+0" [[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "854a9c268c43b77b0a27f22d7fab8d33cdb3a731" uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.1+0" +version = "2.10.2+1" [[deps.LaTeXStrings]] -git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.3.1" +version = "1.4.0" [[deps.LazyArtifacts]] deps = ["Artifacts", "Pkg"] uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" +version = "1.11.0" [[deps.LazyModules]] git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" @@ -722,16 +713,17 @@ version = "0.6.4" [[deps.LibCURL_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.4.0+0" +version = "8.6.0+0" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" [[deps.LibGit2_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.6.4+0" +version = "1.7.2+0" [[deps.LibSSH2_jll]] deps = ["Artifacts", "Libdl", "MbedTLS_jll"] @@ -740,6 +732,7 @@ version = "1.11.0+1" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" [[deps.Libffi_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -748,10 +741,10 @@ uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" version = "3.2.2+1" [[deps.Libgcrypt_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] -git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll"] +git-tree-sha1 = "8be878062e0ffa2c3f67bb58a595375eda5de80b" uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.7+0" +version = "1.11.0+0" [[deps.Libglvnd_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] @@ -760,28 +753,34 @@ uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" version = "1.6.0+0" [[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c6ce1e19f3aec9b59186bdf06cdf3c4fc5f5f3e6" uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.42.0+0" +version = "1.50.0+0" [[deps.Libiconv_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +git-tree-sha1 = "61dfdba58e585066d8bce214c5a51eaa0539f269" uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.17.0+0" +version = "1.17.0+1" [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +git-tree-sha1 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.39.3+0" +version = "2.40.1+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "b404131d06f7886402758c9ce2214b636eb4d54a" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.0+0" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.39.3+1" +version = "2.40.1+0" [[deps.LightXML]] deps = ["Libdl", "XML2_jll"] @@ -789,27 +788,16 @@ git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" version = "0.9.1" -[[deps.LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.2.0" - [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[deps.LinearAlgebraX]] -deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] -git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" -uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" -version = "0.2.7" +version = "1.11.0" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.27" +version = "0.3.28" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -823,12 +811,13 @@ version = "0.3.27" [[deps.Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" [[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "f046ccd0c6db2832a9f639e2c669c6fe867e5f4f" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.0.0+0" +version = "2024.2.0+0" [[deps.MacroTools]] deps = ["Markdown", "Random"] @@ -837,16 +826,16 @@ uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.13" [[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "35fa3c150cd96fd77417a23965b7037b90d6ffc9" +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "InverseFunctions", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] +git-tree-sha1 = "f7907907eb914138cc9e9ee66ab46f7a9efac8e8" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.19.12" +version = "0.21.15" [[deps.MakieCore]] -deps = ["Observables", "REPL"] -git-tree-sha1 = "9b11acd07f21c4d035bd4156e789532e8ee2cc70" +deps = ["ColorTypes", "GeometryBasics", "IntervalSets", "Observables"] +git-tree-sha1 = "4604f03e5b057e8e62a95a44929cafc9585b0fe9" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.6.9" +version = "0.8.9" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -856,43 +845,28 @@ version = "0.4.2" [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" [[deps.MathTeXEngine]] deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] -git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +git-tree-sha1 = "f45c8916e8385976e1ccd055c9874560c257ab13" uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.5.7" +version = "0.6.2" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+1" - -[[deps.MeshIO]] -deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] -git-tree-sha1 = "8c26ab950860dfca6767f2bbd90fdf1e8ddc678b" -uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" -version = "0.4.11" +version = "2.28.6+0" [[deps.Missings]] deps = ["DataAPI"] -git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.1.0" +version = "1.2.0" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[deps.ModernGL]] -deps = ["Libdl"] -git-tree-sha1 = "b76ea40b5c0f45790ae09492712dd326208c28b2" -uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -version = "1.1.7" - -[[deps.Mods]] -git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" -uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" -version = "2.2.4" +version = "1.11.0" [[deps.MosaicViews]] deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] @@ -902,18 +876,7 @@ version = "0.3.4" [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.1.10" - -[[deps.Multisets]] -git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" -uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" -version = "0.4.4" - -[[deps.NLSolversBase]] -deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] -git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.8.3" +version = "2023.12.12" [[deps.NaNMath]] deps = ["OpenLibm_jll"] @@ -923,9 +886,9 @@ version = "1.0.2" [[deps.NearestNeighbors]] deps = ["Distances", "StaticArrays"] -git-tree-sha1 = "ded64ff6d4fdd1cb68dfcbb818c69e144a5b2e4c" +git-tree-sha1 = "3cebfc94a0754cc329ebc3bab1e6c89621e791ad" uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" -version = "0.4.16" +version = "0.4.20" [[deps.Netpbm]] deps = ["FileIO", "ImageCore", "ImageMetadata"] @@ -943,9 +906,9 @@ uuid = "510215fc-4207-5dde-b226-833fc4488ee2" version = "0.5.5" [[deps.OffsetArrays]] -git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +git-tree-sha1 = "1a27764e945a152f7ca7efa04de513d473e9542e" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.13.0" +version = "1.14.1" weakdeps = ["Adapt"] [deps.OffsetArrays.extensions] @@ -960,7 +923,7 @@ version = "1.3.5+1" [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.23+4" +version = "0.3.27+1" [[deps.OpenEXR]] deps = ["Colors", "FileIO", "OpenEXR_jll"] @@ -970,9 +933,9 @@ version = "0.3.2" [[deps.OpenEXR_jll]] deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +git-tree-sha1 = "8292dd5c8a38257111ada2174000a33745b06d4e" uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.1.4+0" +version = "3.2.4+0" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] @@ -981,9 +944,9 @@ version = "0.8.1+2" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "60e3045590bd104a16fefb12836c00c0ef8c7f8c" +git-tree-sha1 = "7493f61f55a6cce7325f197443aa80d32554ba10" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.13+0" +version = "3.0.15+1" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -991,23 +954,11 @@ git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.5+0" -[[deps.Optim]] -deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "PackageExtensionCompat", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "d1223e69af90b6d26cea5b6f3b289b3148ba702c" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.9.3" - - [deps.Optim.extensions] - OptimMOIExt = "MathOptInterface" - - [deps.Optim.weakdeps] - MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" - [[deps.Opus_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6703a85cb3781bd5909d48730a67205f3f31a575" uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.3.2+0" +version = "1.3.3+0" [[deps.OrderedCollections]] git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" @@ -1031,12 +982,6 @@ git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" version = "0.4.3" -[[deps.PackageExtensionCompat]] -git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" -uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" -version = "1.0.2" -weakdeps = ["Requires", "TOML"] - [[deps.Packing]] deps = ["GeometryBasics"] git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" @@ -1049,11 +994,11 @@ git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" version = "0.5.12" -[[deps.Parameters]] -deps = ["OrderedCollections", "UnPack"] -git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.12.3" +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e127b609fb9ecba6f201ba7ab753d5a605d53801" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.54.1+0" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] @@ -1061,28 +1006,20 @@ git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.8.1" -[[deps.Permutations]] -deps = ["Combinatorics", "LinearAlgebra", "Random"] -git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" -uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" -version = "0.4.20" - -[[deps.PikaParser]] -deps = ["DocStringExtensions"] -git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" -uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" -version = "0.6.1" - [[deps.Pixman_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +git-tree-sha1 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.42.2+0" +version = "0.43.4+0" [[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.10.0" +version = "1.11.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" [[deps.PkgVersion]] deps = ["Pkg"] @@ -1091,40 +1028,16 @@ uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" version = "0.3.3" [[deps.PlotUtils]] -deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] -git-tree-sha1 = "7b1a9df27f072ac4c9c7cbe5efb198489258d1f5" +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.4.1" +version = "1.4.3" [[deps.PolygonOps]] git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" uuid = "647866c9-e3ac-4575-94e7-e3d426903924" version = "0.1.2" -[[deps.Polynomials]] -deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "4.0.6" - - [deps.Polynomials.extensions] - PolynomialsChainRulesCoreExt = "ChainRulesCore" - PolynomialsFFTWExt = "FFTW" - PolynomialsMakieCoreExt = "MakieCore" - PolynomialsMutableArithmeticsExt = "MutableArithmetics" - - [deps.Polynomials.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" - MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" - MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" - -[[deps.PositiveFactorizations]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.4" - [[deps.PrecompileTools]] deps = ["Preferences"] git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" @@ -1137,21 +1050,21 @@ git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.3" -[[deps.Primes]] -deps = ["IntegerMathUtils"] -git-tree-sha1 = "cb420f77dc474d23ee47ca8d14c90810cafe69e7" -uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.5.6" - [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" [[deps.ProgressMeter]] deps = ["Distributed", "Printf"] -git-tree-sha1 = "763a8ceb07833dd51bb9e3bbca372de32c0605ad" +git-tree-sha1 = "8f6bc219586aef8baf0ff9a5fe16ee9c70cb65e4" uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.10.0" +version = "1.10.2" + +[[deps.PtrArrays]] +git-tree-sha1 = "77a42d78b6a92df47ab37e177b2deac405e1c88f" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.2.1" [[deps.QOI]] deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] @@ -1161,17 +1074,25 @@ version = "1.0.0" [[deps.QuadGK]] deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" +git-tree-sha1 = "cda3b045cf9ef07a08ad46731f5a3165e56cf3da" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.9.4" +version = "2.11.1" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" [[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" [[deps.Random]] deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" [[deps.RangeArrays]] git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" @@ -1188,12 +1109,6 @@ weakdeps = ["FixedPointNumbers"] [deps.Ratios.extensions] RatiosFixedPointNumbersExt = "FixedPointNumbers" -[[deps.RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - [[deps.Reexport]] git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" uuid = "189a3867-3050-52da-a836-e630ba90ab69" @@ -1211,23 +1126,17 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" -[[deps.RingLists]] -deps = ["Random"] -git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" -uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" -version = "0.2.8" - [[deps.Rmath]] deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +git-tree-sha1 = "852bd0f55565a9e973fcfee83a84413270224dc4" uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.7.1" +version = "0.8.0" [[deps.Rmath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.0+0" +version = "0.5.1+0" [[deps.RoundingEmulator]] git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" @@ -1240,9 +1149,9 @@ version = "0.7.0" [[deps.SIMD]] deps = ["PrecompileTools"] -git-tree-sha1 = "d8911cc125da009051fb35322415641d02d9e37f" +git-tree-sha1 = "98ca7c29edd6fc79cd74c61accb7010a4e7aee33" uuid = "fdea26ae-647d-5447-a871-4b548cad5224" -version = "3.4.6" +version = "3.6.0" [[deps.Scratch]] deps = ["Dates"] @@ -1252,12 +1161,7 @@ version = "1.2.1" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.1" +version = "1.11.0" [[deps.ShaderAbstractions]] deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] @@ -1268,6 +1172,7 @@ version = "0.4.1" [[deps.SharedArrays]] deps = ["Distributed", "Mmap", "Random", "Serialization"] uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +version = "1.11.0" [[deps.Showoff]] deps = ["Dates", "Grisu"] @@ -1281,30 +1186,6 @@ git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" version = "0.4.0" -[[deps.SimpleGraphs]] -deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] -git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" -uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" -version = "0.8.6" - -[[deps.SimplePartitions]] -deps = ["AbstractLattices", "DataStructures", "Permutations"] -git-tree-sha1 = "e182b9e5afb194142d4668536345a365ea19363a" -uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" -version = "0.3.2" - -[[deps.SimplePolynomials]] -deps = ["Mods", "Multisets", "Polynomials", "Primes"] -git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" -uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" -version = "0.2.17" - -[[deps.SimpleRandom]] -deps = ["Distributions", "LinearAlgebra", "Random"] -git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" -uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" -version = "0.3.1" - [[deps.SimpleTraits]] deps = ["InteractiveUtils", "MacroTools"] git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" @@ -1319,6 +1200,7 @@ version = "0.1.3" [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" [[deps.SortingAlgorithms]] deps = ["DataStructures"] @@ -1329,23 +1211,23 @@ version = "1.2.1" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.10.0" +version = "1.11.0" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +git-tree-sha1 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.1" +version = "2.4.0" weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" -[[deps.StableHashTraits]] -deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] -git-tree-sha1 = "10dc702932fe05a0e09b8e5955f00794ea1e8b12" -uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" -version = "1.1.8" +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "83e6cce8324d49dfaf9ef059227f91ed4441a8e5" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.2" [[deps.StackViews]] deps = ["OffsetArrays"] @@ -1355,9 +1237,9 @@ version = "0.1.1" [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +git-tree-sha1 = "777657803913ffc7e8cc20f0fd04b634f871af8f" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.3" +version = "1.9.8" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -1365,14 +1247,19 @@ weakdeps = ["ChainRulesCore", "Statistics"] StaticArraysStatisticsExt = "Statistics" [[deps.StaticArraysCore]] -git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.2" +version = "1.4.3" [[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] [[deps.StatsAPI]] deps = ["LinearAlgebra"] @@ -1382,24 +1269,21 @@ version = "1.7.0" [[deps.StatsBase]] deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" +git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.2" +version = "0.34.3" [[deps.StatsFuns]] deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a" +git-tree-sha1 = "b423576adc27097764a90e163157bcfc9acf0f46" uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.3.1" +version = "1.3.2" +weakdeps = ["ChainRulesCore", "InverseFunctions"] [deps.StatsFuns.extensions] StatsFunsChainRulesCoreExt = "ChainRulesCore" StatsFunsInverseFunctionsExt = "InverseFunctions" - [deps.StatsFuns.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - [[deps.StructArrays]] deps = ["ConstructionBase", "DataAPI", "Tables"] git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" @@ -1418,6 +1302,10 @@ version = "0.6.18" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + [[deps.SuiteSparse]] deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" @@ -1425,7 +1313,7 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" +version = "7.7.0+0" [[deps.TOML]] deps = ["Dates"] @@ -1439,10 +1327,10 @@ uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" version = "1.0.1" [[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.1" +version = "1.12.0" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -1464,43 +1352,32 @@ version = "1.16.1" [[deps.Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" [[deps.TiffImages]] -deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] -git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "SIMD", "UUIDs"] +git-tree-sha1 = "6ee0c220d0aecad18792c277ae358129cc50a475" uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.6.8" +version = "0.11.0" [[deps.TranscodingStreams]] -git-tree-sha1 = "a09c933bebed12501890d8e92946bbab6a1690f1" +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.5" -weakdeps = ["Random", "Test"] - - [deps.TranscodingStreams.extensions] - TestExt = ["Test", "Random"] +version = "0.11.3" [[deps.TriplotBase]] git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" uuid = "981d1d27-644d-49a2-9326-4793e63143c3" version = "0.1.0" -[[deps.TupleTools]] -git-tree-sha1 = "41d61b1c545b06279871ef1a4b5fcb2cac2191cd" -uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" -version = "1.5.0" - [[deps.UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" +version = "1.11.0" [[deps.Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" [[deps.UnicodeFun]] deps = ["REPL"] @@ -1508,11 +1385,28 @@ git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" version = "0.4.1" +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "d95fe458f26209c66a187b1114df96fd70839efd" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.21.0" +weakdeps = ["ConstructionBase", "InverseFunctions"] + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + InverseFunctionsUnitfulExt = "InverseFunctions" + [[deps.VTKBase]] git-tree-sha1 = "c2d0db3ef09f1942d08ea455a9e252594be5f3b6" uuid = "4004b06d-e244-455f-a6ce-a5f9919cc534" version = "1.0.1" +[[deps.WebP]] +deps = ["CEnum", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "libwebp_jll"] +git-tree-sha1 = "f1f6d497ff84039deeb37f264396dac0c2250497" +uuid = "e3aaa7dc-3e4b-44e0-be63-ffb868ccd7c1" +version = "0.1.2" + [[deps.WoodburyMatrices]] deps = ["LinearAlgebra", "SparseArrays"] git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" @@ -1521,21 +1415,27 @@ version = "1.0.0" [[deps.WriteVTK]] deps = ["Base64", "CodecZlib", "FillArrays", "LightXML", "TranscodingStreams", "VTKBase"] -git-tree-sha1 = "17877c404fd20090e3998a66f6f44cf01e2b1e60" +git-tree-sha1 = "1d8042d58334ab7947ce505709df7009da6f3375" uuid = "64499a7a-5c06-52f2-abe2-ccb03c286192" -version = "1.18.3" +version = "1.21.1" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "07e470dabc5a6a4254ffebc29a1b3fc01464e105" +git-tree-sha1 = "6a451c6f33a176150f315726eba8b92fbfdb9ae7" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.5+0" +version = "2.13.4+0" [[deps.XSLT_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] -git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "a54ee957f4c86b526460a720dbc882fa5edcbefc" uuid = "aed1982a-8fda-507f-9586-7b0439959a61" -version = "1.1.34+0" +version = "1.1.41+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "15e637a697345f6743674f1322beefbc5dcd5cfc" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.6.3+0" [[deps.Xorg_libX11_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] @@ -1549,12 +1449,6 @@ git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" version = "1.0.11+0" -[[deps.Xorg_libXcursor_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] -git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" -uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" -version = "1.2.0+4" - [[deps.Xorg_libXdmcp_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" @@ -1562,40 +1456,16 @@ uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" version = "1.1.4+0" [[deps.Xorg_libXext_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.4+4" - -[[deps.Xorg_libXfixes_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" -uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" -version = "5.0.3+4" - -[[deps.Xorg_libXi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] -git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" -uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" -version = "1.7.10+4" - -[[deps.Xorg_libXinerama_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] -git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" -uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" -version = "1.1.4+4" - -[[deps.Xorg_libXrandr_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] -git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" -uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" -version = "1.5.2+4" +version = "1.3.6+0" [[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.10+4" +version = "0.9.11+0" [[deps.Xorg_libpthread_stubs_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1605,9 +1475,9 @@ version = "0.1.1+0" [[deps.Xorg_libxcb_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] -git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +git-tree-sha1 = "bcd466676fef0878338c61e655629fa7bbc69d8e" uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.15.0+0" +version = "1.17.0+0" [[deps.Xorg_xtrans_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1620,6 +1490,12 @@ deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" version = "1.2.13+1" +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "555d1076590a6cc2fdee2ef1469451f872d8b41b" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.6+1" + [[deps.isoband_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" @@ -1627,50 +1503,62 @@ uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" version = "0.2.3+0" [[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.4.0+0" +version = "3.9.0+0" [[deps.libass_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "e17c115d55c5fbb7e52ebedb427a0dca79d4484e" uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" -version = "0.15.1+0" +version = "0.15.2+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+1" +version = "5.11.0+0" [[deps.libfdk_aac_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a22cf860a7d27e4f3498a0fe0811a7957badb38" uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" -version = "2.0.2+0" +version = "2.0.3+0" [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" +git-tree-sha1 = "b70c870239dc3d7bc094eb2d6be9b73d27bef280" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.43+1" +version = "1.6.44+0" [[deps.libsixel_jll]] deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] -git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +git-tree-sha1 = "7dfa0fd9c783d3d0cc43ea1af53d69ba45c447df" uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" -version = "1.10.3+0" +version = "1.10.3+1" [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] -git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +git-tree-sha1 = "490376214c4721cdaca654041f635213c6165cb3" uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.7+1" +version = "1.3.7+2" + +[[deps.libwebp_jll]] +deps = ["Artifacts", "Giflib_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libglvnd_jll", "Libtiff_jll", "libpng_jll"] +git-tree-sha1 = "ccbb625a89ec6195856a50aa2b668a5c08712c94" +uuid = "c5f90fcd-3b7e-5836-afba-fc50a0988cb2" +version = "1.4.0+0" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" +version = "1.59.0+0" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2021.12.0+0" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] @@ -1678,13 +1566,13 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" [[deps.x264_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "35976a1216d6c066ea32cba2150c4fa682b276fc" uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" -version = "2021.5.5+0" +version = "10164.0.0+0" [[deps.x265_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dcc541bb19ed5b0ede95581fb2e41ecf179527d2" uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" -version = "3.5.0+0" +version = "3.6.0+0" diff --git a/visualization/Project.toml b/visualization/Project.toml index c5b64e5103..ecf047c111 100644 --- a/visualization/Project.toml +++ b/visualization/Project.toml @@ -1,4 +1,3 @@ [deps] +CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" Ferrite = "c061ca5d-56c9-439f-9c0e-210fe06d3992" -FerriteViz = "59d0093e-b1f1-4fb7-ac85-ab57e45f39d9" -GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" From a696fe00b92ea27ebdf613d1064850c579fb5c63 Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Tue, 12 Nov 2024 11:00:49 +0100 Subject: [PATCH 135/145] Fix BrezziDouglasMarini --- src/interpolations.jl | 10 ++--- test/test_interpolations.jl | 6 ++- .../2d_vector_interpolation_checkplots.jl | 44 +++++++++++++++++-- visualization/Manifest.toml | 2 +- visualization/Project.toml | 1 + 5 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/interpolations.jl b/src/interpolations.jl index b6fc6c4f9b..4513674073 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1861,7 +1861,7 @@ end struct BrezziDouglasMarini{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end mapping_type(::BrezziDouglasMarini) = ContravariantPiolaMapping() reference_coordinates(ip::BrezziDouglasMarini{vdim}) where vdim = fill(NaN*zero(Vec{vdim}), getnbasefunctions(ip)) -dirichlet_facedof_indices(ip::BrezziDouglasMarini) = facetdof_interior_indices(ip) +#dirichlet_facedof_indices(ip::BrezziDouglasMarini) = facetdof_interior_indices(ip) n_dbc_components(::BrezziDouglasMarini) = 1 #= ----------------+-------------------- @@ -1886,11 +1886,11 @@ Edge numbers: | Edge identifiers: function reference_shape_value(ip::BrezziDouglasMarini{2, RefTriangle, 1}, ξ::Vec{2}, i::Int) x, y = ξ # Edge 1 - i == 1 && return Vec(4x, -2y) # Changed sign to make positive outwards + i == 1 && return Vec(4x, -2y) # Changed sign to integrated value positive outwards i == 2 && return Vec(-2x, 4y) # Changed sign to make positive outwards # Edge 2 (reverse order to follow Ferrite convention) - i == 3 && return Vec(-2x - 6y + 2, 4y) - i == 4 && return Vec(4x + 6y - 4, -2y) + i == 3 && return Vec(-2x - 6y + 2, 4y) # N ⋅ n = (6y - 2) + i == 4 && return Vec(4x + 6y - 4, -2y) # N ⋅ n = (4 - 6y) # Edge 3 i == 5 && return Vec(-2x, 6x + 4y - 4) # Changed sign to make positive outwards i == 6 && return Vec(4x, -6x - 2y + 2) # Changed sign to make positive outwards @@ -1899,7 +1899,7 @@ end getnbasefunctions(::BrezziDouglasMarini{2, RefTriangle, 1}) = 6 edgedof_interior_indices(::BrezziDouglasMarini{2, RefTriangle, 1}) = ((1, 2), (3, 4), (5, 6)) -adjust_dofs_during_distribution(::BrezziDouglasMarini{2, RefTriangle, 1}) = false +adjust_dofs_during_distribution(::BrezziDouglasMarini{2, RefTriangle, 1}) = true function get_direction(::BrezziDouglasMarini{2, RefTriangle, 1}, j, cell) edge = edges(cell)[(j + 1) ÷ 2] diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index 6ca757869f..17b52e55ff 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -309,7 +309,11 @@ end # 2) Zero normal component on other edges: Nⱼ ⋅ n = 0 if j∉𝔇 @testset "H(div) on RefCell" begin lineqr = QuadratureRule{RefLine}(20) - for ip in (RaviartThomas{2, RefTriangle, 1}(), Ferrite.BrezziDouglasMarini{2, RefTriangle, 1}(), ) + for ip in ( + RaviartThomas{2, RefTriangle, 1}(), + RaviartThomas{2, RefTriangle, 2}(), + Ferrite.BrezziDouglasMarini{2, RefTriangle, 1}(), + ) cell = reference_cell(getrefshape(ip)) cell_facets = Ferrite.facets(cell) dofs = Ferrite.facetdof_interior_indices(ip) diff --git a/visualization/2d_vector_interpolation_checkplots.jl b/visualization/2d_vector_interpolation_checkplots.jl index d51487bbc3..d48b4ad360 100644 --- a/visualization/2d_vector_interpolation_checkplots.jl +++ b/visualization/2d_vector_interpolation_checkplots.jl @@ -1,6 +1,13 @@ using Ferrite import CairoMakie as Plt +function facet_quadrature(::Type{RefShape}, nqp::Int) where RefShape + fqr = FacetQuadratureRule{RefShape}(nqp) + points = [p for rule in fqr.face_rules for p in rule.points] + weights = [w for rule in fqr.face_rules for w in rule.weights] + return QuadratureRule{RefShape}(weights, points) +end + function plot_shape_function(ip::VectorInterpolation{2, RefShape}, qr::Int, i::Int) where {RefShape<:Ferrite.AbstractRefShape{2}} return plot_shape_function(ip, QuadratureRule{RefShape}(qr), i) end @@ -12,12 +19,41 @@ function plot_shape_function(ip::VectorInterpolation{2, RefShape}, qr::Quadratur push!(vertices, first(vertices)) fig = Plt.Figure() - ax = Plt.Axis(fig[1,1]) + ax = Plt.Axis(fig[1,1]; aspect=Plt.DataAspect()) + Plt.xlims!(ax, (-1.0, 1.5)) Plt.lines!(ax, first.(vertices), last.(vertices)) - Plt.arrows!(ax, first.(points), last.(points), first.(N), last.(N); lengthscale = 0.3) + Plt.arrows!(ax, first.(points), last.(points), first.(N), last.(N); lengthscale = 0.1) + Plt.scatter!(ax, first.(points), last.(points)) return fig end -function plot_global_shape_function(ip, qr, nx, ny, i) - #TODO: Plot a single global shape function to investigate continuity +function plot_global_shape_function(ip::VectorInterpolation{2, RefShape}; qr_order::Int=0, nel, i, qr=nothing) where RefShape + fig = Plt.Figure() + ax = Plt.Axis(fig[1,1]) + _qr = qr === nothing ? QuadratureRule{RefShape}(qr_order) : qr + CT = RefShape === RefTriangle ? Triangle : Quadrilateral + grid = generate_grid(CT, (nel, nel)) + dh = close!(add!(DofHandler(grid), :u, ip)) + points = Vec{2, Float64}[] + directions = Vec{2, Float64}[] + cv = CellValues(_qr, ip, Lagrange{RefShape, 1}()) + cell_contour = getcoordinates(grid, 1) + resize!(cell_contour, length(cell_contour) + 1) + for cell in CellIterator(dh) + copyto!(cell_contour, getcoordinates(cell)) + cell_contour[end] = cell_contour[1] # Close contour + Plt.lines!(ax, first.(cell_contour), last.(cell_contour)) + if i ∈ celldofs(cell) + reinit!(cv, cell) + for q_point in 1:getnquadpoints(cv) + x = spatial_coordinate(cv, q_point, getcoordinates(cell)) + shape_index = findfirst(x -> x == i, celldofs(cell)) + push!(points, x) + push!(directions, shape_value(cv, q_point, shape_index)) + end + end + end + Plt.arrows!(ax, first.(points), last.(points), first.(directions), last.(directions); lengthscale = 0.1) + Plt.scatter!(ax, first.(points), last.(points)) + return fig end diff --git a/visualization/Manifest.toml b/visualization/Manifest.toml index 96331314ab..dfda582b2d 100644 --- a/visualization/Manifest.toml +++ b/visualization/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.11.1" manifest_format = "2.0" -project_hash = "f8140ea440af404cde81e65338add89dc118d0fc" +project_hash = "3f9b12f33e28e03dfcb3edf6f53efa43b44e834b" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] diff --git a/visualization/Project.toml b/visualization/Project.toml index ecf047c111..e101770250 100644 --- a/visualization/Project.toml +++ b/visualization/Project.toml @@ -1,3 +1,4 @@ [deps] CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" Ferrite = "c061ca5d-56c9-439f-9c0e-210fe06d3992" +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" From 80f5b251fb9b58bf41be465906b0a27989776189 Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Tue, 12 Nov 2024 15:03:29 +0100 Subject: [PATCH 136/145] Work through tutorial --- docs/make.jl | 3 +- docs/src/assets/references.bib | 22 ++ .../literate-tutorials/heat_equation_hdiv.jl | 233 +++++++++++ .../literate-tutorials/heat_equation_rt.jl | 372 ------------------ .../heat_equation_triangle.jl | 252 ------------ test/test_interpolations.jl | 4 +- 6 files changed, 258 insertions(+), 628 deletions(-) create mode 100644 docs/src/literate-tutorials/heat_equation_hdiv.jl delete mode 100644 docs/src/literate-tutorials/heat_equation_rt.jl delete mode 100644 docs/src/literate-tutorials/heat_equation_triangle.jl diff --git a/docs/make.jl b/docs/make.jl index 8876469345..1d5a7b6a10 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -55,8 +55,7 @@ bibtex_plugin = CitationBibliography( "Tutorials" => [ "Tutorials overview" => "tutorials/index.md", "tutorials/heat_equation.md", - "tutorials/heat_equation_rt.md", - "tutorials/heat_equation_triangle.md", + "tutorials/heat_equation_hdiv.md", "tutorials/linear_elasticity.md", "tutorials/incompressible_elasticity.md", "tutorials/hyperelasticity.md", diff --git a/docs/src/assets/references.bib b/docs/src/assets/references.bib index c240c43833..0678618983 100644 --- a/docs/src/assets/references.bib +++ b/docs/src/assets/references.bib @@ -190,3 +190,25 @@ @article{CroRav:1973:cnf year={1973}, publisher={EDP Sciences} } +@book{Gatica2014, +title = {A Simple Introduction to the Mixed Finite Element Method: Theory and Applications}, +ISBN = {9783319036953}, +ISSN = {2191-8201}, +url = {http://dx.doi.org/10.1007/978-3-319-03695-3}, +DOI = {10.1007/978-3-319-03695-3}, +journal = {SpringerBriefs in Mathematics}, +publisher = {Springer International Publishing}, +author = {Gatica, Gabriel N.}, +year = {2014} +} +@book{Boffi2013, + title = {Mixed Finite Element Methods and Applications}, + ISBN = {9783642365195}, + ISSN = {0179-3632}, + url = {http://dx.doi.org/10.1007/978-3-642-36519-5}, + DOI = {10.1007/978-3-642-36519-5}, + journal = {Springer Series in Computational Mathematics}, + publisher = {Springer Berlin Heidelberg}, + author = {Boffi, Daniele and Brezzi, Franco and Fortin, Michel}, + year = {2013} +} diff --git a/docs/src/literate-tutorials/heat_equation_hdiv.jl b/docs/src/literate-tutorials/heat_equation_hdiv.jl new file mode 100644 index 0000000000..155e42bd66 --- /dev/null +++ b/docs/src/literate-tutorials/heat_equation_hdiv.jl @@ -0,0 +1,233 @@ +# # [Heat equation - Mixed H(div) conforming formulation)](@id tutorial-heat-equation-hdiv) +# As an alternative to the standard formulation for solving the heat equation used in +# the [heat equation tutorial](@ref tutorial-heat-equation), we can used a mixed formulation +# where both the temperature, $u(\mathbf{x})$, and the heat flux, $\boldsymbol{q}(\boldsymbol{x})$, +# are primary variables. From a theoretical standpoint, there are many details on e.g. which combinations +# of interpolations that are stable. See e.g. [Gatica2014](@cite) and [Boffi2013](@cite) for further reading. +# This tutorial is based on the theory in +# [Fenics' mixed poisson example](https://fenicsproject.org/olddocs/dolfin/1.4.0/python/demo/documented/mixed-poisson/python/documentation.html). +# +# ![Temperature solution](https://raw.githubusercontent.com/Ferrite-FEM/Ferrite.jl/refs/heads/gh-pages/assets/heat_equation_hdiv.png) +# **Figure:** Temperature distribution considering a central part with lower heat conductivity. +# +# The advantage with the mixed formulation is that the heat flux is approximated better. However, the +# temperature becomes discontinuous where the conductivity is discontinuous. +# +# ## Theory +# We start with the strong form of the heat equation: Find the temperature, $u(\boldsymbol{x})$, and heat flux, $\boldsymbol{q}(x)$, +# such that +# ```math +# \begin{align*} +# \boldsymbol{\nabla}\cdot \boldsymbol{q} &= h(\boldsymbol{x}), \quad \forall \boldsymbol{x} \in \Omega \\ +# \boldsymbol{q}(\boldsymbol{x}) &= - k\ \boldsymbol{\nabla} u(\boldsymbol{x}), \quad \forall \boldsymbol{x} \in \Omega \\ +# \boldsymbol{q}(\boldsymbol{x})\cdot \boldsymbol{n}(\boldsymbol{x}) &= q_n, \quad \forall \boldsymbol{x} \in \Gamma_\mathrm{N}\\ +# u(\boldsymbol{x}) &= u_\mathrm{D}, \quad \forall \boldsymbol{x} \in \Gamma_\mathrm{D} +# \end{align*} +# ``` +# +# From this strong form, we can formulate the weak form as a mixed formulation. +# Find $u \in \mathbb{U}$ and $\boldsymbol{q}\in\mathbb{Q}$ such that +# ```math +# \begin{align*} +# \int_{\Omega} \delta u [\boldsymbol{\nabla} \cdot \boldsymbol{q}]\ \mathrm{d}\Omega &= \int_\Omega \delta u h\ \mathrm{d}\Omega, \quad \forall\ \delta u \in \delta\mathbb{U} \\ +# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= -\int_\Omega \boldsymbol{\delta q} \cdot [k\ \boldsymbol{\nabla} u]\ \mathrm{d}\Omega \\ +# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega - \int_{\Omega} [\boldsymbol{\nabla} \cdot \boldsymbol{\delta q}] k u \ \mathrm{d}\Omega &= +# -\int_\Gamma \boldsymbol{\delta q} \cdot \boldsymbol{n} k\ u\ \mathrm{d}\Omega, \quad \forall\ \boldsymbol{\delta q} \in \delta\mathbb{Q} +# \end{align*} +# ``` +# where we have the function spaces, +# ```math +# \begin{align*} +# \mathbb{U} &= \delta\mathbb{U} = L^2 \\ +# \mathbb{Q} &= \lbrace \boldsymbol{q} \in H(\mathrm{div}) \text{ such that } \boldsymbol{q}\cdot\boldsymbol{n} = q_\mathrm{n} \text{ on } \Gamma_\mathrm{D}\rbrace \\ +# \delta\mathbb{Q} &= \lbrace \boldsymbol{q} \in H(\mathrm{div}) \text{ such that } \boldsymbol{q}\cdot\boldsymbol{n} = 0 \text{ on } \Gamma_\mathrm{D}\rbrace +# \end{align*} +# ``` +# A stable choice of finite element spaces for this problem on grid with triangles is using +# * `DiscontinuousLagrange{RefTriangle, k-1}` for approximating $L^2$ +# * `BrezziDouglasMarini{RefTriangle, k}` for approximating $H(\mathrm{div})$ +# +# We will also investigate the consequences of using $H^1$ `Lagrange` instead of $H(\mathrm{div})$ interpolations. +# +# ## Commented Program +# +# Now we solve the problem in Ferrite. What follows is a program spliced with comments. +# +# First we load Ferrite, +using Ferrite +# And define our grid, representing a channel with a central part having a lower +# conductivity, $k$, than the surrounding. +function create_grid(ny::Int) + width = 10.0 + length = 40.0 + center_width = 5.0 + center_length = 20.0 + upper_right = Vec((length / 2, width / 2)) + grid = generate_grid(Triangle, (round(Int, ny * length / width), ny), -upper_right, upper_right); + addcellset!(grid, "center", x -> abs(x[1]) < center_length/2 && abs(x[2]) < center_width / 2) + addcellset!(grid, "around", setdiff(1:getncells(grid), getcellset(grid, "center"))) + return grid +end + +grid = create_grid(100) + +# ### Setup +# We define one `CellValues` for each field which share the same quadrature rule. +ip_geo = geometric_interpolation(getcelltype(grid)) +ipu = DiscontinuousLagrange{RefTriangle, 0}() +ipq = Ferrite.BrezziDouglasMarini{2, RefTriangle, 1}() +qr = QuadratureRule{RefTriangle}(2) +cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) + +# Distribute the degrees of freedom +dh = DofHandler(grid) +add!(dh, :u, ipu) +add!(dh, :q, ipq) +close!(dh); + +# In this problem, we have a zero temperature on the boundary, Γ, which is enforced +# via zero Neumann boundary conditions. Hence, we don't need a `Constrainthandler`. +Γ = union((getfacetset(grid, name) for name in ("left", "right", "bottom", "top"))...) + +# ### Element implementation + +function assemble_element!(Ke::Matrix, fe::Vector, cv::NamedTuple, dr::NamedTuple, k::Number) + cvu = cv[:u] + cvq = cv[:q] + dru = dr[:u] + drq = dr[:q] + h = 1.0 # Heat source + ## Loop over quadrature points + for q_point in 1:getnquadpoints(cvu) + ## Get the quadrature weight + dΩ = getdetJdV(cvu, q_point) + ## Loop over test shape functions + for (iu, Iu) in pairs(dru) + δNu = shape_value(cvu, q_point, iu) + ## Add contribution to fe + fe[Iu] += δNu * h * dΩ + ## Loop over trial shape functions + for (jq, Jq) in pairs(drq) + div_Nq = shape_divergence(cvq, q_point, jq) + ## Add contribution to Ke + Ke[Iu, Jq] += (δNu * div_Nq) * dΩ + end + end + for (iq, Iq) in pairs(drq) + δNq = shape_value(cvq, q_point, iq) + div_δNq = shape_divergence(cvq, q_point, iq) + for (ju, Ju) in pairs(dru) + Nu = shape_value(cvu, q_point, ju) + Ke[Iq, Ju] -= div_δNq * k * Nu * dΩ + end + for (jq, Jq) in pairs(drq) + Nq = shape_value(cvq, q_point, jq) + Ke[Iq, Jq] += (δNq ⋅ Nq) * dΩ + end + end + end + return Ke, fe +end +#md nothing # hide + +# ### Global assembly + +function assemble_global(cellvalues, dh::DofHandler) + grid = dh.grid + ## Allocate the element stiffness matrix and element force vector + dofranges = (u = dof_range(dh, :u), q = dof_range(dh, :q)) + ncelldofs = ndofs_per_cell(dh) + Ke = zeros(ncelldofs, ncelldofs) + fe = zeros(ncelldofs) + ## Allocate global system matrix and vector + K = allocate_matrix(dh) + f = zeros(ndofs(dh)) + ## Create an assembler + assembler = start_assemble(K, f) + x = copy(getcoordinates(grid, 1)) + dofs = copy(celldofs(dh, 1)) + ## Loop over all cells + for (cells, k) in ( + (getcellset(grid, "center"), 0.1), + (getcellset(grid, "around"), 1.00)) + for cellnr in cells + ## Reinitialize cellvalues for this cell + cell = getcells(grid, cellnr) + getcoordinates!(x, grid, cell) + celldofs!(dofs, dh, cellnr) + reinit!(cellvalues[:u], cell, x) + reinit!(cellvalues[:q], cell, x) + ## Reset to 0 + fill!(Ke, 0) + fill!(fe, 0) + ## Compute element contribution + assemble_element!(Ke, fe, cellvalues, dofranges, k) + ## Assemble Ke and fe into K and f + assemble!(assembler, dofs, Ke, fe) + end + end + return K, f +end +#md nothing # hide + +# ### Solution of the system +K, f = assemble_global(cellvalues, dh); +u = K \ f; + +# ### Exporting to VTK +# Currently, exporting discontinuous interpolations is not supported. +# Since in this case, we have a single temperature degree of freedom +# per cell, we work around this by calculating the per-cell temperature. +temperature_dof = first(dof_range(dh, :u)) +u_cells = map(1:getncells(grid)) do i + u[celldofs(dh, i)[temperature_dof]] +end +VTKGridFile("heat_equation_hdiv", dh) do vtk + write_cell_data(vtk, u_cells, "temperature") +end + +# ## Postprocess the total flux +# We applied a constant unit heat source to the body, and the +# total heat flux exiting across the boundary should therefore +# match the area for the considered stationary case. +function calculate_flux(dh, boundary_facets, ip, a) + grid = dh.grid + qr = FacetQuadratureRule{RefTriangle}(4) + ip_geo = geometric_interpolation(getcelltype(grid)) + fv = FacetValues(qr, ip, ip_geo) + + dofrange = dof_range(dh, :q) + flux = 0.0 + dofs = celldofs(dh, 1) + ae = zeros(length(dofs)) + x = getcoordinates(grid, 1) + for (cellnr, facetnr) in boundary_facets + getcoordinates!(x, grid, cellnr) + cell = getcells(grid, cellnr) + celldofs!(dofs, dh, cellnr) + map!(i->a[i], ae, dofs) + reinit!(fv, cell, x, facetnr) + for q_point in 1:getnquadpoints(fv) + dΓ = getdetJdV(fv, q_point) + n = getnormal(fv, q_point) + q = function_value(fv, q_point, ae, dofrange) + flux += (q ⋅ n)*dΓ + end + end + return flux +end + +println("Outward flux: ", calculate_flux(dh, Γ, ipq, u)) + +# Note that this is not the case for the standard [Heat equation](@id tutorial-heat-equation), +# as the flux terms are less accurately approximated. A fine mesh is required to converge in that case. +# However, the present example gives a worse approximation of the temperature field. + +#md # ## [Plain program](@id tutorial-heat-equation-hdiv-plain) +#md # +#md # Here follows a version of the program without any comments. +#md # The file is also available here: [`heat_equation_hdiv.jl`](heat_equation_hdiv.jl). +#md # +#md # ```julia +#md # @__CODE__ +#md # ``` diff --git a/docs/src/literate-tutorials/heat_equation_rt.jl b/docs/src/literate-tutorials/heat_equation_rt.jl deleted file mode 100644 index 2d22955038..0000000000 --- a/docs/src/literate-tutorials/heat_equation_rt.jl +++ /dev/null @@ -1,372 +0,0 @@ -# # [Heat equation (Mixed, RaviartThomas)](@id tutorial-heat-equation-rt) -# Note, there are a lot to consider here it seems like. Good refs, -# ``` -# @book{Gatica2014, -# title = {A Simple Introduction to the Mixed Finite Element Method: Theory and Applications}, -# ISBN = {9783319036953}, -# ISSN = {2191-8201}, -# url = {http://dx.doi.org/10.1007/978-3-319-03695-3}, -# DOI = {10.1007/978-3-319-03695-3}, -# journal = {SpringerBriefs in Mathematics}, -# publisher = {Springer International Publishing}, -# author = {Gatica, Gabriel N.}, -# year = {2014} -# } -# See also, -# @book{Boffi2013, -# title = {Mixed Finite Element Methods and Applications}, -# ISBN = {9783642365195}, -# ISSN = {0179-3632}, -# url = {http://dx.doi.org/10.1007/978-3-642-36519-5}, -# DOI = {10.1007/978-3-642-36519-5}, -# journal = {Springer Series in Computational Mathematics}, -# publisher = {Springer Berlin Heidelberg}, -# author = {Boffi, Daniele and Brezzi, Franco and Fortin, Michel}, -# year = {2013} -# } -# for a(n even) more comprehensive book. -# ``` -# -# ## Theory -# We start with the strong form of the heat equation: Find the temperature, $u(\boldsymbol{x})$, and heat flux, $\boldsymbol{q}(x)$, -# such that -# ```math -# \begin{align*} -# \boldsymbol{\nabla}\cdot \boldsymbol{q} &= h(\boldsymbol{x}), \quad \forall \boldsymbol{x} \in \Omega \\ -# \boldsymbol{q}(\boldsymbol{x}) &= - k\ \boldsymbol{\nabla} u(\boldsymbol{x}), \quad \forall \boldsymbol{x} \in \Omega \\ -# \boldsymbol{q}(\boldsymbol{x})\cdot \boldsymbol{n}(\boldsymbol{x}) &= q_n, \quad \forall \boldsymbol{x} \in \Gamma_\mathrm{N}\\ -# u(\boldsymbol{x}) &= u_\mathrm{D}, \quad \forall \boldsymbol{x} \in \Gamma_\mathrm{D} -# \end{align*} -# ``` -# -# From this strong form, we can formulate the weak form as a mixed formulation. -# Find $u \in \mathbb{U}$ and $\boldsymbol{q}\in\mathbb{Q}$ such that -# ```math -# \begin{align*} -# \int_{\Omega} \delta u [\boldsymbol{\nabla} \cdot \boldsymbol{q}]\ \mathrm{d}\Omega &= - \int_\Omega \delta u h\ \mathrm{d}\Omega, \quad \forall\ \delta u \in \delta\mathbb{U} \\ -# %\int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= \int_\Omega \boldsymbol{\delta q} \cdot [k\ \boldsymbol{\nabla} u]\ \mathrm{d}\Omega \\ -# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega + \int_{\Omega} [\boldsymbol{\nabla} \cdot \boldsymbol{\delta q}] k u \ \mathrm{d}\Omega &= -# \int_\Gamma \boldsymbol{\delta q} \cdot \boldsymbol{n} k\ u\ \mathrm{d}\Omega, \quad \forall\ \boldsymbol{\delta q} \in \delta\mathbb{Q} -# \end{align*} -# ``` -# where we have the function spaces -# * $\mathbb{U} = \delta\mathbb{U} = L^2$ -# * $\mathbb{Q} = \lbrace \boldsymbol{q} \in H(\mathrm{div}) \text{such that} \boldsymbol{q}\cdot\boldsymbol{n} = q_\mathrm{n} \text{ on } \Gamma_\mathrm{D}\rbrace$ -# * $\mathbb{Q} = \lbrace \boldsymbol{q} \in H(\mathrm{div}) \text{such that} \boldsymbol{q}\cdot\boldsymbol{n} = 0 \text{ on } \Gamma_\mathrm{D}\rbrace$ -# -# A stable choice of finite element spaces for this problem on grid with triangles is using -# * `DiscontinuousLagrange{RefTriangle, k-1}` for approximating $L^2$ -# * `BrezziDouglasMarini{RefTriangle, k}` for approximating $H(\mathrm{div})$ -# following [fenics](https://fenicsproject.org/olddocs/dolfin/1.4.0/python/demo/documented/mixed-poisson/python/documentation.html). -# For further details, see Boffi2013. -# We will also see what happens if we instead use `Lagrange` elements which are a subspace of $H^1$ instead of $H(\mathrm{div})$ elements. -# -# ## Commented Program -# -# Now we solve the problem in Ferrite. What follows is a program spliced with comments. -# -# First we load Ferrite, -using Ferrite -# And define our grid, representing a channel with a central part having a lower -# conductivity, $k$, than the surrounding. -function create_grid(ny::Int) - width = 10.0 - length = 40.0 - center_width = 5.0 - center_length = 20.0 - upper_right = Vec((length / 2, width / 2)) - grid = generate_grid(Triangle, (round(Int, ny * length / width), ny), -upper_right, upper_right); - addcellset!(grid, "center", x -> abs(x[1]) < center_width/2 && abs(x[2]) < center_length / 2) - addcellset!(grid, "around", setdiff(1:getncells(grid), getcellset(grid, "center"))) - return grid -end - -grid = create_grid(10) - -# ### Trial and test functions -# A `CellValues` facilitates the process of evaluating values and gradients of -# test and trial functions (among other things). To define -# this we need to specify an interpolation space for the shape functions. -# We use Lagrange functions -# based on the two-dimensional reference quadrilateral. We also define a quadrature rule based on -# the same reference element. We combine the interpolation and the quadrature rule -# to a `CellValues` object. -ip_geo = geometric_interpolation(getcelltype(grid)) -ipu = DiscontinuousLagrange{RefTriangle, 1}() # Why does it "explode" for 2nd order ipu? -ipq = RaviartThomas{2,RefTriangle, 1}() -qr = QuadratureRule{RefTriangle}(2) -cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) - -# ### Degrees of freedom -# Next we need to define a `DofHandler`, which will take care of numbering -# and distribution of degrees of freedom for our approximated fields. -# We create the `DofHandler` and then add a single scalar field called `:u` based on -# our interpolation `ip` defined above. -# Lastly we `close!` the `DofHandler`, it is now that the dofs are distributed -# for all the elements. -dh = DofHandler(grid) -add!(dh, :u, ipu) -add!(dh, :q, ipq) -close!(dh); - -# Now that we have distributed all our dofs we can create our tangent matrix, -# using `create_sparsity_pattern`. This function returns a sparse matrix -# with the correct entries stored. -K = allocate_matrix(dh) - -# ### Boundary conditions -# In Ferrite constraints like Dirichlet boundary conditions -# are handled by a `ConstraintHandler`. -ch = ConstraintHandler(dh); - -# Next we need to add constraints to `ch`. For this problem we define -# homogeneous Dirichlet boundary conditions on the whole boundary, i.e. -# the `union` of all the boundary facet sets. -∂Ω = union( - getfacetset(grid, "left"), - getfacetset(grid, "right"), - getfacetset(grid, "top"), - getfacetset(grid, "bottom"), -); - -# Now we are set up to define our constraint. We specify which field -# the condition is for, and our combined face set `∂Ω`. The last -# argument is a function of the form $f(\textbf{x})$ or $f(\textbf{x}, t)$, -# where $\textbf{x}$ is the spatial coordinate and -# $t$ the current time, and returns the prescribed value. Since the boundary condition in -# this case do not depend on time we define our function as $f(\textbf{x}) = 0$, i.e. -# no matter what $\textbf{x}$ we return $0$. When we have -# specified our constraint we `add!` it to `ch`. -dbc = Dirichlet(:u, ∂Ω, (x, t) -> 0) -add!(ch, dbc); - -# Finally we also need to `close!` our constraint handler. When we call `close!` -# the dofs corresponding to our constraints are calculated and stored -# in our `ch` object. -close!(ch) - -# Note that if one or more of the constraints are time dependent we would use -# [`update!`](@ref) to recompute prescribed values in each new timestep. - -# ### Assembling the linear system -# -# Now we have all the pieces needed to assemble the linear system, $K u = f$. -# Assembling of the global system is done by looping over all the elements in order to -# compute the element contributions ``K_e`` and ``f_e``, which are then assembled to the -# appropriate place in the global ``K`` and ``f``. -# -# #### Element assembly -# We define the function `assemble_element!` (see below) which computes the contribution for -# an element. The function takes pre-allocated `ke` and `fe` (they are allocated once and -# then reused for all elements) so we first need to make sure that they are all zeroes at -# the start of the function by using `fill!`. Then we loop over all the quadrature points, -# and for each quadrature point we loop over all the (local) shape functions. We need the -# value and gradient of the test function, `δu` and also the gradient of the trial function -# `u`. We get all of these from `cellvalues`. -# -# !!! note "Notation" -# Comparing with the brief finite element introduction in [Introduction to FEM](@ref), -# the variables `δu`, `∇δu` and `∇u` are actually $\phi_i(\textbf{x}_q)$, $\nabla -# \phi_i(\textbf{x}_q)$ and $\nabla \phi_j(\textbf{x}_q)$, i.e. the evaluation of the -# trial and test functions in the quadrature point ``\textbf{x}_q``. However, to -# underline the strong parallel between the weak form and the implementation, this -# example uses the symbols appearing in the weak form. - -function assemble_element!(Ke::Matrix, fe::Vector, cv::NamedTuple, dr::NamedTuple) - cvu = cv[:u] - cvq = cv[:q] - dru = dr[:u] - drq = dr[:q] - ## Loop over quadrature points - for q_point in 1:getnquadpoints(cvu) - ## Get the quadrature weight - dΩ = getdetJdV(cvu, q_point) - ## Loop over test shape functions - for (iu, Iu) in pairs(dru) - δu = shape_value(cvu, q_point, iu) - ∇δu = shape_gradient(cvu, q_point, iu) - ## Add contribution to fe - fe[Iu] -= δu * dΩ - ## Loop over trial shape functions - for (jq, Jq) in pairs(drq) - q = shape_value(cvq, q_point, jq) - ## Add contribution to Ke - Ke[Iu, Jq] += (∇δu ⋅ q) * dΩ - end - end - for (iq, Iq) in pairs(drq) - δq = shape_value(cvq, q_point, iq) - for (ju, Ju) in pairs(dru) - ∇u = shape_gradient(cvu, q_point, ju) - Ke[Iq, Ju] += (δq ⋅ ∇u) * dΩ - end - for (jq, Jq) in pairs(drq) - q = shape_value(cvq, q_point, jq) - Ke[Iq, Jq] += (δq ⋅ q) * dΩ - end - end - end - return Ke, fe -end -#md nothing # hide - -# #### Global assembly -# We define the function `assemble_global` to loop over the elements and do the global -# assembly. The function takes our `cellvalues`, the sparse matrix `K`, and our DofHandler -# as input arguments and returns the assembled global stiffness matrix, and the assembled -# global force vector. We start by allocating `Ke`, `fe`, and the global force vector `f`. -# We also create an assembler by using `start_assemble`. The assembler lets us assemble into -# `K` and `f` efficiently. We then start the loop over all the elements. In each loop -# iteration we reinitialize `cellvalues` (to update derivatives of shape functions etc.), -# compute the element contribution with `assemble_element!`, and then assemble into the -# global `K` and `f` with `assemble!`. -# -# !!! note "Notation" -# Comparing again with [Introduction to FEM](@ref), `f` and `u` correspond to -# $\underline{\hat{f}}$ and $\underline{\hat{u}}$, since they represent the discretized -# versions. However, through the code we use `f` and `u` instead to reflect the strong -# connection between the weak form and the Ferrite implementation. - -function assemble_global(cellvalues, K::SparseMatrixCSC, dh::DofHandler) - grid = dh.grid - ## Allocate the element stiffness matrix and element force vector - dofranges = (u = dof_range(dh, :u), q = dof_range(dh, :q)) - ncelldofs = ndofs_per_cell(dh) - Ke = zeros(ncelldofs, ncelldofs) - fe = zeros(ncelldofs) - ## Allocate global force vector f - f = zeros(ndofs(dh)) - ## Create an assembler - assembler = start_assemble(K, f) - x = copy(getcoordinates(grid, 1)) - dofs = copy(celldofs(dh, 1)) - ## Loop over all cels - for cellnr in 1:getncells(grid) - ## Reinitialize cellvalues for this cell - cell = getcells(grid, cellnr) - getcoordinates!(x, grid, cell) - celldofs!(dofs, dh, cellnr) - reinit!(cellvalues[:u], cell, x) - reinit!(cellvalues[:q], cell, x) - ## Reset to 0 - fill!(Ke, 0) - fill!(fe, 0) - ## Compute element contribution - assemble_element!(Ke, fe, cellvalues, dofranges) - ## Assemble Ke and fe into K and f - assemble!(assembler, dofs, Ke, fe) - end - return K, f -end -#md nothing # hide - -# ### Solution of the system -# The last step is to solve the system. First we call `assemble_global` -# to obtain the global stiffness matrix `K` and force vector `f`. -K, f = assemble_global(cellvalues, K, dh); - -# To account for the boundary conditions we use the `apply!` function. -# This modifies elements in `K` and `f` respectively, such that -# we can get the correct solution vector `u` by using `\`. -apply!(K, f, ch) -u = K \ f; - -# ### Exporting to VTK -# To visualize the result we export the grid and our field `u` -# to a VTK-file, which can be viewed in e.g. [ParaView](https://www.paraview.org/). -u_nodes = evaluate_at_grid_nodes(dh, u, :u) -∂Ω_cells = zeros(Int, getncells(grid)) -for (cellnr, _) in ∂Ω - ∂Ω_cells[cellnr] = 1 -end -VTKGridFile("heat_equation_rt", dh) do vtk - write_node_data(vtk, u_nodes, "u") - write_cell_data(vtk, ∂Ω_cells, "dO") -end - -@show norm(u_nodes)/length(u_nodes) - -# ## Postprocess the total flux -function calculate_flux(dh, dΩ, ip, a) - grid = dh.grid - qr = FacetQuadratureRule{RefTriangle}(4) - ip_geo = geometric_interpolation(getcelltype(grid)) - fv = FacetValues(qr, ip, ip_geo) - - dofrange = dof_range(dh, :q) - flux = 0.0 - dofs = celldofs(dh, 1) - ae = zeros(length(dofs)) - x = getcoordinates(grid, 1) - for (cellnr, facenr) in dΩ - getcoordinates!(x, grid, cellnr) - cell = getcells(grid, cellnr) - celldofs!(dofs, dh, cellnr) - map!(i->a[i], ae, dofs) - reinit!(fv, cell, x, facenr) - for q_point in 1:getnquadpoints(fv) - dΓ = getdetJdV(fv, q_point) - n = getnormal(fv, q_point) - q = function_value(fv, q_point, ae, dofrange) - flux += (q ⋅ n)*dΓ - end - end - return flux -end - -function calculate_flux_lag(dh, dΩ, ip, a) - grid = dh.grid - qr = FacetQuadratureRule{RefTriangle}(4) - ip_geo = geometric_interpolation(getcelltype(grid)) - fv = FacetValues(qr, ip, ip_geo) - dofrange = dof_range(dh, :u) - flux = 0.0 - dofs = celldofs(dh, 1) - ae = zeros(length(dofs)) - x = getcoordinates(grid, 1) - for (cellnr, facenr) in dΩ - getcoordinates!(x, grid, cellnr) - cell = getcells(grid, cellnr) - celldofs!(dofs, dh, cellnr) - map!(i->a[i], ae, dofs) - reinit!(fv, cell, x, facenr) - for q_point in 1:getnquadpoints(fv) - dΓ = getdetJdV(fv, q_point) - n = getnormal(fv, q_point) - q = function_gradient(fv, q_point, ae, dofrange) - flux -= (q ⋅ n)*dΓ - end - end - return flux -end - -flux = calculate_flux(dh, ∂Ω, ipq, u) -flux_lag = calculate_flux_lag(dh, ∂Ω, ipu, u) -@show flux, flux_lag - - -function get_Ke(dh, cellvalues; cellnr=1) - dofranges = (u = dof_range(dh, :u), q = dof_range(dh, :q)) - ncelldofs = ndofs_per_cell(dh) - Ke = zeros(ncelldofs, ncelldofs) - fe = zeros(ncelldofs) - x = getcoordinates(grid, cellnr) - cell = getcells(grid, cellnr) - reinit!(cellvalues[:u], cell, x) - reinit!(cellvalues[:q], cell, x) - - ## Reset to 0 - fill!(Ke, 0) - fill!(fe, 0) - ## Compute element contribution - assemble_element!(Ke, fe, cellvalues, dofranges) - return Ke -end -#md # ## [Plain program](@id heat_equation-plain-program) -#md # -#md # Here follows a version of the program without any comments. -#md # The file is also available here: [`heat_equation.jl`](heat_equation.jl). -#md # -#md # ```julia -#md # @__CODE__ -#md # ``` diff --git a/docs/src/literate-tutorials/heat_equation_triangle.jl b/docs/src/literate-tutorials/heat_equation_triangle.jl deleted file mode 100644 index c5505ef026..0000000000 --- a/docs/src/literate-tutorials/heat_equation_triangle.jl +++ /dev/null @@ -1,252 +0,0 @@ -# # [Heat equation (Triangle)](@id tutorial-heat-equation-triangle) -# -# ![](heat_square.png) -# -# *Figure 1*: Temperature field on the unit square with an internal uniform heat source -# solved with homogeneous Dirichlet boundary conditions on the boundary. -# -# ## Introduction -# -# The heat equation is the "Hello, world!" equation of finite elements. -# Here we solve the equation on a unit square, with a uniform internal source. -# The strong form of the (linear) heat equation is given by -# -# ```math -# -\nabla \cdot (k \nabla u) = f \quad \textbf{x} \in \Omega, -# ``` -# -# where $u$ is the unknown temperature field, $k$ the heat conductivity, -# $f$ the heat source and $\Omega$ the domain. For simplicity we set $f = 1$ -# and $k = 1$. We will consider homogeneous Dirichlet boundary conditions such that -# ```math -# u(\textbf{x}) = 0 \quad \textbf{x} \in \partial \Omega, -# ``` -# where $\partial \Omega$ denotes the boundary of $\Omega$. -# The resulting weak form is given given as follows: Find ``u \in \mathbb{U}`` such that -# ```math -# \int_{\Omega} \nabla \delta u \cdot \nabla u \ d\Omega = \int_{\Omega} \delta u \ d\Omega \quad \forall \delta u \in \mathbb{T}, -# ``` -# where $\delta u$ is a test function, and where $\mathbb{U}$ and $\mathbb{T}$ are suitable -# trial and test function sets, respectively. -#- -# ## Commented Program -# -# Now we solve the problem in Ferrite. What follows is a program spliced with comments. -# -# First we load Ferrite, and some other packages we need -using Ferrite, SparseArrays -# We start by generating a simple grid with 20x20 quadrilateral elements -# using `generate_grid`. The generator defaults to the unit square, -# so we don't need to specify the corners of the domain. -grid = generate_grid(Triangle, (20, 20)); - -# ### Trial and test functions -# A `CellValues` facilitates the process of evaluating values and gradients of -# test and trial functions (among other things). To define -# this we need to specify an interpolation space for the shape functions. -# We use Lagrange functions -# based on the two-dimensional reference quadrilateral. We also define a quadrature rule based on -# the same reference element. We combine the interpolation and the quadrature rule -# to a `CellValues` object. -ip = Lagrange{RefTriangle, 1}() -qr = QuadratureRule{RefTriangle}(2) -cellvalues = CellValues(qr, ip); - -# ### Degrees of freedom -# Next we need to define a `DofHandler`, which will take care of numbering -# and distribution of degrees of freedom for our approximated fields. -# We create the `DofHandler` and then add a single scalar field called `:u` based on -# our interpolation `ip` defined above. -# Lastly we `close!` the `DofHandler`, it is now that the dofs are distributed -# for all the elements. -dh = DofHandler(grid) -add!(dh, :u, ip) -close!(dh); - -# Now that we have distributed all our dofs we can create our tangent matrix, -# using `create_sparsity_pattern`. This function returns a sparse matrix -# with the correct entries stored. -K = allocate_matrix(dh) - -# ### Boundary conditions -# In Ferrite constraints like Dirichlet boundary conditions -# are handled by a `ConstraintHandler`. -ch = ConstraintHandler(dh); - -# Next we need to add constraints to `ch`. For this problem we define -# homogeneous Dirichlet boundary conditions on the whole boundary, i.e. -# the `union` of all the face sets on the boundary. -∂Ω = union( - getfacetset(grid, "left"), - getfacetset(grid, "right"), - getfacetset(grid, "top"), - getfacetset(grid, "bottom"), -); - -# Now we are set up to define our constraint. We specify which field -# the condition is for, and our combined face set `∂Ω`. The last -# argument is a function of the form $f(\textbf{x})$ or $f(\textbf{x}, t)$, -# where $\textbf{x}$ is the spatial coordinate and -# $t$ the current time, and returns the prescribed value. Since the boundary condition in -# this case do not depend on time we define our function as $f(\textbf{x}) = 0$, i.e. -# no matter what $\textbf{x}$ we return $0$. When we have -# specified our constraint we `add!` it to `ch`. -dbc = Dirichlet(:u, ∂Ω, (x, t) -> 0) -add!(ch, dbc); - -# Finally we also need to `close!` our constraint handler. When we call `close!` -# the dofs corresponding to our constraints are calculated and stored -# in our `ch` object. -close!(ch) - -# Note that if one or more of the constraints are time dependent we would use -# [`update!`](@ref) to recompute prescribed values in each new timestep. - -# ### Assembling the linear system -# -# Now we have all the pieces needed to assemble the linear system, $K u = f$. -# Assembling of the global system is done by looping over all the elements in order to -# compute the element contributions ``K_e`` and ``f_e``, which are then assembled to the -# appropriate place in the global ``K`` and ``f``. -# -# #### Element assembly -# We define the function `assemble_element!` (see below) which computes the contribution for -# an element. The function takes pre-allocated `ke` and `fe` (they are allocated once and -# then reused for all elements) so we first need to make sure that they are all zeroes at -# the start of the function by using `fill!`. Then we loop over all the quadrature points, -# and for each quadrature point we loop over all the (local) shape functions. We need the -# value and gradient of the test function, `δu` and also the gradient of the trial function -# `u`. We get all of these from `cellvalues`. -# -# !!! note "Notation" -# Comparing with the brief finite element introduction in [Introduction to FEM](@ref), -# the variables `δu`, `∇δu` and `∇u` are actually $\phi_i(\textbf{x}_q)$, $\nabla -# \phi_i(\textbf{x}_q)$ and $\nabla \phi_j(\textbf{x}_q)$, i.e. the evaluation of the -# trial and test functions in the quadrature point ``\textbf{x}_q``. However, to -# underline the strong parallel between the weak form and the implementation, this -# example uses the symbols appearing in the weak form. - -function assemble_element!(Ke::Matrix, fe::Vector, cellvalues::CellValues) - n_basefuncs = getnbasefunctions(cellvalues) - ## Reset to 0 - fill!(Ke, 0) - fill!(fe, 0) - ## Loop over quadrature points - for q_point in 1:getnquadpoints(cellvalues) - ## Get the quadrature weight - dΩ = getdetJdV(cellvalues, q_point) - ## Loop over test shape functions - for i in 1:n_basefuncs - δu = shape_value(cellvalues, q_point, i) - ∇δu = shape_gradient(cellvalues, q_point, i) - ## Add contribution to fe - fe[i] += δu * dΩ - ## Loop over trial shape functions - for j in 1:n_basefuncs - ∇u = shape_gradient(cellvalues, q_point, j) - ## Add contribution to Ke - Ke[i, j] += (∇δu ⋅ ∇u) * dΩ - end - end - end - return Ke, fe -end -#md nothing # hide - -# #### Global assembly -# We define the function `assemble_global` to loop over the elements and do the global -# assembly. The function takes our `cellvalues`, the sparse matrix `K`, and our DofHandler -# as input arguments and returns the assembled global stiffness matrix, and the assembled -# global force vector. We start by allocating `Ke`, `fe`, and the global force vector `f`. -# We also create an assembler by using `start_assemble`. The assembler lets us assemble into -# `K` and `f` efficiently. We then start the loop over all the elements. In each loop -# iteration we reinitialize `cellvalues` (to update derivatives of shape functions etc.), -# compute the element contribution with `assemble_element!`, and then assemble into the -# global `K` and `f` with `assemble!`. -# -# !!! note "Notation" -# Comparing again with [Introduction to FEM](@ref), `f` and `u` correspond to -# $\underline{\hat{f}}$ and $\underline{\hat{u}}$, since they represent the discretized -# versions. However, through the code we use `f` and `u` instead to reflect the strong -# connection between the weak form and the Ferrite implementation. - -function assemble_global(cellvalues::CellValues, K::SparseMatrixCSC, dh::DofHandler) - ## Allocate the element stiffness matrix and element force vector - n_basefuncs = getnbasefunctions(cellvalues) - Ke = zeros(n_basefuncs, n_basefuncs) - fe = zeros(n_basefuncs) - ## Allocate global force vector f - f = zeros(ndofs(dh)) - ## Create an assembler - assembler = start_assemble(K, f) - ## Loop over all cels - for cell in CellIterator(dh) - ## Reinitialize cellvalues for this cell - reinit!(cellvalues, cell) - ## Compute element contribution - assemble_element!(Ke, fe, cellvalues) - ## Assemble Ke and fe into K and f - assemble!(assembler, celldofs(cell), Ke, fe) - end - return K, f -end -#md nothing # hide - -# ### Solution of the system -# The last step is to solve the system. First we call `assemble_global` -# to obtain the global stiffness matrix `K` and force vector `f`. -K, f = assemble_global(cellvalues, K, dh); - -# To account for the boundary conditions we use the `apply!` function. -# This modifies elements in `K` and `f` respectively, such that -# we can get the correct solution vector `u` by using `\`. -apply!(K, f, ch) -u = K \ f; - -# ### Exporting to VTK -# To visualize the result we export the grid and our field `u` -# to a VTK-file, which can be viewed in e.g. [ParaView](https://www.paraview.org/). -VTKGridFile("heat_equation", dh) do vtk - write_solution(vtk, dh, u) -end - -@show norm(u)/length(u) - -# ### Postprocessing the total flux - -function calculate_flux_lag(dh, dΩ, ip, a) - qr = FacetQuadratureRule{RefTriangle}(2) - fv = FacetValues(qr, ip, Lagrange{RefTriangle,1}()) - grid = dh.grid - dofrange = dof_range(dh, :u) - flux = 0.0 - dofs = celldofs(dh, 1) - ae = zeros(length(dofs)) - x = getcoordinates(grid, 1) - for (cellnr, facenr) in dΩ - getcoordinates!(x, grid, cellnr) - cell = getcells(grid, cellnr) - celldofs!(dofs, dh, cellnr) - map!(i->a[i], ae, dofs) - reinit!(fv, cell, x, facenr) - for q_point in 1:getnquadpoints(fv) - dΓ = getdetJdV(fv, q_point) - n = getnormal(fv, q_point) - q = function_gradient(fv, q_point, ae, dofrange) - flux -= (q ⋅ n)*dΓ - end - end - return flux -end - -flux = calculate_flux_lag(dh, ∂Ω, ip, u) -@show flux - -#md # ## [Plain program](@id heat_equation-plain-program) -#md # -#md # Here follows a version of the program without any comments. -#md # The file is also available here: [`heat_equation.jl`](heat_equation.jl). -#md # -#md # ```julia -#md # @__CODE__ -#md # ``` diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index 17b52e55ff..4405a09b76 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -266,7 +266,7 @@ function line_integral(qr::QuadratureRule{RefLine}, ip, shape_nr, x0, Δx, L, v, end # Required properties of shape value Nⱼ of an edge-elements (Hcurl) on an edge with direction v, length L, and dofs ∈ 𝔇 -# 1) Unit property: ∑_{j∈𝔇} ∫(Nⱼ ⋅ v f(s) dS) = 1 +# 1) Unit property: ∫(Nⱼ ⋅ v f(s) dS) = 1 ∀ ∈ 𝔇 # Where f(s) = 1 for linear interpolation and f(s)=1-s and f(s)=s for 2nd order interpolation (first and second shape function) # And s is the path parameter ∈[0,1] along the positive direction of the path. # 2) Zero along other edges: Nⱼ ⋅ v = 0 if j∉𝔇 @@ -303,7 +303,7 @@ end end # Required properties of shape value Nⱼ of an edge-elements (Hdiv) on an edge with normal n, length L, and dofs ∈ 𝔇 -# 1) Unit property: ∫(Nⱼ ⋅ n f(s) dS) = 1 +# 1) Unit property: ∫(Nⱼ ⋅ n f(s) dS) = 1 ∀ ∈ 𝔇 # Where f(s) = 1 for single shape function on edge, and f(s)=1-s and f(s)=s for two shape functions on edge # s is the path parameter ∈[0,1] along the positive direction of the path. # 2) Zero normal component on other edges: Nⱼ ⋅ n = 0 if j∉𝔇 From c60e53042375c1d9e55a5d118a3ee88e59c3682f Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Tue, 12 Nov 2024 16:02:02 +0100 Subject: [PATCH 137/145] Clean and run runic --- .../literate-tutorials/heat_equation_hdiv.jl | 17 +- src/FEValues/FunctionValues.jl | 16 +- src/interpolations.jl | 128 +- test/InterpolationTestUtils.jl | 202 +-- test/test_interpolations.jl | 326 ++-- .../2d_vector_interpolation_checkplots.jl | 59 - visualization/Manifest.toml | 1578 ----------------- visualization/Project.toml | 4 - visualization/reference_cell_ip.jl | 85 - 9 files changed, 355 insertions(+), 2060 deletions(-) delete mode 100644 visualization/2d_vector_interpolation_checkplots.jl delete mode 100644 visualization/Manifest.toml delete mode 100644 visualization/Project.toml delete mode 100644 visualization/reference_cell_ip.jl diff --git a/docs/src/literate-tutorials/heat_equation_hdiv.jl b/docs/src/literate-tutorials/heat_equation_hdiv.jl index 155e42bd66..e3f2bee293 100644 --- a/docs/src/literate-tutorials/heat_equation_hdiv.jl +++ b/docs/src/literate-tutorials/heat_equation_hdiv.jl @@ -63,8 +63,8 @@ function create_grid(ny::Int) center_width = 5.0 center_length = 20.0 upper_right = Vec((length / 2, width / 2)) - grid = generate_grid(Triangle, (round(Int, ny * length / width), ny), -upper_right, upper_right); - addcellset!(grid, "center", x -> abs(x[1]) < center_length/2 && abs(x[2]) < center_width / 2) + grid = generate_grid(Triangle, (round(Int, ny * length / width), ny), -upper_right, upper_right) + addcellset!(grid, "center", x -> abs(x[1]) < center_length / 2 && abs(x[2]) < center_width / 2) addcellset!(grid, "around", setdiff(1:getncells(grid), getcellset(grid, "center"))) return grid end @@ -77,7 +77,7 @@ ip_geo = geometric_interpolation(getcelltype(grid)) ipu = DiscontinuousLagrange{RefTriangle, 0}() ipq = Ferrite.BrezziDouglasMarini{2, RefTriangle, 1}() qr = QuadratureRule{RefTriangle}(2) -cellvalues = (u=CellValues(qr, ipu, ip_geo), q=CellValues(qr, ipq, ip_geo)) +cellvalues = (u = CellValues(qr, ipu, ip_geo), q = CellValues(qr, ipq, ip_geo)) # Distribute the degrees of freedom dh = DofHandler(grid) @@ -103,7 +103,7 @@ function assemble_element!(Ke::Matrix, fe::Vector, cv::NamedTuple, dr::NamedTupl dΩ = getdetJdV(cvu, q_point) ## Loop over test shape functions for (iu, Iu) in pairs(dru) - δNu = shape_value(cvu, q_point, iu) + δNu = shape_value(cvu, q_point, iu) ## Add contribution to fe fe[Iu] += δNu * h * dΩ ## Loop over trial shape functions @@ -148,8 +148,9 @@ function assemble_global(cellvalues, dh::DofHandler) dofs = copy(celldofs(dh, 1)) ## Loop over all cells for (cells, k) in ( - (getcellset(grid, "center"), 0.1), - (getcellset(grid, "around"), 1.00)) + (getcellset(grid, "center"), 0.1), + (getcellset(grid, "around"), 1.0), + ) for cellnr in cells ## Reinitialize cellvalues for this cell cell = getcells(grid, cellnr) @@ -205,13 +206,13 @@ function calculate_flux(dh, boundary_facets, ip, a) getcoordinates!(x, grid, cellnr) cell = getcells(grid, cellnr) celldofs!(dofs, dh, cellnr) - map!(i->a[i], ae, dofs) + map!(i -> a[i], ae, dofs) reinit!(fv, cell, x, facetnr) for q_point in 1:getnquadpoints(fv) dΓ = getdetJdV(fv, q_point) n = getnormal(fv, q_point) q = function_value(fv, q_point, ae, dofrange) - flux += (q ⋅ n)*dΓ + flux += (q ⋅ n) * dΓ end end return flux diff --git a/src/FEValues/FunctionValues.jl b/src/FEValues/FunctionValues.jl index d0bf3d5183..a4726801ed 100644 --- a/src/FEValues/FunctionValues.jl +++ b/src/FEValues/FunctionValues.jl @@ -226,7 +226,7 @@ end @inbounds for j in 1:getnbasefunctions(funvals) d = get_direction(funvals.ip, j, cell) Nξ = funvals.Nξ[j, q_point] - funvals.Nx[j, q_point] = d*(Nξ ⋅ Jinv) + funvals.Nx[j, q_point] = d * (Nξ ⋅ Jinv) end return nothing end @@ -238,8 +238,8 @@ end d = get_direction(funvals.ip, j, cell) dNdξ = funvals.dNdξ[j, q_point] Nξ = funvals.Nξ[j, q_point] - funvals.Nx[j, q_point] = d*(Nξ ⋅ Jinv) - funvals.dNdx[j, q_point] = d*(Jinv' ⋅ dNdξ ⋅ Jinv - Jinv' ⋅ (Nξ ⋅ Jinv ⋅ H ⋅ Jinv)) + funvals.Nx[j, q_point] = d * (Nξ ⋅ Jinv) + funvals.dNdx[j, q_point] = d * (Jinv' ⋅ dNdξ ⋅ Jinv - Jinv' ⋅ (Nξ ⋅ Jinv ⋅ H ⋅ Jinv)) end return nothing end @@ -251,7 +251,7 @@ end @inbounds for j in 1:getnbasefunctions(funvals) d = get_direction(funvals.ip, j, cell) Nξ = funvals.Nξ[j, q_point] - funvals.Nx[j, q_point] = d*(J ⋅ Nξ)/detJ + funvals.Nx[j, q_point] = d * (J ⋅ Nξ) / detJ end return nothing end @@ -262,15 +262,15 @@ end Jinv = inv(J) detJ = det(J) I2 = one(J) - H_Jinv = H⋅Jinv - A1 = (H_Jinv ⊡ (otimesl(I2,I2))) / detJ + H_Jinv = H ⋅ Jinv + A1 = (H_Jinv ⊡ (otimesl(I2, I2))) / detJ A2 = (Jinv' ⊡ H_Jinv) / detJ @inbounds for j in 1:getnbasefunctions(funvals) d = get_direction(funvals.ip, j, cell) dNdξ = funvals.dNdξ[j, q_point] Nξ = funvals.Nξ[j, q_point] - funvals.Nx[j, q_point] = d*(J ⋅ Nξ)/detJ - funvals.dNdx[j, q_point] = d*(J ⋅ dNdξ ⋅ Jinv/detJ + A1 ⋅ Nξ - (J ⋅ Nξ) ⊗ A2) + funvals.Nx[j, q_point] = d * (J ⋅ Nξ) / detJ + funvals.dNdx[j, q_point] = d * (J ⋅ dNdξ ⋅ Jinv / detJ + A1 ⋅ Nξ - (J ⋅ Nξ) ⊗ A2) end return nothing end diff --git a/src/interpolations.jl b/src/interpolations.jl index d4e65174f9..1dc0876c1e 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1800,7 +1800,7 @@ n_dbc_components(::RaviartThomas) = 1 function reference_shape_value(ip::RaviartThomas{2, RefTriangle, 1}, ξ::Vec{2}, i::Int) x, y = ξ i == 1 && return ξ # Flip sign - i == 2 && return Vec(x-1, y) # Keep sign + i == 2 && return Vec(x - 1, y) # Keep sign i == 3 && return Vec(x, y - 1) # Flip sign throw(ArgumentError("no shape function $i for interpolation $ip")) end @@ -1809,7 +1809,7 @@ getnbasefunctions(::RaviartThomas{2, RefTriangle, 1}) = 3 edgedof_interior_indices(::RaviartThomas{2, RefTriangle, 1}) = ((1,), (2,), (3,)) adjust_dofs_during_distribution(::RaviartThomas) = false -function get_direction(::RaviartThomas{2,RefTriangle,1}, j, cell) +function get_direction(::RaviartThomas{2, RefTriangle, 1}, j, cell) edge = edges(cell)[j] return ifelse(edge[2] > edge[1], 1, -1) end @@ -1841,24 +1841,24 @@ RefTriangle function reference_shape_value(ip::RaviartThomas{2, RefTriangle, 2}, ξ::Vec{2}, i::Int) x, y = ξ # Face 1 (keep ordering, flip sign) - i == 1 && return Vec(4x*(2x-1), 2y*(4x-1)) - i == 2 && return Vec(2x*(4y-1), 4y*(2y-1)) + i == 1 && return Vec(4x * (2x - 1), 2y * (4x - 1)) + i == 2 && return Vec(2x * (4y - 1), 4y * (2y - 1)) # Face 2 (flip ordering, keep signs) - i == 3 && return Vec( 8x*y - 2x - 6y + 2, 4y*(2y - 1)) - i == 4 && return Vec(-8x^2 - 8x*y + 12x + 6y - 4, 2y*(-4x - 4y + 3)) + i == 3 && return Vec(8x * y - 2x - 6y + 2, 4y * (2y - 1)) + i == 4 && return Vec(-8x^2 - 8x * y + 12x + 6y - 4, 2y * (-4x - 4y + 3)) # Face 3 (keep ordering, flip sign) - i == 5 && return Vec(2x*(3 - 4x - 4y), -8x*y + 6x - 8y^2 + 12y - 4) - i == 6 && return Vec(4x*(2x-1), 8x*y - 6x - 2y + 2) + i == 5 && return Vec(2x * (3 - 4x - 4y), -8x * y + 6x - 8y^2 + 12y - 4) + i == 6 && return Vec(4x * (2x - 1), 8x * y - 6x - 2y + 2) # Cell - i == 7 && return Vec(8x*(-2x - y + 2), 8y*(-2x - y + 1)) - i == 8 && return Vec(8x*(-2y - x + 1), 8y*(-2y - x + 2)) + i == 7 && return Vec(8x * (-2x - y + 2), 8y * (-2x - y + 1)) + i == 8 && return Vec(8x * (-2y - x + 1), 8y * (-2y - x + 2)) throw(ArgumentError("no shape function $i for interpolation $ip")) end -getnbasefunctions(::RaviartThomas{2,RefTriangle,2}) = 8 -edgedof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = ((1, 2), (3, 4), (5, 6)) -volumedof_interior_indices(::RaviartThomas{2,RefTriangle,2}) = (7,8) -adjust_dofs_during_distribution(::RaviartThomas{2,RefTriangle,2}) = true +getnbasefunctions(::RaviartThomas{2, RefTriangle, 2}) = 8 +edgedof_interior_indices(::RaviartThomas{2, RefTriangle, 2}) = ((1, 2), (3, 4), (5, 6)) +volumedof_interior_indices(::RaviartThomas{2, RefTriangle, 2}) = (7, 8) +adjust_dofs_during_distribution(::RaviartThomas{2, RefTriangle, 2}) = true function get_direction(::RaviartThomas{2, RefTriangle, 2}, j, cell) j > 6 && return 1 @@ -1871,7 +1871,7 @@ end ##################################### struct BrezziDouglasMarini{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end mapping_type(::BrezziDouglasMarini) = ContravariantPiolaMapping() -reference_coordinates(ip::BrezziDouglasMarini{vdim}) where vdim = fill(NaN*zero(Vec{vdim}), getnbasefunctions(ip)) +reference_coordinates(ip::BrezziDouglasMarini{vdim}) where {vdim} = fill(NaN * zero(Vec{vdim}), getnbasefunctions(ip)) #dirichlet_facedof_indices(ip::BrezziDouglasMarini) = facetdof_interior_indices(ip) n_dbc_components(::BrezziDouglasMarini) = 1 #= @@ -1922,16 +1922,16 @@ end ##################################### struct Nedelec{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end mapping_type(::Nedelec) = CovariantPiolaMapping() -reference_coordinates(ip::Nedelec{vdim}) where vdim = fill(NaN*zero(Vec{vdim}), getnbasefunctions(ip)) +reference_coordinates(ip::Nedelec{vdim}) where {vdim} = fill(NaN * zero(Vec{vdim}), getnbasefunctions(ip)) dirichlet_facedof_indices(ip::Nedelec) = facetdof_interior_indices(ip) n_dbc_components(::Nedelec) = 1 # RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-1.html -function reference_shape_value(ip::Nedelec{2,RefTriangle,1}, ξ::Vec{2}, i::Int) +function reference_shape_value(ip::Nedelec{2, RefTriangle, 1}, ξ::Vec{2}, i::Int) x, y = ξ - i == 1 && return Vec( - y, x) - i == 2 && return Vec( - y, x - 1) # Changed signed, follow Ferrite's sign convention - i == 3 && return Vec(1 - y, x) + i == 1 && return Vec(- y, x) + i == 2 && return Vec(- y, x - 1) # Changed signed, follow Ferrite's sign convention + i == 3 && return Vec(1 - y, x) throw(ArgumentError("no shape function $i for interpolation $ip")) end @@ -1946,34 +1946,50 @@ end # RefTriangle, 2nd order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-2.html -function reference_shape_value(ip::Nedelec{2,RefTriangle,2}, ξ::Vec{2}, i::Int) +function reference_shape_value(ip::Nedelec{2, RefTriangle, 2}, ξ::Vec{2}, i::Int) x, y = ξ # Face 1 - i == 1 && return Vec( 2*y*(1 - 4*x), - 4*x*(2*x - 1)) - i == 2 && return Vec( 4*y*(1 - 2*y), - 2*x*(4*y - 1)) + i == 1 && return Vec( + 2 * y * (1 - 4 * x), + 4 * x * (2 * x - 1) + ) + i == 2 && return Vec( + 4 * y * (1 - 2 * y), + 2 * x * (4 * y - 1) + ) # Face 2 (flip order and sign compared to defelement) - i == 3 && return Vec( 4*y*(1 - 2*y), - 8*x*y - 2*x - 6*y + 2) - i == 4 && return Vec( 2*y*(4*x + 4*y - 3), - -8*x^2 - 8*x*y + 12*x + 6*y - 4) + i == 3 && return Vec( + 4 * y * (1 - 2 * y), + 8 * x * y - 2 * x - 6 * y + 2 + ) + i == 4 && return Vec( + 2 * y * (4 * x + 4 * y - 3), + -8 * x^2 - 8 * x * y + 12 * x + 6 * y - 4 + ) # Face 3 - i == 5 && return Vec( 8*x*y - 6*x + 8*y^2 - 12*y + 4, - 2*x*(-4*x - 4*y + 3)) - i == 6 && return Vec(-8*x*y + 6*x + 2*y - 2, - 4*x*(2*x - 1)) + i == 5 && return Vec( + 8 * x * y - 6 * x + 8 * y^2 - 12 * y + 4, + 2 * x * (-4 * x - 4 * y + 3) + ) + i == 6 && return Vec( + -8 * x * y + 6 * x + 2 * y - 2, + 4 * x * (2 * x - 1) + ) # Cell - i == 7 && return Vec( 8*y*(-x - 2*y + 2), - 8*x*( x + 2*y - 1)) - i == 8 && return Vec( 8*y*( 2*x + y - 1), - 8*x*(-2*x - y + 2)) + i == 7 && return Vec( + 8 * y * (-x - 2 * y + 2), + 8 * x * (x + 2 * y - 1) + ) + i == 8 && return Vec( + 8 * y * (2 * x + y - 1), + 8 * x * (-2 * x - y + 2) + ) throw(ArgumentError("no shape function $i for interpolation $ip")) end getnbasefunctions(::Nedelec{2, RefTriangle, 2}) = 8 -edgedof_interior_indices(::Nedelec{2, RefTriangle, 2}) = ((1,2), (3,4), (5,6)) -volumedof_interior_indices(::Nedelec{2, RefTriangle, 2}) = (7,8) +edgedof_interior_indices(::Nedelec{2, RefTriangle, 2}) = ((1, 2), (3, 4), (5, 6)) +volumedof_interior_indices(::Nedelec{2, RefTriangle, 2}) = (7, 8) adjust_dofs_during_distribution(::Nedelec{2, RefTriangle, 2}) = true function get_direction(::Nedelec{2, RefTriangle, 2}, j, cell) @@ -1983,7 +1999,7 @@ function get_direction(::Nedelec{2, RefTriangle, 2}, j, cell) end # https://defelement.com/elements/examples/tetrahedron-nedelec1-lagrange-1.html -function reference_shape_value(ip::Nedelec{3, RefTetrahedron, 1}, ξ::Vec{3, T}, i::Int) where T +function reference_shape_value(ip::Nedelec{3, RefTetrahedron, 1}, ξ::Vec{3, T}, i::Int) where {T} x, y, z = ξ # Edge 1 (defelement 5, positive) i == 1 && return Vec(- y - z + 1, x, x) @@ -2002,7 +2018,7 @@ function reference_shape_value(ip::Nedelec{3, RefTetrahedron, 1}, ξ::Vec{3, T}, end getnbasefunctions(::Nedelec{3, RefTetrahedron, 1}) = 6 -edgedof_interior_indices(::Nedelec{3, RefTetrahedron, 1}) = ntuple(i->(i,), 6) +edgedof_interior_indices(::Nedelec{3, RefTetrahedron, 1}) = ntuple(i -> (i,), 6) adjust_dofs_during_distribution(::Nedelec{3, RefTetrahedron, 1}) = false function get_direction(::Nedelec{3, RefTetrahedron, 1}, j, cell) @@ -2022,38 +2038,38 @@ No point in implementing guesses that cannot be verified... # https://defelement.com/elements/examples/hexahedron-nedelec1-lagrange-1.html # Note: Divide by 2 since J=2I compared to DefElement's reference shape, and mapping is N ⋅ J^-T -function reference_shape_value(ip::Nedelec{3, RefHexahedron, 1}, ξ::Vec{3, T}, i::Int) where T - x, y, z = (ξ + ones(ξ))/2 +function reference_shape_value(ip::Nedelec{3, RefHexahedron, 1}, ξ::Vec{3, T}, i::Int) where {T} + x, y, z = (ξ + ones(ξ)) / 2 # Edge 1 (defelement 0, positive) - i == 1 && return Vec(y*z - y - z + 1, zero(T), zero(T))/2 + i == 1 && return Vec(y * z - y - z + 1, zero(T), zero(T)) / 2 # Edge 2 (defelement 3, positive) - i == 2 && return Vec(zero(T), x * (1 - z), zero(T))/2 + i == 2 && return Vec(zero(T), x * (1 - z), zero(T)) / 2 # Edge 3 (defelement 5, negative) - i == 3 && return Vec(-y*(1-z), zero(T), zero(T))/2 + i == 3 && return Vec(-y * (1 - z), zero(T), zero(T)) / 2 # Edge 4 (defelement 1, negative) - i == 4 && return Vec(zero(T), - x*z + x + z - 1, zero(T))/2 + i == 4 && return Vec(zero(T), - x * z + x + z - 1, zero(T)) / 2 # Edge 5 (defelement 8, positive) - i == 5 && return Vec(z*(1-y), zero(T), zero(T))/2 + i == 5 && return Vec(z * (1 - y), zero(T), zero(T)) / 2 # Edge 6 (defelement 10, positive) - i == 6 && return Vec(zero(T), x * z, zero(T))/2 + i == 6 && return Vec(zero(T), x * z, zero(T)) / 2 # Edge 7 (defelement 11, negative) - i == 7 && return Vec(- y*z, zero(T), zero(T))/2 + i == 7 && return Vec(- y * z, zero(T), zero(T)) / 2 # Edge 8 (defelement 9, negative) - i == 8 && return Vec(zero(T), - z * (1 - x), zero(T))/2 + i == 8 && return Vec(zero(T), - z * (1 - x), zero(T)) / 2 # Edge 9 (defelement 2, positive) - i == 9 && return Vec(zero(T), zero(T), x*y - x - y + 1)/2 + i == 9 && return Vec(zero(T), zero(T), x * y - x - y + 1) / 2 # Edge 10 (defelement 4, positive) - i == 10 && return Vec(zero(T), zero(T), x * (1 - y))/2 + i == 10 && return Vec(zero(T), zero(T), x * (1 - y)) / 2 # Edge 11 (defelement 7, positive) - i == 11 && return Vec(zero(T), zero(T), x * y)/2 + i == 11 && return Vec(zero(T), zero(T), x * y) / 2 # Edge 12 (defelement 6, positive) - i == 12 && return Vec(zero(T), zero(T), y * (1 - x))/2 + i == 12 && return Vec(zero(T), zero(T), y * (1 - x)) / 2 throw(ArgumentError("no shape function $i for interpolation $ip")) end getnbasefunctions(::Nedelec{3, RefHexahedron, 1}) = 12 -edgedof_interior_indices(::Nedelec{3, RefHexahedron, 1}) = ntuple(i->(i,), 12) +edgedof_interior_indices(::Nedelec{3, RefHexahedron, 1}) = ntuple(i -> (i,), 12) adjust_dofs_during_distribution(::Nedelec{3, RefHexahedron, 1}) = false function get_direction(::Nedelec{3, RefHexahedron, 1}, j, cell) diff --git a/test/InterpolationTestUtils.jl b/test/InterpolationTestUtils.jl index a983edacc9..4acf153026 100644 --- a/test/InterpolationTestUtils.jl +++ b/test/InterpolationTestUtils.jl @@ -1,116 +1,118 @@ module InterpolationTestUtils - using Ferrite - using Test - import LinearAlgebra: normalize - import Random: randperm +using Ferrite +using Test +import LinearAlgebra: normalize +import Random: randperm - function find_matching_facet(grid, facet::FacetIndex) - cell, facetnr = facet - facet_vertices = Set(Ferrite.facets(getcells(grid, cell))[facetnr]) - for cnr in 1:getncells(grid) - cnr == cell && continue - for (i, f_vert) in enumerate(Ferrite.facets(getcells(grid, cnr))) - facet_vertices == Set(f_vert) && return FacetIndex(cnr, i) - end +function find_matching_facet(grid, facet::FacetIndex) + cell, facetnr = facet + facet_vertices = Set(Ferrite.facets(getcells(grid, cell))[facetnr]) + for cnr in 1:getncells(grid) + cnr == cell && continue + for (i, f_vert) in enumerate(Ferrite.facets(getcells(grid, cnr))) + facet_vertices == Set(f_vert) && return FacetIndex(cnr, i) end - return nothing end + return nothing +end - function test_continuity(dh::DofHandler, facet::FacetIndex; - transformation_function::Function=identity, - value_function::Function=function_value) - # transformation_function: (v,n) -> z - # Examples - # * Tangential continuity: fun(v, n) = v - (v ⋅ n)*n - # * Normal continuity: fun(v, n) = v ⋅ n - # value_function: (fe_v, q_point, ue) -> z - - # Check validity of input - @assert length(dh.subdofhandlers) == 1 - @assert length(Ferrite.getfieldnames(dh)) == 1 - - # Find the matching FaceIndex - cellnr, facetnr = facet - facet2 = find_matching_facet(dh.grid, facet) - facet2 === nothing && return false +function test_continuity( + dh::DofHandler, facet::FacetIndex; + transformation_function::Function = identity, + value_function::Function = function_value + ) + # transformation_function: (v,n) -> z + # Examples + # * Tangential continuity: fun(v, n) = v - (v ⋅ n)*n + # * Normal continuity: fun(v, n) = v ⋅ n + # value_function: (fe_v, q_point, ue) -> z - # Pick "random" points on the facet - cell = getcells(dh.grid, cellnr) - RefShape = Ferrite.getrefshape(getcells(dh.grid, cellnr)) - ip_geo = geometric_interpolation(typeof(cell)) - ip_fun = Ferrite.getfieldinterpolation(dh, (1,1)) - fqr = FacetQuadratureRule{RefShape}(8) - fv = FacetValues(fqr, ip_fun, ip_geo) - cell_coords = getcoordinates(dh.grid, cellnr) - inds = randperm(getnquadpoints(fv))[1:min(4, getnquadpoints(fv))] + # Check validity of input + @assert length(dh.subdofhandlers) == 1 + @assert length(Ferrite.getfieldnames(dh)) == 1 - # Random dof vector to test continuity - u = rand(ndofs(dh)) + # Find the matching FaceIndex + cellnr, facetnr = facet + facet2 = find_matching_facet(dh.grid, facet) + facet2 === nothing && return false - # Calculate coordinates and function values for these - point_coords = zeros(eltype(cell_coords), length(inds)) - point_normal = similar(point_coords) - fun_vals = zeros(typeof(shape_value(fv, 1, 1)), length(inds)) - reinit!(fv, cell, cell_coords, facetnr) - ue = u[celldofs(dh, cellnr)] - for (i, q_point) in enumerate(inds) - point_coords[i] = spatial_coordinate(fv, q_point, cell_coords) - point_normal[i] = getnormal(fv, q_point) - fun_vals[i] = value_function(fv, q_point, ue) - end + # Pick "random" points on the facet + cell = getcells(dh.grid, cellnr) + RefShape = Ferrite.getrefshape(getcells(dh.grid, cellnr)) + ip_geo = geometric_interpolation(typeof(cell)) + ip_fun = Ferrite.getfieldinterpolation(dh, (1, 1)) + fqr = FacetQuadratureRule{RefShape}(8) + fv = FacetValues(fqr, ip_fun, ip_geo) + cell_coords = getcoordinates(dh.grid, cellnr) + inds = randperm(getnquadpoints(fv))[1:min(4, getnquadpoints(fv))] - # Calculate function values on the other cell - cell2 = getcells(dh.grid, facet2[1]) - cell_coords2 = getcoordinates(dh.grid, facet2[1]) - local_coords = map(x->Ferrite.find_local_coordinate(ip_geo, cell_coords2, x, Ferrite.NewtonLineSearchPointFinder()), point_coords) - @assert all(first.(local_coords)) # check that find_local_coordinate converged - ξs = collect(last.(local_coords)) # Extract the local coordinates - qr = QuadratureRule{RefShape}(zeros(length(ξs)), ξs) - cv = CellValues(qr, ip_fun, ip_geo) - reinit!(cv, cell2, cell_coords2) - fun_vals2 = similar(fun_vals) - ue2 = u[celldofs(dh, facet2[1])] - for q_point in 1:getnquadpoints(cv) - @assert spatial_coordinate(cv, q_point, cell_coords2) ≈ point_coords[q_point] - fun_vals2[q_point] = value_function(cv, q_point, ue2) - end + # Random dof vector to test continuity + u = rand(ndofs(dh)) - d1 = map((v,n)->transformation_function(v,n), fun_vals, point_normal) - d2 = map((v,n)->transformation_function(v,n), fun_vals2, point_normal) - @test isapprox(d1, d2; rtol=1e-6) # Approximate points can contribute to the inexactness - return true + # Calculate coordinates and function values for these + point_coords = zeros(eltype(cell_coords), length(inds)) + point_normal = similar(point_coords) + fun_vals = zeros(typeof(shape_value(fv, 1, 1)), length(inds)) + reinit!(fv, cell, cell_coords, facetnr) + ue = u[celldofs(dh, cellnr)] + for (i, q_point) in enumerate(inds) + point_coords[i] = spatial_coordinate(fv, q_point, cell_coords) + point_normal[i] = getnormal(fv, q_point) + fun_vals[i] = value_function(fv, q_point, ue) end - function create_gradcheck_qr(ip_geo::Interpolation{RefShape}, ΔL) where RefShape - dim = Ferrite.getrefdim(ip_geo) - xref = Ferrite.reference_coordinates(ip_geo) - xc = sum(xref)/length(xref) - ws = rand(length(xref))*((1-ΔL)/length(xref)) - xp = xc + sum(map((x,w) -> w*(x - xc), xref, ws)) - v = normalize(rand(Vec{dim}) - ones(Vec{dim})/2) - x1 = xp + ΔL*v - qr_w = [NaN, NaN] - qr_x = [xp, x1] - return QuadratureRule{RefShape}(qr_w, qr_x) + # Calculate function values on the other cell + cell2 = getcells(dh.grid, facet2[1]) + cell_coords2 = getcoordinates(dh.grid, facet2[1]) + local_coords = map(x -> Ferrite.find_local_coordinate(ip_geo, cell_coords2, x, Ferrite.NewtonLineSearchPointFinder()), point_coords) + @assert all(first.(local_coords)) # check that find_local_coordinate converged + ξs = collect(last.(local_coords)) # Extract the local coordinates + qr = QuadratureRule{RefShape}(zeros(length(ξs)), ξs) + cv = CellValues(qr, ip_fun, ip_geo) + reinit!(cv, cell2, cell_coords2) + fun_vals2 = similar(fun_vals) + ue2 = u[celldofs(dh, facet2[1])] + for q_point in 1:getnquadpoints(cv) + @assert spatial_coordinate(cv, q_point, cell_coords2) ≈ point_coords[q_point] + fun_vals2[q_point] = value_function(cv, q_point, ue2) end - function test_gradient(dh, cellnr; ΔL=1e-6) - ue = rand(ndofs_per_cell(dh, cellnr)) - x = getcoordinates(dh.grid, cellnr) - cell = getcells(dh.grid, cellnr) - ip_geo = geometric_interpolation(typeof(cell)) - ip_fun = Ferrite.getfieldinterpolation(dh, (1,1)) - qr = create_gradcheck_qr(ip_geo, ΔL) - cv = CellValues(qr, ip_fun, ip_geo) - reinit!(cv, cell, x) - Δu_num = function_value(cv, 2, ue) - function_value(cv, 1, ue) - Δx = spatial_coordinate(cv, 2, x) - spatial_coordinate(cv, 1, x) - ∇u1 = function_gradient(cv, 1, ue) - ∇u2 = function_gradient(cv, 2, ue) - Δu_ana = 0.5*(∇u1+∇u2) ⋅ Δx - # Δu_ana_var = 0.5*(∇u2-∇u1) ⋅ Δx # Relevant to compare magnitude if test fails - @test isapprox(Δu_num, Δu_ana; rtol=1e-6) - return nothing - end + d1 = map((v, n) -> transformation_function(v, n), fun_vals, point_normal) + d2 = map((v, n) -> transformation_function(v, n), fun_vals2, point_normal) + @test isapprox(d1, d2; rtol = 1.0e-6) # Approximate points can contribute to the inexactness + return true +end + +function create_gradcheck_qr(ip_geo::Interpolation{RefShape}, ΔL) where {RefShape} + dim = Ferrite.getrefdim(ip_geo) + xref = Ferrite.reference_coordinates(ip_geo) + xc = sum(xref) / length(xref) + ws = rand(length(xref)) * ((1 - ΔL) / length(xref)) + xp = xc + sum(map((x, w) -> w * (x - xc), xref, ws)) + v = normalize(rand(Vec{dim}) - ones(Vec{dim}) / 2) + x1 = xp + ΔL * v + qr_w = [NaN, NaN] + qr_x = [xp, x1] + return QuadratureRule{RefShape}(qr_w, qr_x) +end + +function test_gradient(dh, cellnr; ΔL = 1.0e-6) + ue = rand(ndofs_per_cell(dh, cellnr)) + x = getcoordinates(dh.grid, cellnr) + cell = getcells(dh.grid, cellnr) + ip_geo = geometric_interpolation(typeof(cell)) + ip_fun = Ferrite.getfieldinterpolation(dh, (1, 1)) + qr = create_gradcheck_qr(ip_geo, ΔL) + cv = CellValues(qr, ip_fun, ip_geo) + reinit!(cv, cell, x) + Δu_num = function_value(cv, 2, ue) - function_value(cv, 1, ue) + Δx = spatial_coordinate(cv, 2, x) - spatial_coordinate(cv, 1, x) + ∇u1 = function_gradient(cv, 1, ue) + ∇u2 = function_gradient(cv, 2, ue) + Δu_ana = 0.5 * (∇u1 + ∇u2) ⋅ Δx + # Δu_ana_var = 0.5*(∇u2-∇u1) ⋅ Δx # Relevant to compare magnitude if test fails + @test isapprox(Δu_num, Δu_ana; rtol = 1.0e-6) + return nothing +end end diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index 4405a09b76..53f552feb7 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -225,8 +225,8 @@ using Ferrite: reference_shape_value, reference_shape_gradient end @testset "Correctness of AD of embedded interpolations" begin - ip = Lagrange{RefHexahedron,2}()^3 - ξ = rand(Vec{3,Float64}) + ip = Lagrange{RefHexahedron, 2}()^3 + ξ = rand(Vec{3, Float64}) for I in 1:getnbasefunctions(ip) #Call StaticArray-version H_sa, G_sa, V_sa = Ferrite._reference_shape_hessian_gradient_and_value_static_array(ip, ξ, I) @@ -251,92 +251,93 @@ using Ferrite: reference_shape_value, reference_shape_gradient end end -reference_cell(::Type{RefTriangle}) = Triangle((1,2,3)) -reference_cell(::Type{RefQuadrilateral}) = Quadrilateral((1,2,3,4)) -reference_cell(::Type{RefTetrahedron}) = Tetrahedron((1,2,3,4)) -reference_cell(::Type{RefHexahedron}) = Hexahedron((ntuple(identity, 8))) + reference_cell(::Type{RefTriangle}) = Triangle((1, 2, 3)) + reference_cell(::Type{RefQuadrilateral}) = Quadrilateral((1, 2, 3, 4)) + reference_cell(::Type{RefTetrahedron}) = Tetrahedron((1, 2, 3, 4)) + reference_cell(::Type{RefHexahedron}) = Hexahedron((ntuple(identity, 8))) -function line_integral(qr::QuadratureRule{RefLine}, ip, shape_nr, x0, Δx, L, v, f) - s = 0.0 - for (ξ1d, w) in zip(Ferrite.getpoints(qr), Ferrite.getweights(qr)) - ξ = x0 + (ξ1d[1]/2) * Δx - s += (reference_shape_value(ip, ξ, shape_nr) ⋅ v) * (w*L/2) * f((ξ1d[1]+1)/2) + function line_integral(qr::QuadratureRule{RefLine}, ip, shape_nr, x0, Δx, L, v, f) + s = 0.0 + for (ξ1d, w) in zip(Ferrite.getpoints(qr), Ferrite.getweights(qr)) + ξ = x0 + (ξ1d[1] / 2) * Δx + s += (reference_shape_value(ip, ξ, shape_nr) ⋅ v) * (w * L / 2) * f((ξ1d[1] + 1) / 2) + end + return s end - return s -end - -# Required properties of shape value Nⱼ of an edge-elements (Hcurl) on an edge with direction v, length L, and dofs ∈ 𝔇 -# 1) Unit property: ∫(Nⱼ ⋅ v f(s) dS) = 1 ∀ ∈ 𝔇 -# Where f(s) = 1 for linear interpolation and f(s)=1-s and f(s)=s for 2nd order interpolation (first and second shape function) -# And s is the path parameter ∈[0,1] along the positive direction of the path. -# 2) Zero along other edges: Nⱼ ⋅ v = 0 if j∉𝔇 -@testset "H(curl) on RefCell" begin - lineqr = QuadratureRule{RefLine}(20) - for ip in (Nedelec{2,RefTriangle,1}(), Nedelec{2,RefTriangle,2}(), Nedelec{3,RefTetrahedron,1}(), Nedelec{3,RefHexahedron,1}()) - cell = reference_cell(getrefshape(ip)) - edges = Ferrite.edges(cell) - dofs = Ferrite.edgedof_interior_indices(ip) - x = Ferrite.reference_coordinates(geometric_interpolation(typeof(cell))) - @testset "$(getrefshape(ip)), order=$(Ferrite.getorder(ip))" begin - for (edge_nr, (i1, i2)) in enumerate(edges) - Δx = x[i2]-x[i1] - x0 = (x[i1]+x[i2])/2 - L = norm(Δx) - v = Δx/L - for (idof, shape_nr) in enumerate(dofs[edge_nr]) - nedgedofs = length(dofs[edge_nr]) - f(x) = nedgedofs == 1 ? 1.0 : (idof == 1 ? 1-x : x) - s = line_integral(lineqr, ip, shape_nr, x0, Δx, L, v, f) - @test s ≈ one(s) - end - for (j_edge, shape_nrs) in enumerate(dofs) - j_edge == edge_nr && continue - for shape_nr in shape_nrs - for ξ in (x[i1] + r*Δx for r in [0.0, rand(3)..., 1.0]) - @test abs(reference_shape_value(ip, ξ, shape_nr) ⋅ v) < eps()*100 + + # Required properties of shape value Nⱼ of an edge-elements (Hcurl) on an edge with direction v, length L, and dofs ∈ 𝔇 + # 1) Unit property: ∫(Nⱼ ⋅ v f(s) dS) = 1 ∀ ∈ 𝔇 + # Where f(s) = 1 for linear interpolation and f(s)=1-s and f(s)=s for 2nd order interpolation (first and second shape function) + # And s is the path parameter ∈[0,1] along the positive direction of the path. + # 2) Zero along other edges: Nⱼ ⋅ v = 0 if j∉𝔇 + @testset "H(curl) on RefCell" begin + lineqr = QuadratureRule{RefLine}(20) + for ip in (Nedelec{2, RefTriangle, 1}(), Nedelec{2, RefTriangle, 2}(), Nedelec{3, RefTetrahedron, 1}(), Nedelec{3, RefHexahedron, 1}()) + cell = reference_cell(getrefshape(ip)) + edges = Ferrite.edges(cell) + dofs = Ferrite.edgedof_interior_indices(ip) + x = Ferrite.reference_coordinates(geometric_interpolation(typeof(cell))) + @testset "$(getrefshape(ip)), order=$(Ferrite.getorder(ip))" begin + for (edge_nr, (i1, i2)) in enumerate(edges) + Δx = x[i2] - x[i1] + x0 = (x[i1] + x[i2]) / 2 + L = norm(Δx) + v = Δx / L + for (idof, shape_nr) in enumerate(dofs[edge_nr]) + nedgedofs = length(dofs[edge_nr]) + f(x) = nedgedofs == 1 ? 1.0 : (idof == 1 ? 1 - x : x) + s = line_integral(lineqr, ip, shape_nr, x0, Δx, L, v, f) + @test s ≈ one(s) + end + for (j_edge, shape_nrs) in enumerate(dofs) + j_edge == edge_nr && continue + for shape_nr in shape_nrs + for ξ in (x[i1] + r * Δx for r in [0.0, rand(3)..., 1.0]) + @test abs(reference_shape_value(ip, ξ, shape_nr) ⋅ v) < eps() * 100 + end end end end end end end -end - -# Required properties of shape value Nⱼ of an edge-elements (Hdiv) on an edge with normal n, length L, and dofs ∈ 𝔇 -# 1) Unit property: ∫(Nⱼ ⋅ n f(s) dS) = 1 ∀ ∈ 𝔇 -# Where f(s) = 1 for single shape function on edge, and f(s)=1-s and f(s)=s for two shape functions on edge -# s is the path parameter ∈[0,1] along the positive direction of the path. -# 2) Zero normal component on other edges: Nⱼ ⋅ n = 0 if j∉𝔇 -@testset "H(div) on RefCell" begin - lineqr = QuadratureRule{RefLine}(20) - for ip in ( - RaviartThomas{2, RefTriangle, 1}(), - RaviartThomas{2, RefTriangle, 2}(), - Ferrite.BrezziDouglasMarini{2, RefTriangle, 1}(), + + # Required properties of shape value Nⱼ of an edge-elements (Hdiv) on an edge with normal n, length L, and dofs ∈ 𝔇 + # 1) Unit property: ∫(Nⱼ ⋅ n f(s) dS) = 1 ∀ ∈ 𝔇 + # Where f(s) = 1 for single shape function on edge, and f(s)=1-s and f(s)=s for two shape functions on edge + # s is the path parameter ∈[0,1] along the positive direction of the path. + # 2) Zero normal component on other edges: Nⱼ ⋅ n = 0 if j∉𝔇 + @testset "H(div) on RefCell" begin + lineqr = QuadratureRule{RefLine}(20) + for ip in ( + RaviartThomas{2, RefTriangle, 1}(), + RaviartThomas{2, RefTriangle, 2}(), + Ferrite.BrezziDouglasMarini{2, RefTriangle, 1}(), ) - cell = reference_cell(getrefshape(ip)) - cell_facets = Ferrite.facets(cell) - dofs = Ferrite.facetdof_interior_indices(ip) - x = Ferrite.reference_coordinates(geometric_interpolation(typeof(cell))) - normals = reference_normals(geometric_interpolation(typeof(cell))) - @testset "$ip" begin - for (facet_nr, (i1, i2)) in enumerate(cell_facets) - @testset "Facet $facet_nr" begin - Δx = x[i2]-x[i1] - x0 = (x[i1]+x[i2])/2 - L = norm(Δx) - n = normals[facet_nr] - for (idof, shape_nr) in enumerate(dofs[facet_nr]) - nfacetdofs = length(dofs[facet_nr]) - f(x) = nfacetdofs == 1 ? 1.0 : (idof == 1 ? 1-x : x) - s = line_integral(lineqr, ip, shape_nr, x0, Δx, L, n, f) - @test s ≈ one(s) - end - for (j_facet, shape_nrs) in enumerate(dofs) - j_facet == facet_nr && continue - for shape_nr in shape_nrs - for ξ in (x[i1] + r*Δx for r in [0.0, rand(3)..., 1.0]) - @test abs(reference_shape_value(ip, ξ, shape_nr) ⋅ n) < eps()*100 + cell = reference_cell(getrefshape(ip)) + cell_facets = Ferrite.facets(cell) + dofs = Ferrite.facetdof_interior_indices(ip) + x = Ferrite.reference_coordinates(geometric_interpolation(typeof(cell))) + normals = reference_normals(geometric_interpolation(typeof(cell))) + @testset "$ip" begin + for (facet_nr, (i1, i2)) in enumerate(cell_facets) + @testset "Facet $facet_nr" begin + Δx = x[i2] - x[i1] + x0 = (x[i1] + x[i2]) / 2 + L = norm(Δx) + n = normals[facet_nr] + for (idof, shape_nr) in enumerate(dofs[facet_nr]) + nfacetdofs = length(dofs[facet_nr]) + f(x) = nfacetdofs == 1 ? 1.0 : (idof == 1 ? 1 - x : x) + s = line_integral(lineqr, ip, shape_nr, x0, Δx, L, n, f) + @test s ≈ one(s) + end + for (j_facet, shape_nrs) in enumerate(dofs) + j_facet == facet_nr && continue + for shape_nr in shape_nrs + for ξ in (x[i1] + r * Δx for r in [0.0, rand(3)..., 1.0]) + @test abs(reference_shape_value(ip, ξ, shape_nr) ⋅ n) < eps() * 100 + end end end end @@ -344,98 +345,99 @@ end end end end -end - -tupleshift(t::NTuple{N}, shift::Int) where N = ntuple(i -> t[mod(i - 1 - shift, N) + 1], N) -#tupleshift(t::NTuple, shift::Int) = tuple(circshift(SVector(t), shift)...) -cell_permutations(cell::Quadrilateral) = (Quadrilateral(tupleshift(cell.nodes, shift)) for shift in 0:3) -cell_permutations(cell::Triangle) = ( Triangle(tupleshift(cell.nodes, shift)) for shift in 0:2) -cell_permutations(cell::QuadraticTriangle) = (QuadraticTriangle((tupleshift(cell.nodes[1:3], shift)..., tupleshift(cell.nodes[4:6], shift)...)) for shift in 0:3) - -function cell_permutations(cell::Hexahedron) - idx = ( #Logic on refshape: Select 1st and 2nd vertex (must be neighbours) - # The next follows to create inward vector with RHR, and then 4th is in same plane. - # The last four must be the neighbours on the other plane to the first four (same order) - (1,2,3,4,5,6,7,8), (1,4,8,5,2,3,7,6), (1,5,6,2,4,8,7,3), - (2,1,5,6,3,4,8,7), (2,3,4,1,6,7,8,5), (2,6,7,3,1,5,8,4), - (3,2,6,7,4,1,5,8), (3,4,1,2,7,8,5,6), (3,7,8,4,2,6,5,1), - (4,1,2,3,8,5,6,7), (4,3,7,8,1,2,6,5), (4,8,5,1,3,7,6,1), - (5,1,4,8,6,2,3,7), (5,6,2,1,8,7,3,4), (5,8,7,6,1,4,3,2), - (6,2,1,5,7,3,4,8), (6,5,8,7,2,1,4,3), (6,7,3,2,5,8,4,1), - (7,3,2,6,8,4,1,5), (7,6,5,8,3,2,1,4), (7,8,4,3,6,5,1,2), - (8,4,3,7,5,1,2,6), (8,5,1,4,7,6,2,3), (8,7,6,5,4,3,2,1), - ) - return (Hexahedron(ntuple(i -> cell.nodes[perm[i]], 8)) for perm in idx) -end - -function cell_permutations(cell::Tetrahedron) - idx = ( (1,2,3,4), (1,3,4,2), (1,4,2,3), - (2,1,4,3), (2,3,1,4), (2,4,3,1), - (3,1,2,4), (3,2,4,1), (3,4,1,2), - (4,1,3,2), (4,3,2,1), (4,2,1,3)) - return (Tetrahedron(ntuple(i -> cell.nodes[perm[i]], 4)) for perm in idx) -end - -@testset "Hcurl and Hdiv" begin - include(joinpath(@__DIR__, "InterpolationTestUtils.jl")) - import .InterpolationTestUtils as ITU - nel = 3 - hdiv_check(v, n) = v ⋅ n # Hdiv (normal continuity) - hcurl_check(v, n) = v - n*(v⋅n) # Hcurl (tangent continuity) - transformation_functions = ((Nedelec, hcurl_check), (RaviartThomas, hdiv_check), (Ferrite.BrezziDouglasMarini, hdiv_check)) - - for CT in (Triangle, QuadraticTriangle, Tetrahedron, Hexahedron) - dim = Ferrite.getrefdim(CT) # dim = sdim = rdim - p1, p2 = (rand(Vec{dim}), ones(Vec{dim})+rand(Vec{dim})) - grid = generate_grid(CT, ntuple(_->nel, dim), p1, p2) - # Smoothly distort grid (to avoid spuriously badly deformed elements). - # A distorted grid is important to properly test the geometry mapping - # for 2nd order elements. - transfun(x) = typeof(x)(i->sinpi(x[mod(i, length(x))+1]+i/3))/10 - transform_coordinates!(grid, x->(x + transfun(x))) - cellnr = getncells(grid)÷2 + 1 # Should be a cell in the center - basecell = getcells(grid, cellnr) - RefShape = Ferrite.getrefshape(basecell) - for order in (1, 2) - for (IPT, transformation_function) in transformation_functions - dim == 3 && order > 1 && continue - IPT == RaviartThomas && (dim == 3 || order > 1) && continue - IPT == RaviartThomas && (RefShape == RefHexahedron) && continue - IPT == Ferrite.BrezziDouglasMarini && !(RefShape == RefTriangle && order == 1) && continue - ip = IPT{dim, RefShape, order}() - @testset "$CT, $ip" begin - for testcell in cell_permutations(basecell) - grid.cells[cellnr] = testcell - dh = DofHandler(grid) - add!(dh, :u, ip) - close!(dh) - for facetnr in 1:nfacets(RefShape) - fi = FacetIndex(cellnr, facetnr) - # Check continuity of tangential function value - ITU.test_continuity(dh, fi; transformation_function) + + tupleshift(t::NTuple{N}, shift::Int) where {N} = ntuple(i -> t[mod(i - 1 - shift, N) + 1], N) + #tupleshift(t::NTuple, shift::Int) = tuple(circshift(SVector(t), shift)...) + cell_permutations(cell::Quadrilateral) = (Quadrilateral(tupleshift(cell.nodes, shift)) for shift in 0:3) + cell_permutations(cell::Triangle) = (Triangle(tupleshift(cell.nodes, shift)) for shift in 0:2) + cell_permutations(cell::QuadraticTriangle) = (QuadraticTriangle((tupleshift(cell.nodes[1:3], shift)..., tupleshift(cell.nodes[4:6], shift)...)) for shift in 0:3) + + function cell_permutations(cell::Hexahedron) + idx = ( #Logic on refshape: Select 1st and 2nd vertex (must be neighbours) + # The next follows to create inward vector with RHR, and then 4th is in same plane. + # The last four must be the neighbours on the other plane to the first four (same order) + (1, 2, 3, 4, 5, 6, 7, 8), (1, 4, 8, 5, 2, 3, 7, 6), (1, 5, 6, 2, 4, 8, 7, 3), + (2, 1, 5, 6, 3, 4, 8, 7), (2, 3, 4, 1, 6, 7, 8, 5), (2, 6, 7, 3, 1, 5, 8, 4), + (3, 2, 6, 7, 4, 1, 5, 8), (3, 4, 1, 2, 7, 8, 5, 6), (3, 7, 8, 4, 2, 6, 5, 1), + (4, 1, 2, 3, 8, 5, 6, 7), (4, 3, 7, 8, 1, 2, 6, 5), (4, 8, 5, 1, 3, 7, 6, 1), + (5, 1, 4, 8, 6, 2, 3, 7), (5, 6, 2, 1, 8, 7, 3, 4), (5, 8, 7, 6, 1, 4, 3, 2), + (6, 2, 1, 5, 7, 3, 4, 8), (6, 5, 8, 7, 2, 1, 4, 3), (6, 7, 3, 2, 5, 8, 4, 1), + (7, 3, 2, 6, 8, 4, 1, 5), (7, 6, 5, 8, 3, 2, 1, 4), (7, 8, 4, 3, 6, 5, 1, 2), + (8, 4, 3, 7, 5, 1, 2, 6), (8, 5, 1, 4, 7, 6, 2, 3), (8, 7, 6, 5, 4, 3, 2, 1), + ) + return (Hexahedron(ntuple(i -> cell.nodes[perm[i]], 8)) for perm in idx) + end + + function cell_permutations(cell::Tetrahedron) + idx = ( + (1, 2, 3, 4), (1, 3, 4, 2), (1, 4, 2, 3), + (2, 1, 4, 3), (2, 3, 1, 4), (2, 4, 3, 1), + (3, 1, 2, 4), (3, 2, 4, 1), (3, 4, 1, 2), + (4, 1, 3, 2), (4, 3, 2, 1), (4, 2, 1, 3), + ) + return (Tetrahedron(ntuple(i -> cell.nodes[perm[i]], 4)) for perm in idx) + end + + @testset "Hcurl and Hdiv" begin + include(joinpath(@__DIR__, "InterpolationTestUtils.jl")) + import .InterpolationTestUtils as ITU + nel = 3 + hdiv_check(v, n) = v ⋅ n # Hdiv (normal continuity) + hcurl_check(v, n) = v - n * (v ⋅ n) # Hcurl (tangent continuity) + transformation_functions = ((Nedelec, hcurl_check), (RaviartThomas, hdiv_check), (Ferrite.BrezziDouglasMarini, hdiv_check)) + + for CT in (Triangle, QuadraticTriangle, Tetrahedron, Hexahedron) + dim = Ferrite.getrefdim(CT) # dim = sdim = rdim + p1, p2 = (rand(Vec{dim}), ones(Vec{dim}) + rand(Vec{dim})) + grid = generate_grid(CT, ntuple(_ -> nel, dim), p1, p2) + # Smoothly distort grid (to avoid spuriously badly deformed elements). + # A distorted grid is important to properly test the geometry mapping + # for 2nd order elements. + transfun(x) = typeof(x)(i -> sinpi(x[mod(i, length(x)) + 1] + i / 3)) / 10 + transform_coordinates!(grid, x -> (x + transfun(x))) + cellnr = getncells(grid) ÷ 2 + 1 # Should be a cell in the center + basecell = getcells(grid, cellnr) + RefShape = Ferrite.getrefshape(basecell) + for order in (1, 2) + for (IPT, transformation_function) in transformation_functions + dim == 3 && order > 1 && continue + IPT == RaviartThomas && (dim == 3 || order > 1) && continue + IPT == RaviartThomas && (RefShape == RefHexahedron) && continue + IPT == Ferrite.BrezziDouglasMarini && !(RefShape == RefTriangle && order == 1) && continue + ip = IPT{dim, RefShape, order}() + @testset "$CT, $ip" begin + for testcell in cell_permutations(basecell) + grid.cells[cellnr] = testcell + dh = DofHandler(grid) + add!(dh, :u, ip) + close!(dh) + for facetnr in 1:nfacets(RefShape) + fi = FacetIndex(cellnr, facetnr) + # Check continuity of tangential function value + ITU.test_continuity(dh, fi; transformation_function) + end + # Check gradient calculation + ITU.test_gradient(dh, cellnr) end - # Check gradient calculation - ITU.test_gradient(dh, cellnr) end end end end end -end -@testset "Errors for entitydof_indices on VectorizedInterpolations" begin - ip = Lagrange{RefQuadrilateral, 2}()^2 - @test_throws ArgumentError Ferrite.vertexdof_indices(ip) - @test_throws ArgumentError Ferrite.edgedof_indices(ip) - @test_throws ArgumentError Ferrite.facedof_indices(ip) - @test_throws ArgumentError Ferrite.facetdof_indices(ip) + @testset "Errors for entitydof_indices on VectorizedInterpolations" begin + ip = Lagrange{RefQuadrilateral, 2}()^2 + @test_throws ArgumentError Ferrite.vertexdof_indices(ip) + @test_throws ArgumentError Ferrite.edgedof_indices(ip) + @test_throws ArgumentError Ferrite.facedof_indices(ip) + @test_throws ArgumentError Ferrite.facetdof_indices(ip) - @test_throws ArgumentError Ferrite.edgedof_interior_indices(ip) - @test_throws ArgumentError Ferrite.facedof_interior_indices(ip) - @test_throws ArgumentError Ferrite.volumedof_interior_indices(ip) - @test_throws ArgumentError Ferrite.facetdof_interior_indices(ip) -end + @test_throws ArgumentError Ferrite.edgedof_interior_indices(ip) + @test_throws ArgumentError Ferrite.facedof_interior_indices(ip) + @test_throws ArgumentError Ferrite.volumedof_interior_indices(ip) + @test_throws ArgumentError Ferrite.facetdof_interior_indices(ip) + end end # testset diff --git a/visualization/2d_vector_interpolation_checkplots.jl b/visualization/2d_vector_interpolation_checkplots.jl deleted file mode 100644 index d48b4ad360..0000000000 --- a/visualization/2d_vector_interpolation_checkplots.jl +++ /dev/null @@ -1,59 +0,0 @@ -using Ferrite -import CairoMakie as Plt - -function facet_quadrature(::Type{RefShape}, nqp::Int) where RefShape - fqr = FacetQuadratureRule{RefShape}(nqp) - points = [p for rule in fqr.face_rules for p in rule.points] - weights = [w for rule in fqr.face_rules for w in rule.weights] - return QuadratureRule{RefShape}(weights, points) -end - -function plot_shape_function(ip::VectorInterpolation{2, RefShape}, qr::Int, i::Int) where {RefShape<:Ferrite.AbstractRefShape{2}} - return plot_shape_function(ip, QuadratureRule{RefShape}(qr), i) -end - -function plot_shape_function(ip::VectorInterpolation{2, RefShape}, qr::QuadratureRule{RefShape}, i::Int) where {RefShape<:Ferrite.AbstractRefShape{2}} - points = Ferrite.getpoints(qr) - N = map(ξ -> Ferrite.reference_shape_value(ip, ξ, i), points) - vertices = Ferrite.reference_coordinates(Lagrange{RefShape, 1}()) - push!(vertices, first(vertices)) - - fig = Plt.Figure() - ax = Plt.Axis(fig[1,1]; aspect=Plt.DataAspect()) - Plt.xlims!(ax, (-1.0, 1.5)) - Plt.lines!(ax, first.(vertices), last.(vertices)) - Plt.arrows!(ax, first.(points), last.(points), first.(N), last.(N); lengthscale = 0.1) - Plt.scatter!(ax, first.(points), last.(points)) - return fig -end - -function plot_global_shape_function(ip::VectorInterpolation{2, RefShape}; qr_order::Int=0, nel, i, qr=nothing) where RefShape - fig = Plt.Figure() - ax = Plt.Axis(fig[1,1]) - _qr = qr === nothing ? QuadratureRule{RefShape}(qr_order) : qr - CT = RefShape === RefTriangle ? Triangle : Quadrilateral - grid = generate_grid(CT, (nel, nel)) - dh = close!(add!(DofHandler(grid), :u, ip)) - points = Vec{2, Float64}[] - directions = Vec{2, Float64}[] - cv = CellValues(_qr, ip, Lagrange{RefShape, 1}()) - cell_contour = getcoordinates(grid, 1) - resize!(cell_contour, length(cell_contour) + 1) - for cell in CellIterator(dh) - copyto!(cell_contour, getcoordinates(cell)) - cell_contour[end] = cell_contour[1] # Close contour - Plt.lines!(ax, first.(cell_contour), last.(cell_contour)) - if i ∈ celldofs(cell) - reinit!(cv, cell) - for q_point in 1:getnquadpoints(cv) - x = spatial_coordinate(cv, q_point, getcoordinates(cell)) - shape_index = findfirst(x -> x == i, celldofs(cell)) - push!(points, x) - push!(directions, shape_value(cv, q_point, shape_index)) - end - end - end - Plt.arrows!(ax, first.(points), last.(points), first.(directions), last.(directions); lengthscale = 0.1) - Plt.scatter!(ax, first.(points), last.(points)) - return fig -end diff --git a/visualization/Manifest.toml b/visualization/Manifest.toml deleted file mode 100644 index dfda582b2d..0000000000 --- a/visualization/Manifest.toml +++ /dev/null @@ -1,1578 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.11.1" -manifest_format = "2.0" -project_hash = "3f9b12f33e28e03dfcb3edf6f53efa43b44e834b" - -[[deps.AbstractFFTs]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.5.0" -weakdeps = ["ChainRulesCore", "Test"] - - [deps.AbstractFFTs.extensions] - AbstractFFTsChainRulesCoreExt = "ChainRulesCore" - AbstractFFTsTestExt = "Test" - -[[deps.AbstractTrees]] -git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" -uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" -version = "0.4.5" - -[[deps.Adapt]] -deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "50c3c56a52972d78e8be9fd135bfb91c9574c140" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.1.1" -weakdeps = ["StaticArrays"] - - [deps.Adapt.extensions] - AdaptStaticArraysExt = "StaticArrays" - -[[deps.AdaptivePredicates]] -git-tree-sha1 = "7e651ea8d262d2d74ce75fdf47c4d63c07dba7a6" -uuid = "35492f91-a3bd-45ad-95db-fcad7dcfedb7" -version = "1.2.0" - -[[deps.AliasTables]] -deps = ["PtrArrays", "Random"] -git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" -uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" -version = "1.1.3" - -[[deps.Animations]] -deps = ["Colors"] -git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" -uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" -version = "0.4.1" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.2" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" -version = "1.11.0" - -[[deps.Automa]] -deps = ["PrecompileTools", "SIMD", "TranscodingStreams"] -git-tree-sha1 = "a8f503e8e1a5f583fbef15a8440c8c7e32185df2" -uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "1.1.0" - -[[deps.AxisAlgorithms]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] -git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "1.1.0" - -[[deps.AxisArrays]] -deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] -git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" -uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.4.7" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" -version = "1.11.0" - -[[deps.Bzip2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "8873e196c2eb87962a2048b3b8e08946535864a1" -uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.8+2" - -[[deps.CEnum]] -git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" -uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.5.0" - -[[deps.CRC32c]] -uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" -version = "1.11.0" - -[[deps.CRlibm_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" -uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" -version = "1.0.1+0" - -[[deps.Cairo]] -deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] -git-tree-sha1 = "7b6ad8c35f4bc3bca8eb78127c8b99719506a5fb" -uuid = "159f3aea-2a34-519c-b102-8c37f9878175" -version = "1.1.0" - -[[deps.CairoMakie]] -deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] -git-tree-sha1 = "fbfdb7cbe17bd14b60646c14c27a16e5038cde54" -uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.12.15" - -[[deps.Cairo_jll]] -deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "009060c9a6168704143100f36ab08f06c2af4642" -uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.2+1" - -[[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "3e4b134270b372f2ed4d4d0e936aabaefc1802bc" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.25.0" -weakdeps = ["SparseArrays"] - - [deps.ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "bce6804e5e6044c6daab27bb533d1295e4a2e759" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.6" - -[[deps.ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - -[[deps.ColorSchemes]] -deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "13951eb68769ad1cd460cdb2e64e5e95f1bf123d" -uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.27.0" - -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.5" - -[[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.10.0" -weakdeps = ["SpecialFunctions"] - - [deps.ColorVectorSpace.extensions] - SpecialFunctionsExt = "SpecialFunctions" - -[[deps.Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.11" - -[[deps.CommonSubexpressions]] -deps = ["MacroTools"] -git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.1" - -[[deps.Compat]] -deps = ["TOML", "UUIDs"] -git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.16.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.1+0" - -[[deps.ConstructionBase]] -git-tree-sha1 = "76219f1ed5771adbb096743bff43fb5fdd4c1157" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.8" -weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseLinearAlgebraExt = "LinearAlgebra" - ConstructionBaseStaticArraysExt = "StaticArrays" - -[[deps.Contour]] -git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.6.3" - -[[deps.DataAPI]] -git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.16.0" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.20" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" -version = "1.11.0" - -[[deps.DelaunayTriangulation]] -deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "PrecompileTools", "Random"] -git-tree-sha1 = "89df54fbe66e5872d91d8c2cd3a375f660c3fd64" -uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "1.6.1" - -[[deps.DiffResults]] -deps = ["StaticArraysCore"] -git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "1.1.0" - -[[deps.DiffRules]] -deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.15.1" - -[[deps.Distances]] -deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.12" -weakdeps = ["ChainRulesCore", "SparseArrays"] - - [deps.Distances.extensions] - DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesSparseArraysExt = "SparseArrays" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" -version = "1.11.0" - -[[deps.Distributions]] -deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "d7477ecdafb813ddee2ae727afa94e9dcb5f3fb0" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.112" - - [deps.Distributions.extensions] - DistributionsChainRulesCoreExt = "ChainRulesCore" - DistributionsDensityInterfaceExt = "DensityInterface" - DistributionsTestExt = "Test" - - [deps.Distributions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.DocStringExtensions]] -deps = ["LibGit2"] -git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.3" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.EarCut_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" -uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" -version = "2.2.4+0" - -[[deps.EnumX]] -git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" -uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" -version = "1.0.4" - -[[deps.ExactPredicates]] -deps = ["IntervalArithmetic", "Random", "StaticArrays"] -git-tree-sha1 = "b3f2ff58735b5f024c392fde763f29b057e4b025" -uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" -version = "2.2.8" - -[[deps.Expat_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1c6317308b9dc757616f0b5cb379db10494443a7" -uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.6.2+0" - -[[deps.Extents]] -git-tree-sha1 = "81023caa0021a41712685887db1fc03db26f41f5" -uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.4" - -[[deps.FFMPEG_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "8cc47f299902e13f90405ddb5bf87e5d474c0d38" -uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "6.1.2+0" - -[[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.8.0" - -[[deps.FFTW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4d81ed14783ec49ce9f2e168208a12ce1815aa25" -uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.10+1" - -[[deps.Ferrite]] -deps = ["EnumX", "ForwardDiff", "LinearAlgebra", "NearestNeighbors", "OrderedCollections", "Preferences", "Reexport", "SparseArrays", "StaticArrays", "Tensors", "WriteVTK"] -path = ".." -uuid = "c061ca5d-56c9-439f-9c0e-210fe06d3992" -version = "1.0.0" - - [deps.Ferrite.extensions] - FerriteBlockArrays = "BlockArrays" - FerriteMetis = "Metis" - - [deps.Ferrite.weakdeps] - BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" - Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b" - -[[deps.FileIO]] -deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "62ca0547a14c57e98154423419d8a342dca75ca9" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.4" - -[[deps.FilePaths]] -deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] -git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" -uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" -version = "0.8.3" - -[[deps.FilePathsBase]] -deps = ["Compat", "Dates"] -git-tree-sha1 = "7878ff7172a8e6beedd1dea14bd27c3c6340d361" -uuid = "48062228-2e41-5def-b9a4-89aafe57970f" -version = "0.9.22" -weakdeps = ["Mmap", "Test"] - - [deps.FilePathsBase.extensions] - FilePathsBaseMmapExt = "Mmap" - FilePathsBaseTestExt = "Test" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" -version = "1.11.0" - -[[deps.FillArrays]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "6a70198746448456524cb442b8af316927ff3e1a" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.13.0" -weakdeps = ["PDMats", "SparseArrays", "Statistics"] - - [deps.FillArrays.extensions] - FillArraysPDMatsExt = "PDMats" - FillArraysSparseArraysExt = "SparseArrays" - FillArraysStatisticsExt = "Statistics" - -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" - -[[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] -git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" -uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.96+0" - -[[deps.Format]] -git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" -uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" -version = "1.3.7" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "a9ce73d3c827adab2d70bf168aaece8cce196898" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.37" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.FreeType]] -deps = ["CEnum", "FreeType2_jll"] -git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "4.1.1" - -[[deps.FreeType2_jll]] -deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" -uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.2+0" - -[[deps.FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] -git-tree-sha1 = "84dfe824bd6fdf2a5d73bb187ff31b5549b2a79c" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.4" - -[[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" -uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.14+0" - -[[deps.GeoFormatTypes]] -git-tree-sha1 = "59107c179a586f0fe667024c5eb7033e81333271" -uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f" -version = "0.4.2" - -[[deps.GeoInterface]] -deps = ["Extents", "GeoFormatTypes"] -git-tree-sha1 = "2f6fce56cdb8373637a6614e14a5768a88450de2" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.7" - -[[deps.GeometryBasics]] -deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "b62f2b2d76cee0d61a2ef2b3118cd2a3215d3134" -uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.4.11" - -[[deps.Gettext_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] -git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" -uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" -version = "0.21.0+0" - -[[deps.Giflib_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0224cce99284d997f6880a42ef715a37c99338d1" -uuid = "59f7168a-df46-5410-90c8-f2779963d0ec" -version = "5.2.2+0" - -[[deps.Glib_jll]] -deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "674ff0db93fffcd11a3573986e550d66cd4fd71f" -uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.5+0" - -[[deps.Graphics]] -deps = ["Colors", "LinearAlgebra", "NaNMath"] -git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" -uuid = "a2bd30eb-e257-5431-a919-1863eab51364" -version = "1.1.2" - -[[deps.Graphite2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" -uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" -version = "1.3.14+0" - -[[deps.GridLayoutBase]] -deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "fc713f007cff99ff9e50accba6373624ddd33588" -uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.11.0" - -[[deps.Grisu]] -git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" -uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" -version = "1.0.2" - -[[deps.HarfBuzz_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] -git-tree-sha1 = "401e4f3f30f43af2c8478fc008da50096ea5240f" -uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" -version = "8.3.1+0" - -[[deps.HypergeometricFunctions]] -deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "7c4195be1649ae622304031ed46a2f4df989f1eb" -uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.24" - -[[deps.ImageAxes]] -deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] -git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" -uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -version = "0.6.11" - -[[deps.ImageBase]] -deps = ["ImageCore", "Reexport"] -git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" -uuid = "c817782e-172a-44cc-b673-b171935fbb9e" -version = "0.1.7" - -[[deps.ImageCore]] -deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] -git-tree-sha1 = "b2a7eaa169c13f5bcae8131a83bc30eff8f71be0" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.10.2" - -[[deps.ImageIO]] -deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs", "WebP"] -git-tree-sha1 = "696144904b76e1ca433b886b4e7edd067d76cbf7" -uuid = "82e4d734-157c-48bb-816b-45c225c6df19" -version = "0.6.9" - -[[deps.ImageMetadata]] -deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] -git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" -uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" -version = "0.9.9" - -[[deps.Imath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0936ba688c6d201805a83da835b55c61a180db52" -uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" -version = "3.1.11+0" - -[[deps.IndirectArrays]] -git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" -uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" -version = "1.0.0" - -[[deps.Inflate]] -git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.5" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "10bd689145d2c3b2a9844005d01087cc1194e79e" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.2.1+0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" -version = "1.11.0" - -[[deps.Interpolations]] -deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.15.1" -weakdeps = ["Unitful"] - - [deps.Interpolations.extensions] - InterpolationsUnitfulExt = "Unitful" - -[[deps.IntervalArithmetic]] -deps = ["CRlibm_jll", "LinearAlgebra", "MacroTools", "RoundingEmulator"] -git-tree-sha1 = "c59c57c36683aa17c563be6edaac888163f35285" -uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.18" - - [deps.IntervalArithmetic.extensions] - IntervalArithmeticDiffRulesExt = "DiffRules" - IntervalArithmeticForwardDiffExt = "ForwardDiff" - IntervalArithmeticIntervalSetsExt = "IntervalSets" - IntervalArithmeticRecipesBaseExt = "RecipesBase" - - [deps.IntervalArithmetic.weakdeps] - DiffRules = "b552c78f-8df3-52c6-915a-8e097449b14b" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" - -[[deps.IntervalSets]] -git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.10" - - [deps.IntervalSets.extensions] - IntervalSetsRandomExt = "Random" - IntervalSetsRecipesBaseExt = "RecipesBase" - IntervalSetsStatisticsExt = "Statistics" - - [deps.IntervalSets.weakdeps] - Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[deps.InverseFunctions]] -git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb" -uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.17" -weakdeps = ["Dates", "Test"] - - [deps.InverseFunctions.extensions] - InverseFunctionsDatesExt = "Dates" - InverseFunctionsTestExt = "Test" - -[[deps.IrrationalConstants]] -git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.2" - -[[deps.Isoband]] -deps = ["isoband_jll"] -git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" -uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" -version = "0.1.1" - -[[deps.IterTools]] -git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.10.0" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[deps.JLLWrappers]] -deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "be3dc50a92e5a386872a493a10050136d4703f9b" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.6.1" - -[[deps.JSON]] -deps = ["Dates", "Mmap", "Parsers", "Unicode"] -git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.21.4" - -[[deps.JpegTurbo]] -deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] -git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" -uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" -version = "0.1.5" - -[[deps.JpegTurbo_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "25ee0be4d43d0269027024d75a24c24d6c6e590c" -uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.0.4+0" - -[[deps.KernelDensity]] -deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "7d703202e65efa1369de1279c162b915e245eed1" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.9" - -[[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" -uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.2+0" - -[[deps.LERC_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "36bdbc52f13a7d1dcb0f3cd694e01677a515655b" -uuid = "88015f11-f218-50d7-93a8-a6af411a945d" -version = "4.0.0+0" - -[[deps.LLVMOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "78211fb6cbc872f77cad3fc0b6cf647d923f4929" -uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "18.1.7+0" - -[[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "854a9c268c43b77b0a27f22d7fab8d33cdb3a731" -uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.2+1" - -[[deps.LaTeXStrings]] -git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" -uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.4.0" - -[[deps.LazyArtifacts]] -deps = ["Artifacts", "Pkg"] -uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" -version = "1.11.0" - -[[deps.LazyModules]] -git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" -uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" -version = "0.3.1" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" -version = "1.11.0" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.7.2+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" -version = "1.11.0" - -[[deps.Libffi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" -uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" -version = "3.2.2+1" - -[[deps.Libgcrypt_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll"] -git-tree-sha1 = "8be878062e0ffa2c3f67bb58a595375eda5de80b" -uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.11.0+0" - -[[deps.Libglvnd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] -git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" -uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" -version = "1.6.0+0" - -[[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "c6ce1e19f3aec9b59186bdf06cdf3c4fc5f5f3e6" -uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.50.0+0" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "61dfdba58e585066d8bce214c5a51eaa0539f269" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.17.0+1" - -[[deps.Libmount_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" -uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.40.1+0" - -[[deps.Libtiff_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "b404131d06f7886402758c9ce2214b636eb4d54a" -uuid = "89763e89-9b03-5906-acba-b20f662cd828" -version = "4.7.0+0" - -[[deps.Libuuid_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" -uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.40.1+0" - -[[deps.LightXML]] -deps = ["Libdl", "XML2_jll"] -git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" -uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" -version = "0.9.1" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -version = "1.11.0" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.28" - - [deps.LogExpFunctions.extensions] - LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" - LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" - LogExpFunctionsInverseFunctionsExt = "InverseFunctions" - - [deps.LogExpFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - -[[deps.Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" -version = "1.11.0" - -[[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] -git-tree-sha1 = "f046ccd0c6db2832a9f639e2c669c6fe867e5f4f" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.2.0+0" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.13" - -[[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "InverseFunctions", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] -git-tree-sha1 = "f7907907eb914138cc9e9ee66ab46f7a9efac8e8" -uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.21.15" - -[[deps.MakieCore]] -deps = ["ColorTypes", "GeometryBasics", "IntervalSets", "Observables"] -git-tree-sha1 = "4604f03e5b057e8e62a95a44929cafc9585b0fe9" -uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.8.9" - -[[deps.MappedArrays]] -git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.2" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" -version = "1.11.0" - -[[deps.MathTeXEngine]] -deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] -git-tree-sha1 = "f45c8916e8385976e1ccd055c9874560c257ab13" -uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.6.2" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+0" - -[[deps.Missings]] -deps = ["DataAPI"] -git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.2.0" - -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" -version = "1.11.0" - -[[deps.MosaicViews]] -deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] -git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" -uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" -version = "0.3.4" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.12.12" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.0.2" - -[[deps.NearestNeighbors]] -deps = ["Distances", "StaticArrays"] -git-tree-sha1 = "3cebfc94a0754cc329ebc3bab1e6c89621e791ad" -uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" -version = "0.4.20" - -[[deps.Netpbm]] -deps = ["FileIO", "ImageCore", "ImageMetadata"] -git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" -uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" -version = "1.1.1" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.Observables]] -git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.5.5" - -[[deps.OffsetArrays]] -git-tree-sha1 = "1a27764e945a152f7ca7efa04de513d473e9542e" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.14.1" -weakdeps = ["Adapt"] - - [deps.OffsetArrays.extensions] - OffsetArraysAdaptExt = "Adapt" - -[[deps.Ogg_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" -uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" -version = "1.3.5+1" - -[[deps.OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.27+1" - -[[deps.OpenEXR]] -deps = ["Colors", "FileIO", "OpenEXR_jll"] -git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" -uuid = "52e1d378-f018-4a11-a4be-720524705ac7" -version = "0.3.2" - -[[deps.OpenEXR_jll]] -deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "8292dd5c8a38257111ada2174000a33745b06d4e" -uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.2.4+0" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+2" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "7493f61f55a6cce7325f197443aa80d32554ba10" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.15+1" - -[[deps.OpenSpecFun_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" -uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" -version = "0.5.5+0" - -[[deps.Opus_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6703a85cb3781bd5909d48730a67205f3f31a575" -uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.3.3+0" - -[[deps.OrderedCollections]] -git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.3" - -[[deps.PCRE2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.42.0+1" - -[[deps.PDMats]] -deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.31" - -[[deps.PNGFiles]] -deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] -git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" -uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" -version = "0.4.3" - -[[deps.Packing]] -deps = ["GeometryBasics"] -git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.5.0" - -[[deps.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[deps.Pango_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e127b609fb9ecba6f201ba7ab753d5a605d53801" -uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.54.1+0" - -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.1" - -[[deps.Pixman_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" -uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.43.4+0" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.11.0" -weakdeps = ["REPL"] - - [deps.Pkg.extensions] - REPLExt = "REPL" - -[[deps.PkgVersion]] -deps = ["Pkg"] -git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" -uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.3" - -[[deps.PlotUtils]] -deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] -git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.4.3" - -[[deps.PolygonOps]] -git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" -uuid = "647866c9-e3ac-4575-94e7-e3d426903924" -version = "0.1.2" - -[[deps.PrecompileTools]] -deps = ["Preferences"] -git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.1" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.3" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" -version = "1.11.0" - -[[deps.ProgressMeter]] -deps = ["Distributed", "Printf"] -git-tree-sha1 = "8f6bc219586aef8baf0ff9a5fe16ee9c70cb65e4" -uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.10.2" - -[[deps.PtrArrays]] -git-tree-sha1 = "77a42d78b6a92df47ab37e177b2deac405e1c88f" -uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" -version = "1.2.1" - -[[deps.QOI]] -deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] -git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" -uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" -version = "1.0.0" - -[[deps.QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "cda3b045cf9ef07a08ad46731f5a3165e56cf3da" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.11.1" - - [deps.QuadGK.extensions] - QuadGKEnzymeExt = "Enzyme" - - [deps.QuadGK.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - -[[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" -version = "1.11.0" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -version = "1.11.0" - -[[deps.RangeArrays]] -git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" -uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" -version = "0.3.2" - -[[deps.Ratios]] -deps = ["Requires"] -git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.4.5" -weakdeps = ["FixedPointNumbers"] - - [deps.Ratios.extensions] - RatiosFixedPointNumbersExt = "FixedPointNumbers" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.RelocatableFolders]] -deps = ["SHA", "Scratch"] -git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" -uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.1" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.0" - -[[deps.Rmath]] -deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "852bd0f55565a9e973fcfee83a84413270224dc4" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.8.0" - -[[deps.Rmath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.5.1+0" - -[[deps.RoundingEmulator]] -git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" -uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" -version = "0.2.1" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.SIMD]] -deps = ["PrecompileTools"] -git-tree-sha1 = "98ca7c29edd6fc79cd74c61accb7010a4e7aee33" -uuid = "fdea26ae-647d-5447-a871-4b548cad5224" -version = "3.6.0" - -[[deps.Scratch]] -deps = ["Dates"] -git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" -uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.2.1" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -version = "1.11.0" - -[[deps.ShaderAbstractions]] -deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "79123bc60c5507f035e6d1d9e563bb2971954ec8" -uuid = "65257c39-d410-5151-9873-9b3e5be5013e" -version = "0.4.1" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" -version = "1.11.0" - -[[deps.Showoff]] -deps = ["Dates", "Grisu"] -git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "1.0.3" - -[[deps.SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - -[[deps.SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" - -[[deps.Sixel]] -deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] -git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" -uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" -version = "0.1.3" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" -version = "1.11.0" - -[[deps.SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.11.0" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.4.0" -weakdeps = ["ChainRulesCore"] - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - -[[deps.StableRNGs]] -deps = ["Random"] -git-tree-sha1 = "83e6cce8324d49dfaf9ef059227f91ed4441a8e5" -uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" -version = "1.0.2" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.1" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "777657803913ffc7e8cc20f0fd04b634f871af8f" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.8" -weakdeps = ["ChainRulesCore", "Statistics"] - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.3" - -[[deps.Statistics]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.11.1" -weakdeps = ["SparseArrays"] - - [deps.Statistics.extensions] - SparseArraysExt = ["SparseArrays"] - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.0" - -[[deps.StatsBase]] -deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.3" - -[[deps.StatsFuns]] -deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "b423576adc27097764a90e163157bcfc9acf0f46" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.3.2" -weakdeps = ["ChainRulesCore", "InverseFunctions"] - - [deps.StatsFuns.extensions] - StatsFunsChainRulesCoreExt = "ChainRulesCore" - StatsFunsInverseFunctionsExt = "InverseFunctions" - -[[deps.StructArrays]] -deps = ["ConstructionBase", "DataAPI", "Tables"] -git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.18" - - [deps.StructArrays.extensions] - StructArraysAdaptExt = "Adapt" - StructArraysGPUArraysCoreExt = "GPUArraysCore" - StructArraysSparseArraysExt = "SparseArrays" - StructArraysStaticArraysExt = "StaticArrays" - - [deps.StructArrays.weakdeps] - Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.StyledStrings]] -uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" -version = "1.11.0" - -[[deps.SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.7.0+0" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.12.0" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[deps.TensorCore]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" -uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" -version = "0.1.1" - -[[deps.Tensors]] -deps = ["ForwardDiff", "LinearAlgebra", "PrecompileTools", "SIMD", "StaticArrays", "Statistics"] -git-tree-sha1 = "957f256fb380cad64cae4da39e562ecfb5c3fec9" -uuid = "48a634ad-e948-5137-8d70-aa71f2a747f4" -version = "1.16.1" - -[[deps.Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -version = "1.11.0" - -[[deps.TiffImages]] -deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "SIMD", "UUIDs"] -git-tree-sha1 = "6ee0c220d0aecad18792c277ae358129cc50a475" -uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.11.0" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.11.3" - -[[deps.TriplotBase]] -git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" -uuid = "981d1d27-644d-49a2-9326-4793e63143c3" -version = "0.1.0" - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" -version = "1.11.0" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" -version = "1.11.0" - -[[deps.UnicodeFun]] -deps = ["REPL"] -git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.1" - -[[deps.Unitful]] -deps = ["Dates", "LinearAlgebra", "Random"] -git-tree-sha1 = "d95fe458f26209c66a187b1114df96fd70839efd" -uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" -version = "1.21.0" -weakdeps = ["ConstructionBase", "InverseFunctions"] - - [deps.Unitful.extensions] - ConstructionBaseUnitfulExt = "ConstructionBase" - InverseFunctionsUnitfulExt = "InverseFunctions" - -[[deps.VTKBase]] -git-tree-sha1 = "c2d0db3ef09f1942d08ea455a9e252594be5f3b6" -uuid = "4004b06d-e244-455f-a6ce-a5f9919cc534" -version = "1.0.1" - -[[deps.WebP]] -deps = ["CEnum", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "libwebp_jll"] -git-tree-sha1 = "f1f6d497ff84039deeb37f264396dac0c2250497" -uuid = "e3aaa7dc-3e4b-44e0-be63-ffb868ccd7c1" -version = "0.1.2" - -[[deps.WoodburyMatrices]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "1.0.0" - -[[deps.WriteVTK]] -deps = ["Base64", "CodecZlib", "FillArrays", "LightXML", "TranscodingStreams", "VTKBase"] -git-tree-sha1 = "1d8042d58334ab7947ce505709df7009da6f3375" -uuid = "64499a7a-5c06-52f2-abe2-ccb03c286192" -version = "1.21.1" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "6a451c6f33a176150f315726eba8b92fbfdb9ae7" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.4+0" - -[[deps.XSLT_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "XML2_jll", "Zlib_jll"] -git-tree-sha1 = "a54ee957f4c86b526460a720dbc882fa5edcbefc" -uuid = "aed1982a-8fda-507f-9586-7b0439959a61" -version = "1.1.41+0" - -[[deps.XZ_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "15e637a697345f6743674f1322beefbc5dcd5cfc" -uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.6.3+0" - -[[deps.Xorg_libX11_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] -git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" -uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" -version = "1.8.6+0" - -[[deps.Xorg_libXau_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" -uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" -version = "1.0.11+0" - -[[deps.Xorg_libXdmcp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" -uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" -version = "1.1.4+0" - -[[deps.Xorg_libXext_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" -uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.6+0" - -[[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" -uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.11+0" - -[[deps.Xorg_libpthread_stubs_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" -uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" -version = "0.1.1+0" - -[[deps.Xorg_libxcb_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] -git-tree-sha1 = "bcd466676fef0878338c61e655629fa7bbc69d8e" -uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.17.0+0" - -[[deps.Xorg_xtrans_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" -uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" -version = "1.5.0+0" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+1" - -[[deps.Zstd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "555d1076590a6cc2fdee2ef1469451f872d8b41b" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.6+1" - -[[deps.isoband_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" -uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" -version = "0.2.3+0" - -[[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" -uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.9.0+0" - -[[deps.libass_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "e17c115d55c5fbb7e52ebedb427a0dca79d4484e" -uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" -version = "0.15.2+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.11.0+0" - -[[deps.libfdk_aac_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8a22cf860a7d27e4f3498a0fe0811a7957badb38" -uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" -version = "2.0.3+0" - -[[deps.libpng_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "b70c870239dc3d7bc094eb2d6be9b73d27bef280" -uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.44+0" - -[[deps.libsixel_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] -git-tree-sha1 = "7dfa0fd9c783d3d0cc43ea1af53d69ba45c447df" -uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" -version = "1.10.3+1" - -[[deps.libvorbis_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] -git-tree-sha1 = "490376214c4721cdaca654041f635213c6165cb3" -uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.7+2" - -[[deps.libwebp_jll]] -deps = ["Artifacts", "Giflib_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libglvnd_jll", "Libtiff_jll", "libpng_jll"] -git-tree-sha1 = "ccbb625a89ec6195856a50aa2b668a5c08712c94" -uuid = "c5f90fcd-3b7e-5836-afba-fc50a0988cb2" -version = "1.4.0+0" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.59.0+0" - -[[deps.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2021.12.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" - -[[deps.x264_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "35976a1216d6c066ea32cba2150c4fa682b276fc" -uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" -version = "10164.0.0+0" - -[[deps.x265_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "dcc541bb19ed5b0ede95581fb2e41ecf179527d2" -uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" -version = "3.6.0+0" diff --git a/visualization/Project.toml b/visualization/Project.toml deleted file mode 100644 index e101770250..0000000000 --- a/visualization/Project.toml +++ /dev/null @@ -1,4 +0,0 @@ -[deps] -CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -Ferrite = "c061ca5d-56c9-439f-9c0e-210fe06d3992" -ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" diff --git a/visualization/reference_cell_ip.jl b/visualization/reference_cell_ip.jl deleted file mode 100644 index d60e354674..0000000000 --- a/visualization/reference_cell_ip.jl +++ /dev/null @@ -1,85 +0,0 @@ -using Ferrite -import FerriteViz as Viz -import GLMakie as Plt - - -function refshape_shapevalues(ip::VectorInterpolation{3, RefHexahedron}, shape_nr; npoints = 5) - x, y, z, u, v, w = (zeros(npoints^3) for _ in 1:6) - idx = 1 - for i in 1:npoints - for j in 1:npoints - for k in 1:npoints - x[idx], y[idx], z[idx] = (i-1, j-1, k-1) .* (2/(npoints-1)) .- 1 - u[idx], v[idx], w[idx] = shape_value(ip, Vec((x[idx], y[idx], z[idx])), shape_nr) - idx += 1 - end - end - end - return x, y, z, u, v, w -end - -refcell(::Type{RefHexahedron}) = Hexahedron(ntuple(i->i, 8)) -refcell(::Type{RefTetrahedron}) = Tetrahedron(ntuple(i->i, 4)) -refip(::Type{RefShape}) where {RefShape <: Ferrite.AbstractRefShape} = Lagrange{RefShape,1}() - - -function plot_refcell(::Type{RefShape}; kwargs...) where {RefShape <: Ferrite.AbstractRefShape{3}} - fig = Plt.Figure() - ax = Plt.Axis3(fig[1,1]; xlabel="ξ₁", ylabel="ξ₂", zlabel="ξ₃") - plot_refcell!(ax, RefShape; kwargs...) - return fig, ax -end - -function plot_refcell!(ax, ::Type{RefShape}; vertices=true, edges=true, faces=true) where {RefShape <: Ferrite.AbstractRefShape{3}} - plot_vertices!(ax, RefShape; label=vertices) - plot_edges!(ax, RefShape; label=edges) - plot_faces!(ax, RefShape; label=faces) - return ax -end - -function plot_vertices!(ax, ::Type{RefShape}; label) where {RefShape <: Ferrite.AbstractRefShape{3}} - ξ = Ferrite.reference_coordinates(refip(RefShape)) - ξ1, ξ2, ξ3 = (getindex.(ξ, i) for i in 1:3) - Plt.scatter!(ax, ξ1, ξ2, ξ3) - if label - Plt.text!(ax, ξ1, ξ2, ξ3; text=[string(i) for i in 1:length(ξ)]) - end - return ax -end - -function plot_edges!(ax, ::Type{RefShape}; label) where {RefShape <: Ferrite.AbstractRefShape{3}} - arrowheadpos = 2/3 - cell = refcell(RefShape) - ξ = Ferrite.reference_coordinates(refip(RefShape)) - x, y, z, u, v, w = (zeros(length(Ferrite.edges(cell))) for _ in 1:6) - for (k, e) in enumerate(Ferrite.edges(cell)) - ξa, ξb = getindex.((ξ,), e) - Plt.lines!(ax, ([ξa[i], ξb[i]] for i in 1:3)...) - x[k], y[k], z[k] = ξa - u[k], v[k], w[k] = ξb - ξa - end - Plt.arrows!(ax, x, y, z, u * arrowheadpos, v * arrowheadpos, w * arrowheadpos; linewidth=0.05, arrowsize=0.1) - if label - s = arrowheadpos + (1-arrowheadpos)/6 - Plt.text!(ax, x + u*s, y + v*s, z + w*s; text=[string(i) for i in 1:length(x)]) - end -end - -plot_faces!(ax, RefShape; label) = nothing - -function testit(nshape=1) - ip = Nedelec{3,RefHexahedron,1}(); - - fig, ax = plot_refcell(RefHexahedron; vertices=true, edges=true); - vals = refshape_shapevalues(ip, nshape) - lengths = sqrt.(vals[4].^2 + vals[5].^2 + vals[6].^2) - Plt.arrows!(ax, vals...; lengthscale=0.1, arrowsize=0.1, color=lengths) - return fig -end - -# Possible tests -#= -1) Check shape_value(ip, ξ, i) ⋅ v_edge[i] = |shape_value(ip, ξ, i)| (checks alignment) -2) Check ∫ Ni ⋅ v dL = 1 on each edge -3) Check shape_value(ip, ξ, i) ⋅ v_edge[j] = 0 for i≠j -=# From c26cad639a328f5abd09f6197622a272687a8c47 Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Tue, 12 Nov 2024 16:23:11 +0100 Subject: [PATCH 138/145] Fix link and imports --- docs/src/literate-tutorials/heat_equation_hdiv.jl | 2 +- src/Ferrite.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/literate-tutorials/heat_equation_hdiv.jl b/docs/src/literate-tutorials/heat_equation_hdiv.jl index e3f2bee293..7fceeb6ad2 100644 --- a/docs/src/literate-tutorials/heat_equation_hdiv.jl +++ b/docs/src/literate-tutorials/heat_equation_hdiv.jl @@ -220,7 +220,7 @@ end println("Outward flux: ", calculate_flux(dh, Γ, ipq, u)) -# Note that this is not the case for the standard [Heat equation](@id tutorial-heat-equation), +# Note that this is not the case for the standard [Heat equation](@ref tutorial-heat-equation), # as the flux terms are less accurately approximated. A fine mesh is required to converge in that case. # However, the present example gives a worse approximation of the temperature field. diff --git a/src/Ferrite.jl b/src/Ferrite.jl index 7b358463be..f30ea21f84 100644 --- a/src/Ferrite.jl +++ b/src/Ferrite.jl @@ -21,7 +21,7 @@ using WriteVTK: WriteVTK, VTKCellTypes using Tensors: Tensors, AbstractTensor, SecondOrderTensor, SymmetricTensor, Tensor, Vec, gradient, - rotation_tensor, symmetric, tovoigt!, hessian, otimesu + rotation_tensor, symmetric, tovoigt!, hessian, otimesu, otimesl using ForwardDiff: ForwardDiff From e0935ddd3111752076826ad1052497d5c812540b Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Wed, 13 Nov 2024 17:57:09 +0100 Subject: [PATCH 139/145] Add nonworking maxwell eigenvalues example --- docs/Manifest.toml | 30 ++++++++- docs/Project.toml | 2 + docs/make.jl | 1 + docs/src/literate-tutorials/maxwell.jl | 91 ++++++++++++++++++++++++++ src/interpolations.jl | 7 +- 5 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 docs/src/literate-tutorials/maxwell.jl diff --git a/docs/Manifest.toml b/docs/Manifest.toml index d627674895..b19c814d6a 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.11.1" manifest_format = "2.0" -project_hash = "4e52f4aa4cee9f66ec4f633f0ae538fbd227ac5e" +project_hash = "c8cd4f9010376e633064839ca68de8e4b622021f" [[deps.ADTypes]] git-tree-sha1 = "eea5d80188827b35333801ef97a40c2ed653b081" @@ -69,6 +69,18 @@ git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" uuid = "ec485272-7323-5ecc-a04f-4719b315124d" version = "0.4.0" +[[deps.Arpack]] +deps = ["Arpack_jll", "Libdl", "LinearAlgebra", "Logging"] +git-tree-sha1 = "9b9b347613394885fd1c8c7729bfc60528faa436" +uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +version = "0.5.4" + +[[deps.Arpack_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "OpenBLAS_jll", "Pkg"] +git-tree-sha1 = "5ba6c757e8feccf03a1554dfaf3e26b3cfc7fd5e" +uuid = "68821587-b530-5797-8361-c406ea357684" +version = "3.5.1+1" + [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] git-tree-sha1 = "3640d077b6dafd64ceb8fd5c1ec76f7ca53bcf76" @@ -931,6 +943,16 @@ git-tree-sha1 = "267dad6b4b7b5d529c76d40ff48d33f7e94cb834" uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" version = "0.9.6" +[[deps.KrylovKit]] +deps = ["GPUArraysCore", "LinearAlgebra", "PackageExtensionCompat", "Printf", "Random", "VectorInterface"] +git-tree-sha1 = "3ba86a12066c19a6ed0bc963984bcf89d495133e" +uuid = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" +version = "0.8.2" +weakdeps = ["ChainRulesCore"] + + [deps.KrylovKit.extensions] + KrylovKitChainRulesCoreExt = "ChainRulesCore" + [[deps.LAME_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" @@ -2325,6 +2347,12 @@ git-tree-sha1 = "c2d0db3ef09f1942d08ea455a9e252594be5f3b6" uuid = "4004b06d-e244-455f-a6ce-a5f9919cc534" version = "1.0.1" +[[deps.VectorInterface]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "cea8abaa6e43f72f97a09cf95b80c9eb53ff75cf" +uuid = "409d34a3-91d5-4945-b6ec-7529ddf182d8" +version = "0.4.9" + [[deps.VectorizationBase]] deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] git-tree-sha1 = "e7f5b81c65eb858bed630fe006837b935518aca5" diff --git a/docs/Project.toml b/docs/Project.toml index ead8045637..d21f86c895 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,4 +1,5 @@ [deps] +Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" Changelog = "5217a498-cd5d-4ec6-b8c2-9b85a09b6e3e" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" @@ -9,6 +10,7 @@ FerriteMeshParser = "0f8c756f-80dd-4a75-85c6-b0a5ab9d4620" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Gmsh = "705231aa-382f-11e9-3f0c-b7cb4346fdeb" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" +KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" diff --git a/docs/make.jl b/docs/make.jl index 1d5a7b6a10..ed61182d43 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -68,6 +68,7 @@ bibtex_plugin = CitationBibliography( "tutorials/reactive_surface.md", "tutorials/linear_shell.md", "tutorials/dg_heat_equation.md", + "tutorials/maxwell.md", ], "Topic guides" => [ "Topic guide overview" => "topics/index.md", diff --git a/docs/src/literate-tutorials/maxwell.jl b/docs/src/literate-tutorials/maxwell.jl new file mode 100644 index 0000000000..a68967cb16 --- /dev/null +++ b/docs/src/literate-tutorials/maxwell.jl @@ -0,0 +1,91 @@ +#= +# Solving Maxwell's equations +```math +\begin{align*} +\nabla \cdot \boldsymbol{D} &= \rho_\mathrm{f} \\ +\nabla \times \boldsymbol{H} &= \boldsymbol{J}_\mathrm{f} + \frac{\partial \boldsymbol{D}}{\partial t} \\ +\nabla \cdot \boldsymbol{B} &= 0 \\ +\nabla \times \boldsymbol{E} &= -\frac{\partial \boldsymbol{B}}{\partial t} +\end{align*} +``` +=# + +#= +# Maxwell eigenvalue problem +Strong form +```math +\begin{align*} +\mathrm{curl}(\mathrm{curl}(\boldsymbol{u})) &= \lambda \boldsymbol{u} \text{ in } \Omega \\ +\boldsymbol{u} \times \boldsymbol{n} &= \boldsymbol{0} \text{ on } \partial\Omega +\end{align*} +``` +Weak form +```math +\int_\Omega \mathrm{curl}(\boldsymbol{\delta u}) \cdot \mathrm{curl}(\boldsymbol{u})\ \mathrm{d}\Omega = \lambda \int_\Omega \boldsymbol{\delta u} \cdot \boldsymbol{u}\ \mathrm{d}\Omega \quad \forall\ \boldsymbol{\delta u} \in H_0(\text{curl}) +``` +Finite element formulation +```math +\underbrace{\int_\Omega \mathrm{curl}(\boldsymbol{\delta N}_i) \cdot \mathrm{curl}(\boldsymbol{N_j})\ \mathrm{d}\Omega}_{A_{ij}}\ x_j = \lambda \underbrace{\int_\Omega \boldsymbol{\delta N_i} \cdot \boldsymbol{N_j}\ \mathrm{d}\Omega}_{B_{ij}}\ x_j +``` +=# + +# ## Implementation +using Ferrite, Tensors, KrylovKit +using Arpack: Arpack +# ### Element routine +function element_routine!(Ae, Be, cv::CellValues) + for q_point in 1:getnquadpoints(cv) + dΩ = getdetJdV(cv, q_point) + for i in 1:getnbasefunctions(cv) + δN = shape_value(cv, q_point, i) + curl_δN = shape_curl(cv, q_point, i) + for j in 1:getnbasefunctions(cv) + N = shape_value(cv, q_point, j) + curl_N = shape_curl(cv, q_point, j) + Ae[i, j] = (curl_δN ⋅ curl_N) * dΩ + Be[i, j] = (δN ⋅ N) * dΩ + end + end + end + return +end + +# ### FE setup +function doassemble!(A, B, dh, cv) + n = ndofs_per_cell(dh) + Ae = zeros(n, n) + Be = zeros(n, n) + a_assem, b_assem = start_assemble.((A, B)) + for cc in CellIterator(dh) + cell = getcells(dh.grid, cellid(cc)) + reinit!(cv, cell, getcoordinates(cc)) + element_routine!(Ae, Be, cv) + assemble!(a_assem, celldofs(cc), Ae) + assemble!(b_assem, celldofs(cc), Be) + end + return A, B +end + +function setup_and_assemble(ip::VectorInterpolation{2, RefTriangle}) + grid = generate_grid(Triangle, (10, 10)) + cv = CellValues(QuadratureRule{RefTriangle}(2), ip, geometric_interpolation(Triangle)) + dh = close!(add!(DofHandler(grid), :u, ip)) + ∂Ω = union((getfacetset(grid, k) for k in ("left", "top", "right", "bottom"))...) + dbc = Dirichlet(:u, ∂Ω, ip isa VectorizedInterpolation ? Returns([0.0, 0.0]) : Returns(0.0)) + ch = close!(add!(ConstraintHandler(dh), dbc)) + sp = init_sparsity_pattern(dh) + add_sparsity_entries!(sp, dh) + A = allocate_matrix(sp) + B = allocate_matrix(sp) + doassemble!(A, B, dh, cv) + Ferrite.zero_out_rows!(B, ch.dofmapping) + Ferrite.zero_out_columns!(B, ch.prescribed_dofs) + return A, B, dh +end + +ip = Nedelec{2, RefTriangle, 1}() + +A, B, dh = setup_and_assemble(ip) + +vals, vecs, info = geneigsolve((A, B), 1, EigSorter(x -> abs(x - 5.0)); maxiter = 1000); +# λ, ϕ = Arpack.eigs(A, B, nev = 2, sigma=5.5); diff --git a/src/interpolations.jl b/src/interpolations.jl index 1dc0876c1e..f9a4a2ba6c 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1793,6 +1793,8 @@ mapping_type(::VectorizedInterpolation) = IdentityMapping() struct RaviartThomas{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end mapping_type(::RaviartThomas) = ContravariantPiolaMapping() n_dbc_components(::RaviartThomas) = 1 +dirichlet_edgedof_indices(ip::RaviartThomas{2}) = edgedof_interior_indices(ip) +dirichlet_facedof_indices(ip::RaviartThomas{3}) = facedof_interior_indices(ip) # RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-raviart-thomas-lagrange-1.html @@ -1807,6 +1809,7 @@ end getnbasefunctions(::RaviartThomas{2, RefTriangle, 1}) = 3 edgedof_interior_indices(::RaviartThomas{2, RefTriangle, 1}) = ((1,), (2,), (3,)) + adjust_dofs_during_distribution(::RaviartThomas) = false function get_direction(::RaviartThomas{2, RefTriangle, 1}, j, cell) @@ -1872,7 +1875,7 @@ end struct BrezziDouglasMarini{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end mapping_type(::BrezziDouglasMarini) = ContravariantPiolaMapping() reference_coordinates(ip::BrezziDouglasMarini{vdim}) where {vdim} = fill(NaN * zero(Vec{vdim}), getnbasefunctions(ip)) -#dirichlet_facedof_indices(ip::BrezziDouglasMarini) = facetdof_interior_indices(ip) +dirichlet_edgedof_indices(ip::BrezziDouglasMarini{2}) = edgedof_interior_indices(ip) n_dbc_components(::BrezziDouglasMarini) = 1 #= ----------------+-------------------- @@ -1923,7 +1926,7 @@ end struct Nedelec{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end mapping_type(::Nedelec) = CovariantPiolaMapping() reference_coordinates(ip::Nedelec{vdim}) where {vdim} = fill(NaN * zero(Vec{vdim}), getnbasefunctions(ip)) -dirichlet_facedof_indices(ip::Nedelec) = facetdof_interior_indices(ip) +dirichlet_edgedof_indices(ip::Nedelec) = edgedof_interior_indices(ip) n_dbc_components(::Nedelec) = 1 # RefTriangle, 1st order Lagrange # https://defelement.com/elements/examples/triangle-nedelec1-lagrange-1.html From f0a8d1bcfe84d2834f97ff3090c445a90da458e9 Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Wed, 13 Nov 2024 17:57:32 +0100 Subject: [PATCH 140/145] Reduce elements in hdiv example --- docs/src/literate-tutorials/heat_equation_hdiv.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/literate-tutorials/heat_equation_hdiv.jl b/docs/src/literate-tutorials/heat_equation_hdiv.jl index 7fceeb6ad2..81ce3203b0 100644 --- a/docs/src/literate-tutorials/heat_equation_hdiv.jl +++ b/docs/src/literate-tutorials/heat_equation_hdiv.jl @@ -69,7 +69,7 @@ function create_grid(ny::Int) return grid end -grid = create_grid(100) +grid = create_grid(10) # ### Setup # We define one `CellValues` for each field which share the same quadrature rule. From 5140c9822fbedb8238d985a985477dac332d885b Mon Sep 17 00:00:00 2001 From: Knut Andreas Meyer Date: Wed, 13 Nov 2024 18:08:14 +0100 Subject: [PATCH 141/145] Disable failing Maxwell eigenvalue solve --- docs/src/literate-tutorials/maxwell.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/literate-tutorials/maxwell.jl b/docs/src/literate-tutorials/maxwell.jl index a68967cb16..b6a459b3d3 100644 --- a/docs/src/literate-tutorials/maxwell.jl +++ b/docs/src/literate-tutorials/maxwell.jl @@ -87,5 +87,5 @@ ip = Nedelec{2, RefTriangle, 1}() A, B, dh = setup_and_assemble(ip) -vals, vecs, info = geneigsolve((A, B), 1, EigSorter(x -> abs(x - 5.0)); maxiter = 1000); +# vals, vecs, info = geneigsolve((A, B), 1, EigSorter(x -> abs(x - 5.0)); maxiter = 1000); # λ, ϕ = Arpack.eigs(A, B, nev = 2, sigma=5.5); From 7911cbdedeba762ad5e10a6b94be1d92a78ec0f4 Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Thu, 14 Nov 2024 19:12:45 +0100 Subject: [PATCH 142/145] Add test for correct BC indices, non-homogeneous not yet working --- src/interpolations.jl | 2 +- test/test_interpolations.jl | 54 +++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/interpolations.jl b/src/interpolations.jl index f9a4a2ba6c..eee217678f 100644 --- a/src/interpolations.jl +++ b/src/interpolations.jl @@ -1793,6 +1793,7 @@ mapping_type(::VectorizedInterpolation) = IdentityMapping() struct RaviartThomas{vdim, shape, order} <: VectorInterpolation{vdim, shape, order} end mapping_type(::RaviartThomas) = ContravariantPiolaMapping() n_dbc_components(::RaviartThomas) = 1 +reference_coordinates(ip::RaviartThomas{vdim}) where {vdim} = fill(NaN * zero(Vec{vdim}), getnbasefunctions(ip)) dirichlet_edgedof_indices(ip::RaviartThomas{2}) = edgedof_interior_indices(ip) dirichlet_facedof_indices(ip::RaviartThomas{3}) = facedof_interior_indices(ip) @@ -1809,7 +1810,6 @@ end getnbasefunctions(::RaviartThomas{2, RefTriangle, 1}) = 3 edgedof_interior_indices(::RaviartThomas{2, RefTriangle, 1}) = ((1,), (2,), (3,)) - adjust_dofs_during_distribution(::RaviartThomas) = false function get_direction(::RaviartThomas{2, RefTriangle, 1}, j, cell) diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index 53f552feb7..35cc50bd21 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -1,7 +1,7 @@ using Ferrite: reference_shape_value, reference_shape_gradient @testset "interpolations" begin - + #= @testset "Value Type $value_type" for value_type in (Float32, Float64) @testset "Correctness of $interpolation" for interpolation in ( Lagrange{RefLine, 1}(), @@ -223,7 +223,7 @@ using Ferrite: reference_shape_value, reference_shape_gradient @test Ferrite.is_discontinuous(d_ip) == true @test Ferrite.is_discontinuous(d_ip_t) == true end - + =# @testset "Correctness of AD of embedded interpolations" begin ip = Lagrange{RefHexahedron, 2}()^3 ξ = rand(Vec{3, Float64}) @@ -425,6 +425,56 @@ using Ferrite: reference_shape_value, reference_shape_gradient end end + @testset "Hcurl and Hdiv BC" begin + hdiv_ips = ( + RaviartThomas{2, RefTriangle, 1}(), + RaviartThomas{2, RefTriangle, 2}(), + Ferrite.BrezziDouglasMarini{2, RefTriangle, 1}(), + ) + hdiv_check(v, n) = v ⋅ n + + hcurl_ips = ( + Nedelec{2, RefTriangle, 1}(), + Nedelec{2, RefTriangle, 2}(), + ) + function hcurl_check(v, n::Vec{2}) # 3d not supported yet + t = rotate(n, π / 2) + return v ⋅ t + end + for (f, interpolations) in ((hdiv_check, hdiv_ips), (hcurl_check, hcurl_ips)) + for ip in interpolations + @testset "$ip" begin + RefShape = Ferrite.getrefshape(ip) + CT = typeof(reference_cell(RefShape)) + dim = Ferrite.getrefdim(CT) # dim=sdim=vdim + grid = generate_grid(CT, ntuple(Returns(2), dim)) + qr = FacetQuadratureRule{RefShape}(4) + fv = FacetValues(qr, ip, geometric_interpolation(CT)) + dh = close!(add!(DofHandler(grid), :u, ip)) + for bval in (0.0,) # 1.0) # Need to add mapping in _update! for this to work correctly + a = rand(ndofs(dh)) + ch = ConstraintHandler(dh) + add!(ch, Dirichlet(:u, getfacetset(grid, "left"), Returns(bval))) + close!(ch) + apply!(a, ch) + test_val = 0.0 + for (cellidx, facetidx) in getfacetset(grid, "left") + reinit!(fv, getcells(grid, cellidx), getcoordinates(grid, cellidx), facetidx) + ae = a[celldofs(dh, cellidx)] + val = 0.0 + for q_point in 1:getnquadpoints(fv) + dΓ = getdetJdV(fv, q_point) + val += f(function_value(fv, q_point, ae), getnormal(fv, q_point)) * dΓ + end + test_val += f === hdiv_check ? val : abs(val) + end + println(bval, ": ", test_val) + @test abs(test_val - 2 * bval) < 1.0e-6 + end + end + end + end + end @testset "Errors for entitydof_indices on VectorizedInterpolations" begin ip = Lagrange{RefQuadrilateral, 2}()^2 From 01a830664418be917ab4ed47b7f0c9c4433a9139 Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Thu, 14 Nov 2024 19:16:11 +0100 Subject: [PATCH 143/145] Reenable tests --- test/test_interpolations.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_interpolations.jl b/test/test_interpolations.jl index 35cc50bd21..7b5e0eedc1 100644 --- a/test/test_interpolations.jl +++ b/test/test_interpolations.jl @@ -1,7 +1,6 @@ using Ferrite: reference_shape_value, reference_shape_gradient @testset "interpolations" begin - #= @testset "Value Type $value_type" for value_type in (Float32, Float64) @testset "Correctness of $interpolation" for interpolation in ( Lagrange{RefLine, 1}(), @@ -223,7 +222,6 @@ using Ferrite: reference_shape_value, reference_shape_gradient @test Ferrite.is_discontinuous(d_ip) == true @test Ferrite.is_discontinuous(d_ip_t) == true end - =# @testset "Correctness of AD of embedded interpolations" begin ip = Lagrange{RefHexahedron, 2}()^3 ξ = rand(Vec{3, Float64}) From 508eec7b7932c6373c3209f0e40c0815e4559a2f Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Fri, 15 Nov 2024 11:30:21 +0100 Subject: [PATCH 144/145] Improve tutorial formatting --- .../literate-tutorials/heat_equation_hdiv.jl | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/docs/src/literate-tutorials/heat_equation_hdiv.jl b/docs/src/literate-tutorials/heat_equation_hdiv.jl index 81ce3203b0..93c4bd3f90 100644 --- a/docs/src/literate-tutorials/heat_equation_hdiv.jl +++ b/docs/src/literate-tutorials/heat_equation_hdiv.jl @@ -18,10 +18,10 @@ # such that # ```math # \begin{align*} -# \boldsymbol{\nabla}\cdot \boldsymbol{q} &= h(\boldsymbol{x}), \quad \forall \boldsymbol{x} \in \Omega \\ -# \boldsymbol{q}(\boldsymbol{x}) &= - k\ \boldsymbol{\nabla} u(\boldsymbol{x}), \quad \forall \boldsymbol{x} \in \Omega \\ -# \boldsymbol{q}(\boldsymbol{x})\cdot \boldsymbol{n}(\boldsymbol{x}) &= q_n, \quad \forall \boldsymbol{x} \in \Gamma_\mathrm{N}\\ -# u(\boldsymbol{x}) &= u_\mathrm{D}, \quad \forall \boldsymbol{x} \in \Gamma_\mathrm{D} +# \boldsymbol{\nabla}\cdot \boldsymbol{q} &= h(\boldsymbol{x}), \quad \text{in } \Omega \\ +# \boldsymbol{q}(\boldsymbol{x}) &= - k\ \boldsymbol{\nabla} u(\boldsymbol{x}), \quad \text{in } \Omega \\ +# \boldsymbol{q}(\boldsymbol{x})\cdot \boldsymbol{n}(\boldsymbol{x}) &= q_n, \quad \text{on } \Gamma_\mathrm{N}\\ +# u(\boldsymbol{x}) &= u_\mathrm{D}, \quad \text{on } \Gamma_\mathrm{D} # \end{align*} # ``` # @@ -30,9 +30,9 @@ # ```math # \begin{align*} # \int_{\Omega} \delta u [\boldsymbol{\nabla} \cdot \boldsymbol{q}]\ \mathrm{d}\Omega &= \int_\Omega \delta u h\ \mathrm{d}\Omega, \quad \forall\ \delta u \in \delta\mathbb{U} \\ -# \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= -\int_\Omega \boldsymbol{\delta q} \cdot [k\ \boldsymbol{\nabla} u]\ \mathrm{d}\Omega \\ +# % \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega &= -\int_\Omega \boldsymbol{\delta q} \cdot [k\ \boldsymbol{\nabla} u]\ \mathrm{d}\Omega \\ # \int_{\Omega} \boldsymbol{\delta q} \cdot \boldsymbol{q}\ \mathrm{d}\Omega - \int_{\Omega} [\boldsymbol{\nabla} \cdot \boldsymbol{\delta q}] k u \ \mathrm{d}\Omega &= -# -\int_\Gamma \boldsymbol{\delta q} \cdot \boldsymbol{n} k\ u\ \mathrm{d}\Omega, \quad \forall\ \boldsymbol{\delta q} \in \delta\mathbb{Q} +# -\int_\Gamma \boldsymbol{\delta q} \cdot \boldsymbol{n} k\ u\ \mathrm{d}\Gamma, \quad \forall\ \boldsymbol{\delta q} \in \delta\mathbb{Q} # \end{align*} # ``` # where we have the function spaces, @@ -47,8 +47,6 @@ # * `DiscontinuousLagrange{RefTriangle, k-1}` for approximating $L^2$ # * `BrezziDouglasMarini{RefTriangle, k}` for approximating $H(\mathrm{div})$ # -# We will also investigate the consequences of using $H^1$ `Lagrange` instead of $H(\mathrm{div})$ interpolations. -# # ## Commented Program # # Now we solve the problem in Ferrite. What follows is a program spliced with comments. @@ -70,6 +68,7 @@ function create_grid(ny::Int) end grid = create_grid(10) +#md nothing # hide # ### Setup # We define one `CellValues` for each field which share the same quadrature rule. @@ -78,16 +77,19 @@ ipu = DiscontinuousLagrange{RefTriangle, 0}() ipq = Ferrite.BrezziDouglasMarini{2, RefTriangle, 1}() qr = QuadratureRule{RefTriangle}(2) cellvalues = (u = CellValues(qr, ipu, ip_geo), q = CellValues(qr, ipq, ip_geo)) +#md nothing # hide # Distribute the degrees of freedom dh = DofHandler(grid) add!(dh, :u, ipu) add!(dh, :q, ipq) -close!(dh); +close!(dh) +#md nothing # hide # In this problem, we have a zero temperature on the boundary, Γ, which is enforced # via zero Neumann boundary conditions. Hence, we don't need a `Constrainthandler`. Γ = union((getfacetset(grid, name) for name in ("left", "right", "bottom", "top"))...) +#md nothing # hide # ### Element implementation @@ -131,7 +133,6 @@ end #md nothing # hide # ### Global assembly - function assemble_global(cellvalues, dh::DofHandler) grid = dh.grid ## Allocate the element stiffness matrix and element force vector @@ -173,7 +174,8 @@ end # ### Solution of the system K, f = assemble_global(cellvalues, dh); -u = K \ f; +u = K \ f +#md nothing # hide # ### Exporting to VTK # Currently, exporting discontinuous interpolations is not supported. @@ -186,6 +188,7 @@ end VTKGridFile("heat_equation_hdiv", dh) do vtk write_cell_data(vtk, u_cells, "temperature") end +#md nothing # hide # ## Postprocess the total flux # We applied a constant unit heat source to the body, and the @@ -219,6 +222,7 @@ function calculate_flux(dh, boundary_facets, ip, a) end println("Outward flux: ", calculate_flux(dh, Γ, ipq, u)) +#md nothing # hide # Note that this is not the case for the standard [Heat equation](@ref tutorial-heat-equation), # as the flux terms are less accurately approximated. A fine mesh is required to converge in that case. From 5ebcccff78b0b35069dbabd6ff0fc14b10f8cd05 Mon Sep 17 00:00:00 2001 From: Knut Andreas Date: Fri, 15 Nov 2024 16:00:43 +0100 Subject: [PATCH 145/145] Add link to potential test case to check for maxwell problem --- docs/src/literate-tutorials/maxwell.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/src/literate-tutorials/maxwell.jl b/docs/src/literate-tutorials/maxwell.jl index b6a459b3d3..a959416094 100644 --- a/docs/src/literate-tutorials/maxwell.jl +++ b/docs/src/literate-tutorials/maxwell.jl @@ -11,6 +11,9 @@ =# #= +**Not working:** Maybe try the standard laplace eigenvalue problem +https://www.cambridge.org/core/services/aop-cambridge-core/content/view/4BD87CC520C7E11CF402981AA58D77E2/S0962492910000012a.pdf/finite-element-approximation-of-eigenvalue-problems.pdf + # Maxwell eigenvalue problem Strong form ```math