1#ifndef COMMA_PROJECT_DUAL_GRAPH_H
2#define COMMA_PROJECT_DUAL_GRAPH_H
24#include <unordered_map>
25#include <unordered_set>
43 typename CoMMAIndexType,
44 typename CoMMAWeightType,
45 typename CoMMAIntType>
67 const CoMMAIndexType &nb_c,
107 void DFS(
const CoMMAIndexType &i_fc) {
119 void BFS(
const CoMMAIndexType &root) {
120 std::deque<CoMMAIndexType> coda;
122 coda.push_back(root);
124 visited[root] =
true;
125 std::vector<std::optional<CoMMAIndexType>> prev(
128 while (!coda.empty()) {
129 CoMMAIndexType node = coda.front();
142 while (retro.has_value()) {
143 path.push_back(retro);
146 reverse(path.begin(), path.end());
259 const std::unordered_set<CoMMAIndexType> &s_fc
263 if (s_fc.size() > 1) {
264 std::unordered_map<CoMMAIndexType, CoMMAIntType> dict_fc_compactness =
266 if (dict_fc_compactness.empty()) {
270 dict_fc_compactness.begin(),
271 dict_fc_compactness.end(),
272 [](
const auto &left,
const auto &right) {
273 return left.second < right.second;
286 std::unordered_map<CoMMAIndexType, CoMMAIntType>
288 const std::unordered_set<CoMMAIndexType> &s_fc
290 std::unordered_map<CoMMAIndexType, CoMMAIntType> dict_fc_compactness;
292 if (s_fc.size() == 1) {
293 dict_fc_compactness[*s_fc.begin()] = 0;
295 for (
const CoMMAIndexType &i_fc : s_fc) {
296 dict_fc_compactness[i_fc] = count_if(
297 this->_m_CRS_Col_Ind.cbegin() + this->_m_CRS_Row_Ptr[i_fc],
298 this->_m_CRS_Col_Ind.cbegin() + this->_m_CRS_Row_Ptr[i_fc + 1],
299 [&](
const auto &neigh) { return s_fc.count(neigh) > 0; }
304 return dict_fc_compactness;
317 typename CoMMAIndexType,
318 typename CoMMAWeightType,
319 typename CoMMAIntType>
320class Subgraph :
public Graph<CoMMAIndexType, CoMMAWeightType, CoMMAIntType> {
343 const CoMMAIndexType &nb_c,
349 const bool &is_isotropic
351 Graph<CoMMAIndexType, CoMMAWeightType, CoMMAIntType>(
352 nb_c, m_crs_row_ptr, m_crs_col_ind, m_crs_values, volumes
359 for (
auto c =
decltype(nb_c){0}; c < nb_c; ++c) {
360 const auto n_neighs =
361 static_cast<CoMMAIntType
>(m_crs_row_ptr[c + 1] - m_crs_row_ptr[c]);
400 const CoMMAIndexType &i_fc,
401 const CoMMAWeightType &volume,
409 for (
const auto &elem : v_neigh) {
417 CoMMAIntType iter_weight = 0;
424 for (
const auto &elem : v_l_neigh) {
430 this->
_m_CRS_Col_Ind.begin() + this->_m_CRS_Row_Ptr[elem], local_index
439 it != this->_m_CRS_Row_Ptr.end();
471 for (
const auto &elem : v_neigh) {
475 for (
auto it = pos_col + ind; it != pos_col + ind_p_one; ++it) {
483 it_bis != this->_m_CRS_Row_Ptr.end();
485 *it_bis = *it_bis - 1;
494 for (
auto it = pos_col + ind; it != pos_col + ind_p_one; ++it) {
501 it_bis != this->_m_CRS_Row_Ptr.end();
503 *it_bis = *it_bis - 1;
510 auto volumes_pointer = this->
_volumes.begin() + i_fc;
511 this->
_volumes.erase(volumes_pointer);
517 std::vector<std::optional<CoMMAIndexType>> internal_mapping;
519 CoMMAIndexType indice = 0;
523 if (
static_cast<decltype(i_fc)
>(ix) != i_fc) {
524 internal_mapping.push_back(indice);
527 internal_mapping.push_back(std::nullopt);
531 assert(internal_mapping[actual].has_value());
532 actual = internal_mapping[actual].value();
545 typename CoMMAIndexType,
546 typename CoMMAWeightType,
547 typename CoMMAIntType>
560 std::set<CoMMAPairType, CustomPairGreaterFunctor<CoMMAPairType>>;
578 const CoMMAIndexType &nb_c,
583 const std::vector<std::vector<CoMMAWeightType>> ¢ers,
584 const std::vector<CoMMAIntType> &n_bnd_faces,
585 const CoMMAIntType dimension,
588 Graph<CoMMAIndexType, CoMMAWeightType, CoMMAIntType>(
589 nb_c, m_crs_row_ptr, m_crs_col_ind, m_crs_values, volumes
593 anisotropic_compliant_fc.begin(), anisotropic_compliant_fc.end()
599 const CoMMAWeightType min_s,
const CoMMAWeightType max_s
600 ) -> CoMMAWeightType {
return max_s / min_s; }
602 const CoMMAWeightType min_s,
const CoMMAWeightType max_s
603 ) -> CoMMAWeightType {
return sqrt(max_s / min_s); };
620 const std::vector<std::vector<CoMMAWeightType>> &
_centers;
627 std::function<CoMMAWeightType(
const CoMMAWeightType,
const CoMMAWeightType)>
669 return this->_n_bnd_faces[idx_c] == 0 ? 0.
670 : this->_n_bnd_faces[idx_c]
677 * pow(std::accumulate(
709 const CoMMAIndexType &a,
710 const CoMMAIndexType &b,
711 std::vector<CoMMAWeightType> &dir
713 return get_direction<CoMMAWeightType>(
714 this->_centers[a], this->_centers[b], dir
740 std::vector<CoMMAWeightType> &alt_weights,
742 std::vector<bool> &is_anisotropic,
743 std::deque<CoMMAIndexType> &aniso_seeds_pool,
744 const CoMMAWeightType threshold_anisotropy,
747 const CoMMAIndexType preserving
752 std::fill(alt_weights.begin(), alt_weights.end(), 0.0);
755 if (threshold_anisotropy < 0) {
756 switch (cell_coupling) {
759 aniso_w_weights.emplace(i_fc, priority_weights[i_fc]);
760 max_weights[i_fc] = *(
768 aniso_w_weights.emplace(i_fc, priority_weights[i_fc]);
769 CoMMAWeightType max_ov_dist = 0.0;
772 auto w_it = std::next(alt_weights.begin(), offset);
775 / squared_euclidean_distance<CoMMAWeightType>(
776 this->_centers[i_fc], this->_centers[*n_it]
779 if (dist > max_ov_dist) max_ov_dist = dist;
781 max_weights[i_fc] = max_ov_dist;
791 CoMMAWeightType max_weight = 0.0;
792 CoMMAWeightType min_weight =
793 std::numeric_limits<CoMMAWeightType>::max();
807 if (max_weight < *w_it) {
810 if (min_weight > *w_it) {
818 const auto ar =
_compute_AR(min_weight, max_weight);
820 if (ar >= threshold_anisotropy) {
821 switch (preserving) {
824 || nb_neighbours == 4)
825 aniso_w_weights.emplace(i_fc, priority_weights[i_fc]);
829 || nb_neighbours == 6)
830 aniso_w_weights.emplace(i_fc, priority_weights[i_fc]);
835 aniso_w_weights.emplace(i_fc, priority_weights[i_fc]);
841 switch (cell_coupling) {
843 max_weights[i_fc] = max_weight;
849 auto w_it = std::next(alt_weights.begin(), offset);
850 CoMMAWeightType max_ov_dist = 0.0;
853 / squared_euclidean_distance<CoMMAWeightType>(
854 this->_centers[i_fc], this->_centers[*n_it]
857 if (dist > max_ov_dist) max_ov_dist = dist;
859 max_weights[i_fc] = max_ov_dist;
870 for (
const auto &[i_fc, w] : aniso_w_weights) {
871 is_anisotropic[i_fc] =
true;
872 aniso_seeds_pool.emplace_back(i_fc);
890 const std::unordered_set<CoMMAIndexType> &s_seeds,
891 const std::vector<bool> &is_fc_agglomerated_tmp
893 std::unordered_set<CoMMAIndexType> cc_neighs{};
894 for (
const auto fc : s_seeds)
897 if (!is_fc_agglomerated_tmp[*n] && s_seeds.find(*n) == s_seeds.end())
899 cc_neighs.insert(*n);
918 const std::unordered_set<CoMMAIndexType> &s_seeds,
919 CoMMAIntType &nb_of_order_of_neighbourhood,
920 std::unordered_map<CoMMAIndexType, CoMMAIntType> &d_n_of_seed,
921 const CoMMAIntType max_card,
922 const std::vector<bool> &is_fc_agglomerated_tmp
925 assert(max_card > 1);
927 std::unordered_map<CoMMAIndexType, CoMMAIntType> d_n_of_order_o_m_one;
929 for (
const CoMMAIndexType &i_fc : s_seeds) {
930 d_n_of_order_o_m_one[i_fc] = 0;
933 CoMMAIntType i_order = 1;
935 while ((i_order < nb_of_order_of_neighbourhood + 1)
936 ||
static_cast<CoMMAIntType
>(
937 d_n_of_seed.size() + d_n_of_order_o_m_one.size()
940 std::unordered_map<CoMMAIndexType, CoMMAIntType> d_n_of_order_o;
943 for (
auto id_M_one : d_n_of_order_o_m_one) {
944 d_n_of_seed[id_M_one.first] = id_M_one.second;
947 for (
const auto &i_k_v : d_n_of_order_o_m_one) {
950 CoMMAIndexType seed_tmp = i_k_v.first;
957 if ((d_n_of_seed.count(*i_fc_n) == 0)
958 && ((!is_fc_agglomerated_tmp[*i_fc_n]))) {
961 if (d_n_of_order_o.count(*i_fc_n) == 0) {
964 if (d_n_of_order_o_m_one.count(*i_fc_n)) {
967 if (i_order < d_n_of_order_o_m_one[*i_fc_n]) {
970 d_n_of_order_o[*i_fc_n] = i_order;
974 d_n_of_order_o[*i_fc_n] = i_order;
982 if (d_n_of_order_o.empty()) {
988 d_n_of_order_o_m_one.clear();
989 for (
auto id : d_n_of_order_o) {
990 d_n_of_order_o_m_one[
id.first] =
id.second;
996 for (
auto id_M_one : d_n_of_order_o_m_one) {
997 d_n_of_seed[id_M_one.first] = id_M_one.second;
1001 for (
const CoMMAIndexType &i_fc : s_seeds) {
1002 d_n_of_seed.erase(i_fc);
1005 nb_of_order_of_neighbourhood = i_order;
A class implementing the CRS global graph representation of the global mesh.
Definition: Dual_Graph.h:548
CoMMAIntType get_n_boundary_faces(const CoMMAIndexType idx_c) const
Return how many boundary faces a certain cell has.
Definition: Dual_Graph.h:634
void compute_neighbourhood_of_cc(const std::unordered_set< CoMMAIndexType > &s_seeds, CoMMAIntType &nb_of_order_of_neighbourhood, std::unordered_map< CoMMAIndexType, CoMMAIntType > &d_n_of_seed, const CoMMAIntType max_card, const std::vector< bool > &is_fc_agglomerated_tmp) const
Compute the dictionary of compactness of fine cells inside a coarse cell.
Definition: Dual_Graph.h:917
bool is_on_boundary(const CoMMAIndexType idx_c) const
Whether a cell is on the boundary.
Definition: Dual_Graph.h:651
CoMMAIntType get_total_n_faces(const CoMMAIndexType idx_c) const
Return total number of faces, that is, number of neighbours plus number of boundaries.
Definition: Dual_Graph.h:643
const std::vector< std::vector< CoMMAWeightType > > & _centers
Vector of cell centers.
Definition: Dual_Graph.h:620
CoMMAWeightType estimated_total_weight(const CoMMAIndexType idx_c) const
Sum of wall the weights (faces) of a cell. Since there is no knowledge about boundary faces,...
Definition: Dual_Graph.h:693
Dual_Graph(const CoMMAIndexType &nb_c, const ContainerIndexType &m_crs_row_ptr, const ContainerIndexType &m_crs_col_ind, const ContainerWeightType &m_crs_values, const ContainerWeightType &volumes, const std::vector< std::vector< CoMMAWeightType > > ¢ers, const std::vector< CoMMAIntType > &n_bnd_faces, const CoMMAIntType dimension, const ContainerIndexType &anisotropic_compliant_fc)
Constructor of the class.
Definition: Dual_Graph.h:577
void tag_anisotropic_cells(std::vector< CoMMAWeightType > &alt_weights, ContainerWeightType &max_weights, std::vector< bool > &is_anisotropic, std::deque< CoMMAIndexType > &aniso_seeds_pool, const CoMMAWeightType threshold_anisotropy, const ContainerWeightType &priority_weights, const CoMMACellCouplingT cell_coupling, const CoMMAIndexType preserving)
Tag cells as anisotropic if their aspect-ratio is over a given threshold and order them according to ...
Definition: Dual_Graph.h:739
CoMMAIndexType get_nb_cells() const
Getter that returns the number of cells.
Definition: Dual_Graph.h:879
std::unordered_set< CoMMAIndexType > get_neighbourhood_of_cc(const std::unordered_set< CoMMAIndexType > &s_seeds, const std::vector< bool > &is_fc_agglomerated_tmp) const
Get the fine cells neighbours of a coarse cell.
Definition: Dual_Graph.h:889
std::pair< CoMMAIndexType, CoMMAWeightType > CoMMAPairType
Type of pair.
Definition: Dual_Graph.h:557
const std::vector< CoMMAIntType > & _n_bnd_faces
Vector telling how many boundary faces each cell has.
Definition: Dual_Graph.h:610
CoMMAWeightType get_center_direction(const CoMMAIndexType &a, const CoMMAIndexType &b, std::vector< CoMMAWeightType > &dir)
Compute the direction from vertex a to vertex b and store it as unit vector in dir.
Definition: Dual_Graph.h:708
std::vector< CoMMAWeightType > ContainerWeightType
Type for containers of weights.
Definition: Dual_Graph.h:51
std::vector< CoMMAIndexType > ContainerIndexType
Type for containers of indices.
Definition: Dual_Graph.h:49
std::set< CoMMAPairType, CustomPairGreaterFunctor< CoMMAPairType > > CoMMASetOfPairType
Type of set of pairs.
Definition: Dual_Graph.h:560
~Dual_Graph() override=default
Destructor of the class.
std::function< CoMMAWeightType(const CoMMAWeightType, const CoMMAWeightType)> _compute_AR
Function which computes the aspect-ratio from the minimum and maximum faces In 3D: In 2D: (Recal...
Definition: Dual_Graph.h:628
const std::unordered_set< CoMMAIndexType > _s_anisotropic_compliant_cells
Elements that are checked if they are anisotropic. If an element satisfies the condition for being an...
Definition: Dual_Graph.h:617
CoMMAWeightType estimated_boundary_weight(const CoMMAIndexType idx_c) const
Approximate the value of a boundary face using the known internal faces. It uses a (geometric) averag...
Definition: Dual_Graph.h:661
An interface class responsible of storing the cell centered dual graph and of acting on it (it is an ...
Definition: Dual_Graph.h:46
ContainerWeightConstIt weights_cbegin(const CoMMAIndexType &i_c) const
Get constant pointer to the first neighbour of cell i_c.
Definition: Dual_Graph.h:221
ContainerWeightType _m_CRS_Values
Vector of area weight of CRS representation.
Definition: Dual_Graph.h:99
void DFS(const CoMMAIndexType &i_fc)
Depth First Search (DFS) recursive function.
Definition: Dual_Graph.h:107
Graph(const CoMMAIndexType &nb_c, const ContainerIndexType &m_crs_row_ptr, const ContainerIndexType &m_crs_col_ind, const ContainerWeightType &m_crs_values, const ContainerWeightType &volumes)
Constructor of the class.
Definition: Dual_Graph.h:66
ContainerIndexType get_neighbours(const CoMMAIndexType &i_c) const
Based on the CRS representation retrieves the neighbours of the cell given as an input.
Definition: Dual_Graph.h:166
typename ContainerWeightType::const_iterator ContainerWeightConstIt
Type for constant iterators of containers of weights.
Definition: Dual_Graph.h:55
ContainerIndexConstIt neighbours_cend(const CoMMAIndexType &i_c) const
Get constant pointer to the element following the last neighbour of cell i_c.
Definition: Dual_Graph.h:193
CoMMAIntType compute_min_fc_compactness_inside_a_cc(const std::unordered_set< CoMMAIndexType > &s_fc) const
Compute the minimum compactness of fine cells inside a coarse cell.
Definition: Dual_Graph.h:258
std::unordered_map< CoMMAIndexType, CoMMAIntType > compute_fc_compactness_inside_a_cc(const std::unordered_set< CoMMAIndexType > &s_fc) const
Compute the dictionary of compactness of fine cells inside a coarse cell.
Definition: Dual_Graph.h:287
CoMMAIntType get_nb_of_neighbours(const CoMMAIndexType i_c) const
Retrieve the number of neighbours.
Definition: Dual_Graph.h:156
typename ContainerIndexType::const_iterator ContainerIndexConstIt
Type for constant iterators of containers of indices.
Definition: Dual_Graph.h:53
ContainerIndexType _m_CRS_Row_Ptr
Vector of row pointer of CRS representation.
Definition: Dual_Graph.h:93
bool check_connectivity()
Check the connectivity of the graph.
Definition: Dual_Graph.h:238
ContainerWeightConstIt weights_cend(const CoMMAIndexType &i_c) const
Get constant pointer to the element following the last neighbour of cell i_c.
Definition: Dual_Graph.h:231
ContainerIndexType _m_CRS_Col_Ind
Vector of column index of CRS representation.
Definition: Dual_Graph.h:96
std::vector< CoMMAWeightType > ContainerWeightType
Type for containers of weights.
Definition: Dual_Graph.h:51
std::vector< CoMMAIndexType > ContainerIndexType
Type for containers of indices.
Definition: Dual_Graph.h:49
CoMMAIndexType _number_of_cells
Number of nodes in the Graph (it corresponds to the number of cells in the subgraph or the dual graph...
Definition: Dual_Graph.h:87
virtual ~Graph()=default
Destructor of the class.
ContainerWeightType _volumes
Vector of volumes.
Definition: Dual_Graph.h:102
ContainerIndexConstIt neighbours_cbegin(const CoMMAIndexType &i_c) const
Get constant pointer to the first neighbour of cell i_c.
Definition: Dual_Graph.h:183
ContainerWeightType get_weights(const CoMMAIndexType &i_c) const
Based on the area of the faces composing the cell given as an input, we retrieve the faces connecting...
Definition: Dual_Graph.h:204
std::vector< bool > _visited
Helper vector for the DFS.
Definition: Dual_Graph.h:90
void BFS(const CoMMAIndexType &root)
Breadth First Search (BFS) function.
Definition: Dual_Graph.h:119
A class implementing the CRS subgraph representation. It is used in the framework of CoMMA for the im...
Definition: Dual_Graph.h:320
bool _is_isotropic
Whether it originates from an isotropic cell.
Definition: Dual_Graph.h:372
CoMMAIntType _compactness
Compactness of the given subgraph. The compactness is the minimum number of internal neighbours.
Definition: Dual_Graph.h:382
~Subgraph() override=default
Destructor of the class.
void insert_node(const ContainerIndexType &v_neigh, const CoMMAIndexType &i_fc, const CoMMAWeightType &volume, const ContainerWeightType &weight)
Insert a node in the subgraph and add it to the mapping the.
Definition: Dual_Graph.h:398
ContainerIndexType _mapping_l_to_g
Mapping from the local number of node to the global. Being a subgraph this variable connect the local...
Definition: Dual_Graph.h:388
Subgraph(const CoMMAIndexType &nb_c, const ContainerIndexType &m_crs_row_ptr, const ContainerIndexType &m_crs_col_ind, const ContainerWeightType &m_crs_values, const ContainerWeightType &volumes, const ContainerIndexType &mapping_l_to_g, const bool &is_isotropic)
Constructor of the class.
Definition: Dual_Graph.h:342
CoMMAIntType _cardinality
Cardinality of the given subgraph, alias the number of nodes contained.
Definition: Dual_Graph.h:377
std::vector< CoMMAWeightType > ContainerWeightType
Type for containers of weights.
Definition: Dual_Graph.h:51
void remove_node(const CoMMAIndexType &elemento)
Remove a node from the CRS representation and automatically adjust the mapping.
Definition: Dual_Graph.h:460
std::vector< CoMMAIndexType > ContainerIndexType
Type for containers of indices.
Definition: Dual_Graph.h:49
Definition: Agglomerator.h:37
CoMMACellCouplingT
Type of coupling between cells in an anisotropic line.
Definition: CoMMADefs.h:103
@ MIN_DISTANCE
Definition: CoMMADefs.h:107
@ MAX_WEIGHT
Definition: CoMMADefs.h:105