9#include <kernel/adjacency/coloring.hpp> 
   10#include <kernel/adjacency/cuthill_mckee.hpp> 
   11#include <kernel/adjacency/graph.hpp> 
   12#include <kernel/adjacency/permutation.hpp> 
   13#include <kernel/geometry/index_set.hpp> 
   14#include <kernel/geometry/target_set.hpp> 
   15#include <kernel/geometry/vertex_set.hpp> 
   30      template<
typename Shape_, 
int face_dim_ = Shape_::dimension-1>
 
   34        static void render(std::array<Adjacency::Graph, Shape_::dimension>& idx,
 
   35          const IndexSetWrapper<Shape_, face_dim_>& isw)
 
   37          ISWRenderer<Shape_, face_dim_-1>::render(idx, isw);
 
   38          idx.at(face_dim_) = Adjacency::Graph(Adjacency::RenderType::as_is,
 
   39            isw.template get_index_set<face_dim_>());
 
   43      template<
typename Shape_>
 
   44      class ISWRenderer<Shape_, 0>
 
   47        static void render(std::array<Adjacency::Graph, Shape_::dimension>& idx,
 
   48          const IndexSetWrapper<Shape_, 0>& isw)
 
   50          idx.at(0) = Adjacency::Graph(Adjacency::RenderType::as_is,
 
   51            isw.template get_index_set<0>());
 
   56      template<
typename Coord_, 
int dim_>
 
   63        Tiny::Vector<Coord_, dim_> v;
 
   66        static constexpr Coord_ tol_ = Coord_(1e-6);
 
   72        explicit LexiPoint(Index _idx) :
 
   79        explicit LexiPoint(Index _idx, 
const Tiny::Vector<Coord_, dim_, s_>& _vtx) :
 
   91        void add(
const Tiny::Vector<Coord_, dim_, s_>& vtx)
 
   96        bool operator<(
const LexiPoint& other)
 const 
   99          for(
int i(dim_-1); i > 0; --i)
 
  101            if(v[i] + tol_ < 
other.v[i])
 
  103            if(
other.v[i] + tol_ <= v[i])
 
  107          return v[0] < 
other.v[0];
 
  112      template<
typename Shape_, 
int shape_dim_ = Shape_::dimension>
 
  116        template<
int nc_, 
typename Coord_>
 
  118          std::array<Adjacency::Permutation, Shape_::dimension + 1>& perms,
 
  119          const IndexSetHolder<Shape_>& ish, 
const VertexSet<nc_, Coord_>& vtx)
 
  122          LexiPermuter<Shape_, shape_dim_-1>::compute(perms, ish, vtx);
 
  125          const auto& idx = ish.template get_index_set<shape_dim_, 0>();
 
  126          const Index n = idx.get_num_entities();
 
  127          const int nidx = idx.get_num_indices();
 
  129          std::vector<LexiPoint<Coord_, nc_>> vset(n);
 
  132          for(Index i(0); i < n; ++i)
 
  134            LexiPoint<Coord_, nc_> v(i);
 
  135            for(
int j(0); j < nidx; ++j)
 
  136              v.add(vtx[idx(i,j)]);
 
  141          std::sort(vset.begin(), vset.end());
 
  144          Adjacency::Permutation p(n);
 
  145          Index* vp = p.get_perm_pos();
 
  146          for(
auto it = vset.begin(); it != vset.end(); ++it, ++vp)
 
  148          p.calc_swap_from_perm();
 
  149          perms.at(shape_dim_) = std::move(p);
 
  154      template<
typename Shape_>
 
  155      class LexiPermuter<Shape_, 0>
 
  158        template<
int nc_, 
typename Coord_>
 
  160          std::array<Adjacency::Permutation, Shape_::dimension + 1>& perms,
 
  161          const IndexSetHolder<Shape_>&, 
const VertexSet<nc_, Coord_>& vtx)
 
  163          const Index n = vtx.get_num_vertices();
 
  164          std::vector<LexiPoint<Coord_, nc_>> vset(n);
 
  167          for(Index i(0); i < n; ++i)
 
  169            vset.at(i) = LexiPoint<Coord_, nc_>(i, vtx[i]);
 
  173          std::sort(vset.begin(), vset.end());
 
  176          Adjacency::Permutation p(n);
 
  177          Index* vp = p.get_perm_pos();
 
  178          for(
auto it = vset.begin(); it != vset.end(); ++it, ++vp)
 
  180          p.calc_swap_from_perm();
 
  181          perms.front() = std::move(p);
 
  359    template<
