diff --git a/NEWS.md b/NEWS.md index 86a11ff..c79e552 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - New overloads for the `TrialFESpace` constructor where the data to be imposed is passed as a `DistributedCellField`. Since PR[#183](https://github.com/gridap/GridapDistributed.jl/pull/183). +- Added missing `FESpace` constructors for distributed triangulations specialized for the RT FEs case. Since PR[#188](https://github.com/gridap/GridapDistributed.jl/pull/188) ## [0.4.10] - 2025-09-29 diff --git a/src/DivConformingFESpaces.jl b/src/DivConformingFESpaces.jl index c814e75..b29a074 100644 --- a/src/DivConformingFESpaces.jl +++ b/src/DivConformingFESpaces.jl @@ -1,25 +1,78 @@ - function FESpaces.FESpace(model::DistributedDiscreteModel, reffe::Tuple{RaviartThomas,Any,Any}; - conformity=nothing,kwargs...) + conformity=nothing, + split_own_and_ghost=false, + constraint=nothing, + kwargs...) cell_reffes = map(local_views(model)) do m basis,reffe_args,reffe_kwargs = reffe cell_reffe = ReferenceFE(m,basis,reffe_args...;reffe_kwargs...) end - _common_fe_space_constructor(model,cell_reffes;conformity,kwargs...) + _common_fe_space_constructor(model,cell_reffes;conformity,split_own_and_ghost,kwargs...) end function FESpace(model::DistributedDiscreteModel, reffe::GenericRefFE{RaviartThomas}; - conformity=nothing, kwargs...) + conformity=nothing, + split_own_and_ghost=false, + constraint=nothing, + kwargs...) cell_reffes = map(local_views(model)) do m Fill(reffe,num_cells(m)) end - _common_fe_space_constructor(model,cell_reffes;conformity,kwargs...) + _common_fe_space_constructor(model,cell_reffes;conformity,split_own_and_ghost,kwargs...) +end + +function _setup_dmodel_and_dtrian(_trian::DistributedTriangulation) + trian = add_ghost_cells(_trian) + models = map(local_views(trian)) do t + get_active_model(t) + end + GenericDistributedDiscreteModel(models, generate_cell_gids(trian)), trian +end + +function FESpace( + _trian::DistributedTriangulation, + reffe::Tuple{RaviartThomas,Any,Any}; + conformity=nothing, + split_own_and_ghost=false, + constraint=nothing,kwargs... +) + dmodel, dtrian = _setup_dmodel_and_dtrian(_trian) + cell_reffes = map(local_views(dmodel)) do m + basis,reffe_args,reffe_kwargs = reffe + cell_reffe = ReferenceFE(m,basis,reffe_args...;reffe_kwargs...) + end + _common_fe_space_constructor(dmodel,cell_reffes,dtrian;conformity,split_own_and_ghost,kwargs...) +end + +function FESpace(_trian::DistributedTriangulation, + reffe::GenericRefFE{RaviartThomas}; + conformity=nothing, + split_own_and_ghost=false, + constraint=nothing, + kwargs...) + dmodel, dtrian = _setup_dmodel_and_dtrian(_trian) + cell_reffes = map(local_views(dmodel)) do m + Fill(reffe,num_cells(m)) + end + _common_fe_space_constructor(dmodel,cell_reffes,dtrian;conformity,split_own_and_ghost,kwargs...) +end + +function _common_fe_space_constructor(model,cell_reffes,trian;conformity,split_own_and_ghost,kwargs...) + sign_flips=_generate_sign_flips(model,cell_reffes) + spaces = map(local_views(model),sign_flips,cell_reffes,local_views(trian)) do m,sign_flip,cell_reffe,trian + conf = Conformity(testitem(cell_reffe),conformity) + cell_fe = CellFE(m,cell_reffe,conf,sign_flip) + FESpace(m, cell_fe; trian=trian, kwargs...) + end + gids = generate_gids(model,spaces) + vector_type = _find_vector_type(spaces,gids;split_own_and_ghost=split_own_and_ghost) + DistributedSingleFieldFESpace(spaces,gids,trian,vector_type) end -function _common_fe_space_constructor(model,cell_reffes;conformity,kwargs...) +function _common_fe_space_constructor(model,cell_reffes;conformity,split_own_and_ghost,kwargs...) sign_flips=_generate_sign_flips(model,cell_reffes) spaces = map(local_views(model),sign_flips,cell_reffes) do m,sign_flip,cell_reffe conf = Conformity(testitem(cell_reffe),conformity) @@ -28,7 +81,7 @@ function _common_fe_space_constructor(model,cell_reffes;conformity,kwargs...) end gids = generate_gids(model,spaces) trian = DistributedTriangulation(map(get_triangulation,spaces),model) - vector_type = _find_vector_type(spaces,gids) + vector_type = _find_vector_type(spaces,gids;split_own_and_ghost=split_own_and_ghost) DistributedSingleFieldFESpace(spaces,gids,trian,vector_type) end diff --git a/test/DivConformingTests.jl b/test/DivConformingTests.jl index 2a1886b..33fc3a3 100644 --- a/test/DivConformingTests.jl +++ b/test/DivConformingTests.jl @@ -59,12 +59,10 @@ function setup_p2_model() Gridap.Geometry.UnstructuredDiscreteModel(grid) end -function f(model,reffe) +function f(model,reffe,trian,das) V = FESpace(model,reffe,conformity=:Hdiv) U = TrialFESpace(V) - das = FullyAssembledRows() - trian = Triangulation(das,model) degree = 2 dΩ = Measure(trian,degree) a(u,v) = ∫( u⋅v )*dΩ @@ -82,6 +80,7 @@ function f(model,reffe) dc2 = dc.contribs.items[2] c1 = Gridap.CellData.get_contribution(dc1,t1) c2 = Gridap.CellData.get_contribution(dc2,t2) + tol = 1.0e-12 @test norm(c1[1]-c2[2]) < tol @test norm(c1[2]-c2[1]) < tol @@ -122,10 +121,18 @@ function main(distribute,nranks) model = GridapDistributed.DistributedDiscreteModel(models,gids) + das = FullyAssembledRows() + trian = Triangulation(das,model) + reffe=ReferenceFE(raviart_thomas,Float64,0) - f(model,reffe) + f(model,reffe,trian,das) + f(trian,reffe,trian,das) + f(Triangulation(model),reffe,trian,das) + reffe=ReferenceFE(QUAD, raviart_thomas, 0) - f(model,reffe) + f(model,reffe,trian,das) + f(trian,reffe,trian,das) + f(Triangulation(model),reffe,trian,das) end end # module