Skip to content

Commit c7d4762

Browse files
* Treatment of hanging DoFs on ghost cells seems to be working
* Fixed an issue in redistribute_fe_function(). In general, for FESpaceWithLinearConstraints we cannot directly use the output provided by get_cell_dof_ids()
1 parent 659bac2 commit c7d4762

File tree

4 files changed

+539
-230
lines changed

4 files changed

+539
-230
lines changed

src/FESpaces.jl

Lines changed: 112 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,28 @@ function _generate_hanging_faces_owner_face_dofs(num_hanging_faces,
4949
ptrs[1] = 1
5050
for fid_hanging = 1:num_hanging_faces
5151
glue = hanging_faces_glue[fid_hanging]
52-
ocell_lface = glue[2]
53-
ptrs[fid_hanging+1] = ptrs[fid_hanging] + length(face_dofs[ocell_lface])
52+
if (glue[1]!=-1)
53+
ocell_lface = glue[2]
54+
ptrs[fid_hanging+1] = ptrs[fid_hanging] + length(face_dofs[ocell_lface])
55+
else
56+
ptrs[fid_hanging+1] = ptrs[fid_hanging] + 1
57+
end
5458
end
5559
data_owner_face_dofs = Vector{Int}(undef, ptrs[num_hanging_faces+1] - 1)
5660
for fid_hanging = 1:num_hanging_faces
5761
glue = hanging_faces_glue[fid_hanging]
5862
ocell = glue[1]
59-
ocell_lface = glue[2]
60-
s = ptrs[fid_hanging]
61-
e = ptrs[fid_hanging+1] - 1
62-
current_cell_dof_ids = getindex!(cache, cell_dof_ids, ocell)
63-
for (j, ldof) in enumerate(face_dofs[ocell_lface])
63+
if (ocell!=-1)
64+
ocell_lface = glue[2]
65+
s = ptrs[fid_hanging]
66+
e = ptrs[fid_hanging+1] - 1
67+
current_cell_dof_ids = getindex!(cache, cell_dof_ids, ocell)
68+
for (j, ldof) in enumerate(face_dofs[ocell_lface])
6469
data_owner_face_dofs[s+j-1] = current_cell_dof_ids[ldof]
70+
end
71+
else
72+
s = ptrs[fid_hanging]
73+
data_owner_face_dofs[s] = 1
6574
end
6675
end
6776
Gridap.Arrays.Table(data_owner_face_dofs, ptrs)
@@ -141,61 +150,72 @@ function _generate_constraints!(Df,
141150
current_cell_dof_ids = getindex!(cache_dof_ids, cell_dof_ids, cell)
142151
lface = hanging_faces_to_lface[fid_hanging]
143152
ocell, ocell_lface, subface = hanging_faces_glue[fid_hanging]
144-
ocell_lface_within_dim = face_lid_within_dim(Val{Dc}, ocell_lface)
145-
oface_dim = face_dim(Val{Dc}, ocell_lface)
146-
147-
if (Df == 0) # Am I a vertex?
148-
hanging_lvertex_within_first_subface = 2^oface_dim
149-
cur_subface_own_dofs = subface_own_dofs[oface_dim][hanging_lvertex_within_first_subface]
150-
elseif (Df == 1 && Dc == 3) # Am I an edge?
151-
if (subface < 0) # Edge hanging in the interior of a face
152-
@assert subface == -1 || subface == -2 || subface == -3 || subface == -4
153-
@assert oface_dim == Dc - 1
154-
abs_subface = abs(subface)
155-
if (abs_subface == 1)
156-
subface = 1
157-
edge = 4 + 4 # num_vertices+edge_id
158-
elseif (abs_subface == 2)
159-
subface = 3
160-
edge = 4 + 4 # num_vertices+edge_id
161-
elseif (abs_subface == 3)
162-
subface = 3
163-
edge = 4 + 1 # num_vertices+edge_id
164-
elseif (abs_subface == 4)
165-
subface = 4
166-
edge = 4 + 1 # num_vertices+edge_id
167-
end
168-
cur_subface_own_dofs = subface_own_dofs[oface_dim][edge]
169-
else
170-
@assert subface == 1 || subface == 2
171-
@assert oface_dim == 1
153+
if (ocell!=-1)
154+
ocell_lface_within_dim = face_lid_within_dim(Val{Dc}, ocell_lface)
155+
oface_dim = face_dim(Val{Dc}, ocell_lface)
156+
157+
if (Df == 0) # Am I a vertex?
172158
hanging_lvertex_within_first_subface = 2^oface_dim
159+
cur_subface_own_dofs = subface_own_dofs[oface_dim][hanging_lvertex_within_first_subface]
160+
elseif (Df == 1 && Dc == 3) # Am I an edge?
161+
if (subface < 0) # Edge hanging in the interior of a face
162+
@assert subface == -1 || subface == -2 || subface == -3 || subface == -4
163+
@assert oface_dim == Dc - 1
164+
abs_subface = abs(subface)
165+
if (abs_subface == 1)
166+
subface = 1
167+
edge = 4 + 4 # num_vertices+edge_id
168+
elseif (abs_subface == 2)
169+
subface = 3
170+
edge = 4 + 4 # num_vertices+edge_id
171+
elseif (abs_subface == 3)
172+
subface = 3
173+
edge = 4 + 1 # num_vertices+edge_id
174+
elseif (abs_subface == 4)
175+
subface = 4
176+
edge = 4 + 1 # num_vertices+edge_id
177+
end
178+
cur_subface_own_dofs = subface_own_dofs[oface_dim][edge]
179+
else
180+
@assert subface == 1 || subface == 2
181+
@assert oface_dim == 1
182+
hanging_lvertex_within_first_subface = 2^oface_dim
183+
cur_subface_own_dofs = subface_own_dofs[oface_dim][end]
184+
end
185+
elseif (Df == Dc - 1) # Am I a face?
186+
@assert oface_dim == Dc - 1
173187
cur_subface_own_dofs = subface_own_dofs[oface_dim][end]
174188
end
175-
elseif (Df == Dc - 1) # Am I a face?
176-
@assert oface_dim == Dc - 1
177-
cur_subface_own_dofs = subface_own_dofs[oface_dim][end]
178-
end
179189

180190

181-
oface = getindex!(cache_cell_faces[oface_dim+1], cell_faces[oface_dim+1], ocell)[ocell_lface_within_dim]
182-
oface_lid, _ = owner_faces_lids[oface_dim][oface]
183-
pindex = owner_faces_pindex[oface_dim][oface_lid]
184-
for ((ldof, dof), ldof_subface) in zip(enumerate(face_own_dofs[offset+lface]), cur_subface_own_dofs)
185-
push!(sDOF_to_dof, current_cell_dof_ids[dof])
186-
push!(sDOF_to_dofs, hanging_faces_owner_face_dofs[fid_hanging])
187-
coeffs = Vector{Float64}(undef, length(hanging_faces_owner_face_dofs[fid_hanging]))
188-
# Go over dofs of ocell_lface
189-
for (ifdof, icdof) in enumerate(face_dofs[ocell_lface])
190-
pifdof = node_permutations[oface_dim][pindex][ifdof]
191-
println("XXXX: $(ifdof) $(pifdof)")
192-
ldof_coarse = face_dofs[ocell_lface][pifdof]
193-
coeffs[ifdof] =
194-
ref_constraints[face_subface_ldof_to_cell_ldof[oface_dim][ocell_lface_within_dim][subface][ldof_subface], ldof_coarse]
191+
oface = getindex!(cache_cell_faces[oface_dim+1], cell_faces[oface_dim+1], ocell)[ocell_lface_within_dim]
192+
oface_lid, _ = owner_faces_lids[oface_dim][oface]
193+
pindex = owner_faces_pindex[oface_dim][oface_lid]
194+
for ((ldof, dof), ldof_subface) in zip(enumerate(face_own_dofs[offset+lface]), cur_subface_own_dofs)
195+
push!(sDOF_to_dof, current_cell_dof_ids[dof])
196+
push!(sDOF_to_dofs, hanging_faces_owner_face_dofs[fid_hanging])
197+
coeffs = Vector{Float64}(undef, length(hanging_faces_owner_face_dofs[fid_hanging]))
198+
# Go over dofs of ocell_lface
199+
for (ifdof, icdof) in enumerate(face_dofs[ocell_lface])
200+
pifdof = node_permutations[oface_dim][pindex][ifdof]
201+
println("XXXX: $(ifdof) $(pifdof)")
202+
ldof_coarse = face_dofs[ocell_lface][pifdof]
203+
coeffs[ifdof] =
204+
ref_constraints[face_subface_ldof_to_cell_ldof[oface_dim][ocell_lface_within_dim][subface][ldof_subface], ldof_coarse]
205+
end
206+
push!(sDOF_to_coeffs, coeffs)
195207
end
196-
push!(sDOF_to_coeffs, coeffs)
197-
end
208+
else
209+
for (ldof, dof) in enumerate(face_own_dofs[offset+lface])
210+
push!(sDOF_to_dof, current_cell_dof_ids[dof])
211+
push!(sDOF_to_dofs, hanging_faces_owner_face_dofs[fid_hanging])
212+
push!(sDOF_to_coeffs, [1.0])
213+
end
214+
end
198215
end
216+
println("sDOF_to_dof [$(Df)]= $(sDOF_to_dof)")
217+
println("sDOF_to_dofs [$(Df)]= $(sDOF_to_dofs)")
218+
println("sDOF_to_coeffs [$(Df)]= $(sDOF_to_coeffs)")
199219
end
200220

201221
# count how many different owner faces
@@ -217,13 +237,15 @@ function _compute_owner_faces_pindex_and_lids(Df,
217237
owner_faces_lids = Dict{Int,Tuple{Int,Int,Int}}()
218238
for fid_hanging = 1:num_hanging_faces
219239
ocell, ocell_lface, _ = hanging_faces_glue[fid_hanging]
220-
ocell_dim = face_dim(Val{Dc}, ocell_lface)
221-
if (ocell_dim == Df)
222-
ocell_lface_within_dim = face_lid_within_dim(Val{Dc}, ocell_lface)
223-
owner_face = cell_faces[ocell][ocell_lface_within_dim]
224-
if !(haskey(owner_faces_lids, owner_face))
225-
num_owner_faces += 1
226-
owner_faces_lids[owner_face] = (num_owner_faces, ocell, ocell_lface)
240+
if (ocell!=-1)
241+
ocell_dim = face_dim(Val{Dc}, ocell_lface)
242+
if (ocell_dim == Df)
243+
ocell_lface_within_dim = face_lid_within_dim(Val{Dc}, ocell_lface)
244+
owner_face = cell_faces[ocell][ocell_lface_within_dim]
245+
if !(haskey(owner_faces_lids, owner_face))
246+
num_owner_faces += 1
247+
owner_faces_lids[owner_face] = (num_owner_faces, ocell, ocell_lface)
248+
end
227249
end
228250
end
229251
end
@@ -236,16 +258,18 @@ function _compute_owner_faces_pindex_and_lids(Df,
236258

237259
for fid_hanging = 1:num_hanging_faces
238260
ocell, ocell_lface, subface = hanging_faces_glue[fid_hanging]
239-
ocell_dim = face_dim(Val{Dc}, ocell_lface)
240-
if (ocell_dim == Df)
241-
cell = hanging_faces_to_cell[fid_hanging]
242-
lface = hanging_faces_to_lface[fid_hanging]
243-
cvertex = lface_to_cvertices[lface][subface]
244-
vertex = cell_vertices[cell][cvertex]
245-
ocell_lface_within_dim = face_lid_within_dim(Val{Dc}, ocell_lface)
246-
owner_face = cell_faces[ocell][ocell_lface_within_dim]
247-
owner_face_lid, _ = owner_faces_lids[owner_face]
248-
owner_face_vertex_ids[(owner_face_lid-1)*num_face_vertices+subface] = vertex
261+
if (ocell!=-1)
262+
ocell_dim = face_dim(Val{Dc}, ocell_lface)
263+
if (ocell_dim == Df)
264+
cell = hanging_faces_to_cell[fid_hanging]
265+
lface = hanging_faces_to_lface[fid_hanging]
266+
cvertex = lface_to_cvertices[lface][subface]
267+
vertex = cell_vertices[cell][cvertex]
268+
ocell_lface_within_dim = face_lid_within_dim(Val{Dc}, ocell_lface)
269+
owner_face = cell_faces[ocell][ocell_lface_within_dim]
270+
owner_face_lid, _ = owner_faces_lids[owner_face]
271+
owner_face_vertex_ids[(owner_face_lid-1)*num_face_vertices+subface] = vertex
272+
end
249273
end
250274
end
251275

@@ -314,11 +338,11 @@ function generate_constraints(dmodel::OctreeDistributedDiscreteModel{Dc},
314338
hanging_faces_glue,
315339
dmodel.models,
316340
spaces_wo_constraints) do gridap_cell_faces,
317-
num_regular_faces,
318-
num_hanging_faces,
319-
hanging_faces_glue,
320-
model,
321-
V
341+
num_regular_faces,
342+
num_hanging_faces,
343+
hanging_faces_glue,
344+
model,
345+
V
322346

323347
hanging_faces_to_cell = Vector{Vector{Int}}(undef, Dc)
324348
hanging_faces_to_lface = Vector{Vector{Int}}(undef, Dc)
@@ -502,7 +526,7 @@ end
502526
# An auxiliary function which we use in order to generate a version of
503527
# get_cell_dof_ids() for FE spaces with linear constraints which is suitable
504528
# for the algorithm which generates the global DoFs identifiers
505-
function fe_space_with_linear_constraints_cell_dof_ids(Uc::FESpaceWithLinearConstraints)
529+
function fe_space_with_linear_constraints_cell_dof_ids(Uc::FESpaceWithLinearConstraints,sDOF_to_dof)
506530
U_cell_dof_ids = Gridap.Arrays.Table(get_cell_dof_ids(Uc.space))
507531
ndata = U_cell_dof_ids.ptrs[end] - 1
508532
Uc_cell_dof_ids_data = zeros(eltype(U_cell_dof_ids.data), ndata)
@@ -515,20 +539,21 @@ function fe_space_with_linear_constraints_cell_dof_ids(Uc::FESpaceWithLinearCons
515539
n_cells = length(U_cell_dof_ids)
516540
n_fdofs = num_free_dofs(Uc.space)
517541
n_fmdofs = Uc.n_fmdofs
542+
dof_to_sDOF = Dict(val=>key for (key,val) in enumerate(sDOF_to_dof))
518543
for cell in 1:n_cells
519544
pini = U_cell_dof_ids.ptrs[cell]
520545
pend = U_cell_dof_ids.ptrs[cell+1] - 1
521546
for p in pini:pend
522547
dof = U_cell_dof_ids.data[p]
523548
DOF = Gridap.FESpaces._dof_to_DOF(dof, n_fdofs)
524549
qini = Uc.DOF_to_mDOFs.ptrs[DOF]
525-
qend = Uc.DOF_to_mDOFs.ptrs[DOF+1] - 1
526-
if (qend - qini == 0) # master DOF
550+
qend = Uc.DOF_to_mDOFs.ptrs[DOF+1]-1
551+
if (!haskey(dof_to_sDOF,dof)) # master DoF
552+
@assert qend-qini==0
527553
mDOF = Uc.DOF_to_mDOFs.data[qini]
528554
mdof = Gridap.FESpaces._DOF_to_dof(mDOF, n_fmdofs)
529555
Uc_cell_dof_ids_data[p] = mdof
530556
else # slave DoF
531-
@assert qend - qini > 0
532557
Uc_cell_dof_ids_data[p] = max_negative_minus_one
533558
end
534559
end
@@ -563,14 +588,18 @@ function Gridap.FESpaces.FESpace(model::OctreeDistributedDiscreteModel{Dc}, reff
563588
Vc = FESpaceWithLinearConstraints(sDOF_to_dof, sDOF_to_dofs, sDOF_to_coeffs, V)
564589
end
565590

566-
local_cell_dof_ids = map(spaces_w_constraints) do Vc
567-
result = fe_space_with_linear_constraints_cell_dof_ids(Vc)
591+
local_cell_dof_ids = map(spaces_w_constraints,sDOF_to_dof) do Vc,sDOF_to_dof
592+
result = fe_space_with_linear_constraints_cell_dof_ids(Vc,sDOF_to_dof)
568593
println("result=", result)
569594
result
570595
end
571596
nldofs = map(num_free_dofs,spaces_w_constraints)
572597
cell_gids = get_cell_gids(model)
573598
gids=GridapDistributed.generate_gids(cell_gids,local_cell_dof_ids,nldofs)
599+
map(partition(gids)) do indices
600+
println("[$(part_id(indices))]: l2g=$(local_to_global(indices))")
601+
println("[$(part_id(indices))]: l2o=$(local_to_owner(indices))")
602+
end
574603
vector_type = GridapDistributed._find_vector_type(spaces_w_constraints,gids)
575604
GridapDistributed.DistributedSingleFieldFESpace(spaces_w_constraints,gids,vector_type)
576605
end

0 commit comments

Comments
 (0)