@@ -83,6 +83,24 @@ function dof_wise_to_cell_wise!(cell_wise_vector,dof_wise_vector,cell_to_ldofs,c
8383 return cell_wise_vector
8484end
8585
86+ function posneg_wise_to_cell_wise! (cell_wise_vector,pos_wise_vector,neg_wise_vector,cell_to_posneg,cell_ids)
87+ map (cell_wise_vector,pos_wise_vector,neg_wise_vector,cell_to_posneg,cell_ids) do cwv,pwv,nwv,cell_to_posneg,cell_ids
88+ cache = array_cache (cell_to_posneg)
89+ for cell in cell_ids
90+ lids = getindex! (cache,cell_to_posneg,cell)
91+ p = cwv. ptrs[cell]- 1
92+ for (i,lid) in enumerate (lids)
93+ if lid > 0
94+ cwv. data[i+ p] = pwv[lid]
95+ elseif lid < 0
96+ cwv. data[i+ p] = nwv[- lid]
97+ end
98+ end
99+ end
100+ end
101+ return cell_wise_vector
102+ end
103+
86104function cell_wise_to_dof_wise! (dof_wise_vector,cell_wise_vector,cell_to_ldofs,cell_ids)
87105 map (dof_wise_vector,cell_wise_vector,cell_to_ldofs,cell_ids) do dwv,cwv,cell_to_ldofs,cell_ids
88106 cache = array_cache (cell_to_ldofs)
@@ -99,6 +117,24 @@ function cell_wise_to_dof_wise!(dof_wise_vector,cell_wise_vector,cell_to_ldofs,c
99117 return dof_wise_vector
100118end
101119
120+ function cell_wise_to_posneg_wise! (pos_wise_vector,neg_wise_vector,cell_wise_vector,cell_to_posneg,cell_ids)
121+ map (pos_wise_vector,neg_wise_vector,cell_wise_vector,cell_to_posneg,cell_ids) do pwv,nwv,cwv,cell_to_posneg,cell_ids
122+ cache = array_cache (cell_to_posneg)
123+ for cell in cell_ids
124+ lids = getindex! (cache,cell_to_posneg,cell)
125+ p = cwv. ptrs[cell]- 1
126+ for (i,lid) in enumerate (lids)
127+ if lid > 0
128+ pwv[lid] = cwv. data[i+ p]
129+ elseif lid < 0
130+ nwv[- lid] = cwv. data[i+ p]
131+ end
132+ end
133+ end
134+ end
135+ return pos_wise_vector, neg_wise_vector
136+ end
137+
102138function allocate_cell_wise_vector (T, cell_to_lids)
103139 map (cell_to_lids) do cell_to_lids
104140 ptrs = Arrays. generate_ptrs (cell_to_lids)
@@ -212,6 +248,118 @@ function generate_gids(
212248 return PRange (local_indices)
213249end
214250
251+ function generate_posneg_gids (
252+ cell_range:: PRange ,
253+ cell_to_lposneg:: AbstractArray{<:AbstractArray} ,
254+ nlpos:: AbstractArray{<:Integer} ,
255+ nlneg:: AbstractArray{<:Integer}
256+ )
257+ ranks = linear_indices (partition (cell_range))
258+ cell_lids_to_data = allocate_cell_wise_vector (Int, cell_to_lposneg)
259+ cache_fetch = fetch_vector_ghost_values_cache (cell_lids_to_data,partition (cell_range))
260+
261+ # Find and count number owned dofs
262+ lpos_to_owner, lneg_to_owner, nopos, noneg = map (
263+ partition (cell_range),cell_to_lposneg,nlpos,nlneg
264+ ) do indices,cell_to_lposneg,nlpos,nlneg
265+ lpos_to_owner = fill (zero (Int32),nlpos)
266+ lneg_to_owner = fill (zero (Int32),nlneg)
267+ cache = array_cache (cell_to_lposneg)
268+ for (cell, owner) in enumerate (local_to_owner (indices))
269+ lids = getindex! (cache,cell_to_lposneg,cell)
270+ for lid in lids
271+ if lid > 0
272+ lpos_to_owner[lid] = max (owner,lpos_to_owner[lid])
273+ elseif lid < 0
274+ lneg_to_owner[- lid] = max (owner,lneg_to_owner[- lid])
275+ end
276+ end
277+ end
278+ rank = part_id (indices)
279+ nopos = count (isequal (rank),lpos_to_owner)
280+ noneg = count (isequal (rank),lneg_to_owner)
281+ return lpos_to_owner, lneg_to_owner, nopos, noneg
282+ end |> tuple_of_arrays
283+
284+ # Find the global range of owned dofs
285+ first_gpos = scan (+ ,nopos,type= :exclusive ,init= 1 )
286+ first_gneg = scan (+ ,noneg,type= :exclusive ,init= 1 )
287+
288+ # Exchange the dof owners. Cell owner always has correct dof owner.
289+ cell_ldofs_to_owner = posneg_wise_to_cell_wise! (
290+ cell_lids_to_data,lpos_to_owner,lneg_to_owner,cell_to_lposneg,own_to_local (cell_range)
291+ )
292+ fetch_vector_ghost_values! (cell_ldofs_to_owner,cache_fetch) |> wait
293+ cell_wise_to_posneg_wise! (
294+ lpos_to_owner,lneg_to_owner,cell_ldofs_to_owner,cell_to_lposneg,ghost_to_local (cell_range)
295+ )
296+
297+ # Fill owned gids
298+ lpos_to_gpos = map (ranks,first_gpos,lpos_to_owner) do rank,first_gpos,lpos_to_owner
299+ offset = first_gpos- 1
300+ lpos_to_gpos = zeros (Int,length (lpos_to_owner))
301+ opos = 0
302+ for (lpos,owner) in enumerate (lpos_to_owner)
303+ if owner == rank
304+ opos += 1
305+ lpos_to_gpos[lpos] = opos + offset
306+ end
307+ end
308+ lpos_to_gpos
309+ end
310+
311+ lneg_to_gneg = map (ranks,first_gneg,lneg_to_owner) do rank,first_gneg,lneg_to_owner
312+ offset = first_gneg- 1
313+ lneg_to_gneg = zeros (Int,length (lneg_to_owner))
314+ oneg = 0
315+ for (lneg,owner) in enumerate (lneg_to_owner)
316+ if owner == rank
317+ oneg += 1
318+ lneg_to_gneg[lneg] = oneg + offset
319+ end
320+ end
321+ lneg_to_gneg
322+ end
323+
324+ # Exchange gids
325+ cell_to_gposneg = posneg_wise_to_cell_wise! (
326+ cell_lids_to_data,lpos_to_gpos,lneg_to_gneg,cell_to_lposneg,own_to_local (cell_range)
327+ )
328+ fetch_vector_ghost_values! (cell_to_gposneg,cache_fetch) |> wait
329+
330+ # Fill ghost gids with exchanged information
331+ map (
332+ cell_to_lposneg,cell_to_gposneg,lpos_to_gpos,lneg_to_gneg,lpos_to_owner,lneg_to_owner,partition (cell_range)
333+ ) do cell_to_lposneg,cell_to_gposneg,lpos_to_gpos,lneg_to_gneg,lpos_to_owner,lneg_to_owner,indices
334+ cache = array_cache (cell_to_lposneg)
335+ lcell_to_owner = local_to_owner (indices)
336+ for cell in ghost_to_local (indices)
337+ p = cell_to_gposneg. ptrs[cell]- 1
338+ lids = getindex! (cache,cell_to_lposneg,cell)
339+ cell_owner = lcell_to_owner[cell]
340+ for (i,lid) in enumerate (lids)
341+ if (lid > 0 ) && isequal (lpos_to_owner[lid],cell_owner)
342+ lpos_to_gpos[lid] = cell_to_gposneg. data[i+ p]
343+ elseif (lid < 0 ) && isequal (lneg_to_owner[- lid],cell_owner)
344+ lneg_to_gneg[- lid] = cell_to_gposneg. data[i+ p]
345+ end
346+ end
347+ end
348+ end
349+
350+ posneg_wise_to_cell_wise! (cell_to_gposneg,lpos_to_gpos,lneg_to_gneg,cell_to_lposneg,own_to_local (cell_range))
351+ fetch_vector_ghost_values! (cell_to_gposneg,cache_fetch) |> wait
352+ cell_wise_to_posneg_wise! (lpos_to_gpos,lneg_to_gneg,cell_to_gposneg,cell_to_lposneg,ghost_to_local (cell_range))
353+
354+ # Setup DoFs LocalIndices
355+ ngpos = reduction (+ ,nopos,destination= :all ,init= 0 )
356+ ngneg = reduction (+ ,noneg,destination= :all ,init= 0 )
357+ local_indices_pos = map (LocalIndices,ngpos,ranks,lpos_to_gpos,lpos_to_owner)
358+ local_indices_neg = map (LocalIndices,ngneg,ranks,lneg_to_gneg,lneg_to_owner)
359+
360+ return PRange (local_indices_pos), PRange (local_indices_neg)
361+ end
362+
215363# FEFunction related
216364
217365"""
0 commit comments