typename Shape_>
 
  370      typedef std::array<Adjacency::Permutation, shape_dim+1> 
PermArray;
 
  405      template<
int num_coords_, 
typename Coord_>
 
  408        const IndexSetHolder<Shape_>& ish,
 
  412        this->
create(strategy, ish, vtx);
 
  456        this->_strategy = 
other._strategy;
 
  457        for(std::size_t i(0); i <= std::size_t(
shape_dim); ++i)
 
  459          this->_perms[i] = 
other._perms[i].clone();
 
  460          this->_inv_perms[i] = 
other._inv_perms[i].clone();
 
  462        this->_element_coloring = 
other._element_coloring;
 
  463        this->_element_layering = 
other._element_layering;
 
  478        for(std::size_t i(0); i <= std::size_t(
shape_dim); ++i)
 
  525        return this->_perms.at(std::size_t(dim));
 
  540        return this->_inv_perms.at(std::size_t(dim));
 
  584      template<
int num_coords_, 
typename Coord_>
 
  593          XABORTM(
"use the MeshPermutation::create_other() function");
 
  678        NumEntitiesExtractor<shape_dim>::set_num_entities_with_numverts(ish, num_entities);
 
  679        for(std::size_t dim(0); dim <= std::size_t(
shape_dim); ++dim)
 
  699      template<
int num_coords_, 
typename Coord_>
 
  705        Intern::LexiPermuter<ShapeType>::compute(this->_perms, ish, vtx);
 
  708        for(std::size_t dim(0); dim <= std::size_t(
shape_dim); ++dim)
 
  734        const auto& verts_at_elem = ish.template get_index_set<shape_dim, 0>();
 
  745        const Index num_elems = elems_at_elem.get_num_nodes_domain();
 
  746        const Index num_colors = cparti.get_num_nodes_domain();
 
  756        this->_element_coloring.assign(dom_ptr, &dom_ptr[num_colors]);
 
  778      void create_cmk(
const IndexSetHolder<Shape_>& ish, 
bool reverse)
 
  782        const auto& verts_at_elem = ish.template get_index_set<shape_dim, 0>();
 
  818      template<
int num_coords_, 
typename Coord_>
 
  822        std::array<Adjacency::Graph, shape_dim> idx_set;
 
  823        Intern::ISWRenderer<Shape_>::render(idx_set, ish.template get_index_set_wrapper<shape_dim>());
 
  831        NumEntitiesExtractor<shape_dim>::set_num_entities_with_numverts(ish, num_entities);
 
  834        const Index num_verts = num_entities[0];
 
  838        std::array<std::vector<Index>, 
shape_dim+1> perms;
 
  839        for(std::size_t i(0); i <= std::size_t(
shape_dim); ++i)
 
  840          perms.at(i).reserve(num_entities[i]);
 
  844        std::array<std::vector<int>, 
