diff --git a/src/Adaptivity/Adaptivity.jl b/src/Adaptivity/Adaptivity.jl index 32a5d1594..8811c68dc 100644 --- a/src/Adaptivity/Adaptivity.jl +++ b/src/Adaptivity/Adaptivity.jl @@ -45,7 +45,6 @@ export DorflerMarking, mark, estimate include("RefinementRules.jl") include("FineToCoarseFields.jl") include("OldToNewFields.jl") -include("FineToCoarseReferenceFEs.jl") include("AdaptivityGlues.jl") include("AdaptedDiscreteModels.jl") include("AdaptedTriangulations.jl") diff --git a/src/Adaptivity/FineToCoarseReferenceFEs.jl b/src/Adaptivity/FineToCoarseReferenceFEs.jl deleted file mode 100644 index f36ad5793..000000000 --- a/src/Adaptivity/FineToCoarseReferenceFEs.jl +++ /dev/null @@ -1,132 +0,0 @@ -""" -""" -struct FineToCoarseDofBasis{T,A,B,C} <: AbstractVector{T} - dof_basis :: A - rrule :: B - child_ids :: C - - function FineToCoarseDofBasis(dof_basis::AbstractVector{T},rrule::RefinementRule) where {T<:Dof} - nodes = get_nodes(dof_basis) - child_ids = map(x -> x_to_cell(rrule,x),nodes) - - A = typeof(dof_basis) - B = typeof(rrule) - C = typeof(child_ids) - new{T,A,B,C}(dof_basis,rrule,child_ids) - end -end - -Base.size(a::FineToCoarseDofBasis) = size(a.dof_basis) -Base.axes(a::FineToCoarseDofBasis) = axes(a.dof_basis) -Base.getindex(a::FineToCoarseDofBasis,i::Integer) = getindex(a.dof_basis,i) -Base.IndexStyle(a::FineToCoarseDofBasis) = IndexStyle(a.dof_basis) - -ReferenceFEs.get_nodes(a::FineToCoarseDofBasis) = get_nodes(a.dof_basis) - -# Default behaviour -Arrays.return_cache(b::FineToCoarseDofBasis,field) = return_cache(b.dof_basis,field) -Arrays.evaluate!(cache,b::FineToCoarseDofBasis,field) = evaluate!(cache,b.dof_basis,field) - -# Spetialized behaviour -function Arrays.return_cache(s::FineToCoarseDofBasis{T,<:LagrangianDofBasis},field::FineToCoarseField) where T - b = s.dof_basis - cf = return_cache(field,b.nodes,s.child_ids) - vals = evaluate!(cf,field,b.nodes,s.child_ids) - ndofs = length(b.dof_to_node) - r = ReferenceFEs._lagr_dof_cache(vals,ndofs) - c = CachedArray(r) - return (c, cf) -end - -function Arrays.evaluate!(cache,s::FineToCoarseDofBasis{T,<:LagrangianDofBasis},field::FineToCoarseField) where T - c, cf = cache - b = s.dof_basis - vals = evaluate!(cf,field,b.nodes,s.child_ids) - ndofs = length(b.dof_to_node) - T2 = eltype(vals) - ncomps = num_indep_components(T2) - @check ncomps == num_indep_components(eltype(b.node_and_comp_to_dof)) """\n - Unable to evaluate LagrangianDofBasis. The number of components of the - given Field does not match with the LagrangianDofBasis. - If you are trying to interpolate a function on a FESpace make sure that - both objects have the same value type. - For instance, trying to interpolate a vector-valued function on a scalar-valued FE space - would raise this error. - """ - ReferenceFEs._evaluate_lagr_dof!(c,vals,b.node_and_comp_to_dof,ndofs,ncomps) -end - -function Arrays.return_cache(s::FineToCoarseDofBasis{T,<:MomentBasedDofBasis},field::FineToCoarseField) where T - b = s.dof_basis - cf = return_cache(field,b.nodes,s.child_ids) - vals = evaluate!(cf,field,b.nodes,s.child_ids) - ndofs = num_dofs(b) - r = ReferenceFEs._moment_dof_basis_cache(vals,ndofs) - c = CachedArray(r) - return (c, cf) -end - -function Arrays.evaluate!(cache,s::FineToCoarseDofBasis{T,<:MomentBasedDofBasis},field::FineToCoarseField) where T - c, cf = cache - b = s.dof_basis - vals = evaluate!(cf,field,b.nodes,s.child_ids) - dofs = c.array - ReferenceFEs._eval_moment_dof_basis!(dofs,vals,b) - dofs -end - - -""" - Wrapper for a ReferenceFE which is specialised for - efficiently evaluating FineToCoarseFields. -""" -struct FineToCoarseRefFE{T,D,A} <: ReferenceFE{D} - reffe :: T - dof_basis :: A - - function FineToCoarseRefFE(reffe::ReferenceFE{D},dof_basis::FineToCoarseDofBasis) where D - T = typeof(reffe) - A = typeof(dof_basis) - new{T,D,A}(reffe,dof_basis) - end -end - -ReferenceFEs.num_dofs(reffe::FineToCoarseRefFE) = num_dofs(reffe.reffe) -ReferenceFEs.get_polytope(reffe::FineToCoarseRefFE) = get_polytope(reffe.reffe) -ReferenceFEs.get_prebasis(reffe::FineToCoarseRefFE) = get_prebasis(reffe.reffe) -ReferenceFEs.get_dof_basis(reffe::FineToCoarseRefFE) = reffe.dof_basis -ReferenceFEs.Conformity(reffe::FineToCoarseRefFE) = Conformity(reffe.reffe) -ReferenceFEs.get_face_dofs(reffe::FineToCoarseRefFE) = get_face_dofs(reffe.reffe) -ReferenceFEs.get_shapefuns(reffe::FineToCoarseRefFE) = get_shapefuns(reffe.reffe) -ReferenceFEs.get_metadata(reffe::FineToCoarseRefFE) = get_metadata(reffe.reffe) -ReferenceFEs.get_orders(reffe::FineToCoarseRefFE) = get_orders(reffe.reffe) -ReferenceFEs.get_order(reffe::FineToCoarseRefFE) = get_order(reffe.reffe) - -ReferenceFEs.Conformity(reffe::FineToCoarseRefFE,sym::Symbol) = Conformity(reffe.reffe,sym) -ReferenceFEs.get_face_own_dofs(reffe::FineToCoarseRefFE,conf::Conformity) = get_face_own_dofs(reffe.reffe,conf) - - -function ReferenceFEs.ReferenceFE(p::Polytope,rrule::RefinementRule,name::ReferenceFEName,order) - FineToCoarseRefFE(p,rrule,name,Float64,order) -end - -function ReferenceFEs.ReferenceFE(p::Polytope,rrule::RefinementRule,name::ReferenceFEName,::Type{T},order) where T - FineToCoarseRefFE(p,rrule,name,T,order) -end - -function FineToCoarseRefFE(p::Polytope,rrule::RefinementRule,name::ReferenceFEName,::Type{T},order) where T - @check p == get_polytope(rrule) - reffe = ReferenceFE(p,name,T,order) - dof_basis = FineToCoarseDofBasis(get_dof_basis(reffe),rrule) - return FineToCoarseRefFE(reffe,dof_basis) -end - -# FESpaces constructors - -function FESpaces.TestFESpace(model::DiscreteModel,rrules::AbstractVector{<:RefinementRule},reffe::Tuple{<:ReferenceFEName,Any,Any};kwargs...) - @check num_cells(model) == length(rrules) - @check all(CompressedArray(get_polytopes(model),get_cell_type(model)) .== lazy_map(get_polytope,rrules)) - basis, reffe_args, reffe_kwargs = reffe - reffes = lazy_map(rr -> ReferenceFE(get_polytope(rr),rr,basis,reffe_args...;reffe_kwargs...),rrules) - return TestFESpace(model,reffes;kwargs...) -end diff --git a/src/ReferenceFEs/Pullbacks.jl b/src/ReferenceFEs/Pullbacks.jl index de49f3a21..dc0a9d45f 100644 --- a/src/ReferenceFEs/Pullbacks.jl +++ b/src/ReferenceFEs/Pullbacks.jl @@ -10,7 +10,7 @@ where """ abstract type Pushforward <: Map end -function lazy_map( +function Arrays.lazy_map( ::Broadcasting{typeof(gradient)}, a::LazyArray{<:Fill{Broadcasting{Operation{<:Pushforward}}}} ) cell_ref_basis, args = a.args @@ -37,21 +37,21 @@ struct InversePushforward{PF} <: Map end end -Arrays.inverse_map(pb::Pushforward) = InversePushforward(pb) -Arrays.inverse_map(ipb::InversePushforward) = ipb.pushforward +Arrays.inverse_map(pf::Pushforward) = InversePushforward(pf) +Arrays.inverse_map(ipf::InversePushforward) = ipf.pushforward # Pushforward """ struct Pullback{PF <: Pushforward} <: Map end -Represents a pushforward map F**, defined as +Represents a pullback map F**, defined as F** : V* -> V̂* where - V̂* is a dof space on the reference cell K̂ and - V* is a dof space on the physical cell K. Its action on physical dofs σ : V -> R is defined in terms of the pushforward map F* as - F**(σ) := σ∘F* : V̂ -> R + ̂σ = F**(σ) := σ∘F* : V̂ -> R """ struct Pullback{PF} <: Map pushforward::PF @@ -64,42 +64,42 @@ end function Arrays.lazy_map( ::typeof{evaluate},k::LazyArray{<:Fill{<:Pushforward}},ref_cell_basis ) - pf = k.maps.value - phys_cell_dofs, cell_map, pb_args = k.args - phys_cell_basis = lazy_map(pf.pushforward,ref_cell_basis,cell_map,pb_args...) + pb = k.maps.value + phys_cell_dofs, cell_map, pf_args = k.args + phys_cell_basis = lazy_map(pb.pushforward,ref_cell_basis,cell_map,pf_args...) return lazy_map(evaluate,phys_cell_dofs,phys_cell_basis) end -# InversePushforward +# InversePullback """ - struct InversePushforward{PF <: Pushforward} <: Map end + struct InversePullback{PF <: Pushforward} <: Map end -Represents the inverse of the pushforward map F**, defined as +Represents the inverse of the pullback map F**, defined as (F**)^-1 : V̂* -> V* where - V̂* is a dof space on the reference cell K̂ and - V* is a dof space on the physical cell K. -Its action on reference dofs ̂σ : V -> R is defined in terms of the pushforward map F* as - F**(̂σ) := ̂σ∘(F*)^-1 : V -> R +Its action on reference dofs ̂σ : V̂ -> R is defined in terms of the pushforward map F* as + σ = F**(̂σ) := ̂σ∘(F*)^-1 : V -> R """ -struct InversePushforward{PF} <: Map +struct InversePullback{PF} <: Map pushforward::PF - function InversePushforward(pushforward::Pushforward) + function InversePullback(pushforward::Pushforward) PF = typeof(pushforward) new{PF}(pushforward) end end -Arrays.inverse_map(pf::Pushforward) = InversePushforward(pf.pushforward) -Arrays.inverse_map(ipf::InversePushforward) = Pushforward(ipf.pushforward) +Arrays.inverse_map(pb::Pullback) = InversePullback(pb.pushforward) +Arrays.inverse_map(ipb::InversePullback) = Pullback(ipb.pushforward) function Arrays.lazy_map( - ::typeof{evaluate},k::LazyArray{<:Fill{<:InversePushforward}},phys_cell_basis + ::typeof{evaluate},k::LazyArray{<:Fill{<:InversePullback}},phys_cell_basis ) - pf = inverse_map(k.maps.value) - ref_cell_dofs, cell_map, pb_args = k.args - ref_cell_basis = lazy_map(inverse_map(pf.pushforward),phys_cell_basis,cell_map,pb_args...) + pb = inverse_map(k.maps.value) + ref_cell_dofs, cell_map, pf_args = k.args + ref_cell_basis = lazy_map(inverse_map(pb.pushforward),phys_cell_basis,cell_map,pf_args...) return lazy_map(evaluate,ref_cell_dofs,ref_cell_basis) end diff --git a/test/AdaptivityTests/FineToCoarseFieldsTests.jl b/test/AdaptivityTests/FineToCoarseFieldsTests.jl deleted file mode 100644 index 89beb196b..000000000 --- a/test/AdaptivityTests/FineToCoarseFieldsTests.jl +++ /dev/null @@ -1,103 +0,0 @@ -module FineToCoarseFieldsTests - -using Test -using Gridap -using Gridap.Arrays -using Gridap.Algebra -using Gridap.Geometry -using Gridap.CellData -using Gridap.Adaptivity -using Gridap.ReferenceFEs -using Gridap.FESpaces -using FillArrays - -sol(x) = x[1] + x[2] - -D = 2 -order = 1 -qorder = order*2+1 -domain = Tuple(repeat([0,1],D)) - -parent = CartesianDiscreteModel(domain,Tuple(fill(2,D))) -model = refine(parent) - -trian = Triangulation(model) -ctrian = Triangulation(parent) - -qorder = order*2+1 -dΩ_c = Measure(ctrian,qorder) -dΩ_f = Measure(trian,qorder) -dΩ_cf = Measure(ctrian,trian,qorder) - -glue = get_adaptivity_glue(model) -rrules = Adaptivity.get_old_cell_refinement_rules(glue) - -cell_reffe_lag = lazy_map(rr->ReferenceFE(get_polytope(rr),rr,lagrangian,Float64,order),rrules) -lazy_map(test_reference_fe,cell_reffe_lag) -cell_reffe_ned = lazy_map(rr->ReferenceFE(get_polytope(rr),rr,nedelec,Float64,order),rrules) -lazy_map(test_reference_fe,cell_reffe_ned) - -# Lagrangian tests -reffe = ReferenceFE(lagrangian,Float64,order) -V_c = TestFESpace(parent,rrules,reffe;conformity=:H1,dirichlet_tags="boundary") -U_c = TrialFESpace(V_c,sol) - -V_f = TestFESpace(model,reffe;conformity=:H1,dirichlet_tags="boundary") -U_f = TrialFESpace(V_f,sol) - -test_fe_space(U_c) -test_fe_space(U_f) - -u_c = interpolate_everywhere(sol,U_c) -u_f = interpolate_everywhere(sol,U_f) - -u_fc = interpolate(u_f,U_c) -u_fc2 = interpolate_everywhere(u_f,U_c) - -eh = u_c - u_f -@test sum(∫(eh⋅eh)*dΩ_f) < 1.e-12 - -eh2 = u_c - u_fc -@test sum(∫(eh2⋅eh2)*dΩ_c) < 1.e-12 - -eh3 = u_c - u_fc2 -@test sum(∫(eh3⋅eh3)*dΩ_c) < 1.e-12 - -# Moment-based (Nedelec) tests -sol((x,y)) = 2*VectorValue(-y,x) - -reffe = ReferenceFE(nedelec,Float64,order) -V_c = TestFESpace(parent,rrules,reffe;dirichlet_tags="boundary") -U_c = TrialFESpace(V_c,sol) - -V_f = TestFESpace(model,reffe;dirichlet_tags="boundary") -U_f = TrialFESpace(V_f,sol) - -test_fe_space(U_c) -test_fe_space(U_f) - -u_c = interpolate_everywhere(sol,U_c) -u_f = interpolate_everywhere(sol,U_f) - -u_fc = interpolate(u_f,U_c) -u_fc2 = interpolate_everywhere(u_f,U_c) - -eh = u_c - u_f -@test sum(∫(eh⋅eh)*dΩ_f) < 1.e-12 - -eh2 = u_c - u_fc -@test sum(∫(eh2⋅eh2)*dΩ_c) < 1.e-12 - -eh3 = u_c - u_fc2 -@test sum(∫(eh3⋅eh3)*dΩ_c) < 1.e-12 - -modelH = CartesianDiscreteModel((0,1,0,1),(1,1)) -modelh = refine(modelH,2) -reffe = LagrangianRefFE(Float64,QUAD,1) -XH = TestFESpace(modelH,reffe) -xH = get_fe_basis(XH) -xHh = change_domain(xH,get_triangulation(modelh),ReferenceDomain()) -evaluate(Gridap.CellData.get_data(xHh)[1],[Point(0.0,0.0),Point(0.5,0.5)]) -evaluate(Gridap.CellData.get_data(xHh)[1],Point(0.5,0.5)) - -end \ No newline at end of file diff --git a/test/AdaptivityTests/runtests.jl b/test/AdaptivityTests/runtests.jl index 2d2a569da..ac63b6f3f 100644 --- a/test/AdaptivityTests/runtests.jl +++ b/test/AdaptivityTests/runtests.jl @@ -9,7 +9,6 @@ using Test include("CartesianRefinementTests.jl") include("ComplexChangeDomainTests.jl") include("EdgeBasedRefinementTests.jl") - include("FineToCoarseFieldsTests.jl") include("RefinementRuleBoundaryTests.jl") include("MultifieldRefinementTests.jl") end