1#ifndef COMMA_PROJECT_UTIL_H
2#define COMMA_PROJECT_UTIL_H
26#include <unordered_map>
27#include <unordered_set>
38#define CoMMAUnused(var) (void)(var)
51inline T
constexpr _sq(
const T x) {
61inline T
constexpr _cb(
const T x) {
71template<
unsigned int p,
typename T>
74 if constexpr (p == 0)
return 1;
75 if constexpr (p == 1)
return x;
76 if constexpr (p == 2)
return x * x;
77 if constexpr (p == 3)
return x * x * x;
80 if constexpr ((p % 2) == 0) {
106inline T
dot_product(
const std::vector<T> &a,
const std::vector<T> &b) {
108 const CoMMAWeightType dot = inner_product(
109 prev_dir.begin(), prev_dir.end(), cur_dir.begin(),
110 CoMMAWeightType{0.});
113 for (
auto i =
decltype(a.size()){0}; i < a.size(); ++i)
129 const std::vector<T> &a,
const std::vector<T> &b, std::vector<T> &dir
132 for (
auto i =
decltype(a.size()){0}; i < a.size(); ++i) {
133 const T di = b[i] - a[i];
138 const T ov_norm = T{1.} / norm;
156 const std::vector<T> &a,
const std::vector<T> &b
160 transform_reduce(a.cbegin(), a.cend(), b.cbegin(), T{0.},
161 [](
const auto sum,
const auto val){return sum + val*val;},
165 for (
auto i =
decltype(a.size()){0}; i < a.size(); ++i) {
166 const auto diff = a[i] - b[i];
187 inline bool operator()(
const PairT &left,
const PairT &right)
const {
188 if (left.second < right.second)
return true;
189 if (left.second > right.second)
return false;
191 return left.first > right.first;
200template<
typename PairT>
210 inline bool operator()(
const PairT &left,
const PairT &right)
const {
213 if (left.second > right.second)
return true;
214 if (left.second < right.second)
return false;
216 return left.first < right.first;
224template<
typename PairT>
232 inline bool operator()(
const PairT &left,
const PairT &right)
const {
233 return left.second < right.second;
243template<
typename CoMMAContainerPairType>
244inline std::vector<typename CoMMAContainerPairType::value_type::first_type>
246 std::vector<typename CoMMAContainerPairType::value_type::first_type> fe;
247 fe.reserve(cont.size());
248 for (
const auto &pr : cont)
249 fe.emplace_back(pr.first);
257template<
typename PairT>
277 inline bool operator()(
const PairT &pr)
const {
return pr.first == _target; }
281 typename PairT::first_type _target;
290template<
typename KeyT,
typename ValueT>
292 const std::unordered_map<KeyT, ValueT> &dict
294 std::unordered_set<KeyT> s_neighbours_of_seed = {};
295 for (
const auto &i_k_v : dict) {
296 s_neighbours_of_seed.insert(i_k_v.first);
298 return s_neighbours_of_seed;
310template<
typename IndexT,
typename IntT>
312 const std::vector<IndexT> &indices,
313 const std::vector<IntT> &n_bnd_faces,
314 const std::unordered_set<IntT> &allowed,
315 std::vector<IndexT> &filtered
318 auto target =
decltype(allowed){};
322 std::inserter(target, target.begin()),
323 [](
const auto n) { return n > 0; }
325 if (!target.empty()) {
326 const auto n_cells =
static_cast<IndexT
>(n_bnd_faces.size());
327 filtered.reserve(n_cells);
328 for (
auto c =
decltype(n_cells){0}; c < n_cells; ++c) {
330 static_cast<IntT
>(indices[c + 1] - indices[c] + n_bnd_faces[c])
333 filtered.emplace_back(c);
335 filtered.shrink_to_fit();
360template<
typename IndexT,
typename DistT>
362 const std::vector<IndexT> &neigh_idxs,
363 const std::vector<IndexT> &neighs,
364 const std::vector<IndexT> &wall,
365 std::vector<DistT> &dist
368 std::is_signed<DistT>::value,
369 "The distance type should be signed to allow flags (negative values)"
371 dist.resize(neigh_idxs.size() - 1);
372 std::fill(dist.begin(), dist.end(), DistT{-1});
373 std::queue<IndexT> to_visit{};
374 for (
const auto &cell : wall) {
375 dist[cell] = DistT{0};
376 to_visit.emplace(cell);
378 while (!to_visit.empty()) {
385 const auto cur = to_visit.front();
387 const auto cur_dist = dist[cur] + DistT{1};
388 for (
auto neigh = neighs.cbegin() + neigh_idxs[cur];
389 neigh < neighs.cbegin() + neigh_idxs[cur + 1];
391 if (dist[*neigh] < DistT{0}) {
392 dist[*neigh] = cur_dist;
393 to_visit.emplace(*neigh);
394 }
else if (dist[*neigh] > cur_dist) {
395 dist[*neigh] = cur_dist;
423template<
typename IndexT,
typename RealT,
typename IntT>
425 const std::vector<IndexT> &f2c,
426 const std::vector<IndexT> &f_adj_idx,
427 const std::vector<IndexT> &f_adj,
428 const std::vector<RealT> &f_weights,
429 const std::vector<RealT> &f_volumes,
430 const std::vector<std::vector<RealT>> &f_centers,
431 const std::vector<RealT> &f_priority,
432 const std::vector<IntT> &f_n_bnd,
434 std::vector<IndexT> &c_adj_idx,
435 std::vector<IndexT> &c_adj,
436 std::vector<RealT> &c_weights,
437 std::vector<RealT> &c_volumes,
438 std::vector<std::vector<RealT>> &c_centers,
439 std::vector<RealT> &c_priority,
440 std::vector<IntT> &c_n_bnd
442 const auto n_cells = *(std::max_element(f2c.begin(), f2c.end())) + 1;
443 const auto dim =
static_cast<IntT
>(f_centers[0].size());
446 c_adj_idx.emplace_back(0);
451 c_volumes.resize(n_cells);
452 std::fill(c_volumes.begin(), c_volumes.end(), RealT{0});
454 c_n_bnd.resize(n_cells);
456 c_priority.resize(n_cells);
457 std::fill(c_n_bnd.begin(), c_n_bnd.end(), IntT{0});
459 c_centers.reserve(n_cells);
460 for (
auto cc =
decltype(n_cells){0}; cc < n_cells; ++cc) {
462 auto tmp = std::vector<RealT>(dim, RealT{0});
463 c_centers.emplace_back(std::move(tmp));
467 std::vector<std::set<IndexT>> c2f(n_cells);
468 for (
auto fc =
decltype(f2c.size()){0}; fc < f2c.size(); ++fc) {
469 const auto cc = f2c[fc];
473 c_volumes[cc] += f_volumes[fc];
475 for (
auto xyz =
decltype(dim){0}; xyz < dim; ++xyz)
476 c_centers[cc][xyz] += f_volumes[fc] * f_centers[fc][xyz];
478 for (
auto cc =
decltype(n_cells){0}; cc < n_cells; ++cc) {
479 const auto &fcs = c2f[cc];
480 const RealT ov_n_fc(RealT{1.} / fcs.size());
482 for (
auto xyz =
decltype(dim){0}; xyz < dim; ++xyz)
483 c_centers[cc][xyz] *= ov_n_fc;
484 auto n_bnd = std::numeric_limits<IntT>::min();
485 auto priority = std::numeric_limits<RealT>::min();
486 std::map<IndexT, RealT> cc_neighs;
487 for (
const auto fc : fcs) {
488 if (f_n_bnd[fc] > n_bnd) n_bnd = f_n_bnd[fc];
489 if (f_priority[fc] > priority) priority = f_priority[fc];
490 for (
auto fc_neigh = f_adj.cbegin() + f_adj_idx[fc];
491 fc_neigh != f_adj.cbegin() + f_adj_idx[fc + 1];
494 if (fcs.find(*fc_neigh) == fcs.end()) {
495 const auto cc_neigh = f2c[*fc_neigh];
497 cc_neighs.try_emplace(cc_neigh, 0.0);
498 cc_neighs.at(cc_neigh) += f_weights[*fc_neigh];
504 c_priority[cc] = priority;
505 c_adj_idx.emplace_back(c_adj_idx.back() + cc_neighs.size());
506 for (
const auto &[neigh, weight] : cc_neighs) {
507 c_adj.emplace_back(neigh);
508 c_weights.emplace_back(weight);
Functor implementing an operator telling if a given value if the first one of pair.
Definition: Util.h:258
bool operator()(const PairT &pr) const
Operator telling if the first value of the given pair is equal to the reference one.
Definition: Util.h:277
~PairFindFirstBasedFunctor()=default
Destructor.
PairFindFirstBasedFunctor()
Constructor.
Definition: Util.h:261
PairFindFirstBasedFunctor(const typename PairT::first_type &target)
Constructor.
Definition: Util.h:267
Definition: Agglomerator.h:37
void build_coarse_graph(const std::vector< IndexT > &f2c, const std::vector< IndexT > &f_adj_idx, const std::vector< IndexT > &f_adj, const std::vector< RealT > &f_weights, const std::vector< RealT > &f_volumes, const std::vector< std::vector< RealT > > &f_centers, const std::vector< RealT > &f_priority, const std::vector< IntT > &f_n_bnd, std::vector< IndexT > &c_adj_idx, std::vector< IndexT > &c_adj, std::vector< RealT > &c_weights, std::vector< RealT > &c_volumes, std::vector< std::vector< RealT > > &c_centers, std::vector< RealT > &c_priority, std::vector< IntT > &c_n_bnd)
Build a coarse graph from the fine graph and the result of a previous agglomeration.
Definition: Util.h:424
T constexpr _cb(const T x)
Cube.
Definition: Util.h:61
T dot_product(const std::vector< T > &a, const std::vector< T > &b)
Compute the dot product between two vectors. No check on size is performed.
Definition: Util.h:106
T squared_euclidean_distance(const std::vector< T > &a, const std::vector< T > &b)
Compute the squared Euclidean distance between two points seen as vectors. We use vectors because we ...
Definition: Util.h:155
bool constexpr dot_deviate(const T dot)
Tell whether the dot product given as input comes from two parallel vectors. Compared against deviate...
Definition: Util.h:94
T get_direction(const std::vector< T > &a, const std::vector< T > &b, std::vector< T > &dir)
Compute the direction from point a to point b and store it as unit vector in dir.
Definition: Util.h:128
T constexpr _sq(const T x)
Square.
Definition: Util.h:51
void filter_cells_by_n_edges(const std::vector< IndexT > &indices, const std::vector< IntT > &n_bnd_faces, const std::unordered_set< IntT > &allowed, std::vector< IndexT > &filtered)
Given the connectivity of the graph, filter cells keeping only those with the desired number of edges...
Definition: Util.h:311
constexpr double deviate_thresh
Threshold used in combination with a dot product to tell whether two vector deviate....
Definition: Util.h:43
std::unordered_set< KeyT > d_keys_to_set(const std::unordered_map< KeyT, ValueT > &dict)
Utility function for creating a set out of the keys of a map.
Definition: Util.h:291
std::vector< typename CoMMAContainerPairType::value_type::first_type > vector_of_first_elements(const CoMMAContainerPairType &cont)
Given a container of pairs, return a vector with first elements only.
Definition: Util.h:245
T constexpr int_power(const T x)
Raise a quantity to an integer power.
Definition: Util.h:72
void compute_neighbourhood_based_wall_distance(const std::vector< IndexT > &neigh_idxs, const std::vector< IndexT > &neighs, const std::vector< IndexT > &wall, std::vector< DistT > &dist)
Compute a neighbourhood-base wall-distance, that is, the distance of a given cell from a wall is the ...
Definition: Util.h:361
Functor for pairs implementing a custom 'greater than'. It relies on the 'greater than' operator for ...
Definition: Util.h:201
bool operator()(const PairT &left, const PairT &right) const
Functor for pairs implementing a custom 'greater than'. It relies on the 'greater than' operator for ...
Definition: Util.h:210
Functor for pairs implementing a custom 'less than'. It relies on the 'less than' operator for the se...
Definition: Util.h:178
bool operator()(const PairT &left, const PairT &right) const
Functor for pairs implementing a custom 'less than'. It relies on the 'less than' operator for the se...
Definition: Util.h:187
Functor for pairs implementing a less operator based only on the second element of the pair.
Definition: Util.h:225
bool operator()(const PairT &left, const PairT &right) const
Functor for pairs implementing a less operator based only on the second element of the pair.
Definition: Util.h:232