shape_dim+1> masks;
 
  845        for(std::size_t i(0); i <= std::size_t(
shape_dim); ++i)
 
  846          masks.at(i).resize(num_entities[i]);
 
  849        std::vector<Index> layer_cur, layer_vert, layer_next;
 
  850        layer_cur.reserve(num_elems);
 
  851        layer_next.reserve(num_elems);
 
  852        layer_vert.reserve(num_verts);
 
  855        this->_element_layering.clear();
 
  856        this->_element_layering.push_back(
Index(0));
 
  862        while(
Index(perms.back().size()) < num_elems)
 
  869          layer_cur.push_back(idx);
 
  870          masks.back()[idx] = 1;
 
  873          while(!layer_cur.empty())
 
  877            for(
auto it = layer_cur.begin(); it != layer_cur.end(); ++it)
 
  880              const Index cur_elem = *it;
 
  881              perms.back().push_back(cur_elem);
 
  885              for(
auto kt = verts_at_elem.
image_begin(cur_elem); kt != verts_at_elem.
image_end(cur_elem); ++kt)
 
  887                const Index cur_vert = *kt;
 
  889                if(masks.front()[cur_vert] != 0)
 
  892                layer_vert.push_back(cur_vert);
 
  893                perms.front().push_back(cur_vert);
 
  894                masks.front()[cur_vert] = 1;
 
  898              for(std::size_t k(1); k < std::size_t(
shape_dim); ++k)
 
  900                for(
auto kt = idx_set.at(k).image_begin(cur_elem); kt != idx_set.at(k).image_end(cur_elem); ++kt)
 
  902                  const Index cur_face = *kt;
 
  903                  if(masks.at(k)[cur_face] != 0)
 
  905                  perms.at(k).push_back(cur_face);
 
  906                  masks.at(k)[cur_face] = 1;
 
  911              for(
auto jt = layer_vert.begin(); jt != layer_vert.end(); ++jt)
 
  913                const Index cur_vert = *jt;
 
  914                for(
auto kt = elems_at_vert.
image_begin(cur_vert); kt != elems_at_vert.
image_end(cur_vert); ++kt)
 
  916                  const Index next_elem = *kt;
 
  917                  if(masks.back()[next_elem] != 0)
 
  919                  layer_next.push_back(next_elem);
 
  920                  masks.back()[next_elem] = 1;
 
  926            layer_cur.swap(layer_next);
 
  929            this->_element_layering.push_back(
Index(perms.back().size()));
 
  938          for(std::size_t dim(0); dim <= std::size_t(
shape_dim); ++dim)
 
  940            for(std::size_t i(0), j(perms[dim].size()-1); i < j; ++i, --j)
 
  941              std::swap(perms[dim][i], perms[dim][j]);
 
  945          const Index lay_back = 
