Interface Documentation
Version: invalid
closure_utils.hh
Go to the documentation of this file.
1 /*
2  @@@@@@@@ @@ @@@@@@ @@@@@@@@ @@
3  /@@///// /@@ @@////@@ @@////// /@@
4  /@@ /@@ @@@@@ @@ // /@@ /@@
5  /@@@@@@@ /@@ @@///@@/@@ /@@@@@@@@@/@@
6  /@@//// /@@/@@@@@@@/@@ ////////@@/@@
7  /@@ /@@/@@//// //@@ @@ /@@/@@
8  /@@ @@@//@@@@@@ //@@@@@@ @@@@@@@@ /@@
9  // /// ////// ////// //////// //
10 
11  Copyright (c) 2016, Los Alamos National Security, LLC
12  All rights reserved.
13  */
14 #pragma once
15 
18 #include "flecsi/flog.hh"
20 #include "flecsi/util/set_utils.hh"
22 
23 #include <map>
24 #include <set>
25 #include <vector>
26 
27 namespace flecsi {
28 namespace topo {
29 namespace unstructured_impl {
30 
46 template<size_t from_dim, size_t to_dim, size_t thru_dim, size_t D>
47 std::set<size_t>
48 entity_neighbors(const definition<D> & md, size_t entity_id) {
49  // Get the vertices of the requested id
50  auto vertices = md.entities_set(from_dim, 0, entity_id);
51 
52  // Put the results into set form
53  std::set<size_t> neighbors;
54 
55  // Go through the entities of the to_dim
56  for(size_t e(0); e < md.num_entities(to_dim); ++e) {
57 
58  // Skip the input id if the dimensions are the same
59  if(from_dim == to_dim && e == entity_id) {
60  continue;
61  } // if
62 
63  // Get the vertices that define the current entity from the to_dim
64  auto other = md.entities_set(to_dim, 0, e);
65 
66  // Get the intersection set
67  auto intersect = util::set_intersection(vertices, other);
68 
69  // Add this entity id if the intersection shares at least
70  // intersections vertices
71  if(intersect.size() > thru_dim) {
72  neighbors.insert(e);
73  } // if
74  } // for
75 
76  return neighbors;
77 } // entity_neighbors
78 
95 template<size_t from_dim,
96  size_t to_dim,
97  size_t thru_dim,
98  size_t D,
99  typename U,
100  typename = std::enable_if_t<util::is_iterative_container_v<U>>>
101 std::set<size_t>
102 entity_neighbors(const definition<D> & md, U && indices) {
103  flog_assert(from_dim == to_dim, "from_dim does not equal to to_dim");
104 
105  // Closure should include the initial set
106  std::set<size_t> closure(
107  std::forward<U>(indices).begin(), std::forward<U>(indices).end());
108 
109  using entityid = size_t;
110  using vertexid = size_t;
111 
112  // essentially vertex to cell and cell to cell through vertices
113  // connectivity.
114  std::map<vertexid, std::vector<entityid>> vertex2entities;
115  std::map<entityid, std::vector<entityid>> entity_neighbors;
116 
117  // build global entity to entity through # of shared vertices connectivity
118  for(size_t cell(0); cell < md.num_entities(from_dim); ++cell) {
119  std::map<entityid, size_t> cell_counts;
120  for(auto vertex : md.entities(from_dim, 0, cell)) {
121  // build vertex to cell connectivity, O(n_cells * n_polygon_sides)
122  // of insert().
123  vertex2entities[vertex].push_back(cell);
124 
125  // Count the number of times this cell shares a common vertex with
126  // some other cell. O(n_cells * n_polygon_sides * vertex to cells degrees)
127  for(auto other : vertex2entities[vertex]) {
128  // for (auto other : md.entities(0, from_dim, vertex)) {
129  if(other != cell)
130  cell_counts[other] += 1;
131  }
132  }
133 
134  for(auto count : cell_counts) {
135  if(count.second > thru_dim) {
136  // append cell to cell through "dimension" connectivity, we need to
137  // add both directions
138  entity_neighbors[cell].push_back(count.first);
139  entity_neighbors[count.first].push_back(cell);
140  }
141  }
142  }
143 
144  for(auto i : indices) {
145  for(auto n : entity_neighbors[i]) {
146  closure.insert(n);
147  }
148  }
149 
150  return closure;
151 } // entity_closure
152 
164 template<size_t from_dim, size_t to_dim, size_t D>
165 std::set<size_t>
166 entity_referencers(const definition<D> & md, size_t id) {
167  std::set<size_t> referencers;
168 
169  // Iterate over entities adding any entity that contains
170  // the vertex id to the set.
171  for(size_t e(0); e < md.num_entities(from_dim); ++e) {
172 
173  // Get the vertex ids of current cell
174  const auto & eset = md.entities(from_dim, to_dim, e);
175 
176  // If the cell references this vertex add it
177  if(std::find(eset.begin(), eset.end(), id) != eset.end())
178  referencers.insert(e);
179 
180  } // for
181 
182  return referencers;
183 } // entity_referencers
184 
197 template<size_t from_dim, size_t to_dim, size_t D, typename U>
198 std::set<size_t>
199 entity_closure(const definition<D> & md, U && indices) {
200  std::set<size_t> closure;
201 
202  // Iterate over the entities in indices and add any vertices that are
203  // referenced by one of the entity indices
204  for(auto i : std::forward<U>(indices)) {
205  const auto & vset = md.entities(from_dim, to_dim, i);
206  closure.insert(vset.begin(), vset.end());
207  } // for
208 
209  return closure;
210 } // entity_closure
211 
212 } // namespace unstructured_impl
213 } // namespace topo
214 } // namespace flecsi
std::set< size_t > entity_closure(const definition< D > &md, U &&indices)
Definition: closure_utils.hh:199
virtual std::set< size_t > entities_set(size_t from_dimension, size_t to_dimension, size_t id) const
Definition: definition.hh:101
#define flog_assert(test, message)
Definition: flog.hh:411
virtual std::vector< size_t > entities(size_t from_dimension, size_t to_dimension, size_t id) const =0
std::set< size_t > entity_referencers(const definition< D > &md, size_t id)
Definition: closure_utils.hh:166
virtual size_t num_entities(size_t dimension) const =0
std::set< size_t > entity_neighbors(const definition< D > &md, size_t entity_id)
Definition: closure_utils.hh:48
Definition: control.hh:31