From 6aa64d8eb77d300438677108ac8e6902be2e0f34 Mon Sep 17 00:00:00 2001 From: Santiago Badia Date: Thu, 6 Oct 2022 12:19:33 +1100 Subject: [PATCH 1/2] added constant space and test --- src/FESpaces/ConstantFESpaces.jl | 96 ++++++++++++++++++++++ test/FESpacesTests/ConstantFESpaceTests.jl | 34 ++++++++ 2 files changed, 130 insertions(+) create mode 100644 src/FESpaces/ConstantFESpaces.jl create mode 100644 test/FESpacesTests/ConstantFESpaceTests.jl diff --git a/src/FESpaces/ConstantFESpaces.jl b/src/FESpaces/ConstantFESpaces.jl new file mode 100644 index 000000000..85bf640ce --- /dev/null +++ b/src/FESpaces/ConstantFESpaces.jl @@ -0,0 +1,96 @@ + +""" + struct ConstantFESpace <: SingleFieldFESpace + # private fields + end +""" +struct ConstantFESpace{V,T,A,B,C} <: SingleFieldFESpace + model::DiscreteModel + cell_basis::A + cell_dof_basis::B + cell_dof_ids::C + function ConstantFESpace(model; + vector_type::Type{V}=Vector{Float64}, + field_type::Type{T}=Float64) where {V,T} + function setup_cell_reffe(model::DiscreteModel, + reffe::Tuple{<:Gridap.FESpaces.ReferenceFEName,Any,Any}; kwargs...) + basis, reffe_args,reffe_kwargs = reffe + cell_reffe = ReferenceFE(model,basis,reffe_args...;reffe_kwargs...) + end + reffe=ReferenceFE(lagrangian,T,0) + cell_reffe = setup_cell_reffe(model,reffe) + cell_basis_array=lazy_map(get_shapefuns,cell_reffe) + + cell_basis=Gridap.FESpaces.SingleFieldFEBasis( + cell_basis_array, + Triangulation(model), + Gridap.FESpaces.TestBasis(), + ReferenceDomain()) + + cell_dof_basis_array=lazy_map(get_dof_basis,cell_reffe) + cell_dof_basis=Gridap.CellData.CellDof(cell_dof_basis_array,Triangulation(model),ReferenceDomain()) + + cell_dof_ids=Fill(Int32[1],num_cells(model)) + A=typeof(cell_basis) + B=typeof(cell_dof_basis) + C=typeof(cell_dof_ids) + new{V,T,A,B,C}(model, + cell_basis, + cell_dof_basis, + cell_dof_ids) + end +end + +# Genuine functions +function Gridap.FESpaces.TrialFESpace(f::ConstantFESpace) + f +end + +# Delegated functions +Gridap.FESpaces.get_triangulation(f::ConstantFESpace) = Triangulation(f.model) + +Gridap.FESpaces.ConstraintStyle(::Type{<:ConstantFESpace}) = UnConstrained() + +Gridap.FESpaces.get_dirichlet_dof_values(f::ConstantFESpace{V}) where V = eltype(V)[] + +Gridap.FESpaces.get_fe_basis(f::ConstantFESpace) = f.cell_basis + +Gridap.FESpaces.get_fe_dof_basis(f::ConstantFESpace) = f.cell_dof_basis + +Gridap.FESpaces.get_free_dof_ids(f::ConstantFESpace) = Base.OneTo(length(f.cell_dof_ids[1])) + +Gridap.FESpaces.get_vector_type(f::ConstantFESpace{V}) where V = V + +Gridap.FESpaces.get_cell_dof_ids(f::ConstantFESpace) = f.cell_dof_ids + +Gridap.FESpaces.get_dirichlet_dof_ids(f::ConstantFESpace) = Base.OneTo(0) + +Gridap.FESpaces.num_dirichlet_tags(f::ConstantFESpace) = 0 + +Gridap.FESpaces.get_dirichlet_dof_tag(f::ConstantFESpace) = Int8[] + +function Gridap.FESpaces.scatter_free_and_dirichlet_values(f::ConstantFESpace,fv,dv) + cell_dof_ids = get_cell_dof_ids(f) + lazy_map(Broadcasting(Gridap.Arrays.PosNegReindex(fv,dv)),cell_dof_ids) +end + +function Gridap.FESpaces.gather_free_and_dirichlet_values(free_vals, + dirichlet_vals, + f::ConstantFESpace, + cell_vals) + cell_dofs = get_cell_dof_ids(f) + cache_vals = array_cache(cv) + cache_dofs = array_cache(cell_dofs) + cells = 1:length(cell_vals) + + Gridap.FESpaces._free_and_dirichlet_values_fill!( + free_vals, + dirichlet_vals, + cache_vals, + cache_dofs, + cv, + cell_dofs, + cells) + + (free_vals,dirichlet_vals) +end diff --git a/test/FESpacesTests/ConstantFESpaceTests.jl b/test/FESpacesTests/ConstantFESpaceTests.jl new file mode 100644 index 000000000..9239e821b --- /dev/null +++ b/test/FESpacesTests/ConstantFESpaceTests.jl @@ -0,0 +1,34 @@ + +module ConstantFESpacesTests + +using Gridap +using GridapBiotElasticity +using Test + +domain = (0,1,0,1) +partition = (4,4) +model = CartesianDiscreteModel(domain,partition) +Λ=ConstantFESpace(model) +Gridap.FESpaces.test_fe_space(Λ) +M=TrialFESpace(Λ) + +order = 2 +u((x,y)) = (x+y)^order +f(x) = -Δ(u,x) +reffe = ReferenceFE(lagrangian,Float64,order) +V = TestFESpace(model,reffe,dirichlet_tags="boundary") +U = TrialFESpace(u,V) +Y = MultiFieldFESpace([V,Λ]) +X = MultiFieldFESpace([U,M]) + +Ω = Triangulation(model) +dΩ = Measure(Ω,2*order) +a((u,μ),(v,λ)) = ∫(∇(v)⋅∇(u))dΩ + ∫(v*μ)dΩ + ∫(λ*u)dΩ +l((v,λ)) = ∫(λ*u)dΩ + ∫(v*f)dΩ +op = AffineFEOperator(a,l,X,Y) +uh = solve(op) + +@assert sum(∫((uh[1]-u)*(uh[1]-u))dΩ) < 1.0e-14 +abs(sum(∫(uh[2])dΩ)) < 1.0e-12 + +end # module From 13c4880e948361709ad257c2d563a2dae2a0d067 Mon Sep 17 00:00:00 2001 From: "Alberto F. Martin" <38347633+amartinhuertas@users.noreply.github.com> Date: Thu, 6 Oct 2022 12:28:47 +1100 Subject: [PATCH 2/2] Update NEWS.md --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 9a95463e7..e97c1dab8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `lastindex` for `MultiValue`s for consistent usage of `[end]` as per `length`. Since PR [#834](https://github.com/gridap/Gridap.jl/pull/834) - BDM (Brezzi-Douglas-Marini) ReferenceFEs in PR [#823](https://github.com/gridap/Gridap.jl/pull/823) +- Implemented `ConstantFESpace`. This space allows, e.g., to impose the mean value of the pressure via an additional unknown/equation (a Lagrange multiplier). Since PR [#836](https://github.com/gridap/Gridap.jl/pull/836) ## [0.17.14] - 2022-07-29