1#ifndef COMMA_PROJECT_AGGLOMERATOR_H
2#define COMMA_PROJECT_AGGLOMERATOR_H
53 typename CoMMAIndexType,
54 typename CoMMAWeightType,
55 typename CoMMAIntType>
74 CoMMAIntType dimension
81 throw std::range_error(
"dimension can only be 2 or 3");
113 const CoMMAIntType goal_card,
114 const CoMMAIntType min_card,
115 const CoMMAIntType max_card,
116 const std::vector<CoMMAWeightType> &priority_weights,
117 bool correction_steps
147 std::shared_ptr<Dual_Graph<CoMMAIndexType, CoMMAWeightType, CoMMAIntType>>
157 std::shared_ptr<Seeds_Pool<CoMMAIndexType, CoMMAWeightType, CoMMAIntType>>
170 typename CoMMAIndexType,
171 typename CoMMAWeightType,
172 typename CoMMAIntType>
174 public Agglomerator<CoMMAIndexType, CoMMAWeightType, CoMMAIntType> {
186 std::set<CoMMAPairType, CustomPairGreaterFunctor<CoMMAPairType>>;
224 CoMMAIntType dimension,
225 const CoMMAWeightType threshold_anisotropy,
226 const std::vector<CoMMAIndexType> &agglomerationLines_Idx,
227 const std::vector<CoMMAIndexType> &agglomerationLines,
228 const std::vector<CoMMAWeightType> &priority_weights,
229 const bool build_lines,
230 const bool odd_line_length,
231 const std::optional<CoMMAIndexType> max_cells_in_line,
233 const bool force_line_direction =
true
235 Agglomerator<CoMMAIndexType, CoMMAWeightType, CoMMAIntType>(
236 graph, cc_graph, seeds_pool, dimension
249 this->
_nb_lines = std::vector<CoMMAIndexType>(2);
250 this->
_v_lines = std::vector<std::vector<AnisotropicLinePtr>>(2);
253 const CoMMAWeightType thr =
254 (threshold_anisotropy > 1 || threshold_anisotropy < 0)
255 ? threshold_anisotropy
256 :
static_cast<CoMMAWeightType
>(1. / threshold_anisotropy);
266 for (
auto idx_ptr = agglomerationLines_Idx.cbegin() + 1;
267 idx_ptr != agglomerationLines_Idx.cend();
269 const auto ln_sz = *idx_ptr - (*(idx_ptr - 1));
271 this->
_v_lines[0].push_back(std::make_shared<AnisotropicLine>(
272 agglomerationLines.cbegin() + (*(idx_ptr - 1)),
273 agglomerationLines.cbegin() + (*idx_ptr)
281 <<
"CoMMA - No anisotropic line was built (e.g., only one-cell "
282 "lines). Skipping anisotropic agglomeration"
307 const CoMMAIntType goal_card,
308 const CoMMAIntType min_card,
309 const CoMMAIntType max_card,
310 const std::vector<CoMMAWeightType> &priority_weights,
311 bool correction_steps
322 constexpr bool is_anisotropic =
true;
323 constexpr CoMMAIntType compactness = 1;
328 auto loop_line = [&](
auto begin,
auto end) {
331 for (
auto line_it = begin; line_it != end; line_it += 2) {
342 std::unordered_set<CoMMAIndexType> s_fc = {
343 *line_it, *std::next(line_it)
351 this->_fc_graph->neighbours_cbegin(*line_it),
352 this->_fc_graph->neighbours_cend(*line_it)
356 this->_fc_graph->neighbours_cbegin(*std::next(line_it)),
357 this->_fc_graph->neighbours_cend(*std::next(line_it))
360 std::distance(line_it, end) == 3
363 && n_cells + 1 == this->_max_cells_in_line.value())) {
366 s_fc.insert(*std::next(line_it, 2));
370 this->_fc_graph->neighbours_cbegin(*std::next(line_it, 2)),
371 this->_fc_graph->neighbours_cend(*std::next(line_it, 2))
377 const CoMMAIndexType i_cc =
378 this->
_cc_graph->create_cc(s_fc, compactness, is_anisotropic);
379 line_lvl_p_one->push_back(i_cc);
382 this->
_v_lines[1].push_back(line_lvl_p_one);
386 for (
auto line_ptr = this->
_v_lines[0].begin();
387 line_ptr != this->
_v_lines[0].end();
393 auto line = *line_ptr;
394 if (line->size() <= 1) {
404 const auto l_fr = line->front(), l_bk = line->back();
405 const auto bnd_fr = this->
_fc_graph->get_n_boundary_faces(l_fr),
406 bnd_bk = this->
_fc_graph->get_n_boundary_faces(l_bk);
407 const auto w_fr = priority_weights[l_fr], w_bk = priority_weights[l_bk];
408 const bool forward_line =
410 || (bnd_fr == bnd_bk &&
412 || (w_fr == w_bk && l_fr < l_bk)
416 loop_line(line->cbegin(), line->cend());
418 loop_line(line->crbegin(), line->crend());
438 it != this->_aniso_neighbours.end();) {
439 if (this->
_cc_graph->_is_fc_agglomerated[*it])
449 this->
_fc_graph->get_n_boundary_faces(this->_aniso_neighbours.front())
457 this->_cc_graph->_is_fc_agglomerated
471 std::vector<CoMMAIndexType> &aniso_lines_idx,
472 std::vector<CoMMAIndexType> &aniso_lines
475 aniso_lines_idx.clear();
483 CoMMAIndexType idx = 0;
484 aniso_lines_idx.reserve(this->
_v_lines[level].size() + 1);
485 aniso_lines_idx.push_back(idx);
487 this->
_cc_graph->_cc_counter > 0 ? this->_cc_graph->_cc_counter
488 : this->_fc_graph->_number_of_cells
491 for (
const auto &line_ptr : this->
_v_lines[level]) {
492 const CoMMAIndexType line_size = line_ptr->size();
497 aniso_lines_idx.push_back(line_size + idx);
500 aniso_lines.end(), line_ptr->cbegin(), line_ptr->cend()
504 aniso_lines_idx.shrink_to_fit();
505 aniso_lines.shrink_to_fit();
518 std::vector<std::vector<AnisotropicLinePtr>>
_v_lines;
538 const std::vector<CoMMAWeightType> &priority_weights,
539 const CoMMAWeightType threshold_anisotropy
541 std::deque<CoMMAIndexType> aniso_seeds_pool;
544 std::vector<CoMMAWeightType> max_weights(
547 std::vector<CoMMAWeightType> alt_weights{};
548 std::vector<bool> to_treat(this->
_fc_graph->_number_of_cells,
false);
557 threshold_anisotropy,
562 std::vector<CoMMAWeightType> &ref_weights =
566 if (aniso_seeds_pool.empty()) {
567 std::cout <<
"CoMMA - No anisotropic cell found. Skipping anisotropic "
573 const auto pts_dim = this->
_fc_graph->_centers[0].size();
575 this->_nb_lines[0] = 0;
577 for (
auto &i_fc : aniso_seeds_pool) {
579 if (!to_treat[i_fc]) {
586 const auto primal_seed = i_fc;
587 std::optional<std::vector<CoMMAWeightType>> primal_dir = std::nullopt;
589 CoMMAIndexType seed = primal_seed;
593 cur_line->push_back(seed);
594 to_treat[seed] =
false;
598 bool opposite_direction_check =
false;
600 std::vector<CoMMAWeightType> prev_dir(pts_dim);
601 bool empty_line =
true;
614 seed, to_treat, ref_weights, max_weights, candidates
620 seed, to_treat, ref_weights, max_weights, prev_dir,
true, candidates
623 if (!candidates.empty()) {
632 const auto old_seed = seed;
633 seed = candidates.begin()->first;
634 if (!opposite_direction_check) {
635 cur_line->push_back(seed);
637 cur_line->push_front(seed);
639 to_treat[seed] =
false;
642 this->
_fc_graph->get_center_direction(seed, old_seed, prev_dir);
643 if (!primal_dir.has_value()) primal_dir = prev_dir;
663 if (!candidates.empty()) {
665 const auto old_seed = seed;
666 seed = candidates.begin()->first;
667 if (!opposite_direction_check) {
668 cur_line->push_back(seed);
670 cur_line->push_front(seed);
672 to_treat[seed] =
false;
676 this->
_fc_graph->get_center_direction(seed, old_seed, prev_dir);
677 if (!primal_dir.has_value()) primal_dir = prev_dir;
682 if (!opposite_direction_check && seed != primal_seed) {
687 for (
auto xyz =
decltype(prev_dir.size()){0};
688 xyz < prev_dir.size();
690 prev_dir[xyz] = -primal_dir.value()[xyz];
692 opposite_direction_check =
true;
702 if (!opposite_direction_check && seed != primal_seed) {
707 for (
auto xyz =
decltype(prev_dir.size()){0};
708 xyz < prev_dir.size();
710 prev_dir[xyz] = -primal_dir.value()[xyz];
712 opposite_direction_check =
true;
720 if (cur_line->size() > 1) {
721 this->_v_lines[0].push_back(cur_line);
722 this->_nb_lines[0] += 1;
726 if (this->_nb_lines[0] == 0) {
727 std::cout <<
"CoMMA - No anisotropic line was built (e.g., only isolated "
728 "anisotropic cells). Skipping anisotropic agglomeration"
742 const CoMMAWeightType weight,
const CoMMAWeightType ref_weight
744 return weight > 0.90 * ref_weight;
759 const CoMMAIndexType seed,
760 const std::vector<bool> &to_treat,
761 const std::vector<CoMMAWeightType> &weights,
762 const std::vector<CoMMAWeightType> &max_weights,
765 const auto offset = this->
_fc_graph->_m_CRS_Row_Ptr[seed];
766 auto n_it = std::next(this->
_fc_graph->_m_CRS_Col_Ind.cbegin(), offset);
767 auto w_it = std::next(weights.cbegin(), offset);
768 for (; n_it != this->
_fc_graph->neighbours_cend(seed); ++n_it, ++w_it) {
770 candidates.emplace(*n_it, *w_it);
791 const CoMMAIndexType seed,
792 const std::vector<bool> &to_treat,
793 const std::vector<CoMMAWeightType> &weights,
794 const std::vector<CoMMAWeightType> &max_weights,
795 const std::vector<CoMMAWeightType> &prev_dir,
796 const bool check_weight,
799 const auto offset = this->
_fc_graph->_m_CRS_Row_Ptr[seed];
800 auto n_it = std::next(this->
_fc_graph->_m_CRS_Col_Ind.cbegin(), offset);
801 auto w_it = std::next(weights.cbegin(), offset);
802 const auto pts_dim = this->
_fc_graph->_centers[0].size();
803 for (; n_it != this->
_fc_graph->neighbours_cend(seed); ++n_it, ++w_it) {
806 std::vector<CoMMAWeightType> cur_dir(pts_dim);
808 this->
_fc_graph->get_center_direction(*n_it, seed, cur_dir);
809 const auto dot = dot_product<CoMMAWeightType>(prev_dir, cur_dir);
811 if (dot > 0 && !dot_deviate<CoMMAWeightType>(dot))
812 candidates.emplace(*n_it, dot);
848 typename CoMMAIndexType,
849 typename CoMMAWeightType,
850 typename CoMMAIntType>
852 public Agglomerator<CoMMAIndexType, CoMMAWeightType, CoMMAIntType> {
874 std::shared_ptr<ARComputer<CoMMAIndexType, CoMMAWeightType, CoMMAIntType>>
901 CoMMAIntType dimension,
906 Agglomerator<CoMMAIndexType, CoMMAWeightType, CoMMAIntType>(
907 graph, cc_graph, seeds_pool, dimension
911 _neigh_crtor = std::make_shared<NeighbourhoodCreatorExtType>();
913 _neigh_crtor = std::make_shared<NeighbourhoodCreatorPFType>();
915 switch (aspect_ratio) {
917 if (dimension == 2) {
955 if (dimension == 2) {
978 if (dimension == 2) {
997 CoMMAIntType>>(graph, 1e-12);
1009 throw std::invalid_argument(
"CoMMA - Error: Unknown aspect-ratio type");
1026 CoMMAIntType goal_card = 0,
1027 CoMMAIntType min_card = 0,
1028 CoMMAIntType max_card = 0
1033 std::unordered_map<CoMMAIntType, CoMMAIntType> d_default_min_card = {
1036 std::unordered_map<CoMMAIntType, CoMMAIntType> d_default_max_card = {
1039 std::unordered_map<CoMMAIntType, CoMMAIntType> d_default_goal_card = {
1042 std::unordered_map<CoMMAIntType, CoMMAIntType> d_default_threshold_card = {
1046 if (min_card == 0) {
1053 if (max_card == 0) {
1059 if (goal_card == 0) {
1093 const CoMMAIntType goal_card,
1094 const CoMMAIntType min_card,
1095 const CoMMAIntType max_card,
1096 const std::vector<CoMMAWeightType> &priority_weights,
1097 bool correction_steps
1100 constexpr bool is_anistropic =
false;
1103 while (this->
_cc_graph->get_number_of_fc_agglomerated() < nb_of_fc) {
1108 assert(seed.has_value());
1111 CoMMAIntType compactness = 0;
1112 const std::unordered_set<CoMMAIndexType> set_current_cc =
1114 seed.value(), priority_weights, compactness
1123 constexpr bool is_creation_delayed =
false;
1125 set_current_cc, compactness, is_anistropic, is_creation_delayed
1131 this->
_cc_graph->cc_create_all_delayed_cc();
1133 if (correction_steps) {
1148 virtual std::unordered_set<CoMMAIndexType>
1150 const CoMMAIndexType seed,
1151 const std::vector<CoMMAWeightType> &priority_weights,
1152 CoMMAIntType &compactness
1165 typename CoMMAIndexType,
1166 typename CoMMAWeightType,
1167 typename CoMMAIntType>
1194 CoMMAIntType dimension,
1197 CoMMAIntType fc_iter
1225 const CoMMAIndexType seed,
1226 const std::vector<CoMMAWeightType> &priority_weights,
1227 CoMMAIntType &compactness
1229 bool is_order_primary =
false;
1234 std::unordered_set<CoMMAIndexType> s_current_cc = {seed};
1238 std::unordered_map<CoMMAIndexType, CoMMAIntType> d_n_of_seed;
1241 CoMMAIntType size_current_cc = 1;
1244 CoMMAIntType max_order_of_neighbourhood =
1248 this->
_fc_graph->compute_neighbourhood_of_cc(
1250 max_order_of_neighbourhood,
1260 if (d_n_of_seed.empty()) {
1264 }
else if (
static_cast<CoMMAIntType
>(
1265 d_n_of_seed.size() + s_current_cc.size()
1267 < this->_goal_card) {
1273 for (
auto &i_k_v : d_n_of_seed) {
1274 s_current_cc.insert(i_k_v.first);
1277 this->
_fc_graph->compute_min_fc_compactness_inside_a_cc(s_current_cc);
1284 decltype(s_current_cc) tmp_cc = {seed};
1295 std::unordered_set<CoMMAIndexType>,
1296 std::unordered_map<CoMMAIndexType, CoMMAIntType>>>
1297 dict_cc_in_creation;
1298 CoMMAIntType min_external_faces =
1299 std::numeric_limits<CoMMAIntType>::max();
1300 CoMMAIntType max_compact = 0;
1301 CoMMAIntType arg_min_card = this->
_min_card;
1307 const CoMMAIntType max_ind = std::min(
1308 this->
_max_card,
static_cast<CoMMAIntType
>(d_n_of_seed.size() + 1)
1311 CoMMAIntType number_of_external_faces_current_cc =
1312 this->
_fc_graph->get_nb_of_neighbours(seed)
1313 + this->
_fc_graph->get_n_boundary_faces(seed) - 1;
1317 const std::unordered_set<CoMMAIndexType> s_neighbours_of_seed =
1318 d_keys_to_set<CoMMAIndexType, CoMMAIntType>(d_n_of_seed);
1321 s_neighbours_of_seed, priority_weights, this->
_dimension
1325 std::unordered_map<CoMMAIndexType, CoMMAIntType> cur_compact_by_fc{};
1326 cur_compact_by_fc.reserve(max_ind);
1327 cur_compact_by_fc[seed] = 0;
1328 constexpr auto second_less = [](
const auto &left,
const auto &right) {
1329 return left.second < right.second;
1331 CoMMAIndexType next_cell = seed;
1334 while (size_current_cc < max_ind) {
1336 neighbourhood->update_it(
1338 this->
_fc_graph->neighbours_cbegin(next_cell),
1339 this->
_fc_graph->neighbours_cend(next_cell)
1344 CoMMAIntType max_faces_in_common = 0;
1350 std::min(max_ind - size_current_cc, this->
_fc_iter),
1358 max_faces_in_common,
1363 number_of_external_faces_current_cc +=
1364 this->
_fc_graph->get_nb_of_neighbours(next_cell)
1365 + this->
_fc_graph->get_n_boundary_faces(next_cell) - 1
1366 - 2 * max_faces_in_common;
1369 tmp_cc.insert(next_cell);
1372 CoMMAIntType argmin_compact{0};
1373 for (
auto neigh = this->
_fc_graph->neighbours_cbegin(next_cell);
1374 neigh != this->_fc_graph->neighbours_cend(next_cell);
1376 if (tmp_cc.find(*neigh) != tmp_cc.end()) {
1378 ++cur_compact_by_fc[*neigh];
1381 cur_compact_by_fc[next_cell] = argmin_compact;
1382 const CoMMAIntType cur_compact =
1384 cur_compact_by_fc.cbegin(), cur_compact_by_fc.cend(), second_less
1395 if ((this->
_min_card <= size_current_cc)
1396 || size_current_cc == max_ind) {
1397 if (cur_compact > max_compact) {
1398 max_compact = cur_compact;
1399 min_external_faces = number_of_external_faces_current_cc;
1400 arg_min_card = size_current_cc;
1402 }
else if (cur_compact == max_compact) {
1404 (number_of_external_faces_current_cc < min_external_faces) ||
1405 (number_of_external_faces_current_cc == min_external_faces &&
1407 min_external_faces = number_of_external_faces_current_cc;
1408 arg_min_card = size_current_cc;
1413 std::unordered_map<CoMMAIndexType, CoMMAIntType> new_dict;
1414 new_dict[next_cell] = d_n_of_seed[next_cell];
1416 std::unordered_set<CoMMAIndexType>,
1417 std::unordered_map<CoMMAIndexType, CoMMAIntType>>
1418 tmp_pair = std::make_pair(tmp_cc, new_dict);
1419 dict_cc_in_creation[size_current_cc] = tmp_pair;
1423 cur_cc_feats = std::move(min_ar_cc_feats);
1426 d_n_of_seed.erase(next_cell);
1430 s_current_cc = std::move(dict_cc_in_creation[arg_min_card].first);
1434 for (
auto i_s = arg_min_card + 1; i_s < max_ind + 1; i_s++) {
1438 for (
auto iKV : dict_cc_in_creation[i_s].second) {
1439 d_n_of_seed[iKV.first] = iKV.second;
1449 const auto cc_neighs = this->
_fc_graph->get_neighbourhood_of_cc(
1450 s_current_cc, this->
_cc_graph->_is_fc_agglomerated
1453 std::map<CoMMAIntType, std::unordered_set<CoMMAIndexType>>
1456 std::unordered_set<CoMMAIndexType> neighs_not_found{};
1457 for (
const auto &neigh : cc_neighs) {
1458 if (d_n_of_seed.find(neigh) != d_n_of_seed.end())
1459 neighs_by_order[d_n_of_seed.at(neigh)].insert(neigh);
1461 neighs_not_found.insert(neigh);
1463 for (
const auto &[o, neighs] : neighs_by_order)
1464 if (!neighs.empty())
1465 this->
_seeds_pool->order_new_seeds_and_update(neighs);
1466 if (!neighs_not_found.empty())
1467 this->
_seeds_pool->order_new_seeds_and_update(neighs_not_found);
1469 assert(arg_min_card ==
static_cast<CoMMAIntType
>(s_current_cc.size()));
1471 compactness = max_compact;
1473 return s_current_cc;
1498 const CoMMAIntType fc_iter,
1499 const std::shared_ptr<
1502 const std::unordered_map<CoMMAIndexType, CoMMAIntType> &d_n_of_seed,
1503 const bool &is_order_primary,
1505 const std::unordered_set<CoMMAIndexType> &s_of_fc_for_current_cc,
1506 CoMMAIndexType &argmin_ar,
1507 CoMMAIntType &max_faces_in_common,
1513 CoMMAWeightType min_ar = std::numeric_limits<CoMMAWeightType>::max();
1514 const auto neighbours = neighbourhood->get_candidates();
1515 CoMMAIndexType arg_max_faces_in_common = neighbours[0];
1517 for (
const auto &i_fc : neighbours) {
1521 CoMMAIntType number_faces_in_common = 0;
1522 CoMMAWeightType new_ar = std::numeric_limits<CoMMAWeightType>::min();
1524 new_min_ar_cc_feats{};
1528 s_of_fc_for_current_cc,
1530 number_faces_in_common,
1538 const CoMMAIntType &order = d_n_of_seed.at(i_fc);
1543 if (number_faces_in_common >= max_faces_in_common
1544 or is_order_primary) {
1546 if (number_faces_in_common == max_faces_in_common or is_order_primary) {
1550 if (order <= d_n_of_seed.at(arg_max_faces_in_common)) {
1552 if (order == d_n_of_seed.at(arg_max_faces_in_common)) {
1553 if (new_ar < min_ar and number_faces_in_common > 0) {
1558 min_ar_cc_feats = std::move(new_min_ar_cc_feats);
1560 arg_max_faces_in_common = i_fc;
1566 arg_max_faces_in_common = i_fc;
1569 min_ar_cc_feats = std::move(new_min_ar_cc_feats);
1576 max_faces_in_common = number_faces_in_common;
1577 arg_max_faces_in_common = i_fc;
1580 min_ar_cc_feats = std::move(new_min_ar_cc_feats);
1595 typename CoMMAIndexType,
1596 typename CoMMAWeightType,
1597 typename CoMMAIntType>
1627 CoMMAIntType dimension,
1630 CoMMAIntType fc_iter
1670 const CoMMAIntType fc_iter,
1671 const std::shared_ptr<
1674 const std::unordered_map<CoMMAIndexType, CoMMAIntType> &d_n_of_seed,
1675 const bool &is_order_primary,
1677 const std::unordered_set<CoMMAIndexType> &s_of_fc_for_current_cc,
1678 CoMMAIndexType &argmin_ar,
1679 CoMMAIntType &max_faces_in_common,
1682 CoMMAIndexType outer_argmax_faces{0};
1683 CoMMAIntType ref_max_faces = max_faces_in_common;
1684 CoMMAWeightType outer_ar = std::numeric_limits<CoMMAWeightType>::max();
1685 for (
const auto &i_fc : neighbourhood->get_candidates()) {
1686 auto cur_neighbourhood = this->
_neigh_crtor->clone(neighbourhood);
1687 CoMMAWeightType inner_ar{-1.};
1688 CoMMAIntType inner_max_faces_in_common{0};
1690 inner_min_ar_cc_feats{};
1694 s_of_fc_for_current_cc,
1695 inner_max_faces_in_common,
1697 inner_min_ar_cc_feats
1699 cur_neighbourhood->update_it(
1701 this->
_fc_graph->neighbours_cbegin(i_fc),
1702 this->_fc_graph->neighbours_cend(i_fc)
1704 std::unordered_set<CoMMAIndexType> cur_fc{
1705 s_of_fc_for_current_cc.begin(), s_of_fc_for_current_cc.end()
1707 cur_fc.insert(i_fc);
1709 const CoMMAIntType ref_inner_faces = inner_max_faces_in_common;
1712 CoMMAIndexType cur_argmin{0};
1713 CoMMAIntType cur_max_faces_in_common{0};
1715 cur_min_ar_cc_feats{};
1716 CoMMAWeightType cur_min_ar{0.};
1722 inner_min_ar_cc_feats,
1726 cur_max_faces_in_common,
1730 if (cur_max_faces_in_common > inner_max_faces_in_common) {
1731 inner_max_faces_in_common = cur_max_faces_in_common;
1732 }
else if (cur_max_faces_in_common == inner_max_faces_in_common
1733 && cur_min_ar < inner_ar) {
1734 inner_ar = cur_min_ar;
1738 const CoMMAIntType &order = d_n_of_seed.at(i_fc);
1743 if (inner_max_faces_in_common >= ref_max_faces
1744 or is_order_primary) {
1746 if (inner_max_faces_in_common == ref_max_faces or is_order_primary) {
1750 if (order <= d_n_of_seed.at(outer_argmax_faces)) {
1752 if (order == d_n_of_seed.at(outer_argmax_faces)) {
1753 if (inner_ar < outer_ar and inner_max_faces_in_common > 0) {
1760 outer_ar = inner_ar;
1761 min_ar_cc_feats = std::move(inner_min_ar_cc_feats);
1763 max_faces_in_common = ref_inner_faces;
1765 outer_argmax_faces = i_fc;
1770 outer_argmax_faces = i_fc;
1775 outer_ar = inner_ar;
1776 min_ar_cc_feats = std::move(inner_min_ar_cc_feats);
1778 max_faces_in_common = ref_inner_faces;
1784 ref_max_faces = inner_max_faces_in_common;
1785 outer_argmax_faces = i_fc;
1790 outer_ar = inner_ar;
1791 min_ar_cc_feats = std::move(inner_min_ar_cc_feats);
1793 max_faces_in_common = ref_inner_faces;
#define CoMMAUnused(var)
Convenient function to avoid unused warnings.
Definition: Util.h:38
ARComputer. Here, AR is the ratio of the diameter over the smallest edge.
Definition: ARComputer.h:466
ARComputer. Here, AR is the ratio of the diameter over the estimated one (typically,...
Definition: ARComputer.h:361
ARComputer. Here, AR is the approximated diameter.
Definition: ARComputer.h:606
ARComputer. Here, AR is the ratio of the external weights over the measure. With dim equal to 2,...
Definition: ARComputer.h:529
ARComputer. Here, AR is the total external weights (that is, from a geometric point of view,...
Definition: ARComputer.h:659
ARComputer. Here, AR is the ratio of the maximum over minimum distance of the cell centers from the b...
Definition: ARComputer.h:764
ARComputer. Here, AR is the ratio of the maximum over minimum distance of the cell centers from the b...
Definition: ARComputer.h:832
ARComputer. Here, AR is one over the internal weights (looking for the minimum leads to the maximizat...
Definition: ARComputer.h:710
ARComputer. Here, AR is the reciprocal of the measure, hence the optimal solution should be the one w...
Definition: ARComputer.h:416
Agglomerator_Anisotropic class is a child class of the Agglomerator class that specializes the implem...
Definition: Agglomerator.h:174
CoMMACellCouplingT _cell_coupling
Definition: Agglomerator.h:831
bool build_anisotropic_lines(const std::vector< CoMMAWeightType > &priority_weights, const CoMMAWeightType threshold_anisotropy)
Build the anisotropic lines at the first level (only called at the first level of agglomeration)....
Definition: Agglomerator.h:537
void export_anisotropic_lines(CoMMAIntType level, std::vector< CoMMAIndexType > &aniso_lines_idx, std::vector< CoMMAIndexType > &aniso_lines) const
Function that prepares the anisotropic lines for output.
Definition: Agglomerator.h:469
std::pair< CoMMAIndexType, CoMMAWeightType > CoMMAPairType
Type of pair.
Definition: Agglomerator.h:183
bool _odd_line_length
Whether anisotropic lines with odd length are allowed.
Definition: Agglomerator.h:823
void find_cell_candidates_for_line_max_weight(const CoMMAIndexType seed, const std::vector< bool > &to_treat, const std::vector< CoMMAWeightType > &weights, const std::vector< CoMMAWeightType > &max_weights, CoMMASetOfPairType &candidates)
Find cells which are good candidates to be added to the anisotropic line. In order to identify the ca...
Definition: Agglomerator.h:758
void update_seeds_pool()
Update the seeds pool with the neighbours of the anisotropic cells agglomerated so far.
Definition: Agglomerator.h:433
Agglomerator_Anisotropic(std::shared_ptr< Dual_Graph< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > graph, std::shared_ptr< Coarse_Cell_Container< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > cc_graph, std::shared_ptr< Seeds_Pool< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > seeds_pool, CoMMAIntType dimension, const CoMMAWeightType threshold_anisotropy, const std::vector< CoMMAIndexType > &agglomerationLines_Idx, const std::vector< CoMMAIndexType > &agglomerationLines, const std::vector< CoMMAWeightType > &priority_weights, const bool build_lines, const bool odd_line_length, const std::optional< CoMMAIndexType > max_cells_in_line, CoMMACellCouplingT cell_coupling=CoMMACellCouplingT::MAX_WEIGHT, const bool force_line_direction=true)
Constructor.
Definition: Agglomerator.h:216
bool _force_line_direction
Definition: Agglomerator.h:836
void agglomerate_one_level(const CoMMAIntType goal_card, const CoMMAIntType min_card, const CoMMAIntType max_card, const std::vector< CoMMAWeightType > &priority_weights, bool correction_steps) override
Specialization of the pure virtual function to the class Agglomerator_Anisotropic....
Definition: Agglomerator.h:306
bool _should_agglomerate
Whether agglomeration is possible: for instance, if anisotropy requested but no anisotropic cells fou...
Definition: Agglomerator.h:523
std::optional< CoMMAIndexType > _max_cells_in_line
Maximum number of cells in an anisotropic line; when this value is reached, all reaming cells are dis...
Definition: Agglomerator.h:828
std::deque< CoMMAIndexType > AnisotropicLine
Container for an anisotropic line.
Definition: Agglomerator.h:177
std::shared_ptr< AnisotropicLine > AnisotropicLinePtr
(Shared) Pointer to an anisotropic line
Definition: Agglomerator.h:180
std::set< CoMMAPairType, CustomPairGreaterFunctor< CoMMAPairType > > CoMMASetOfPairType
Type of set of pairs.
Definition: Agglomerator.h:186
~Agglomerator_Anisotropic() override=default
Destructor.
std::vector< std::vector< AnisotropicLinePtr > > _v_lines
_v_lines : Agglomeration lines structure:
Definition: Agglomerator.h:518
std::deque< CoMMAIndexType > _aniso_neighbours
Neighbours of the anisotropic cells agglomerated. They are used to update the seeds pool.
Definition: Agglomerator.h:820
void find_cell_candidates_for_line_direction(const CoMMAIndexType seed, const std::vector< bool > &to_treat, const std::vector< CoMMAWeightType > &weights, const std::vector< CoMMAWeightType > &max_weights, const std::vector< CoMMAWeightType > &prev_dir, const bool check_weight, CoMMASetOfPairType &candidates)
Find cells which are good candidates to be added to the anisotropic line. In order to identify the ca...
Definition: Agglomerator.h:790
std::vector< CoMMAIndexType > _nb_lines
Vector of number of Anisotropic agglomeration lines per level.
Definition: Agglomerator.h:510
bool is_high_coupling(const CoMMAWeightType weight, const CoMMAWeightType ref_weight)
Tell whether a weight should be considered as high coupling between two cells.
Definition: Agglomerator.h:741
Child class of Agglomerator_Isotropic where is implemented a specific biconnected algorithm for the a...
Definition: Agglomerator.h:1169
~Agglomerator_Biconnected() override=default
Destructor.
std::unordered_set< CoMMAIndexType > choose_optimal_cc_and_update_seeds_pool(const CoMMAIndexType seed, const std::vector< CoMMAWeightType > &priority_weights, CoMMAIntType &compactness) override
Specialization of the pure virtual function in the parent class, to be used in couple with the agglom...
Definition: Agglomerator.h:1224
virtual void compute_best_fc_to_add(const CoMMAIntType fc_iter, const std::shared_ptr< Neighbourhood< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > neighbourhood, const std::unordered_map< CoMMAIndexType, CoMMAIntType > &d_n_of_seed, const bool &is_order_primary, const CellFeatures< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > &cc_feats, const std::unordered_set< CoMMAIndexType > &s_of_fc_for_current_cc, CoMMAIndexType &argmin_ar, CoMMAIntType &max_faces_in_common, CellFeatures< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > &min_ar_cc_feats) const
Computes the best fine cell to add to the coarse cell. The choice depends on: the number of shared fa...
Definition: Agglomerator.h:1497
Agglomerator_Biconnected(std::shared_ptr< Dual_Graph< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > graph, std::shared_ptr< Coarse_Cell_Container< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > cc_graph, std::shared_ptr< Seeds_Pool< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > seeds_pool, CoMMAIntType dimension, CoMMAAspectRatioT aspect_ratio, CoMMANeighbourhoodT neighbourhood_type, CoMMAIntType fc_iter)
Constructor of the class. No specific implementation, it instantiates the base class Agglomerator_Iso...
Definition: Agglomerator.h:1186
Agglomerator_Isotropic class is a child class of the Agglomerator class that specializes the implemen...
Definition: Agglomerator.h:852
std::shared_ptr< ARComputer< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > _ar_computer
Object computing the aspect-ratio of a coarse cell.
Definition: Agglomerator.h:875
virtual std::unordered_set< CoMMAIndexType > choose_optimal_cc_and_update_seeds_pool(const CoMMAIndexType seed, const std::vector< CoMMAWeightType > &priority_weights, CoMMAIntType &compactness)=0
Pure virtual function that must be implemented in child classes to define the optimal coarse cell.
std::shared_ptr< NeighbourhoodCreatorBaseType > _neigh_crtor
Creator responsible for neighborhood objects.
Definition: Agglomerator.h:871
CoMMAIntType _fc_iter
Number of iterations allowed for the algorithm choosing which fine cell to add next.
Definition: Agglomerator.h:868
void set_agglomeration_parameter(CoMMAIntType goal_card=0, CoMMAIntType min_card=0, CoMMAIntType max_card=0)
The task of the function is to set the parameters of determine the cardinality limits with respect to...
Definition: Agglomerator.h:1025
Agglomerator_Isotropic(std::shared_ptr< Dual_Graph< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > graph, std::shared_ptr< Coarse_Cell_Container< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > cc_graph, std::shared_ptr< Seeds_Pool< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > seeds_pool, CoMMAIntType dimension, CoMMAAspectRatioT aspect_ratio, CoMMANeighbourhoodT neighbourhood_type, CoMMAIntType fc_iter)
Constructor. The constructor takes as arguments the same arguments of the father and in this way acti...
Definition: Agglomerator.h:893
void agglomerate_one_level(const CoMMAIntType goal_card, const CoMMAIntType min_card, const CoMMAIntType max_card, const std::vector< CoMMAWeightType > &priority_weights, bool correction_steps) override
Specialization of the pure virtual function to the class Agglomerator_Isotropic. We add the override ...
Definition: Agglomerator.h:1092
~Agglomerator_Isotropic() override=default
Destructor.
Child class of Agglomerator_Isotropic which implements a specialized iterative algorithm for the sear...
Definition: Agglomerator.h:1602
Agglomerator_Iterative(std::shared_ptr< Dual_Graph< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > graph, std::shared_ptr< Coarse_Cell_Container< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > cc_graph, std::shared_ptr< Seeds_Pool< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > seeds_pool, CoMMAIntType dimension, CoMMAAspectRatioT aspect_ratio, CoMMANeighbourhoodT neighbourhood_type, CoMMAIntType fc_iter)
Constructor of the class. No specific implementation, it instantiates the base class Agglomerator_Bic...
Definition: Agglomerator.h:1619
~Agglomerator_Iterative() override=default
Destructor.
void compute_best_fc_to_add(const CoMMAIntType fc_iter, const std::shared_ptr< Neighbourhood< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > neighbourhood, const std::unordered_map< CoMMAIndexType, CoMMAIntType > &d_n_of_seed, const bool &is_order_primary, const CellFeatures< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > &cc_feats, const std::unordered_set< CoMMAIndexType > &s_of_fc_for_current_cc, CoMMAIndexType &argmin_ar, CoMMAIntType &max_faces_in_common, CellFeatures< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > &min_ar_cc_feats) const override
Specialization of the parent function. This is an iterative version. Computes the best fine cell to a...
Definition: Agglomerator.h:1669
A class responsible to do the interface between the different kinds of agglomerator.
Definition: Agglomerator.h:56
std::vector< CoMMAIndexType > _l_nb_of_cells
List of number of cells per coarse cell created.
Definition: Agglomerator.h:143
virtual ~Agglomerator()=default
The destructor of the class.
Agglomerator(std::shared_ptr< Dual_Graph< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > graph, std::shared_ptr< Coarse_Cell_Container< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > cc_graph, std::shared_ptr< Seeds_Pool< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > seeds_pool, CoMMAIntType dimension)
The constructor of the interface.
Definition: Agglomerator.h:66
CoMMAIntType _min_card
Minimum cardinality (default = 0, meaning, equal to the dimension)
Definition: Agglomerator.h:129
std::shared_ptr< Coarse_Cell_Container< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > _cc_graph
pointer to Coarse_Cell_Container element
Definition: Agglomerator.h:153
std::shared_ptr< Dual_Graph< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > _fc_graph
Dual_Graph object determining Fine cells graph and hence the connectivity.
Definition: Agglomerator.h:148
CoMMAIntType _threshold_card
Threshold cardinality (default = 0, meaning, equal to the dimension)
Definition: Agglomerator.h:141
CoMMAIntType _min_neighbourhood
Minimum number of neighbourhood we extend to search the neighbourhood in the greedy algorithm....
Definition: Agglomerator.h:126
CoMMAIntType _dimension
Dimensionality of the problem (_dimension = 2 -> 2D, _dimension = 3 -> 3D)
Definition: Agglomerator.h:123
CoMMAIntType _max_card
Maximum cardinality (default = 0, meaning, 5 or 10 for, resp., 2- and 3D.
Definition: Agglomerator.h:133
std::shared_ptr< Seeds_Pool< CoMMAIndexType, CoMMAWeightType, CoMMAIntType > > _seeds_pool
Seeds_Pool object giving the order in which the fine cells should be considered when agglomerating.
Definition: Agglomerator.h:158
CoMMAIntType _goal_card
Goal cardinality (default = 0, meaning, 4 or 8 for, resp., 2- and 3D.
Definition: Agglomerator.h:137
std::vector< CoMMAIndexType > get_fc_2_cc() const
Accessor to retrieve the fine cells to coarse cells from the coarse cell graphs class.
Definition: Agglomerator.h:97
virtual void agglomerate_one_level(const CoMMAIntType goal_card, const CoMMAIntType min_card, const CoMMAIntType max_card, const std::vector< CoMMAWeightType > &priority_weights, bool correction_steps)=0
Pure virtual function which implementation is specified in the related child classes and that defines...
Convenient class containing salient features of a cell. According to to the chosen AR computation (se...
Definition: ARComputer.h:36
Class implementing a custom container where the coarse cells are stored.
Definition: Coarse_Cell_Container.h:41
A class implementing the CRS global graph representation of the global mesh.
Definition: Dual_Graph.h:548
Pure abstract class for a creator of Neighbourhood objects. It can create from scratch or by copy.
Definition: Neighbourhood.h:427
Creator of Neighbourhood_Extended objects. It can create from scratch or by copy.
Definition: Neighbourhood.h:475
Class representing the neighbourhood of a given cell in the graph. Mind that no information about the...
Definition: Neighbourhood.h:42
Creator of Neighbourhood_Extended objects. It can create from scratch or by copy.
Definition: Neighbourhood.h:543
Class representing the pool of all the seeds for creating a coarse cell.
Definition: Seeds_Pool.h:200
Definition: Agglomerator.h:37
CoMMAAspectRatioT
Type of aspect-ratio. Notation:
Definition: CoMMADefs.h:73
@ ONE_OVER_MEASURE
Definition: CoMMADefs.h:85
@ ONE_OVER_INTERNAL_WEIGHTS
Definition: CoMMADefs.h:87
@ ALGEBRAIC_PERIMETER_OVER_MEASURE
Definition: CoMMADefs.h:99
@ EXTERNAL_WEIGHTS
Definition: CoMMADefs.h:91
@ MAX_BARY_DIST_OVER_RADIUS
Definition: CoMMADefs.h:93
@ DIAMETER_OVER_RADIUS
Definition: CoMMADefs.h:75
@ DIAMETER_OVER_MIN_EDGE
Definition: CoMMADefs.h:79
@ MAX_OVER_MIN_BARY_DIST
Definition: CoMMADefs.h:95
@ DIAMETER
Definition: CoMMADefs.h:81
@ PERIMETER_OVER_RADIUS
Definition: CoMMADefs.h:89
CoMMACellCouplingT
Type of coupling between cells in an anisotropic line.
Definition: CoMMADefs.h:103
@ MAX_WEIGHT
Definition: CoMMADefs.h:105
CoMMANeighbourhoodT
Type of neighbourhood (of a coarse cell) considered when agglomerating.
Definition: CoMMADefs.h:37
@ EXTENDED
Extended, all neighbours of the coarse cell.
Definition: CoMMADefs.h:38