Skip to content

Commit 1866a38

Browse files
committed
Refactored for single-valued objective function
1 parent 6165385 commit 1866a38

File tree

2 files changed

+69
-70
lines changed

2 files changed

+69
-70
lines changed

src/AgFEM/CellAggregation.jl

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ function aggregate(
7878

7979
facet_to_inoutcut = compute_bgfacet_to_inoutcut(cut.bgmodel,geo)
8080
lid_to_gid = 1:num_cells(get_background_model(cut))
81-
cell_to_cellin,_,_,all_aggregated =
81+
cell_to_cellin,_,all_aggregated =
8282
_aggregate_by_threshold(strategy.threshold,cut,geo,in_or_out,facet_to_inoutcut,lid_to_gid)
8383
@assert all_aggregated "Not all cells were aggregated"
8484
cell_to_cellin
@@ -92,14 +92,14 @@ function aggregate(
9292
in_or_out)
9393

9494
facet_to_inoutcut = compute_bgfacet_to_inoutcut(cut.bgmodel,geo)
95-
cell_to_cellin, cell_to_path_length, cell_to_bbox_diam, _ =
95+
cell_to_cellin, cell_to_value, _ =
9696
_aggregate_by_threshold(strategy.threshold,cut,geo,in_or_out,facet_to_inoutcut,lid_to_gid)
9797
for i in eachindex(cell_to_cellin)
9898
if !iszero(cell_to_cellin[i])
9999
cell_to_cellin[i] = lid_to_gid[cell_to_cellin[i]]
100100
end
101101
end
102-
cell_to_cellin, cell_to_path_length, cell_to_bbox_diam
102+
cell_to_cellin, cell_to_value
103103
end
104104

105105
function aggregate(
@@ -111,7 +111,7 @@ function aggregate(
111111

112112
facet_to_inoutcut = compute_bgfacet_to_inoutcut(cut_facets,geo)
113113
lid_to_gid = 1:num_cells(get_background_model(cut))
114-
cell_to_cellin,_,_,all_aggregated =
114+
cell_to_cellin,_,all_aggregated =
115115
_aggregate_by_threshold(strategy.threshold,cut,geo,in_or_out,facet_to_inoutcut,lid_to_gid)
116116
@assert all_aggregated "Not all cells were aggregated"
117117
cell_to_cellin
@@ -125,7 +125,7 @@ function aggregate(
125125
facet_to_inoutcut::AbstractVector)
126126

127127
lid_to_gid = 1:num_cells(get_background_model(cut))
128-
cell_to_cellin,_,_,all_aggregated =
128+
cell_to_cellin,_,all_aggregated =
129129
_aggregate_by_threshold(strategy.threshold,cut,geo,in_or_out,facet_to_inoutcut,lid_to_gid)
130130
@assert all_aggregated "Not all cells were aggregated"
131131
cell_to_cellin
@@ -161,8 +161,7 @@ function _aggregate_by_threshold_barrier(
161161

162162
n_cells = length(cell_to_unit_cut_meas)
163163
cell_to_cellin = zeros(Int32,n_cells)
164-
cell_to_path_length = zeros(Int8,n_cells)
165-
cell_to_bbox_diam = zeros(Float64,n_cells)
164+
cell_to_value = zeros(Int128,n_cells)
166165
cell_to_touched = fill(false,n_cells)
167166

168167
for cell in 1:n_cells
@@ -184,7 +183,7 @@ function _aggregate_by_threshold_barrier(
184183
all_aggregated = true
185184
for cell in 1:n_cells
186185
if ! cell_to_touched[cell] && cell_to_inoutcut[cell] == CUT
187-
neigh_cell, bbox_diam = _find_best_neighbor(
186+
neigh_cell, value = _find_best_neighbor(
188187
c1,c2,c3,c4,cell,
189188
cell_to_faces,
190189
face_to_cells,
@@ -193,12 +192,12 @@ function _aggregate_by_threshold_barrier(
193192
cell_to_cellin,
194193
lid_to_gid,
195194
facet_to_inoutcut,
195+
iter,
196196
loc)
197197
if neigh_cell > 0
198198
cellin = cell_to_cellin[neigh_cell]
199199
cell_to_cellin[cell] = cellin
200-
cell_to_path_length[cell] = iter
201-
cell_to_bbox_diam[cell] = bbox_diam
200+
cell_to_value[cell] = value
202201
else
203202
all_aggregated = false
204203
end
@@ -210,7 +209,7 @@ function _aggregate_by_threshold_barrier(
210209
_touch_aggregated_cells!(cell_to_touched,cell_to_cellin)
211210
end
212211

213-
cell_to_cellin, cell_to_path_length, cell_to_bbox_diam, all_aggregated
212+
cell_to_cellin, cell_to_value, all_aggregated
214213
end
215214

216215
function _find_best_neighbor(
@@ -222,13 +221,13 @@ function _find_best_neighbor(
222221
cell_to_cellin,
223222
lid_to_gid,
224223
facet_to_inoutcut,
224+
iter,
225225
loc)
226226

227227
faces = getindex!(c1,cell_to_faces,cell)
228-
min_bb_diam = Inf
229228
T = eltype(eltype(face_to_cells))
230229
best_neigh_cell = zero(T)
231-
min_cellin = zero(T)
230+
min_value = typemax(Int128)
232231
i_to_coords = getindex!(c3,cell_to_coords,cell)
233232
for face in faces
234233
inoutcut = facet_to_inoutcut[face]
@@ -247,19 +246,19 @@ function _find_best_neighbor(
247246
bb_diam = max(bb_diam,Float64(norm(p-q)))
248247
end
249248
end
250-
if ( min_bb_diam == Inf ) |
251-
( ( bb_diam<min_bb_diam ) &
252-
!isapprox(bb_diam,min_bb_diam,atol=1.0e-9) ) |
253-
( isapprox(bb_diam,min_bb_diam,atol=1.0e-9) &
254-
(lid_to_gid[cellin] < min_cellin ) )
255-
min_bb_diam = bb_diam
249+
# Evaluate objective function and update best values
250+
bit_iter = bitstring(Int8(iter))
251+
bit_bb_diam = bitstring(Float32(round(bb_diam,sigdigits=6)))
252+
bit_cellin = bitstring(lid_to_gid[cellin]) # Assuming ≤ 64-bit
253+
value = parse(Int128,bit_iter*bit_bb_diam*bit_cellin;base=2)
254+
if value < min_value
256255
best_neigh_cell = neigh_cell
257-
min_cellin = lid_to_gid[cellin]
256+
min_value = value
258257
end
259258
end
260259
end
261260
end
262-
best_neigh_cell, min_bb_diam
261+
best_neigh_cell, min_value
263262
end
264263

265264
function _touch_aggregated_cells!(cell_to_touched,cell_to_cellin)
@@ -370,7 +369,7 @@ function aggregate(bgtrian,cell_to_is_active,cell_to_is_cut,in_or_out)
370369

371370
threshold = 1.0
372371
lid_to_gid = 1:num_cells(model)
373-
cell_to_cellin,_,_,all_aggregated = _aggregate_by_threshold_barrier(
372+
cell_to_cellin,_,all_aggregated = _aggregate_by_threshold_barrier(
374373
threshold,cell_to_unit_cut_meas,facet_to_inoutcut,cell_to_inoutcut,
375374
in_or_out,cell_to_coords,cell_to_faces,face_to_cells,lid_to_gid)
376375
@assert all_aggregated "Not all cells were aggregated"
@@ -401,7 +400,7 @@ function aggregate_narrow_band(bgtrian,cell_to_is_in_narrow,cell_to_is_active,ce
401400

402401
threshold = 1.0
403402
lid_to_gid = 1:num_cells(model)
404-
cell_to_cellin,_,_,all_aggregated = _aggregate_by_threshold_barrier(
403+
cell_to_cellin,_,all_aggregated = _aggregate_by_threshold_barrier(
405404
threshold,cell_to_unit_cut_meas,facet_to_inoutcut,cell_to_inoutcut,
406405
in_or_out,cell_to_coords,cell_to_faces,face_to_cells,lid_to_gid)
407406
@assert all_aggregated "Not all cells were aggregated"

test/dev/distributed_aggregation.jl

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,29 @@ using PartitionedArrays
66

77
using GridapEmbedded: aggregate
88

9-
function generate_dumbell(ranks, np, nc, ng)
9+
function generate_asymmetric_kettlebell(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 generate_symmetric_kettlebell(ranks, np, nc, ng)
1032
L = 1
1133
p0 = Point(0.0,0.0)
1234
pmin = Point(-L/4,-L/8)
@@ -43,59 +65,42 @@ function exchange_impl!(vector_partition,cache)
4365
return t
4466
end
4567

46-
function find_optimal_roots!(lcell_to_root,lcell_to_path_length,lcell_to_bbox_diam,cell_indices)
68+
function find_optimal_roots!(lcell_to_root,lcell_to_value,cell_indices)
4769
# Bring all root candidates to the owner of the cut cell
4870
roots_cache = PartitionedArrays.p_vector_cache(lcell_to_root,cell_indices)
4971
t1 = exchange_impl!(lcell_to_root,roots_cache)
50-
lengths_cache = PartitionedArrays.p_vector_cache(lcell_to_path_length,cell_indices)
51-
t2 = exchange_impl!(lcell_to_path_length,lengths_cache)
52-
bb_diams_cache = PartitionedArrays.p_vector_cache(lcell_to_bbox_diam,cell_indices)
53-
t3 = exchange_impl!(lcell_to_bbox_diam,bb_diams_cache)
72+
values_cache = PartitionedArrays.p_vector_cache(lcell_to_value,cell_indices)
73+
t2 = exchange_impl!(lcell_to_value,values_cache)
5474
lcell_to_owner = map(copylocal_to_owner,cell_indices)
5575
owners_cache = PartitionedArrays.p_vector_cache(lcell_to_owner,cell_indices)
5676
wait(t1)
5777
wait(t2)
58-
wait(t3)
5978

6079
# Select the optimal root for each local cut cell
6180
map(
62-
lcell_to_root,lcell_to_path_length,lcell_to_bbox_diam,
63-
lcell_to_owner,roots_cache,lengths_cache,bb_diams_cache
64-
) do lcell_to_root,lcell_to_path_length,lcell_to_bbox_diam,
65-
lcell_to_owner,roots_cache,lengths_cache,bb_diams_cache
66-
81+
lcell_to_root,lcell_to_value,lcell_to_owner,roots_cache,values_cache
82+
) do lcell_to_root, lcell_to_value, lcell_to_owner, roots_cache, values_cache
6783
lids_rcv = roots_cache.local_indices_rcv
68-
lengths_rcv = lengths_cache.buffer_rcv
69-
bb_diams_rcv = bb_diams_cache.buffer_rcv
84+
values_rcv = values_cache.buffer_rcv
7085
roots_rcv = roots_cache.buffer_rcv
71-
72-
for (k,nbor) in enumerate(roots_cache.neighbors_rcv)
73-
for (lcell,root,len,bb_diam) in zip(lids_rcv[k],roots_rcv[k],lengths_rcv[k],bb_diams_rcv[k])
86+
for (k, nbor) in enumerate(roots_cache.neighbors_rcv)
87+
for (lcell,root,value) in zip(lids_rcv[k], roots_rcv[k], values_rcv[k])
7488
root == 0 && continue
75-
if lcell_to_path_length[lcell] > len
89+
if lcell_to_value[lcell] > value # Take the minimum
7690
lcell_to_root[lcell] = root
91+
lcell_to_value[lcell] = value
7792
lcell_to_owner[lcell] = nbor
78-
elseif lcell_to_path_length[lcell] == len
79-
if ( lcell_to_bbox_diam[lcell] > bb_diam ) &
80-
!isapprox(lcell_to_bbox_diam[lcell],bb_diam,atol=1.0e-9)
81-
lcell_to_root[lcell] = root
82-
lcell_to_owner[lcell] = nbor
83-
elseif isapprox(lcell_to_bbox_diam[lcell],bb_diam,atol=1.0e-9) &
84-
( lcell_to_root[lcell] > root )
85-
lcell_to_root[lcell] = root
86-
lcell_to_owner[lcell] = nbor
87-
end
8893
end
8994
end
9095
end
91-
9296
end
9397

9498
# Scatter the optimal roots and values
9599
# Technically, we do not need to scatter the values, it can be removed after
96100
# we are done debugging
97101
t1 = consistent!(PVector(lcell_to_owner,cell_indices,owners_cache))
98102
t2 = consistent!(PVector(lcell_to_root,cell_indices,roots_cache))
103+
t3 = consistent!(PVector(lcell_to_value,cell_indices,values_cache))
99104

100105
wait(t1)
101106

@@ -104,29 +109,30 @@ function find_optimal_roots!(lcell_to_root,lcell_to_path_length,lcell_to_bbox_di
104109
end
105110

106111
wait(t2)
112+
wait(t3)
107113

108-
return lcell_to_root, lcell_to_owner, agg_cell_indices
114+
return lcell_to_root, lcell_to_owner, lcell_to_value, agg_cell_indices
109115
end
110116

111117
distribute = PartitionedArrays.DebugArray
112118
np = (3,1)
113119
ranks = distribute(LinearIndices((prod(np),)))
114-
bgmodel, geo = generate_dumbell(ranks, np, 9, 2)
120+
bgmodel, geo = generate_symmetric_kettlebell(ranks, np, 9, 2)
115121
cutgeo = cut(bgmodel, geo)
116122

117123
cell_indices = partition(get_cell_gids(bgmodel))
118124

119125
strategy = AggregateCutCellsByThreshold(1.0)
120-
lcell_to_root, lcell_to_path_length, lcell_to_bbox_diam =
126+
lcell_to_root, lcell_to_value =
121127
map(local_views(cutgeo),cell_indices) do cutgeo,cell_indices
122128
lid_to_gid = local_to_global(cell_indices)
123129
aggregate(strategy,cutgeo,geo,lid_to_gid,IN)
124130
end |> tuple_of_arrays
125131

126132
lcell_to_inconsistent_root = map(copy,lcell_to_root)
127133

128-
lcell_to_root, lcell_to_owner, agg_cell_indices =
129-
find_optimal_roots!(lcell_to_root,lcell_to_path_length,lcell_to_bbox_diam,cell_indices);
134+
lcell_to_root, lcell_to_owner, lcell_to_value, agg_cell_indices =
135+
find_optimal_roots!(lcell_to_root,lcell_to_value,cell_indices);
130136

131137
# Creating aggregate-conforming cell partition
132138

@@ -137,28 +143,22 @@ end
137143

138144
writevtk(EmbeddedBoundary(cutgeo),"data/bnd");
139145
writevtk(
140-
Triangulation(bgmodel), "data/dumbell_aggregates",
146+
Triangulation(bgmodel), "data/kettlebell_aggregates",
141147
celldata = ["aggregate" => ocell_to_root],
142148
);
143149

144150
map(ranks,
145151
local_views(bgmodel),
146152
lcell_to_root,
147153
lcell_to_inconsistent_root,
148-
lcell_to_owner,
149-
lcell_to_path_length,
150-
lcell_to_bbox_diam) do r,bgmodel,
151-
lcell_to_root,
152-
lcell_to_iroot,
153-
lcell_to_owner,
154-
lcell_to_path_length,
155-
lcell_to_bbox_diam
154+
lcell_to_owner) do r,bgmodel,
155+
lcell_to_root,
156+
lcell_to_iroot,
157+
lcell_to_owner
156158
writevtk(
157-
Triangulation(bgmodel), "data/dumbell_aggregates_$(r)",
159+
Triangulation(bgmodel), "data/kettlebell_aggregates_$(r)",
158160
celldata = [ "roots" => lcell_to_root,
159161
"inconsistent roots" => lcell_to_iroot,
160-
"owners" => lcell_to_owner,
161-
"length" => lcell_to_path_length,
162-
"diameter" => lcell_to_bbox_diam ],
162+
"owners" => lcell_to_owner ],
163163
);
164164
end

0 commit comments

Comments
 (0)