From a76a9c25d69cd2b87969572fa5e4de8f3632c241 Mon Sep 17 00:00:00 2001 From: RiMillo Date: Tue, 19 Dec 2023 11:31:40 +0000 Subject: [PATCH] deploy: 02453efc42b227e5f6b92c771a75145d4dde21dc --- _coarse___cell___container_8h_source.html | 856 +++++++++++----------- class_coarse___cell___container.html | 1 + 2 files changed, 429 insertions(+), 428 deletions(-) diff --git a/_coarse___cell___container_8h_source.html b/_coarse___cell___container_8h_source.html index 26fe0fd..d04d851 100644 --- a/_coarse___cell___container_8h_source.html +++ b/_coarse___cell___container_8h_source.html @@ -134,444 +134,444 @@
49
51 using DualGraphPtr = typename CoarseCellType::DualGraphPtr;
52
-
57 Coarse_Cell_Container(
-
58 DualGraphPtr &fc_graph, const CoMMAIntType singular_card_thresh) :
-
59 _ccs(),
-
60 _fc_graph(fc_graph),
-
61 _cc_counter(0),
-
62 _fc_2_cc(fc_graph->_number_of_cells, nullopt),
-
63 _is_fc_agglomerated(fc_graph->_number_of_cells, false),
-
64 _sing_card_thresh(singular_card_thresh),
-
65 _nb_of_agglomerated_fc(0),
-
66 _delayed_cc(),
-
67 _singular_cc() {}
-
68
-
70 ~Coarse_Cell_Container() = default;
-
71
-
73 map<CoMMAIndexType, CoarseCellPtr> _ccs;
-
74
-
76 DualGraphPtr _fc_graph;
-
77
-
79 CoMMAIndexType _cc_counter;
-
80
-
83 vector<optional<CoMMAIndexType>> _fc_2_cc;
-
84
-
87 vector<bool> _is_fc_agglomerated;
-
88
-
90 CoMMAIntType _sing_card_thresh;
-
91
-
96 inline CoMMAIndexType get_number_of_fc_agglomerated() const {
-
97 return (_nb_of_agglomerated_fc);
-
98 }
-
99
-
103 inline CoMMAIndexType get_nb_of_cc() const { return _cc_counter; }
-
104
-
113 inline set<CoMMAIndexType> get_neighs_cc(
-
114 const CoMMAIndexType &i_fc, const CoMMAIndexType &i_cc) const {
-
115 set<CoMMAIndexType> result;
-
116 for (auto elem = _fc_graph->neighbours_cbegin(i_fc);
-
117 elem != _fc_graph->neighbours_cend(i_fc); ++elem) {
-
118 const auto cc = _fc_2_cc[*elem].value();
-
119 if (cc != i_cc) result.insert(cc);
-
120 }
-
121 return result;
-
122 }
-
123
-
124#if 0
-
125Not used anymore but we leave it for example purposes
-
126
-
128 using CustomMapItT = typename map<CoMMAIndexType, SubGraphPtr>::iterator;
-
133 CustomMapItT remove_cc(CustomMapItT elim) {
-
134 // we delete the element and we obtained the pointer to the next element in
-
135 // memory
-
136 CustomMapItT it = _ccs.erase(elim);
-
137 // update value of the other nodes
-
138 for (auto i = it; i != _ccs.end(); i++) {
-
139 for (auto const &i_fc : i->second->_mapping_l_to_g) {
-
140 _fc_2_cc[i_fc] = (i->first) - 1;
-
141 }
-
142 auto node = _ccs.extract(i);
-
143 if (!node.empty()) {
-
144 node.key() = (i->first) - 1;
-
145 _ccs.insert(move(node));
-
146 }
-
147 }
-
148 // return pointer to the next element
-
149 return (it);
-
150 }
-
151#endif
-
152
-
159 void correct(const CoMMAIntType max_card) {
-
160 // We use it to understand if we have succeeded in the correction
-
161 set<typename decltype(_singular_cc)::value_type> removed_cc{};
-
162 for (const auto &old_cc : _singular_cc) {
-
163 // It might happen that we agglomerate to a singular cell so that the new
-
164 // cell was singular when it was created but it is not any more
-
165 auto &cur_cc = _ccs.at(old_cc);
-
166 if (cur_cc->_cardinality <= _sing_card_thresh) {
-
167 const auto &fcs = cur_cc->_s_fc;
-
168 bool should_remove = false;
-
169 unordered_map<CoMMAIndexType, set<CoMMAIndexType>> neighs_by_fc{};
-
170 neighs_by_fc.reserve(cur_cc->_cardinality);
-
171 for (const auto &i_fc : fcs) {
-
172 neighs_by_fc.emplace(i_fc, get_neighs_cc(i_fc, old_cc));
-
173 }
-
174 if (cur_cc->_cardinality > 1) {
-
175 // First try: agglomerate the whole coarse cell to another one
-
176 set<CoMMAIndexType> glob_neighs = {};
-
177 for (const auto &[i_fc, neighs] : neighs_by_fc) {
-
178 glob_neighs.insert(neighs.begin(), neighs.end());
-
179 }
-
180 if (!glob_neighs.empty()) {
-
181 optional<CoMMAIntType> new_compactness = nullopt;
-
182 const auto new_cc = select_best_cc_to_agglomerate_whole(
-
183 fcs, glob_neighs, max_card, new_compactness);
-
184 if (new_cc.has_value()) {
-
185 // first we assign to the fc_2_cc the new cc (later it will be
-
186 // renumbered considering the deleted cc)
-
187 for (const auto &i_fc : fcs) {
-
188 _fc_2_cc[i_fc] = new_cc.value();
-
189 }
-
190 _ccs[new_cc.value()]->insert_cells(fcs, new_compactness);
-
191 should_remove = true;
-
192 }
-
193 }
-
194 }
-
195 if (!should_remove) {
-
196 // If here, we could not agglomerate the whole cell, hence we look
-
197 // fine cell by fine cell
-
198 for (const auto &[i_fc, neighs] : neighs_by_fc) {
-
199 if (!neighs.empty()) {
-
200 optional<CoMMAIntType> new_compactness = nullopt;
-
201 const auto new_cc = select_best_cc_to_agglomerate(
-
202 i_fc, neighs, max_card, new_compactness);
-
203 if (new_cc.has_value()) {
-
204 _fc_2_cc[i_fc] = new_cc.value();
-
205 _ccs[new_cc.value()]->insert_cell(i_fc, new_compactness);
-
206 should_remove = true;
-
207 }
-
208 }
-
209 // If the cell has no neighbour (this could happen when the
-
210 // partitioning does not give a connected partition), unfortunately,
-
211 // there is nothing that we can do. We just skip it
-
212 }
-
213 }
-
214
-
215 if (should_remove) {
-
216 _ccs.erase(old_cc);
-
217 removed_cc.emplace(old_cc);
-
218 }
-
219 } // End if still singular
-
220 } // End loop over singular cells
-
221
-
222 // Now update the ID if necessary
-
223 if (!removed_cc.empty()) {
-
224 auto new_ID = *(removed_cc.begin());
-
225 // Starting from the CC just after the first removed singular cell, update
-
226 // all cells. Looking for new_ID-1 than doing ++ avoid case of consecutive
-
227 // singular cells. If the first removed cell was cell 0, then start from
-
228 // the beginning
-
229 auto it_cc = _ccs.begin();
-
230 if (new_ID > 0) {
-
231 it_cc = _ccs.find(new_ID - 1);
-
232 ++it_cc;
-
233 }
-
234 for (; it_cc != _ccs.end(); ++it_cc, ++new_ID) {
-
235 // Update fine cells
-
236 for (auto const &i_fc : it_cc->second->_s_fc) {
-
237 _fc_2_cc[i_fc] = new_ID;
-
238 }
-
239 // Update coarse cell ID
-
240 auto node = _ccs.extract(it_cc);
-
241 if (!node.empty()) {
-
242 node.key() = new_ID;
-
243 _ccs.insert(move(node));
-
244 }
-
245 }
-
246 }
-
247 }
-
248
-
263 optional<CoMMAIndexType> select_best_cc_to_agglomerate_whole(
-
264 const unordered_set<CoMMAIndexType> &fcs,
-
265 const set<CoMMAIndexType> &neighs,
-
266 const CoMMAIntType max_card,
-
267 optional<CoMMAIntType> &new_compactness) const {
-
268 CoMMAUnused(max_card);
-
269 unordered_map<CoMMAIndexType, CoMMAIntType> card{};
-
270 unordered_map<CoMMAIndexType, CoMMAIntType> compact{};
-
271 const auto n_neighs = neighs.size();
-
272 card.reserve(n_neighs);
-
273 // Since in the end we sort, wouldn't it be better to just use set instead
-
274 // of deque?
-
275 deque<CoMMAIndexType> argtrue_compact{};
-
276 // Loop on neighbours to compute their features
-
277 for (const auto &cc_idx : neighs) {
-
278 const auto n_cc = _ccs.at(cc_idx);
-
279 if (n_cc->_is_isotropic) {
-
280 if (true /* n_cc->_cardinality < max_card */) {
-
281 // On second thought, let us consider also cells with max cardinality
-
282 // since the number of faces could be important to ensure compactness
-
283 // of the coarse cell
-
284 card[cc_idx] = n_cc->_cardinality;
-
285 // Analysing compactness
-
286 auto tmp_cc = n_cc->_s_fc; // OK copy
-
287 tmp_cc.insert(fcs.begin(), fcs.end());
-
288 const auto new_cpt =
-
289 _fc_graph->compute_min_fc_compactness_inside_a_cc(tmp_cc);
-
290 compact[cc_idx] = new_cpt;
-
291 if (new_cpt > n_cc->_compactness) {
-
292 argtrue_compact.push_back(cc_idx);
-
293 }
-
294 } // End compactness and cardinality
-
295 } // End if isotropic
-
296 }
-
297 if (!argtrue_compact.empty()) {
-
298 // Sort so that, in the end, if nothing worked, we rely on ID numbering
-
299 sort(argtrue_compact.begin(), argtrue_compact.end());
-
300 CoMMAIndexType ret_cc{argtrue_compact[0]};
-
301 CoMMAIntType cur_min{card[ret_cc]};
-
302 // If more than one, maximize shared faces and/or minimize cardinality
-
303 for (const auto &idx : argtrue_compact) {
-
304 const auto cur_card = card[idx];
-
305 if (cur_card < cur_min) {
-
306 cur_min = cur_card;
-
307 ret_cc = idx;
-
308 }
-
309 }
-
310 new_compactness = compact.at(ret_cc);
-
311 return ret_cc;
-
312 }
-
313 return nullopt;
-
314 }
-
315
-
329 optional<CoMMAIndexType> select_best_cc_to_agglomerate(
-
330 const CoMMAIndexType fc,
-
331 const set<CoMMAIndexType> &neighs,
-
332 const CoMMAIntType max_card,
-
333 optional<CoMMAIntType> &new_compactness) const {
-
334 CoMMAUnused(max_card);
-
335 unordered_map<CoMMAIndexType, CoMMAIntType> card{};
-
336 unordered_map<CoMMAIndexType, CoMMAIntType> shared_faces{};
-
337 unordered_map<CoMMAIndexType, CoMMAIntType> compact{};
-
338 const auto n_neighs = neighs.size();
-
339 card.reserve(n_neighs);
-
340 shared_faces.reserve(n_neighs);
-
341 CoMMAIntType min_card = numeric_limits<CoMMAIntType>::max();
-
342 CoMMAIntType max_shared_f{0};
-
343 // Since in the end we sort, wouldn't it be better to just use set instead
-
344 // of deque?
-
345 deque<CoMMAIndexType> argmin_card{};
-
346 deque<CoMMAIndexType> argmax_shared_f{};
-
347 deque<CoMMAIndexType> argtrue_compact{};
-
348 deque<CoMMAIndexType> iso_neighs{};
-
349 // Loop on neighbours to compute their features
-
350 for (const auto &cc_idx : neighs) {
-
351 const auto n_cc = _ccs.at(cc_idx);
-
352 if (n_cc->_is_isotropic) {
-
353 iso_neighs.push_back(cc_idx);
-
354 if (true /* n_cc->_cardinality < max_card */) {
-
355 // On second thought, let us consider also cells with max cardinality
-
356 // since the number of faces could be important to ensure compactness
-
357 // of the coarse cell
-
358 const auto cur_card = n_cc->_cardinality;
-
359 card[cc_idx] = cur_card;
-
360 if (cur_card < min_card) {
-
361 min_card = cur_card;
-
362 argmin_card.clear();
-
363 argmin_card.push_back(cc_idx);
-
364 } else if (cur_card == min_card) {
+
59 Coarse_Cell_Container(
+
60 DualGraphPtr &fc_graph, const CoMMAIntType singular_card_thresh) :
+
61 _ccs(),
+
62 _fc_graph(fc_graph),
+
63 _cc_counter(0),
+
64 _fc_2_cc(fc_graph->_number_of_cells, nullopt),
+
65 _is_fc_agglomerated(fc_graph->_number_of_cells, false),
+
66 _sing_card_thresh(singular_card_thresh),
+
67 _nb_of_agglomerated_fc(0),
+
68 _delayed_cc(),
+
69 _singular_cc() {}
+
70
+
72 ~Coarse_Cell_Container() = default;
+
73
+
75 map<CoMMAIndexType, CoarseCellPtr> _ccs;
+
76
+
78 DualGraphPtr _fc_graph;
+
79
+
81 CoMMAIndexType _cc_counter;
+
82
+
85 vector<optional<CoMMAIndexType>> _fc_2_cc;
+
86
+
89 vector<bool> _is_fc_agglomerated;
+
90
+
92 CoMMAIntType _sing_card_thresh;
+
93
+
98 inline CoMMAIndexType get_number_of_fc_agglomerated() const {
+
99 return (_nb_of_agglomerated_fc);
+
100 }
+
101
+
105 inline CoMMAIndexType get_nb_of_cc() const { return _cc_counter; }
+
106
+
115 inline set<CoMMAIndexType> get_neighs_cc(
+
116 const CoMMAIndexType &i_fc, const CoMMAIndexType &i_cc) const {
+
117 set<CoMMAIndexType> result;
+
118 for (auto elem = _fc_graph->neighbours_cbegin(i_fc);
+
119 elem != _fc_graph->neighbours_cend(i_fc); ++elem) {
+
120 const auto cc = _fc_2_cc[*elem].value();
+
121 if (cc != i_cc) result.insert(cc);
+
122 }
+
123 return result;
+
124 }
+
125
+
126#if 0
+
127Not used anymore but we leave it for example purposes
+
128
+
130 using CustomMapItT = typename map<CoMMAIndexType, SubGraphPtr>::iterator;
+
135 CustomMapItT remove_cc(CustomMapItT elim) {
+
136 // we delete the element and we obtained the pointer to the next element in
+
137 // memory
+
138 CustomMapItT it = _ccs.erase(elim);
+
139 // update value of the other nodes
+
140 for (auto i = it; i != _ccs.end(); i++) {
+
141 for (auto const &i_fc : i->second->_mapping_l_to_g) {
+
142 _fc_2_cc[i_fc] = (i->first) - 1;
+
143 }
+
144 auto node = _ccs.extract(i);
+
145 if (!node.empty()) {
+
146 node.key() = (i->first) - 1;
+
147 _ccs.insert(move(node));
+
148 }
+
149 }
+
150 // return pointer to the next element
+
151 return (it);
+
152 }
+
153#endif
+
154
+
161 void correct(const CoMMAIntType max_card) {
+
162 // We use it to understand if we have succeeded in the correction
+
163 set<typename decltype(_singular_cc)::value_type> removed_cc{};
+
164 for (const auto &old_cc : _singular_cc) {
+
165 // It might happen that we agglomerate to a singular cell so that the new
+
166 // cell was singular when it was created but it is not any more
+
167 auto &cur_cc = _ccs.at(old_cc);
+
168 if (cur_cc->_cardinality <= _sing_card_thresh) {
+
169 const auto &fcs = cur_cc->_s_fc;
+
170 bool should_remove = false;
+
171 unordered_map<CoMMAIndexType, set<CoMMAIndexType>> neighs_by_fc{};
+
172 neighs_by_fc.reserve(cur_cc->_cardinality);
+
173 for (const auto &i_fc : fcs) {
+
174 neighs_by_fc.emplace(i_fc, get_neighs_cc(i_fc, old_cc));
+
175 }
+
176 if (cur_cc->_cardinality > 1) {
+
177 // First try: agglomerate the whole coarse cell to another one
+
178 set<CoMMAIndexType> glob_neighs = {};
+
179 for (const auto &[i_fc, neighs] : neighs_by_fc) {
+
180 glob_neighs.insert(neighs.begin(), neighs.end());
+
181 }
+
182 if (!glob_neighs.empty()) {
+
183 optional<CoMMAIntType> new_compactness = nullopt;
+
184 const auto new_cc = select_best_cc_to_agglomerate_whole(
+
185 fcs, glob_neighs, max_card, new_compactness);
+
186 if (new_cc.has_value()) {
+
187 // first we assign to the fc_2_cc the new cc (later it will be
+
188 // renumbered considering the deleted cc)
+
189 for (const auto &i_fc : fcs) {
+
190 _fc_2_cc[i_fc] = new_cc.value();
+
191 }
+
192 _ccs[new_cc.value()]->insert_cells(fcs, new_compactness);
+
193 should_remove = true;
+
194 }
+
195 }
+
196 }
+
197 if (!should_remove) {
+
198 // If here, we could not agglomerate the whole cell, hence we look
+
199 // fine cell by fine cell
+
200 for (const auto &[i_fc, neighs] : neighs_by_fc) {
+
201 if (!neighs.empty()) {
+
202 optional<CoMMAIntType> new_compactness = nullopt;
+
203 const auto new_cc = select_best_cc_to_agglomerate(
+
204 i_fc, neighs, max_card, new_compactness);
+
205 if (new_cc.has_value()) {
+
206 _fc_2_cc[i_fc] = new_cc.value();
+
207 _ccs[new_cc.value()]->insert_cell(i_fc, new_compactness);
+
208 should_remove = true;
+
209 }
+
210 }
+
211 // If the cell has no neighbour (this could happen when the
+
212 // partitioning does not give a connected partition), unfortunately,
+
213 // there is nothing that we can do. We just skip it
+
214 }
+
215 }
+
216
+
217 if (should_remove) {
+
218 _ccs.erase(old_cc);
+
219 removed_cc.emplace(old_cc);
+
220 }
+
221 } // End if still singular
+
222 } // End loop over singular cells
+
223
+
224 // Now update the ID if necessary
+
225 if (!removed_cc.empty()) {
+
226 auto new_ID = *(removed_cc.begin());
+
227 // Starting from the CC just after the first removed singular cell, update
+
228 // all cells. Looking for new_ID-1 than doing ++ avoid case of consecutive
+
229 // singular cells. If the first removed cell was cell 0, then start from
+
230 // the beginning
+
231 auto it_cc = _ccs.begin();
+
232 if (new_ID > 0) {
+
233 it_cc = _ccs.find(new_ID - 1);
+
234 ++it_cc;
+
235 }
+
236 for (; it_cc != _ccs.end(); ++it_cc, ++new_ID) {
+
237 // Update fine cells
+
238 for (auto const &i_fc : it_cc->second->_s_fc) {
+
239 _fc_2_cc[i_fc] = new_ID;
+
240 }
+
241 // Update coarse cell ID
+
242 auto node = _ccs.extract(it_cc);
+
243 if (!node.empty()) {
+
244 node.key() = new_ID;
+
245 _ccs.insert(move(node));
+
246 }
+
247 }
+
248 }
+
249 }
+
250
+
265 optional<CoMMAIndexType> select_best_cc_to_agglomerate_whole(
+
266 const unordered_set<CoMMAIndexType> &fcs,
+
267 const set<CoMMAIndexType> &neighs,
+
268 const CoMMAIntType max_card,
+
269 optional<CoMMAIntType> &new_compactness) const {
+
270 CoMMAUnused(max_card);
+
271 unordered_map<CoMMAIndexType, CoMMAIntType> card{};
+
272 unordered_map<CoMMAIndexType, CoMMAIntType> compact{};
+
273 const auto n_neighs = neighs.size();
+
274 card.reserve(n_neighs);
+
275 // Since in the end we sort, wouldn't it be better to just use set instead
+
276 // of deque?
+
277 deque<CoMMAIndexType> argtrue_compact{};
+
278 // Loop on neighbours to compute their features
+
279 for (const auto &cc_idx : neighs) {
+
280 const auto n_cc = _ccs.at(cc_idx);
+
281 if (n_cc->_is_isotropic) {
+
282 if (true /* n_cc->_cardinality < max_card */) {
+
283 // On second thought, let us consider also cells with max cardinality
+
284 // since the number of faces could be important to ensure compactness
+
285 // of the coarse cell
+
286 card[cc_idx] = n_cc->_cardinality;
+
287 // Analysing compactness
+
288 auto tmp_cc = n_cc->_s_fc; // OK copy
+
289 tmp_cc.insert(fcs.begin(), fcs.end());
+
290 const auto new_cpt =
+
291 _fc_graph->compute_min_fc_compactness_inside_a_cc(tmp_cc);
+
292 compact[cc_idx] = new_cpt;
+
293 if (new_cpt > n_cc->_compactness) {
+
294 argtrue_compact.push_back(cc_idx);
+
295 }
+
296 } // End compactness and cardinality
+
297 } // End if isotropic
+
298 }
+
299 if (!argtrue_compact.empty()) {
+
300 // Sort so that, in the end, if nothing worked, we rely on ID numbering
+
301 sort(argtrue_compact.begin(), argtrue_compact.end());
+
302 CoMMAIndexType ret_cc{argtrue_compact[0]};
+
303 CoMMAIntType cur_min{card[ret_cc]};
+
304 // If more than one, maximize shared faces and/or minimize cardinality
+
305 for (const auto &idx : argtrue_compact) {
+
306 const auto cur_card = card[idx];
+
307 if (cur_card < cur_min) {
+
308 cur_min = cur_card;
+
309 ret_cc = idx;
+
310 }
+
311 }
+
312 new_compactness = compact.at(ret_cc);
+
313 return ret_cc;
+
314 }
+
315 return nullopt;
+
316 }
+
317
+
331 optional<CoMMAIndexType> select_best_cc_to_agglomerate(
+
332 const CoMMAIndexType fc,
+
333 const set<CoMMAIndexType> &neighs,
+
334 const CoMMAIntType max_card,
+
335 optional<CoMMAIntType> &new_compactness) const {
+
336 CoMMAUnused(max_card);
+
337 unordered_map<CoMMAIndexType, CoMMAIntType> card{};
+
338 unordered_map<CoMMAIndexType, CoMMAIntType> shared_faces{};
+
339 unordered_map<CoMMAIndexType, CoMMAIntType> compact{};
+
340 const auto n_neighs = neighs.size();
+
341 card.reserve(n_neighs);
+
342 shared_faces.reserve(n_neighs);
+
343 CoMMAIntType min_card = numeric_limits<CoMMAIntType>::max();
+
344 CoMMAIntType max_shared_f{0};
+
345 // Since in the end we sort, wouldn't it be better to just use set instead
+
346 // of deque?
+
347 deque<CoMMAIndexType> argmin_card{};
+
348 deque<CoMMAIndexType> argmax_shared_f{};
+
349 deque<CoMMAIndexType> argtrue_compact{};
+
350 deque<CoMMAIndexType> iso_neighs{};
+
351 // Loop on neighbours to compute their features
+
352 for (const auto &cc_idx : neighs) {
+
353 const auto n_cc = _ccs.at(cc_idx);
+
354 if (n_cc->_is_isotropic) {
+
355 iso_neighs.push_back(cc_idx);
+
356 if (true /* n_cc->_cardinality < max_card */) {
+
357 // On second thought, let us consider also cells with max cardinality
+
358 // since the number of faces could be important to ensure compactness
+
359 // of the coarse cell
+
360 const auto cur_card = n_cc->_cardinality;
+
361 card[cc_idx] = cur_card;
+
362 if (cur_card < min_card) {
+
363 min_card = cur_card;
+
364 argmin_card.clear();
365 argmin_card.push_back(cc_idx);
-
366 }
-
367 // @TODO: merge computation of shared faces and compactness?
-
368 const auto cur_sf = get_shared_faces(fc, n_cc);
-
369 shared_faces[cc_idx] = cur_sf;
-
370 if (cur_sf > max_shared_f) {
-
371 max_shared_f = cur_sf;
-
372 argmax_shared_f.clear();
-
373 argmax_shared_f.push_back(cc_idx);
-
374 } else if (cur_sf == max_shared_f) {
+
366 } else if (cur_card == min_card) {
+
367 argmin_card.push_back(cc_idx);
+
368 }
+
369 // @TODO: merge computation of shared faces and compactness?
+
370 const auto cur_sf = get_shared_faces(fc, n_cc);
+
371 shared_faces[cc_idx] = cur_sf;
+
372 if (cur_sf > max_shared_f) {
+
373 max_shared_f = cur_sf;
+
374 argmax_shared_f.clear();
375 argmax_shared_f.push_back(cc_idx);
-
376 }
-
377 // Analysing compactness
-
378 auto tmp_cc = n_cc->_s_fc; // OK copy
-
379 tmp_cc.insert(fc);
-
380 const auto new_cpt =
-
381 _fc_graph->compute_min_fc_compactness_inside_a_cc(tmp_cc);
-
382 compact[cc_idx] = new_cpt;
-
383 if (new_cpt > n_cc->_compactness) {
-
384 argtrue_compact.push_back(cc_idx);
-
385 }
-
386 } // End compactness and cardinality
-
387 } // End if isotropic
-
388 }
-
389 // Now, it's time to choose the best neighbours. Priority is given to those
-
390 // which: 1 - Increase the degree of compactness
-
391 if (!argtrue_compact.empty()) {
-
392 // Sort so that, in the end, if nothing worked, we rely on ID numbering
-
393 sort(argtrue_compact.begin(), argtrue_compact.end());
-
394 CoMMAIndexType ret_cc{argtrue_compact[0]};
-
395 CoMMAIntType cur_max{shared_faces[ret_cc]};
-
396 // If more than one, maximize shared faces and/or minimize cardinality
-
397 for (const auto &idx : argtrue_compact) {
-
398 const auto cur_shf = shared_faces[idx];
-
399 if (cur_shf > cur_max) {
-
400 cur_max = cur_shf;
-
401 ret_cc = idx;
-
402 } else if (cur_shf == cur_max && card[idx] < card[ret_cc]) {
+
376 } else if (cur_sf == max_shared_f) {
+
377 argmax_shared_f.push_back(cc_idx);
+
378 }
+
379 // Analysing compactness
+
380 auto tmp_cc = n_cc->_s_fc; // OK copy
+
381 tmp_cc.insert(fc);
+
382 const auto new_cpt =
+
383 _fc_graph->compute_min_fc_compactness_inside_a_cc(tmp_cc);
+
384 compact[cc_idx] = new_cpt;
+
385 if (new_cpt > n_cc->_compactness) {
+
386 argtrue_compact.push_back(cc_idx);
+
387 }
+
388 } // End compactness and cardinality
+
389 } // End if isotropic
+
390 }
+
391 // Now, it's time to choose the best neighbours. Priority is given to those
+
392 // which: 1 - Increase the degree of compactness
+
393 if (!argtrue_compact.empty()) {
+
394 // Sort so that, in the end, if nothing worked, we rely on ID numbering
+
395 sort(argtrue_compact.begin(), argtrue_compact.end());
+
396 CoMMAIndexType ret_cc{argtrue_compact[0]};
+
397 CoMMAIntType cur_max{shared_faces[ret_cc]};
+
398 // If more than one, maximize shared faces and/or minimize cardinality
+
399 for (const auto &idx : argtrue_compact) {
+
400 const auto cur_shf = shared_faces[idx];
+
401 if (cur_shf > cur_max) {
+
402 cur_max = cur_shf;
403 ret_cc = idx;
-
404 }
-
405 }
-
406 new_compactness = compact.at(ret_cc);
-
407 return ret_cc;
-
408 }
-
409 // 2 - Maximize the number of shared faces
-
410 if (!argmax_shared_f.empty()) {
-
411 // Sort so that, in the end, if nothing worked, we rely on ID numbering
-
412 sort(argmax_shared_f.begin(), argmax_shared_f.end());
-
413 CoMMAIndexType ret_cc{argmax_shared_f[0]};
-
414 CoMMAIntType cur_min{card[ret_cc]};
-
415 // ..but let's see if among all the cells there is one with smaller
-
416 // cardinality
-
417 for (const auto &idx : argmax_shared_f) {
-
418 if (card[idx] < cur_min) {
-
419 ret_cc = idx;
-
420 cur_min = card[ret_cc];
-
421 }
-
422 }
-
423 new_compactness = compact.at(ret_cc);
-
424 return ret_cc;
-
425 }
-
426 // 3 - Minimize the cardinality
-
427 if (!argmin_card.empty()) {
-
428 // We should never need to come here...
-
429 // @TODO: I'm not sure what I could consider here to decide which cell to
-
430 // return. The aspect-ratio maybe? In the mean time, I return the one with
-
431 // the lowest ID
-
432 const auto ret_cc =
-
433 *(min_element(argmin_card.begin(), argmin_card.end()));
-
434 new_compactness = compact.at(ret_cc);
-
435 return ret_cc;
-
436 }
-
437 // If everything failed, look through the neighbours
-
438 if (!iso_neighs.empty()) return iso_neighs[0];
-
439 // otherwise, there is nothing we can do
-
440 return nullopt;
-
441 }
-
442
-
449 inline CoMMAIntType get_shared_faces(
-
450 const CoMMAIndexType fc, const CoarseCellPtr cc) const {
-
451 CoMMAIntType shared_faces{0};
-
452 for (const auto &i_fc : cc->_s_fc) {
-
453 shared_faces += count(
-
454 _fc_graph->neighbours_cbegin(i_fc), _fc_graph->neighbours_cend(i_fc),
-
455 fc);
-
456 }
-
457 return shared_faces;
-
458 }
-
459
-
470 CoMMAIndexType create_cc(
-
471 const unordered_set<CoMMAIndexType> &s_fc,
-
472 const CoMMAIntType compactness,
-
473 bool is_anisotropic = false,
-
474 bool is_creation_delayed = false) {
-
475 // Create a course cell from the fine cells and update the fc_2_cc tree.
-
476 assert((!is_anisotropic) || (!is_creation_delayed));
-
477 for (const auto &i_fc : s_fc) {
-
478 assert(!_fc_2_cc[i_fc].has_value());
-
479 if (!_is_fc_agglomerated[i_fc]) {
-
480 // Rq: initialise to False pour chaque niveau dans agglomerate(...)
-
481 _is_fc_agglomerated[i_fc] = true;
-
482 _nb_of_agglomerated_fc++;
-
483 }
-
484 }
-
485 // Anisotropic case
-
486 bool is_mutable = true;
-
487 if (is_anisotropic) {
-
488 // we collect the various cc, where the index in the vector is the i_cc
-
489 _ccs[_cc_counter] = make_shared<CoarseCellType>(
-
490 _fc_graph, _cc_counter, s_fc, compactness, !is_anisotropic);
-
491 is_mutable = false;
-
492 }
-
493 if (!is_creation_delayed) {
-
494 // We create the cc right now.
-
495 // Everything is updated:
-
496 if (is_mutable) {
-
497 // the cell can be modified afterwards and is thus defined in dict_cc
-
498 // and dict_card_cc, dict_compactness_2_cc, dict_cc_to_compactness
-
499 // Update of dict_cc:
-
500 //==================
-
501 // we collect the various cc, where the index in the vector is the i_cc
-
502 _ccs[_cc_counter] = make_shared<CoarseCellType>(
-
503 _fc_graph, _cc_counter, s_fc, compactness);
-
504 if (
-
505 !is_anisotropic
-
506 && static_cast<decltype(_sing_card_thresh)>(s_fc.size())
-
507 <= _sing_card_thresh)
-
508 _singular_cc.emplace_back(_cc_counter);
-
509 }
-
510 // Update of _associatedCoarseCellNumber the output of the current
-
511 // function agglomerate _fc_2_cc is filled with _cc_counter
-
512 for (const auto &i_fc : s_fc) {
-
513 // Only if not isCreationDelayed:
-
514 assert(!_fc_2_cc[i_fc].has_value());
-
515 _fc_2_cc[i_fc] = _cc_counter;
-
516 }
-
517 // Update of the number of CC
-
518 //####################################
-
519 _cc_counter++; // Only if not isCreationDelayed
-
520 } else {
-
521 // We do not create the coarse cell yet.
-
522 // As this coarse cell will be soon deleted, we want its coarse index to
-
523 // be the greater possible.
-
524 // Only isFineCellAgglomerated_tmp, number_of_fine_agglomerated_cells_tmp
-
525 // and dict_DistributionOfCardinalOfCoarseElements are modified!
-
526 _delayed_cc.emplace_back(s_fc, compactness);
-
527 }
-
528 return (_cc_counter - 1);
-
529 }
-
530
-
534 inline void cc_create_all_delayed_cc() {
-
535 for (const auto &[s_fc, cpt] : _delayed_cc) {
-
536 create_cc(s_fc, cpt);
-
537 }
-
538 _delayed_cc.clear();
-
539 }
-
540
-
541protected:
-
543 CoMMAIndexType _nb_of_agglomerated_fc = 0;
-
544
-
549 vector<pair<unordered_set<CoMMAIndexType>, CoMMAIntType>> _delayed_cc;
-
550
-
553 deque<CoMMAIndexType> _singular_cc;
-
554};
-
555
-
556#endif // COMMA_PROJECT_COARSE_CELL_GRAPH_H
+
404 } else if (cur_shf == cur_max && card[idx] < card[ret_cc]) {
+
405 ret_cc = idx;
+
406 }
+
407 }
+
408 new_compactness = compact.at(ret_cc);
+
409 return ret_cc;
+
410 }
+
411 // 2 - Maximize the number of shared faces
+
412 if (!argmax_shared_f.empty()) {
+
413 // Sort so that, in the end, if nothing worked, we rely on ID numbering
+
414 sort(argmax_shared_f.begin(), argmax_shared_f.end());
+
415 CoMMAIndexType ret_cc{argmax_shared_f[0]};
+
416 CoMMAIntType cur_min{card[ret_cc]};
+
417 // ..but let's see if among all the cells there is one with smaller
+
418 // cardinality
+
419 for (const auto &idx : argmax_shared_f) {
+
420 if (card[idx] < cur_min) {
+
421 ret_cc = idx;
+
422 cur_min = card[ret_cc];
+
423 }
+
424 }
+
425 new_compactness = compact.at(ret_cc);
+
426 return ret_cc;
+
427 }
+
428 // 3 - Minimize the cardinality
+
429 if (!argmin_card.empty()) {
+
430 // We should never need to come here...
+
431 // @TODO: I'm not sure what I could consider here to decide which cell to
+
432 // return. The aspect-ratio maybe? In the mean time, I return the one with
+
433 // the lowest ID
+
434 const auto ret_cc =
+
435 *(min_element(argmin_card.begin(), argmin_card.end()));
+
436 new_compactness = compact.at(ret_cc);
+
437 return ret_cc;
+
438 }
+
439 // If everything failed, look through the neighbours
+
440 if (!iso_neighs.empty()) return iso_neighs[0];
+
441 // otherwise, there is nothing we can do
+
442 return nullopt;
+
443 }
+
444
+
451 inline CoMMAIntType get_shared_faces(
+
452 const CoMMAIndexType fc, const CoarseCellPtr cc) const {
+
453 CoMMAIntType shared_faces{0};
+
454 for (const auto &i_fc : cc->_s_fc) {
+
455 shared_faces += count(
+
456 _fc_graph->neighbours_cbegin(i_fc), _fc_graph->neighbours_cend(i_fc),
+
457 fc);
+
458 }
+
459 return shared_faces;
+
460 }
+
461
+
472 CoMMAIndexType create_cc(
+
473 const unordered_set<CoMMAIndexType> &s_fc,
+
474 const CoMMAIntType compactness,
+
475 bool is_anisotropic = false,
+
476 bool is_creation_delayed = false) {
+
477 // Create a course cell from the fine cells and update the fc_2_cc tree.
+
478 assert((!is_anisotropic) || (!is_creation_delayed));
+
479 for (const auto &i_fc : s_fc) {
+
480 assert(!_fc_2_cc[i_fc].has_value());
+
481 if (!_is_fc_agglomerated[i_fc]) {
+
482 // Rq: initialise to False pour chaque niveau dans agglomerate(...)
+
483 _is_fc_agglomerated[i_fc] = true;
+
484 _nb_of_agglomerated_fc++;
+
485 }
+
486 }
+
487 // Anisotropic case
+
488 bool is_mutable = true;
+
489 if (is_anisotropic) {
+
490 // we collect the various cc, where the index in the vector is the i_cc
+
491 _ccs[_cc_counter] = make_shared<CoarseCellType>(
+
492 _fc_graph, _cc_counter, s_fc, compactness, !is_anisotropic);
+
493 is_mutable = false;
+
494 }
+
495 if (!is_creation_delayed) {
+
496 // We create the cc right now.
+
497 // Everything is updated:
+
498 if (is_mutable) {
+
499 // the cell can be modified afterwards and is thus defined in dict_cc
+
500 // and dict_card_cc, dict_compactness_2_cc, dict_cc_to_compactness
+
501 // Update of dict_cc:
+
502 //==================
+
503 // we collect the various cc, where the index in the vector is the i_cc
+
504 _ccs[_cc_counter] = make_shared<CoarseCellType>(
+
505 _fc_graph, _cc_counter, s_fc, compactness);
+
506 if (
+
507 !is_anisotropic
+
508 && static_cast<decltype(_sing_card_thresh)>(s_fc.size())
+
509 <= _sing_card_thresh)
+
510 _singular_cc.emplace_back(_cc_counter);
+
511 }
+
512 // Update of _associatedCoarseCellNumber the output of the current
+
513 // function agglomerate _fc_2_cc is filled with _cc_counter
+
514 for (const auto &i_fc : s_fc) {
+
515 // Only if not isCreationDelayed:
+
516 assert(!_fc_2_cc[i_fc].has_value());
+
517 _fc_2_cc[i_fc] = _cc_counter;
+
518 }
+
519 // Update of the number of CC
+
520 //####################################
+
521 _cc_counter++; // Only if not isCreationDelayed
+
522 } else {
+
523 // We do not create the coarse cell yet.
+
524 // As this coarse cell will be soon deleted, we want its coarse index to
+
525 // be the greater possible.
+
526 // Only isFineCellAgglomerated_tmp, number_of_fine_agglomerated_cells_tmp
+
527 // and dict_DistributionOfCardinalOfCoarseElements are modified!
+
528 _delayed_cc.emplace_back(s_fc, compactness);
+
529 }
+
530 return (_cc_counter - 1);
+
531 }
+
532
+
536 inline void cc_create_all_delayed_cc() {
+
537 for (const auto &[s_fc, cpt] : _delayed_cc) {
+
538 create_cc(s_fc, cpt);
+
539 }
+
540 _delayed_cc.clear();
+
541 }
+
542
+
543protected:
+
545 CoMMAIndexType _nb_of_agglomerated_fc = 0;
+
546
+
551 vector<pair<unordered_set<CoMMAIndexType>, CoMMAIntType>> _delayed_cc;
+
552
+
555 deque<CoMMAIndexType> _singular_cc;
+
556};
+
557
+
558#endif // COMMA_PROJECT_COARSE_CELL_GRAPH_H
#define CoMMAUnused(var)
Convenient function to avoid unused warnings.
Definition: Util.h:34
Class implementing a custom container where the coarse cells are stored.
Definition: Coarse_Cell_Container.h:41
-
void cc_create_all_delayed_cc()
Creates all the delayed coarse cell. It works only when the delayed cell flag is activated in the agg...
Definition: Coarse_Cell_Container.h:534
-
CoMMAIndexType get_number_of_fc_agglomerated() const
Helper to get the member variable that defines the number of agglomerated fine cells.
Definition: Coarse_Cell_Container.h:96
-
CoMMAIntType get_shared_faces(const CoMMAIndexType fc, const CoarseCellPtr cc) const
Compute the number of faces shared between a fine cell and a coarse one.
Definition: Coarse_Cell_Container.h:449
-
set< CoMMAIndexType > get_neighs_cc(const CoMMAIndexType &i_fc, const CoMMAIndexType &i_cc) const
Retrieve the indexes of the neighbouring coarse cells to a given fine cell in a coarse cell (excludin...
Definition: Coarse_Cell_Container.h:113
+
void cc_create_all_delayed_cc()
Creates all the delayed coarse cell. It works only when the delayed cell flag is activated in the agg...
Definition: Coarse_Cell_Container.h:536
+
CoMMAIndexType get_number_of_fc_agglomerated() const
Helper to get the member variable that defines the number of agglomerated fine cells.
Definition: Coarse_Cell_Container.h:98
+
CoMMAIntType get_shared_faces(const CoMMAIndexType fc, const CoarseCellPtr cc) const
Compute the number of faces shared between a fine cell and a coarse one.
Definition: Coarse_Cell_Container.h:451
+
set< CoMMAIndexType > get_neighs_cc(const CoMMAIndexType &i_fc, const CoMMAIndexType &i_cc) const
Retrieve the indexes of the neighbouring coarse cells to a given fine cell in a coarse cell (excludin...
Definition: Coarse_Cell_Container.h:115
shared_ptr< CoarseCellType > CoarseCellPtr
Type for a shared pointer to a Dual_Graph object.
Definition: Coarse_Cell_Container.h:48
-
CoMMAIntType _sing_card_thresh
Minimum cardinality for receiver CC when correcting.
Definition: Coarse_Cell_Container.h:90
-
optional< CoMMAIndexType > select_best_cc_to_agglomerate_whole(const unordered_set< CoMMAIndexType > &fcs, const set< CoMMAIndexType > &neighs, const CoMMAIntType max_card, optional< CoMMAIntType > &new_compactness) const
Choose among the neighbouring coarse cells, the one to which a singular coarse cell should be assigne...
Definition: Coarse_Cell_Container.h:263
-
vector< optional< CoMMAIndexType > > _fc_2_cc
Output vector identifying to which coarse cell the fine cell belongs.
Definition: Coarse_Cell_Container.h:83
-
Coarse_Cell_Container(DualGraphPtr &fc_graph, const CoMMAIntType singular_card_thresh)
Create a Coarse_Cell_Container.
Definition: Coarse_Cell_Container.h:57
-
vector< bool > _is_fc_agglomerated
Vector of boolean telling whether a fine cell has been agglomerated.
Definition: Coarse_Cell_Container.h:87
-
CoMMAIndexType create_cc(const unordered_set< CoMMAIndexType > &s_fc, const CoMMAIntType compactness, bool is_anisotropic=false, bool is_creation_delayed=false)
It creates a coarse cell based on the set of fine cells given as input.
Definition: Coarse_Cell_Container.h:470
-
CoMMAIndexType get_nb_of_cc() const
Helper to get the number of coarse cells.
Definition: Coarse_Cell_Container.h:103
-
DualGraphPtr _fc_graph
Dual graph representation.
Definition: Coarse_Cell_Container.h:76
-
vector< pair< unordered_set< CoMMAIndexType >, CoMMAIntType > > _delayed_cc
Vector of the set of fine cells composing the too small coarse cells that will be built at the end of...
Definition: Coarse_Cell_Container.h:549
-
CoMMAIndexType _cc_counter
Number of coarse cells.
Definition: Coarse_Cell_Container.h:79
-
optional< CoMMAIndexType > select_best_cc_to_agglomerate(const CoMMAIndexType fc, const set< CoMMAIndexType > &neighs, const CoMMAIntType max_card, optional< CoMMAIntType > &new_compactness) const
Choose among the neighbouring coarse cells, the one to which a fine cell should be assigned to....
Definition: Coarse_Cell_Container.h:329
+
CoMMAIntType _sing_card_thresh
Minimum cardinality for receiver CC when correcting.
Definition: Coarse_Cell_Container.h:92
+
optional< CoMMAIndexType > select_best_cc_to_agglomerate_whole(const unordered_set< CoMMAIndexType > &fcs, const set< CoMMAIndexType > &neighs, const CoMMAIntType max_card, optional< CoMMAIntType > &new_compactness) const
Choose among the neighbouring coarse cells, the one to which a singular coarse cell should be assigne...
Definition: Coarse_Cell_Container.h:265
+
vector< optional< CoMMAIndexType > > _fc_2_cc
Output vector identifying to which coarse cell the fine cell belongs.
Definition: Coarse_Cell_Container.h:85
+
Coarse_Cell_Container(DualGraphPtr &fc_graph, const CoMMAIntType singular_card_thresh)
Create a Coarse_Cell_Container.
Definition: Coarse_Cell_Container.h:59
+
vector< bool > _is_fc_agglomerated
Vector of boolean telling whether a fine cell has been agglomerated.
Definition: Coarse_Cell_Container.h:89
+
CoMMAIndexType create_cc(const unordered_set< CoMMAIndexType > &s_fc, const CoMMAIntType compactness, bool is_anisotropic=false, bool is_creation_delayed=false)
It creates a coarse cell based on the set of fine cells given as input.
Definition: Coarse_Cell_Container.h:472
+
CoMMAIndexType get_nb_of_cc() const
Helper to get the number of coarse cells.
Definition: Coarse_Cell_Container.h:105
+
DualGraphPtr _fc_graph
Dual graph representation.
Definition: Coarse_Cell_Container.h:78
+
vector< pair< unordered_set< CoMMAIndexType >, CoMMAIntType > > _delayed_cc
Vector of the set of fine cells composing the too small coarse cells that will be built at the end of...
Definition: Coarse_Cell_Container.h:551
+
CoMMAIndexType _cc_counter
Number of coarse cells.
Definition: Coarse_Cell_Container.h:81
+
optional< CoMMAIndexType > select_best_cc_to_agglomerate(const CoMMAIndexType fc, const set< CoMMAIndexType > &neighs, const CoMMAIntType max_card, optional< CoMMAIntType > &new_compactness) const
Choose among the neighbouring coarse cells, the one to which a fine cell should be assigned to....
Definition: Coarse_Cell_Container.h:331
~Coarse_Cell_Container()=default
Destructor.
-
map< CoMMAIndexType, CoarseCellPtr > _ccs
Map containing the CC and their ID.
Definition: Coarse_Cell_Container.h:73
-
CoMMAIndexType _nb_of_agglomerated_fc
Number of agglomerated fine cells.
Definition: Coarse_Cell_Container.h:543
-
void correct(const CoMMAIntType max_card)
Implementation of the correction. In this version it implements the correction of singular cells (if ...
Definition: Coarse_Cell_Container.h:159
+
map< CoMMAIndexType, CoarseCellPtr > _ccs
Map containing the CC and their ID.
Definition: Coarse_Cell_Container.h:75
+
CoMMAIndexType _nb_of_agglomerated_fc
Number of agglomerated fine cells.
Definition: Coarse_Cell_Container.h:545
+
void correct(const CoMMAIntType max_card)
Implementation of the correction. In this version it implements the correction of singular cells (if ...
Definition: Coarse_Cell_Container.h:161
typename CoarseCellType::DualGraphPtr DualGraphPtr
Type for a shared pointer to a Dual_Graph object.
Definition: Coarse_Cell_Container.h:51
-
deque< CoMMAIndexType > _singular_cc
Set of singular coarse cells, that is, composed of only one fine cell.
Definition: Coarse_Cell_Container.h:553
+
deque< CoMMAIndexType > _singular_cc
Set of singular coarse cells, that is, composed of only one fine cell.
Definition: Coarse_Cell_Container.h:555
Class describing a coarse cell.
Definition: Coarse_Cell.h:37
shared_ptr< Dual_Graph< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > DualGraphPtr
Type for a shared pointer to a Dual_Graph object.
Definition: Coarse_Cell.h:41
diff --git a/class_coarse___cell___container.html b/class_coarse___cell___container.html index c3e51b3..07ee658 100644 --- a/class_coarse___cell___container.html +++ b/class_coarse___cell___container.html @@ -292,6 +292,7 @@

Parameters
+
[in]fc_graphInput element Dual_Graph to work on the seeds choice and the seeds pool
[in]singular_card_threshThreshold value below which a coarse cell is considered singular