Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Use GeometryMapping in BCValues #849

Open
KnutAM opened this issue Dec 3, 2023 · 0 comments · May be fixed by #859
Open

Use GeometryMapping in BCValues #849

KnutAM opened this issue Dec 3, 2023 · 0 comments · May be fixed by #859

Comments

@KnutAM
Copy link
Member

KnutAM commented Dec 3, 2023

The GeometryMapping in #764 should be reusable in BCValues. To avoid littering that PR with even more stuff, I'm leaving some preliminary and untested code here as a reference.

To be done in a separate PR after merging 764...

"""
    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 geometric interpolation (`geom_interpol`),
for each dof-position determined by the `func_interpol`. Used mainly by the `ConstraintHandler`.
"""
struct BCValues{V_GM, FQR} <: AbstractFaceValues
    geo_mapping::V_GM # AbstractVector{GeometryMapping}
    fqr::FQR          # FaceQuadratureRule
    current_face::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
    fqr = FaceQuadratureRule(qrs)
    geo_mapping = [GeometryMapping{0}(T, geom_interpol, qr) for qr in qrs]

    BCValues(geo_mapping, fqr, ScalarWrapper(1))
end

nfaces(bcv::BCValues) = length(bcv.geo_mapping)
getcurrentface(bcv) = bcv.current_face[]

function set_current_face!(bcv::BCValues, face_nr::Int)
    # Checking face_nr before setting current_face allows us to use @inbounds 
    # when indexing by getcurrentface(fv) in other places!
    checkbounds(Bool, 1:nfaces(bcv), face_nr) || throw(ArgumentError("Face index out of range."))
    bcv.current_face[] = face_nr
end

getnquadpoints(bcv::BCValues) = @inbounds getnquadpoints(bcv.fqr, getcurrentface(bcv))
@KnutAM KnutAM linked a pull request Dec 11, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants