1#ifndef COMMA_PROJECT_COMMA_H
2#define COMMA_PROJECT_COMMA_H
24#include <unordered_set>
37#define CHECK_INT_TYPE(intT, label) \
39 std::numeric_limits<intT>::is_integer, \
40 "CoMMA works with integer types, but " #intT " (" label ") is not" \
134 typename CoMMAIndexType,
135 typename CoMMAWeightType,
136 typename CoMMAIntType>
139 const std::vector<CoMMAIndexType> &adjMatrix_row_ptr,
140 const std::vector<CoMMAIndexType> &adjMatrix_col_ind,
141 const std::vector<CoMMAWeightType> &adjMatrix_areaValues,
142 const std::vector<CoMMAWeightType> &volumes,
145 const std::vector<std::vector<CoMMAWeightType>> ¢ers,
146 const std::vector<CoMMAWeightType> &priority_weights,
147 const std::vector<CoMMAIndexType> &anisotropicCompliantCells,
148 const std::vector<CoMMAIntType> &n_bnd_faces,
151 bool build_anisotropic_lines,
153 bool odd_line_length,
154 CoMMAWeightType threshold_anisotropy,
160 std::vector<CoMMAIndexType> &fc_to_cc,
161 std::vector<CoMMAIndexType> &agglomerationLines_Idx,
162 std::vector<CoMMAIndexType> &agglomerationLines,
166 CoMMAIntType dimension,
167 CoMMAIntType goal_card,
168 CoMMAIntType min_card,
169 CoMMAIntType max_card,
171 CoMMAIntType singular_card_thresh = 1,
172 std::optional<CoMMAIndexType> max_cells_in_line = std::nullopt,
174 bool force_line_direction =
true,
175 CoMMAIntType fc_choice_iter = 1,
185 using SeedsPoolType =
187 using DualGraphType =
189 using CCContainerType =
191 using IsotropicPtr = std::unique_ptr<
196 CHECK_INT_TYPE(CoMMAIndexType,
"first template argument");
197 CHECK_INT_TYPE(CoMMAIntType,
"third template argument");
198 if (!(dimension == 2 || dimension == 3))
199 throw std::invalid_argument(
"CoMMA - Error: dimension must be 2 or 3");
200 if (min_card <= 1 || goal_card <= 1 || max_card <= 1)
201 throw std::invalid_argument(
202 "CoMMA - Error: Cardinalities must be greater than 1"
204 if (!(min_card <= goal_card && goal_card <= max_card))
205 throw std::invalid_argument(
206 "CoMMA - Error: Cardinalities must be in order (min <= goal <= max)"
208 if (fc_choice_iter < 1)
209 throw std::invalid_argument(
210 "CoMMA - Error: the number of iteration for the choice of the fine "
211 "cells must be at least 1"
214 throw std::invalid_argument(
215 "CoMMA - Error: the number of iteration for the choice of the fine "
216 "cells must be at most "
219 if (adjMatrix_row_ptr.empty()
220 || adjMatrix_row_ptr.back()
221 !=
static_cast<CoMMAIndexType
>(adjMatrix_col_ind.size())
222 || adjMatrix_row_ptr.back()
223 !=
static_cast<CoMMAIndexType
>(adjMatrix_areaValues.size()))
224 throw std::invalid_argument(
225 "CoMMA - Error: bad CRS graph (sizes do not match)"
227 if (is_anisotropic) {
228 if (build_anisotropic_lines) {
229 if (anisotropicCompliantCells.empty()) {
230 std::cout <<
"CoMMA - Warning: building anisotropic line requested, no "
231 "compliant cells provided. Switching off anisotropy."
234 if (max_cells_in_line.has_value() && max_cells_in_line.value() <= 0) {
235 std::cout <<
"CoMMA - Requested a negative or null maximum number of "
236 "cells in line. Dropping the limit."
238 max_cells_in_line = std::nullopt;
240 switch (aniso_cell_coupling) {
246 std::cout <<
"CoMMA - Warning: Unknown anisotropic cell coupling."
247 " Switching it to: max weight."
253 if (agglomerationLines_Idx.size() < 2 || agglomerationLines.empty()) {
255 <<
"CoMMA - Warning: usage of input anisotropic line requested, "
256 "but arguments are not enough / invalid to define them. "
257 "Switching off anisotropy."
259 is_anisotropic =
false;
260 }
else if (agglomerationLines_Idx.back()
261 !=
static_cast<CoMMAIndexType
>(agglomerationLines.size())) {
262 throw std::invalid_argument(
263 "CoMMA - Error: bad anisotropic lines definition (sizes do not "
269 auto sing_thresh = singular_card_thresh;
270 if (singular_card_thresh <= 0) {
271 throw std::invalid_argument(
272 "CoMMA - Error: Threshold cardinality for singular cells should be "
276 if (singular_card_thresh >= min_card) {
278 <<
"CoMMA - Warning: Threshold cardinality is equal or larger than "
279 "minimum cardinality. Changing it to this latter value."
281 sing_thresh = min_card - 1;
286 const auto nb_fc =
static_cast<CoMMAIndexType
>(adjMatrix_row_ptr.size() - 1);
292 const CoMMAIntType expected_max_n_bnd = dimension;
293 std::vector<CoMMAIntType> fixed_n_bnd_faces(n_bnd_faces.size());
294 std::replace_copy_if(
297 fixed_n_bnd_faces.begin(),
298 [expected_max_n_bnd](
auto n) { return n > expected_max_n_bnd; },
305 std::shared_ptr<SeedsPoolType> seeds_pool =
nullptr;
306 switch (seed_ordering_type) {
311 CoMMAIntType>>(fixed_n_bnd_faces, priority_weights,
false);
317 CoMMAIntType>>(fixed_n_bnd_faces, priority_weights,
false);
323 CoMMAIntType>>(fixed_n_bnd_faces, priority_weights,
true);
329 CoMMAIntType>>(fixed_n_bnd_faces, priority_weights,
true);
332 throw std::invalid_argument(
"CoMMA - Error: Seeds pool type unsupported");
339 std::shared_ptr<DualGraphType> fc_graph = std::make_shared<DualGraphType>(
343 adjMatrix_areaValues,
348 anisotropicCompliantCells
354 std::shared_ptr<CCContainerType> cc_graph =
355 std::make_shared<CCContainerType>(fc_graph, sing_thresh);
368 if (is_anisotropic) {
376 threshold_anisotropy,
377 agglomerationLines_Idx,
380 build_anisotropic_lines,
389 goal_card, min_card, max_card, priority_weights,
false
396 1, agglomerationLines_Idx, agglomerationLines
399 seeds_pool->initialize();
405 IsotropicPtr agg =
nullptr;
407 if (fc_choice_iter > 1) {
408 agg = std::make_unique<
419 agg = std::make_unique<
432 goal_card, min_card, max_card, priority_weights, correction
437 fc_to_cc.reserve(cc_graph->_fc_2_cc.size());
439 cc_graph->_fc_2_cc.begin(),
440 cc_graph->_fc_2_cc.end(),
441 std::back_inserter(fc_to_cc),
442 [](
const auto &f2c) { return f2c.value(); }
472 typename CoMMAIndexType,
473 typename CoMMAWeightType,
474 typename CoMMAIntType>
479 std::vector<CoMMAIndexType> &fc_to_cc,
480 std::vector<CoMMAIndexType> &aniso_lines_indices,
481 std::vector<CoMMAIndexType> &aniso_lines
483 agglomerate_one_level<CoMMAIndexType, CoMMAWeightType, CoMMAIntType>(
Convenient class holding arguments for the parametrization of the agglomeration algorithm.
Definition: Args.h:99
CoMMAIntType goal_card
Desired cardinality of the coarse cells.
Definition: Args.h:102
CoMMASeedsPoolT seed_ordering_type
Type of ordering for the seeds of the coarse cells (see CoMMASeedsPoolT)
Definition: Args.h:114
CoMMANeighbourhoodT neighbourhood_type
Type of neighbourhood to use when growing a coarse cell. See CoMMANeighbourhoodT for more details.
Definition: Args.h:127
CoMMAIntType min_card
Minimum cardinality accepted for the coarse cells.
Definition: Args.h:104
CoMMAAspectRatioT aspect_ratio
Type of aspect ratio.
Definition: Args.h:116
bool correction
Whether to apply correction step (avoid isolated cells) after agglomeration.
Definition: Args.h:110
CoMMAIntType singular_card_thresh
Cardinality below which a coarse is considered as singular, hence, compliant for correction.
Definition: Args.h:119
CoMMAIntType fc_choice_iter
Number of iterations allowed for the algorithm choosing which fine cell to add next....
Definition: Args.h:123
CoMMAIntType max_card
Maximum cardinality accepted for the coarse cells.
Definition: Args.h:106
Agglomerator_Anisotropic class is a child class of the Agglomerator class that specializes the implem...
Definition: Agglomerator.h:174
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
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
Child class of Agglomerator_Isotropic where is implemented a specific biconnected algorithm for the a...
Definition: Agglomerator.h:1169
Agglomerator_Isotropic class is a child class of the Agglomerator class that specializes the implemen...
Definition: Agglomerator.h:852
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
Child class of Agglomerator_Isotropic which implements a specialized iterative algorithm for the sear...
Definition: Agglomerator.h:1602
Convenient class holding arguments for the parametrization of the anisotropic agglomeration algorithm...
Definition: Args.h:184
CoMMACellCouplingT cell_coupling
Type of coupling to consider when building lines.
Definition: Args.h:201
std::optional< CoMMAIndexType > max_cells_in_line
Maximum number of cells in an anisotropic line.
Definition: Args.h:199
bool is_anisotropic
Whether to consider an anisotropic agglomeration.
Definition: Args.h:187
bool build_lines
Whether lines joining the anisotropic cells should be built.
Definition: Args.h:191
bool line_direction
Whether to force the direction of the anisotropic lines to remain straight.
Definition: Args.h:205
CoMMAWeightType threshold_anisotropy
Value of the aspect-ratio above which a cell is considered as anisotropic.
Definition: Args.h:197
bool odd_line_length
Whether anisotropic lines with odd length are allowed.
Definition: Args.h:193
const std::vector< CoMMAIndexType > & anisotropicCompliantCells
List of cells which have to be looked for anisotropy.
Definition: Args.h:189
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
Convenient class holding arguments defining the graph.
Definition: Args.h:34
const std::vector< CoMMAWeightType > & priority_weights
Priority weights.
Definition: Args.h:47
const std::vector< CoMMAIndexType > & connectivity_indices
Indices of the CSR representation of the graph.
Definition: Args.h:37
const std::vector< CoMMAIndexType > & connectivity
Values of the CSR representation of the graph.
Definition: Args.h:39
const std::vector< CoMMAIntType > & n_bnd_faces
Number of boundary faces per cell.
Definition: Args.h:49
const std::vector< CoMMAWeightType > & volumes
Volumes of the cells.
Definition: Args.h:43
const std::vector< CoMMAWeightType > & connectivity_weights
Weights of the CSR representation of the graph.
Definition: Args.h:41
const std::vector< std::vector< CoMMAWeightType > > & centers
Centers of the cells.
Definition: Args.h:45
CoMMAIntType dimension
Dimensionality of the problem, 2- or 3D.
Definition: Args.h:51
Class representing the pool of all the seeds for creating a coarse cell. This derived class gives hig...
Definition: Seeds_Pool.h:452
Class representing the pool of all the seeds for creating a coarse cell. This derived class gives hig...
Definition: Seeds_Pool.h:612
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
@ DIAMETER_OVER_RADIUS
Definition: CoMMADefs.h:75
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
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
void agglomerate_one_level(const std::vector< CoMMAIndexType > &adjMatrix_row_ptr, const std::vector< CoMMAIndexType > &adjMatrix_col_ind, const std::vector< CoMMAWeightType > &adjMatrix_areaValues, const std::vector< CoMMAWeightType > &volumes, const std::vector< std::vector< CoMMAWeightType > > ¢ers, const std::vector< CoMMAWeightType > &priority_weights, const std::vector< CoMMAIndexType > &anisotropicCompliantCells, const std::vector< CoMMAIntType > &n_bnd_faces, bool build_anisotropic_lines, bool is_anisotropic, bool odd_line_length, CoMMAWeightType threshold_anisotropy, CoMMASeedsPoolT seed_ordering_type, std::vector< CoMMAIndexType > &fc_to_cc, std::vector< CoMMAIndexType > &agglomerationLines_Idx, std::vector< CoMMAIndexType > &agglomerationLines, bool correction, CoMMAIntType dimension, CoMMAIntType goal_card, CoMMAIntType min_card, CoMMAIntType max_card, CoMMAAspectRatioT aspect_ratio=CoMMAAspectRatioT::DIAMETER_OVER_RADIUS, CoMMAIntType singular_card_thresh=1, std::optional< CoMMAIndexType > max_cells_in_line=std::nullopt, CoMMACellCouplingT aniso_cell_coupling=CoMMACellCouplingT::MAX_WEIGHT, bool force_line_direction=true, CoMMAIntType fc_choice_iter=1, CoMMANeighbourhoodT neighbourhood_type=CoMMANeighbourhoodT::EXTENDED)
Main function of the agglomerator, it is used as an interface to build up all the agglomeration proce...
Definition: CoMMA.h:137
CoMMASeedsPoolT
Type of seeds pool ordering.
Definition: CoMMADefs.h:43
@ BOUNDARY_PRIORITY_ONE_POINT_INIT
Definition: CoMMADefs.h:53
@ BOUNDARY_PRIORITY
Definition: CoMMADefs.h:45
@ NEIGHBOURHOOD_PRIORITY_ONE_POINT_INIT
Definition: CoMMADefs.h:57
@ NEIGHBOURHOOD_PRIORITY
Definition: CoMMADefs.h:49
constexpr CoMMAIntT iter_agglo_max_iter
Maximum allowed iterations for the iterative algorithm, see Agglomerator_Iterative.
Definition: CoMMA.h:47