Skip to content

Commit

Permalink
Traits for ScalarValues / VectorValues (#404) + set version to 0.3.2
Browse files Browse the repository at this point in the history
* traits for ScalarValues & VectorValues

* remove outdated / wrong comments

* rename to ScalarValue/VectorValued

* replace isa(VectorValues)

* change version to 0.3.2
  • Loading branch information
kimauth committed Jan 18, 2022
1 parent bbd88a0 commit d1503b7
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "Ferrite"
uuid = "c061ca5d-56c9-439f-9c0e-210fe06d3992"
version = "0.3.1"
version = "0.3.2"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
4 changes: 1 addition & 3 deletions src/FEValues/cell_values.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,8 @@ end

function reinit!(cv::CellValues{dim}, x::AbstractVector{Vec{dim,T}}) where {dim,T}
n_geom_basefuncs = getngeobasefunctions(cv)
n_func_basefuncs = getn_scalarbasefunctions(cv)
n_func_basefuncs = getnbasefunctions(cv)
@assert length(x) == n_geom_basefuncs
isa(cv, CellVectorValues) && (n_func_basefuncs *= dim)


@inbounds for i in 1:length(cv.qr_weights)
w = cv.qr_weights[i]
Expand Down
63 changes: 40 additions & 23 deletions src/FEValues/common_values.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@

using Base: @propagate_inbounds

const ScalarValues{dim,T,shape} = Union{CellScalarValues{dim,T,shape},FaceScalarValues{dim,T,shape},PointScalarValues{dim,T,shape}}
const VectorValues{dim,T,shape} = Union{CellVectorValues{dim,T,shape},FaceVectorValues{dim,T,shape}}
abstract type FieldTrait end
struct VectorValued <: FieldTrait end
struct ScalarValued <: FieldTrait end

FieldTrait(::Type{<:CellScalarValues}) = ScalarValued()
FieldTrait(::Type{<:FaceScalarValues}) = ScalarValued()
FieldTrait(::Type{<:PointScalarValues}) = ScalarValued()
FieldTrait(::Type{<:CellVectorValues}) = VectorValued()
FieldTrait(::Type{<:FaceVectorValues}) = VectorValued()


getnbasefunctions(cv::Values) = size(cv.N, 1)
getngeobasefunctions(cv::Values) = size(cv.M, 1)

getn_scalarbasefunctions(cv::ScalarValues) = size(cv.N, 1)
getn_scalarbasefunctions(cv::VectorValues{dim}) where {dim} = size(cv.N, 1) ÷ dim
getn_scalarbasefunctions(cv::T) where T = getn_scalarbasefunctions(FieldTrait(T), cv)
getn_scalarbasefunctions(::ScalarValued, cv::Values) = size(cv.N, 1)
getn_scalarbasefunctions(::VectorValued, cv::Values{dim}) where {dim} = size(cv.N, 1) ÷ dim

"""
reinit!(cv::CellValues, x::Vector)
Expand Down Expand Up @@ -84,8 +93,9 @@ quadrature point `q_point`.
@propagate_inbounds shape_divergence(cv::CellVectorValues, q_point::Int, base_func::Int) = tr(cv.dNdx[base_func, q_point])
@propagate_inbounds shape_divergence(bv::FaceVectorValues, q_point::Int, base_func::Int) = tr(bv.dNdx[base_func, q_point, bv.current_face[]])

shape_curl(cv::T, q_point, base_func) where T = shape_curl(FieldTrait(T), cv, q_point, base_func)

function shape_curl(cv::VectorValues, q_point::Int, base_func::Int)
function shape_curl(::VectorValued, cv::Values, q_point::Int, base_func::Int)
return curl(shape_gradient(cv, q_point, base_func))
end
curl(∇v) = Vec{3}((∇v[3,2] - ∇v[2,3], ∇v[1,3] - ∇v[3,1], ∇v[2,1] - ∇v[1,2]))
Expand All @@ -103,9 +113,11 @@ where ``u_i`` are the value of ``u`` in the nodes. For a vector valued function
``\\mathbf{u}(\\mathbf{x}) = \\sum\\limits_{i = 1}^n N_i (\\mathbf{x}) \\mathbf{u}_i`` where ``\\mathbf{u}_i`` are the
nodal values of ``\\mathbf{u}``.
"""
function function_value(fe_v::Values{dim}, q_point::Int, u::AbstractVector{T}, dof_range = eachindex(u)) where {dim,T}
n_base_funcs = getn_scalarbasefunctions(fe_v)
isa(fe_v, VectorValues) && (n_base_funcs *= dim)
function_value(fe_v::T, q_point, u, dof_range) where T = function_value(FieldTrait(T), fe_v, q_point, u, dof_range)
function_value(fe_v::T, q_point, u) where T = function_value(FieldTrait(T), fe_v, q_point, u)

function function_value(::FieldTrait, fe_v::Values{dim}, q_point::Int, u::AbstractVector{T}, dof_range = eachindex(u)) where {dim,T}
n_base_funcs = getnbasefunctions(fe_v)
@assert length(dof_range) == n_base_funcs
@boundscheck checkbounds(u, dof_range)
val = zero(_valuetype(fe_v, u))
Expand All @@ -115,7 +127,7 @@ function function_value(fe_v::Values{dim}, q_point::Int, u::AbstractVector{T}, d
return val
end

function function_value(fe_v::VectorValues{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T}
function function_value(::VectorValued, fe_v::Values{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T}
n_base_funcs = getn_scalarbasefunctions(fe_v)
@assert length(u) == n_base_funcs
val = zero(Vec{dim, T})
Expand All @@ -129,9 +141,10 @@ function function_value(fe_v::VectorValues{dim}, q_point::Int, u::AbstractVector
return val
end

Base.@pure _valuetype(::ScalarValues{dim}, ::AbstractVector{T}) where {dim,T} = T
Base.@pure _valuetype(::ScalarValues{dim}, ::AbstractVector{Vec{dim,T}}) where {dim,T} = Vec{dim,T}
Base.@pure _valuetype(::VectorValues{dim}, ::AbstractVector{T}) where {dim,T} = Vec{dim,T}
_valuetype(t::T, v) where T = _valuetype(FieldTrait(T), t, v)
Base.@pure _valuetype(::ScalarValued, ::Values{dim}, ::AbstractVector{T}) where {dim,T} = T
Base.@pure _valuetype(::ScalarValued, ::Values{dim}, ::AbstractVector{Vec{dim,T}}) where {dim,T} = Vec{dim,T}
Base.@pure _valuetype(::VectorValued, ::Values{dim}, ::AbstractVector{T}) where {dim,T} = Vec{dim,T}
# Base.@pure _valuetype(::VectorValues{dim}, ::AbstractVector{Vec{dim,T}}) where {dim,T} = Vec{dim,T}

"""
Expand All @@ -150,9 +163,11 @@ For a vector valued function with use of `ScalarValues` the gradient is computed
``\\mathbf{\\nabla} \\mathbf{u}(\\mathbf{x}) = \\sum\\limits_{i = 1}^n \\mathbf{u}_i \\otimes \\mathbf{\\nabla} N_i (\\mathbf{x})``
where ``\\mathbf{u}_i`` are the nodal values of ``\\mathbf{u}``.
"""
function function_gradient(fe_v::Values{dim}, q_point::Int, u::AbstractVector{T}, dof_range = eachindex(u)) where {dim,T}
n_base_funcs = getn_scalarbasefunctions(fe_v)
isa(fe_v, VectorValues) && (n_base_funcs *= dim)
function_gradient(fe_v::T, q_point, u) where T = function_gradient(FieldTrait(T), fe_v, q_point, u)
function_gradient(fe_v::T, q_point, u, dof_range) where T = function_gradient(FieldTrait(T), fe_v, q_point, u, dof_range)

function function_gradient(::FieldTrait, fe_v::Values{dim}, q_point::Int, u::AbstractVector{T}, dof_range = eachindex(u)) where {dim,T}
n_base_funcs = getnbasefunctions(fe_v)
@assert length(dof_range) == n_base_funcs
@boundscheck checkbounds(u, dof_range)
grad = zero(_gradienttype(fe_v, u))
Expand All @@ -162,10 +177,11 @@ function function_gradient(fe_v::Values{dim}, q_point::Int, u::AbstractVector{T}
return grad
end

Base.@pure _gradienttype(::ScalarValues{dim}, ::AbstractVector{T}) where {dim,T} = Vec{dim,T}
Base.@pure _gradienttype(::VectorValues{dim}, ::AbstractVector{T}) where {dim,T} = Tensor{2,dim,T}
_gradienttype(values::T, v) where T = _gradienttype(FieldTrait(T), values, v)
Base.@pure _gradienttype(::ScalarValued, ::Values{dim}, ::AbstractVector{T}) where {dim,T} = Vec{dim,T}
Base.@pure _gradienttype(::VectorValued, ::Values{dim}, ::AbstractVector{T}) where {dim,T} = Tensor{2,dim,T}

function function_gradient(fe_v::ScalarValues{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T}
function function_gradient(::ScalarValued, fe_v::Values{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T}
n_base_funcs = getn_scalarbasefunctions(fe_v)
@assert length(u) == n_base_funcs
grad = zero(Tensor{2,dim,T})
Expand All @@ -175,7 +191,7 @@ function function_gradient(fe_v::ScalarValues{dim}, q_point::Int, u::AbstractVec
return grad
end

function function_gradient(fe_v::VectorValues{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T}
function function_gradient(::VectorValued, fe_v::Values{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T}
n_base_funcs = getn_scalarbasefunctions(fe_v)
@assert length(u) == n_base_funcs
grad = zero(Tensor{2,dim,T})
Expand Down Expand Up @@ -221,7 +237,9 @@ The divergence of a vector valued functions in the quadrature point ``\\mathbf{x
``\\mathbf{\\nabla} \\cdot \\mathbf{u}(\\mathbf{x_q}) = \\sum\\limits_{i = 1}^n \\mathbf{\\nabla} N_i (\\mathbf{x_q}) \\cdot \\mathbf{u}_i``
where ``\\mathbf{u}_i`` are the nodal values of the function.
"""
function function_divergence(fe_v::ScalarValues{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T}
function_divergence(fe_v::T, q_point, u) where T = function_divergence(FieldTrait(T), fe_v, q_point, u)

function function_divergence(::ScalarValued, fe_v::Values{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T}
n_base_funcs = getn_scalarbasefunctions(fe_v)
@assert length(u) == n_base_funcs
diverg = zero(T)
Expand All @@ -231,11 +249,10 @@ function function_divergence(fe_v::ScalarValues{dim}, q_point::Int, u::AbstractV
return diverg
end

# See https://github.com/Ferrite-FEM/Ferrite.jl/issues/336
function_divergence(fe_v::VectorValues{dim}, q_point::Int, u::AbstractVector{T}, dof_range = eachindex(u)) where {dim,T} =
function_divergence(::VectorValued, fe_v::Values{dim}, q_point::Int, u::AbstractVector{T}, dof_range = eachindex(u)) where {dim,T} =
tr(function_gradient(fe_v, q_point, u, dof_range))

function_divergence(fe_v::VectorValues{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T} =
function_divergence(::VectorValued, fe_v::Values{dim}, q_point::Int, u::AbstractVector{Vec{dim,T}}) where {dim,T} =
tr(function_gradient(fe_v, q_point, u))

function_curl(fe_v::Values, q_point::Int, u::AbstractVector, dof_range = eachindex(u)) =
Expand Down
3 changes: 1 addition & 2 deletions src/FEValues/face_values.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,8 @@ end

function reinit!(fv::FaceValues{dim}, x::AbstractVector{Vec{dim,T}}, face::Int) where {dim,T}
n_geom_basefuncs = getngeobasefunctions(fv)
n_func_basefuncs = getn_scalarbasefunctions(fv)
n_func_basefuncs = getnbasefunctions(fv)
@assert length(x) == n_geom_basefuncs
isa(fv, FaceVectorValues) && (n_func_basefuncs *= dim)

fv.current_face[] = face
cb = getcurrentface(fv)
Expand Down

2 comments on commit d1503b7

@kimauth
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/52689

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.3.2 -m "<description of version>" d1503b7ea06dacf76bef2891d28429a1a1c0d211
git push origin v0.3.2

Please sign in to comment.