1#ifndef COMMA_PROJECT_COARSE_CELL_CONTAINER_H
2#define COMMA_PROJECT_COARSE_CELL_CONTAINER_H
38 typename CoMMAIndexType,
39 typename CoMMAWeightType,
40 typename CoMMAIntType>
60 DualGraphPtr &fc_graph,
const CoMMAIntType singular_card_thresh
65 _fc_2_cc(fc_graph->_number_of_cells, std::nullopt),
76 std::map<CoMMAIndexType, CoarseCellPtr>
_ccs;
86 std::vector<std::optional<CoMMAIndexType>>
_fc_2_cc;
117 const CoMMAIndexType &i_fc,
const CoMMAIndexType &i_cc
119 std::set<CoMMAIndexType> result;
120 for (
auto elem =
_fc_graph->neighbours_cbegin(i_fc);
121 elem !=
_fc_graph->neighbours_cend(i_fc);
123 const auto cc =
_fc_2_cc[*elem].value();
124 if (cc != i_cc) result.insert(cc);
130Not used anymore but we leave it
for example purposes
133 using CustomMapItT =
typename std::map<CoMMAIndexType, SubGraphPtr>::iterator;
138 CustomMapItT remove_cc(CustomMapItT elim) {
141 CustomMapItT it =
_ccs.erase(elim);
143 for (
auto i = it; i !=
_ccs.end(); i++) {
144 for (
auto const &i_fc : i->second->_mapping_l_to_g) {
147 auto node =
_ccs.extract(i);
149 node.key() = (i->first) - 1;
150 _ccs.insert(std::move(node));
166 std::set<
typename decltype(
_singular_cc)::value_type> removed_cc{};
170 auto &cur_cc =
_ccs.at(old_cc);
172 const auto &fcs = cur_cc->_s_fc;
173 bool should_remove =
false;
174 std::unordered_map<CoMMAIndexType, std::set<CoMMAIndexType>>
176 neighs_by_fc.reserve(cur_cc->_cardinality);
177 for (
const auto &i_fc : fcs) {
180 if (cur_cc->_cardinality > 1) {
182 std::set<CoMMAIndexType> glob_neighs = {};
183 for (
const auto &[i_fc, neighs] : neighs_by_fc) {
184 glob_neighs.insert(neighs.begin(), neighs.end());
186 if (!glob_neighs.empty()) {
187 std::optional<CoMMAIntType> new_compactness = std::nullopt;
189 fcs, glob_neighs, max_card, new_compactness
191 if (new_cc.has_value()) {
194 for (
const auto &i_fc : fcs) {
197 _ccs[new_cc.value()]->insert_cells(fcs, new_compactness);
198 should_remove =
true;
202 if (!should_remove) {
205 for (
const auto &[i_fc, neighs] : neighs_by_fc) {
206 if (!neighs.empty()) {
207 std::optional<CoMMAIntType> new_compactness = std::nullopt;
209 i_fc, neighs, max_card, new_compactness
211 if (new_cc.has_value()) {
213 _ccs[new_cc.value()]->insert_cell(i_fc, new_compactness);
214 should_remove =
true;
225 removed_cc.emplace(old_cc);
231 if (!removed_cc.empty()) {
232 auto new_ID = *(removed_cc.begin());
237 auto it_cc =
_ccs.begin();
239 it_cc =
_ccs.find(new_ID - 1);
242 for (; it_cc !=
_ccs.end(); ++it_cc, ++new_ID) {
244 for (
auto const &i_fc : it_cc->second->_s_fc) {
248 auto node =
_ccs.extract(it_cc);
251 _ccs.insert(std::move(node));
272 const std::unordered_set<CoMMAIndexType> &fcs,
273 const std::set<CoMMAIndexType> &neighs,
274 const CoMMAIntType max_card,
275 std::optional<CoMMAIntType> &new_compactness
278 std::unordered_map<CoMMAIndexType, CoMMAIntType> card{};
279 std::unordered_map<CoMMAIndexType, CoMMAIntType> compact{};
280 const auto n_neighs = neighs.size();
281 card.reserve(n_neighs);
284 std::deque<CoMMAIndexType> argtrue_compact{};
286 for (
const auto &cc_idx : neighs) {
287 const auto n_cc =
_ccs.at(cc_idx);
288 if (n_cc->_is_isotropic) {
294 card[cc_idx] = n_cc->_cardinality;
296 auto tmp_cc = n_cc->_s_fc;
297 tmp_cc.insert(fcs.begin(), fcs.end());
299 _fc_graph->compute_min_fc_compactness_inside_a_cc(tmp_cc);
300 compact[cc_idx] = new_cpt;
301 if (new_cpt > n_cc->_compactness) {
302 argtrue_compact.push_back(cc_idx);
307 if (!argtrue_compact.empty()) {
309 sort(argtrue_compact.begin(), argtrue_compact.end());
310 CoMMAIndexType ret_cc{argtrue_compact[0]};
311 CoMMAIntType cur_min{card[ret_cc]};
313 for (
const auto &idx : argtrue_compact) {
314 const auto cur_card = card[idx];
315 if (cur_card < cur_min) {
320 new_compactness = compact.at(ret_cc);
340 const CoMMAIndexType fc,
341 const std::set<CoMMAIndexType> &neighs,
342 const CoMMAIntType max_card,
343 std::optional<CoMMAIntType> &new_compactness
346 std::unordered_map<CoMMAIndexType, CoMMAIntType> card{};
347 std::unordered_map<CoMMAIndexType, CoMMAIntType> shared_faces{};
348 std::unordered_map<CoMMAIndexType, CoMMAIntType> compact{};
349 const auto n_neighs = neighs.size();
350 card.reserve(n_neighs);
351 shared_faces.reserve(n_neighs);
352 CoMMAIntType min_card = std::numeric_limits<CoMMAIntType>::max();
353 CoMMAIntType max_shared_f{0};
356 std::deque<CoMMAIndexType> argmin_card{};
357 std::deque<CoMMAIndexType> argmax_shared_f{};
358 std::deque<CoMMAIndexType> argtrue_compact{};
359 std::deque<CoMMAIndexType> iso_neighs{};
361 for (
const auto &cc_idx : neighs) {
362 const auto n_cc =
_ccs.at(cc_idx);
363 if (n_cc->_is_isotropic) {
364 iso_neighs.push_back(cc_idx);
370 const auto cur_card = n_cc->_cardinality;
371 card[cc_idx] = cur_card;
372 if (cur_card < min_card) {
375 argmin_card.push_back(cc_idx);
376 }
else if (cur_card == min_card) {
377 argmin_card.push_back(cc_idx);
381 shared_faces[cc_idx] = cur_sf;
382 if (cur_sf > max_shared_f) {
383 max_shared_f = cur_sf;
384 argmax_shared_f.clear();
385 argmax_shared_f.push_back(cc_idx);
386 }
else if (cur_sf == max_shared_f) {
387 argmax_shared_f.push_back(cc_idx);
390 auto tmp_cc = n_cc->_s_fc;
393 _fc_graph->compute_min_fc_compactness_inside_a_cc(tmp_cc);
394 compact[cc_idx] = new_cpt;
395 if (new_cpt > n_cc->_compactness) {
396 argtrue_compact.push_back(cc_idx);
403 if (!argtrue_compact.empty()) {
405 sort(argtrue_compact.begin(), argtrue_compact.end());
406 CoMMAIndexType ret_cc{argtrue_compact[0]};
407 CoMMAIntType cur_max{shared_faces[ret_cc]};
409 for (
const auto &idx : argtrue_compact) {
410 const auto cur_shf = shared_faces[idx];
411 if (cur_shf > cur_max) {
414 }
else if (cur_shf == cur_max && card[idx] < card[ret_cc]) {
418 new_compactness = compact.at(ret_cc);
422 if (!argmax_shared_f.empty()) {
424 sort(argmax_shared_f.begin(), argmax_shared_f.end());
425 CoMMAIndexType ret_cc{argmax_shared_f[0]};
426 CoMMAIntType cur_min{card[ret_cc]};
429 for (
const auto &idx : argmax_shared_f) {
430 if (card[idx] < cur_min) {
432 cur_min = card[ret_cc];
435 new_compactness = compact.at(ret_cc);
439 if (!argmin_card.empty()) {
445 *(min_element(argmin_card.begin(), argmin_card.end()));
446 new_compactness = compact.at(ret_cc);
450 if (!iso_neighs.empty())
return iso_neighs[0];
464 CoMMAIntType shared_faces{0};
465 for (
const auto &i_fc : cc->_s_fc) {
466 shared_faces += count(
484 const std::unordered_set<CoMMAIndexType> &s_fc,
485 const CoMMAIntType compactness,
486 bool is_anisotropic =
false,
487 bool is_creation_delayed =
false
490 assert((!is_anisotropic) || (!is_creation_delayed));
491 for (
const auto &i_fc : s_fc) {
492 assert(!
_fc_2_cc[i_fc].has_value());
500 bool is_mutable =
true;
501 if (is_anisotropic) {
508 if (!is_creation_delayed) {
527 for (
const auto &i_fc : s_fc) {
529 assert(!
_fc_2_cc[i_fc].has_value());
564 std::vector<std::pair<std::unordered_set<CoMMAIndexType>, CoMMAIntType>>
#define CoMMAUnused(var)
Convenient function to avoid unused warnings.
Definition: Util.h:38
Class implementing a custom container where the coarse cells are stored.
Definition: Coarse_Cell_Container.h:41
std::map< CoMMAIndexType, CoarseCellPtr > _ccs
Map containing the CC and their ID.
Definition: Coarse_Cell_Container.h:76
std::optional< CoMMAIndexType > select_best_cc_to_agglomerate_whole(const std::unordered_set< CoMMAIndexType > &fcs, const std::set< CoMMAIndexType > &neighs, const CoMMAIntType max_card, std::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:271
std::deque< CoMMAIndexType > _singular_cc
Set of singular coarse cells, that is, composed of only one fine cell.
Definition: Coarse_Cell_Container.h:569
CoMMAIndexType _nb_of_agglomerated_fc
Number of agglomerated fine cells.
Definition: Coarse_Cell_Container.h:558
CoMMAIntType _sing_card_thresh
Minimum cardinality for receiver CC when correcting.
Definition: Coarse_Cell_Container.h:93
std::vector< std::pair< std::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:565
std::vector< std::optional< CoMMAIndexType > > _fc_2_cc
Output vector identifying to which coarse cell the fine cell belongs.
Definition: Coarse_Cell_Container.h:86
std::shared_ptr< CoarseCellType > CoarseCellPtr
Type for a shared pointer to a Dual_Graph object.
Definition: Coarse_Cell_Container.h:48
typename CoarseCellType::DualGraphPtr DualGraphPtr
Type for a shared pointer to a Dual_Graph object.
Definition: Coarse_Cell_Container.h:51
CoMMAIndexType _cc_counter
Number of coarse cells.
Definition: Coarse_Cell_Container.h:82
std::optional< CoMMAIndexType > select_best_cc_to_agglomerate(const CoMMAIndexType fc, const std::set< CoMMAIndexType > &neighs, const CoMMAIntType max_card, std::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:339
CoMMAIndexType create_cc(const std::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:483
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:99
std::vector< bool > _is_fc_agglomerated
Vector of boolean telling whether a fine cell has been agglomerated.
Definition: Coarse_Cell_Container.h:90
CoMMAIndexType get_nb_of_cc() const
Helper to get the number of coarse cells.
Definition: Coarse_Cell_Container.h:106
DualGraphPtr _fc_graph
Dual graph representation.
Definition: Coarse_Cell_Container.h:79
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:461
~Coarse_Cell_Container()=default
Destructor.
Coarse_Cell_Container(DualGraphPtr &fc_graph, const CoMMAIntType singular_card_thresh)
Create a Coarse_Cell_Container.
Definition: Coarse_Cell_Container.h:59
std::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:116
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:164
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:549
Class describing a coarse cell.
Definition: Coarse_Cell.h:37
std::shared_ptr< Dual_Graph< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > DualGraphPtr
Type for a shared pointer to a Dual_Graph object.
Definition: Coarse_Cell.h:41
Definition: Agglomerator.h:37