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

Bugfix: Nonconforming block assembly #147

Merged
merged 2 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.1] 2024-06-25

### Fixed

- Fixed bug in block-assembly whenever owners of touched dofs were not present in the local portion of the FESpace. Since PR[#147](https://github.com/gridap/GridapDistributed.jl/pull/147).

## [0.4.0] 2024-04-12

### Changed
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "GridapDistributed"
uuid = "f9701e48-63b3-45aa-9a63-9bc6c271f355"
authors = ["S. Badia <[email protected]>", "A. F. Martin <[email protected]>", "F. Verdugo <[email protected]>"]
version = "0.4.0"
version = "0.4.1"

[deps]
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
Expand Down
30 changes: 17 additions & 13 deletions src/Algebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1129,25 +1129,29 @@ function _setup_prange(dofs_gids_prange::PRange,gids;ghost=true,owners=nothing,k
end
end

function _setup_prange(dofs_gids_prange::AbstractVector{<:PRange},
gids::AbstractMatrix;
ax=:rows,ghost=true,owners=nothing)
function _setup_prange(
dofs_gids_prange::AbstractVector{<:PRange},
gids::AbstractMatrix;
ax=:rows,ghost=true,owners=nothing
)
@check ax ∈ (:rows,:cols)
block_ids = LinearIndices(dofs_gids_prange)
pvcat(x) = map(xi -> vcat(xi...), to_parray_of_arrays(x))

gids_ax_slice, _owners = map(block_ids,dofs_gids_prange) do id,prange
gids_ax_slice = (ax == :rows) ? gids[id,:] : gids[:,id]
_owners = nothing
if ghost
gids_ax_slice = map(x -> union(x...), to_parray_of_arrays(gids_ax_slice))
if !isa(owners,Nothing) # Recompute owners for the union
_owners = get_gid_owners(gids_ax_slice,prange)
end
gids_union, owners_union = map(block_ids,dofs_gids_prange) do id, prange
gids_slice = (ax == :rows) ? gids[id,:] : gids[:,id]
gids_union = pvcat(gids_slice)

owners_union = nothing
if !isnothing(owners)
owners_slice = (ax == :rows) ? owners[id,:] : owners[:,id]
owners_union = pvcat(owners_slice)
end
return gids_ax_slice, _owners

return gids_union, owners_union
end |> tuple_of_arrays

return map((p,g,o) -> _setup_prange(p,g;ghost=ghost,owners=o),dofs_gids_prange,gids_ax_slice,_owners)
return map((p,g,o) -> _setup_prange(p,g;ghost=ghost,owners=o),dofs_gids_prange,gids_union,owners_union)
end

# Create PRange for the rows of the linear system
Expand Down
42 changes: 38 additions & 4 deletions test/BlockSparseMatrixAssemblersTests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ using GridapDistributed
using PartitionedArrays
using GridapDistributed: BlockPVector, BlockPMatrix

get_edge_measures(Ω::Triangulation,dΩ) = sqrt∘CellField(get_array(∫(1)dΩ),Ω)
function get_edge_measures(Ω::GridapDistributed.DistributedTriangulation,dΩ)
return sqrt∘CellField(map(get_array,local_views(∫(1)*dΩ)),Ω)
end

function is_same_vector(x::BlockPVector,y::PVector,Ub,U)
y_fespace = GridapDistributed.change_ghost(y,U.gids)
x_fespace = GridapDistributed.change_ghost(x,Ub.gids)
Expand All @@ -33,7 +38,7 @@ function is_same_matrix(Ab::BlockPMatrix,A::PSparseMatrix,Xb,X)
return is_same_vector(yb,y,Xb,X)
end

function _main(n_spaces,mfs,weakform,Ω,dΩ,U,V)
function _main(n_spaces,mfs,weakform,U,V)
biform, liform = weakform

# Normal assembly
Expand Down Expand Up @@ -94,13 +99,14 @@ function main(distribute,parts)
ranks = distribute(LinearIndices((prod(parts),)))

model = CartesianDiscreteModel(ranks,parts,(0,1,0,1),(8,8))
Ω = Triangulation(model)

# Conforming tests
sol(x) = sum(x)
reffe = LagrangianRefFE(Float64,QUAD,1)
V = FESpace(Ω, reffe; dirichlet_tags="boundary")
V = FESpace(model, reffe; dirichlet_tags="boundary")
U = TrialFESpace(sol,V)

Ω = Triangulation(model)
dΩ = Measure(Ω, 2)
biform2((u1,u2),(v1,v2)) = ∫(∇(u1)⋅∇(v1) + u2⋅v2 + u1⋅v2)*dΩ
liform2((v1,v2)) = ∫(v1 + v2)*dΩ
Expand All @@ -109,9 +115,37 @@ function main(distribute,parts)

for (n_spaces,weakform) in zip([2,3],[(biform2,liform2),(biform3,liform3)])
for mfs in [BlockMultiFieldStyle(),BlockMultiFieldStyle(2,(1,n_spaces-1))]
_main(n_spaces,mfs,weakform,Ω,dΩ,U,V)
_main(n_spaces,mfs,weakform,U,V)
end
end

# Non-conforming tests (tests whether we can fetch neighbors from non-ghosts)
reffe = ReferenceFE(raviart_thomas,Float64,0)
D = FESpace(model,reffe; dirichlet_tags="boundary")

β_U = 100.0
Γ = Boundary(model)
Λ = Skeleton(model)
n_Γ = get_normal_vector(Γ)
n_Λ = get_normal_vector(Λ)
dΓ = Measure(Γ,2)
dΛ = Measure(Λ,2)
h_e_Λ = get_edge_measures(Λ,dΛ)
h_e_Γ = get_edge_measures(Γ,dΓ)
lap_dg(u,v) = ∫(∇(u)⊙∇(v))dΩ -
∫(jump(v⊗n_Λ)⊙(mean(∇(u))))dΛ -
∫(mean(∇(v))⊙jump(u⊗n_Λ))dΛ -
∫(v⋅(∇(u)⋅n_Γ))dΓ -
∫((∇(v)⋅n_Γ)⋅u)dΓ +
∫(jump(v⊗n_Λ)⊙((β_U/h_e_Λ*jump(u⊗n_Λ))))dΛ +
∫(v⋅(β_U/h_e_Γ*u))dΓ

f = VectorValue(1.0,1.0)
biform4((u1,u2),(v1,v2)) = lap_dg(u1,v1) + lap_dg(u1,v1) + ∫(u2⋅v2)*dΩ
liform4((v1,v2)) = ∫(v1⋅f)*dΩ
_main(2,BlockMultiFieldStyle(),(biform4,liform4),D,D)
end

main(DebugArray, (2,2))

end
Loading