Skip to content

Commit

Permalink
Added MappedDofBasis
Browse files Browse the repository at this point in the history
  • Loading branch information
JordiManyer committed Dec 12, 2024
1 parent b5ab282 commit ea4e350
Showing 1 changed file with 93 additions and 5 deletions.
98 changes: 93 additions & 5 deletions src/ReferenceFEs/Pullbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ Represents the inverse of a pushforward map F*, defined as
where
- V̂ is a function space on the reference cell K̂ and
- V is a function space on the physical cell K.
# Note:
Given a pushforward F*, we provide a default implementation for the inverse (F*)^-1 that
is not optimal (and I think wrong for nonlinear geometries???).
For better performance, the user should overload the following methods for each
specific pushforward type:
- `return_cache(k::InversePushforward{PF}, v_phys::Number, args...)`
- `evaluate!(cache, k::InversePushforward{PF}, v_phys::Number, args...)`
"""
struct InversePushforward{PF} <: Map
pushforward::PF
Expand Down Expand Up @@ -98,6 +110,58 @@ function evaluate!(
Broadcasting(Operation(k))(f_phys,args...)
end

# MappedDofBasis

"""
struct MappedDofBasis{T<:Dof,MT,BT} <: AbstractVector{T}
F :: MT
σ :: BT
args
end
Represents η = σ∘F, evaluated as η(φ) = σ(F(φ,args...))
- σ : V* -> R is a dof basis
- F : W -> V is a map between function spaces
Intended combinations would be:
- σ : V* -> R dof basis in the physical domain and F* : V̂ -> V is a pushforward map.
- ̂σ : V̂* -> R dof basis in the reference domain and (F*)^-1 : V -> V̂ is an inverse pushforward map.
"""
struct MappedDofBasis{T<:Dof,MT,BT,A} <: AbstractVector{T}
F :: MT
dofs :: BT
args :: A

function MappedDofBasis(F::Map, dofs::AbstractVector{<:Dof}, args...)
T = eltype(dofs)
MT = typeof(F)
BT = typeof(dofs)
A = typeof(args)
new{T,MT,BT,A}(F,dofs,args)
end
end

Base.size(b::MappedDofBasis) = size(b.dofs)

# Technically wrong, but the individual dofs are fake anyway
Base.getindex(b::MappedDofBasis, i) = getindex(b.dofs,i)

function Arrays.return_cache(b::MappedDofBasis, fields)
f_cache = return_cache(b.F,fields,b.args...)
ffields = evaluate!(f_cache,b.F,fields,b.args...)
dofs_cache = return_cache(b.dofs,ffields)
return f_cache, dofs_cache
end

function Arrays.evaluate!(cache, b::MappedDofBasis, fields)
f_cache, dofs_cache = cache
ffields = evaluate!(f_cache,b.F,fields,b.args...)
evaluate!(dofs_cache,b.dofs,ffields)
end

# Pullback

"""
Expand Down Expand Up @@ -131,8 +195,7 @@ end
function evaluate!(
cache, k::Pullback, σ_phys::AbstractVector{<:Dof}, args...
)
pf(f_ref) = evaluate(k.pushforward,f_ref,args...) # TODO: Can we avoid this?
return Arrays.OperationMap(σ_phys,pf)
return MappedDofBasis(k.pushforward,σ_phys,args...)
end

# InversePullback
Expand Down Expand Up @@ -171,8 +234,7 @@ end
function evaluate!(
cache, k::InversePullback, σ_ref::AbstractVector{<:Dof}, args...
)
ipf(f_phys) = evaluate(inverse_map(k.pushforward),f_phys,args...) # TODO: Can we avoid this?
return Arrays.OperationMap(σ_ref,ipf)
return MappedDofBasis(inverse_map(k.pushforward),σ_ref,args...)
end

# ContraVariantPiolaMap
Expand All @@ -184,7 +246,21 @@ function evaluate!(
)
sign = (-1)^sign_flip
idetJ = 1. / meas(Jt)
return (sign*v_ref)(idetJ*Jt)
return sign * idetJ * (v_refJt)
end

function return_cache(
::InversePushforward{ContraVariantPiolaMap}, v_phys::Number, Jt::Number, sign_flip::Bool
)
nothing
end

function evaluate!(
cache, ::InversePushforward{ContraVariantPiolaMap}, v_phys::Number, Jt::Number, sign_flip::Bool
)
sign = (-1)^sign_flip
detJ = meas(Jt)
return sign * detJ * (inv(Jt)v_phys)
end

# CoVariantPiolaMap
Expand All @@ -197,3 +273,15 @@ function evaluate!(
# we right-multiply to compute the gradient correctly
return v_reftranspose(inv(Jt))
end

function return_cache(
::InversePushforward{CoVariantPiolaMap}, v_phys::Number, Jt::Number
)
return nothing
end

function evaluate!(
cache, ::InversePushforward{CoVariantPiolaMap}, v_phys::Number, Jt::Number
)
return transpose(Jt)v_phys
end

0 comments on commit ea4e350

Please sign in to comment.