Index(this->_element_layering.size()) - 1u;
 
  946          for(
Index k(lay_back); k > 0u; --k)
 
  949            this->_element_layering.at(k) -= this->_element_layering.at(k-1u);
 
  951          for(
Index k(1u), l(lay_back); k < l; ++k, --l)
 
  954            std::swap(this->_element_layering.at(k), this->_element_layering.at(l));
 
  956          for(
Index k(1u); k <= lay_back; ++k)
 
  959            this->_element_layering.at(k) += this->_element_layering.at(k-1u);
 
  964        for(std::size_t dim(0); dim <= std::size_t(
shape_dim); ++dim)
 
  967          XASSERT(
Index(perms.at(dim).size()) == num_entities[dim]);
 
  984        for(std::size_t dim(0); dim <= std::size_t(
shape_dim); ++dim)
 
  986          if(
_perms.at(dim).empty())
 
 1005        XASSERT(num_entities != 
nullptr);
 
 1008        for(std::size_t i(0); i <= std::size_t(
shape_dim); ++i)
 
 1013          if(!perm.
empty() && (perm.
size() != num_entities[i]))
 
 1015          if(!iperm.
empty() && (iperm.
size() != num_entities[i]))
 
 1028        const std::vector<int>& mask)
 
 1030        std::set<Index> iset;
 
 1033        Index deg = v_at_e.get_num_nodes_domain() + e_at_v.get_num_nodes_domain();
 
 1035        for(
Index i(0); i < v_at_e.get_num_nodes_domain(); ++i)
 
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Coloring object implementation.
Graph create_partition_graph() const
Creates a color partition graph.
@ minimum_degree
Minimum-degree root.
static Permutation compute(std::vector< Index > &layers, const Graph &graph, bool reverse=false, CuthillMcKee::RootType r_type=RootType::standard, CuthillMcKee::SortType t_type=SortType::standard)
Cuthill-McKee permutation computation function.
Adjacency Graph implementation.
ImageIterator image_begin(Index domain_node) const
Returns an iterator for the first adjacent image node.
Index * get_domain_ptr()
Returns the domain pointer array.
ImageIterator image_end(Index domain_node) const
Returns an iterator for the first position past the last adjacent image node.
Index * get_image_idx()
Returns the image node index array.
Index get_num_indices() const
Returns the total number indices.
Index size() const
returns the size of the permutation
bool empty() const
Checks whether the permutation is empty.
@ perm
create from permutation array
Mesh permutation class template.
void clone(const MeshPermutation &other)
Clones another mesh permutation object into this object.
std::size_t bytes() const
const std::vector< Index > & get_element_layering() const
Returns a const reference to the element layering vector.
void create_random(const IndexSetHolder< Shape_ > &ish, Random &rng)
Creates random mesh permutation for a conformal mesh.
void create_cmk(const IndexSetHolder< Shape_ > &ish, bool reverse)
Creates a (reversed) algebraic Cuthill-McKee mesh permutation for a conformal mesh.
void create_gcmk(const IndexSetHolder< Shape_ > &ish, const VertexSet< num_coords_, Coord_ > &vtx, bool reverse)
Creates a (reversed) geometric Cuthill-McKee mesh permutation for a conformal mesh.
PermArray _inv_perms
the inverse permutations
MeshPermutation & operator=(const MeshPermutation &)=delete
delete copy-assign operator
int validate_sizes(const Index *num_entities) const
Validates the permutation sizes.
std::vector< Index > _element_coloring
const PermArray & get_perms() const
const Adjacency::Permutation & get_inv_perm(int dim=shape_dim) const
Returns a const reference to an inverse permutation.
std::vector< Index > _element_layering
void create_lexicographic(const IndexSetHolder< Shape_ > &ish, const VertexSet< num_coords_, Coord_ > &vtx)
Creates a lexicographic mesh permutation for a conformal mesh.
void create_colored(const IndexSetHolder< Shape_ > &ish)
Creates a colored mesh permutation for a conformal mesh.
void create_inverse_permutations()
(Re)Creates the inverse permutations from the forward ones.
static Index _pick_gcmk_root(const Adjacency::Graph &v_at_e, const Adjacency::Graph &e_at_v, const std::vector< int > &mask)
Auxiliary helper function: pick an unmasked root element for GCMK.
PermArray & create_other()
Initializes a custom permutation.
PermutationStrategy _strategy
the permutation strategy
MeshPermutation(MeshPermutation &&other)
move constructor
Shape_ ShapeType
the underlying shape type
PermutationStrategy get_strategy() const
bool empty() const
Checks whether this permutation is empty.
PermArray _perms
the actual permutations
std::array< Adjacency::Permutation, shape_dim+1 > PermArray
permutation array typedef
MeshPermutation clone() const
MeshPermutation(PermutationStrategy strategy, const IndexSetHolder< Shape_ > &ish, const VertexSet< num_coords_, Coord_ > &vtx)
Creates a mesh permutation for a conformal mesh.
const PermArray & get_inv_perms() const
MeshPermutation & operator=(MeshPermutation &&other)
move-assignment operator
MeshPermutation()
standard constructor
static constexpr int shape_dim
the shape dimension
const std::vector< Index > & get_element_coloring() const
Returns a const reference to the element coloring vector.
void create_random(const IndexSetHolder< Shape_ > &ish)
Creates random mesh permutation for a conformal mesh.
virtual ~MeshPermutation()
virtual destructor
void create(PermutationStrategy strategy, const IndexSetHolder< Shape_ > &ish, const VertexSet< num_coords_, Coord_ > &vtx)
Creates a mesh permutation for a conformal mesh.
const Adjacency::Permutation & get_perm(int dim=shape_dim) const
Returns a const reference to a (forward) permutation.
MeshPermutation(const MeshPermutation &)=delete
delete copy constructor
Pseudo-Random Number Generator.
@ transpose
Render-Transpose mode.
@ injectify
Render-Injectified mode.
PermutationStrategy
Mesh permutation strategy enumeration.
@ colored
colored permutation strategy a.k.a. "red-black" strategy
@ none
no permutation strategy
@ cuthill_mckee_reversed
reversed (algebraic) Cuthill-McKee permutation strategy
@ other
generic/other permutation strategy
@ cuthill_mckee
(algebraic) Cuthill-McKee permutation strategy
@ random
random permutation strategy
@ geometric_cuthill_mckee_reversed
reversed geometric Cuthill-McKee permutation strategy
@ lexicographic
lexicographic permutation strategy
@ geometric_cuthill_mckee
geometric Cuthill-McKee permutation strategy
std::uint64_t Index
Index data type.
Fixed-Sized Vertex Set class template.