Skip to content

Commit 7fbdfb3

Browse files
committed
Started developping distributed aggregation
1 parent 04eda20 commit 7fbdfb3

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ Manifest.toml
99
LocalPreferences.toml
1010
.vscode/
1111
*.swp
12+
data
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
2+
using Gridap
3+
using GridapEmbedded
4+
using GridapDistributed
5+
using PartitionedArrays
6+
7+
using GridapEmbedded: aggregate
8+
9+
function generate_dumbell(ranks, np, nc, ng)
10+
L = 1
11+
p0 = Point(0.0,0.0)
12+
pmin = Point(-L/4,-L/8)
13+
pmax = Point(L/4,3*L/8)
14+
15+
R = 0.2
16+
x = VectorValue(1.0,0.0)
17+
h = L/(2*nc)
18+
19+
geo1 = disk(R,x0=p0)
20+
geo2 = quadrilateral(;x0=Point(-L/4+h/4,5*h/4),
21+
d1=VectorValue(6*h+h/2,0.0),
22+
d2=VectorValue(0.0,4*h+h/2))
23+
geo3 = quadrilateral(;x0=Point(-L/4+3*h/4,7*h/4),
24+
d1=VectorValue(6*h-h/2,0.0),
25+
d2=VectorValue(0.0,4*h-h/2))
26+
geo = union(geo1,intersect(geo2,!geo3))
27+
bgmodel = CartesianDiscreteModel(ranks,np,pmin,pmax,(nc,nc);ghost=(ng,ng))
28+
return bgmodel, geo
29+
end
30+
31+
function exchange_impl!(vector_partition,cache)
32+
buffer_snd = map(vector_partition,cache) do values, cache
33+
local_indices_snd = cache.local_indices_snd
34+
for (p,lid) in enumerate(local_indices_snd.data)
35+
cache.buffer_snd.data[p] = values[lid]
36+
end
37+
cache.buffer_snd
38+
end
39+
neighbors_snd, neighbors_rcv, buffer_rcv = map(cache) do cache
40+
cache.neighbors_snd, cache.neighbors_rcv, cache.buffer_rcv
41+
end |> tuple_of_arrays
42+
graph = ExchangeGraph(neighbors_snd,neighbors_rcv)
43+
t = exchange!(buffer_rcv,buffer_snd,graph)
44+
return t
45+
end
46+
47+
function find_optimal_root!(lcell_to_root,lcell_to_value,cell_indices)
48+
# Bring all root candidates to the owner of the cut cell
49+
roots_cache = PartitionedArrays.p_vector_cache(lcell_to_lroot,cell_indices)
50+
t1 = exchange_impl!(lcell_to_lroot,cache)
51+
values_cache = PartitionedArrays.p_vector_cache(lcell_to_value,cell_indices)
52+
t2 = exchange_impl!(lcell_to_value,values_cache)
53+
wait(t1)
54+
wait(t2)
55+
56+
# Select the optimal root for each local cut cell
57+
map(lcell_to_root,lcell_to_value,roots_cache,values_cache) do lcell_to_root, lcell_to_value, roots_cache, values_cache
58+
local_indices_rcv = roots_cache.local_indices_rcv.data
59+
values_rcv = values_cache.buffer_rcv.data
60+
roots_rcv = roots_cache.buffer_rcv.data
61+
for (p, lcell) in enumerate(local_indices_rcv)
62+
value, root = values_rcv[p], roots_rcv[p]
63+
if lcell_to_value[lcell] > value # Take the minimum
64+
lcell_to_root[lcell] = root
65+
lcell_to_value[lcell] = value
66+
end
67+
end
68+
end
69+
70+
# Scatter the optimal roots and values
71+
# Technically, we do not need to scatter the values, it can be removed after
72+
# we are done debugging
73+
t1 = consistent!(PVector(lcell_to_root,cell_indices,roots_cache))
74+
t2 = consistent!(PVector(lcell_to_value,cell_indices,values_cache))
75+
wait(t1)
76+
wait(t2)
77+
78+
return lcell_to_root, lcell_to_value
79+
end
80+
81+
82+
distribute = PartitionedArrays.DebugArray
83+
np = (2,1)
84+
ranks = distribute(LinearIndices((prod(np),)))
85+
bgmodel, geo = generate_dumbell(ranks, np, 8, 3)
86+
cutgeo = cut(bgmodel, geo)
87+
88+
cell_indices = partition(get_cell_gids(bgmodel))
89+
90+
strategy = AggregateCutCellsByThreshold(1.0)
91+
lcell_to_lroot = map(local_views(cutgeo)) do cutgeo
92+
aggregate(strategy,cutgeo,geo,IN)
93+
end
94+
95+
# This would ideally come from the serial algorithm, but we simulate it here
96+
lcell_to_value = map(local_views(bgmodel),lcell_to_lroot) do bgmodel, lcell_to_lroot
97+
lcell_centroid = lazy_map(mean, get_cell_coordinates(bgmodel))
98+
lcell_to_value = fill(Inf, num_cells(bgmodel))
99+
for (lcell, lroot) in enumerate(lcell_to_lroot)
100+
if !iszero(lroot)
101+
value = norm(lcell_centroid[lcell] - lcell_centroid[lroot])
102+
lcell_to_value[lcell] = value
103+
end
104+
end
105+
return lcell_to_value
106+
end
107+
108+
# This can also be done in place, but we duplicate infor for now
109+
lcell_to_root = map(lcell_to_lroot,cell_indices) do lcell_to_lroot, cell_indices
110+
lcell_to_root = fill(0, length(cell_indices))
111+
lid_to_gid = local_to_global(cell_indices)
112+
for i in eachindex(lcell_to_root)
113+
if !iszero(lcell_to_lroot[i])
114+
lcell_to_root[i] = lid_to_gid[lcell_to_lroot[i]]
115+
end
116+
end
117+
return lcell_to_root
118+
end
119+
120+
lcell_to_root, lcell_to_value = find_optimal_root!(lcell_to_root,lcell_to_value,cell_indices);
121+
122+
display(lcell_to_root)
123+
124+
writevtk(EmbeddedBoundary(cutgeo),"data/bnd");
125+
writevtk(
126+
Triangulation(bgmodel), "data/dumbell_aggregates",
127+
celldata = ["aggregate" => lcell_to_root, "local_aggregates" => lcell_to_lroot],
128+
);
129+

0 commit comments

Comments
 (0)