HyperHDG
epsilon_neighborhood_graph.hxx
Go to the documentation of this file.
1 #pragma once // Ensure that file is included only once in a single compilation.
2 
3 #include <HyperHDG/hy_assert.hxx>
4 
5 #include <algorithm>
6 #include <deque>
7 #include <fstream>
8 #include <sstream>
9 #include <string>
10 
11 /*!*************************************************************************************************
12  * \brief Construct epsilon neighborhood graph from a file that contains only points.
13  *
14  * This function takes a filename that belongs to a .pts file containing only points and writes the
15  * corresponding epsilon neighborhood graph (if it is a valid one) to filename.geo.
16  *
17  * \param filename Name of the file containing the points.
18  * \retval filename.geo File containing the respective epsilon neighborhood graph.
19  **************************************************************************************************/
20 template <unsigned int dim,
21  template <typename...> typename vectorT = std::vector,
22  typename pointT = Point<dim, float>,
23  typename index_t = decltype(std::declval<vectorT>().size())>
24 void make_epsilon_neighborhood_graph(std::string& filename)
25 {
26  using float_t = typename pointT::value_type;
27 
28  hy_assert(filename.substr(filename.size() - 4, filename.size()) == ".pts",
29  "The given file needs to be a .pts file for this function to be applicable!");
30 
31  struct Pair
32  {
33  const index_t left, right;
34  Pair(const index_t left_, const index_t right_) : left(left_), right(right_) {}
35  };
36 
37  std::ifstream infile(filename);
38  std::istringstream linestream;
39  std::string line, keyword, equal_sign;
40 
41  unsigned int space_dim;
42  float_t epsilon;
43  index_t index;
44 
45  vectorT<pointT> points;
46  vectorT<Pair> connections;
47  std::deque<index_t> search;
48  pointT pt;
49 
50  while (keyword != "Space_Dim" && std::getline(infile, line))
51  {
52  linestream = std::istringstream(line);
53  linestream >> keyword;
54  }
55  linestream >> equal_sign >> space_dim;
56 
57  hy_assert(keyword == "Space_Dim",
58  "The keyword Space_Dim has not been found in the file " << filename << "!");
59  hy_assert(equal_sign == "=", "The keyword " << keyword << " has not been followd by = symbol!");
60  hy_assert(space_dim == dim,
61  "Space_Dim in " << filename << " is " << space_dim << ", but should be " << dim << "!");
62 
63  while (keyword != "Epsilon" && std::getline(infile, line))
64  {
65  linestream = std::istringstream(line);
66  linestream >> keyword;
67  }
68  linestream >> equal_sign >> epsilon;
69 
70  hy_assert(keyword == "Epsilon",
71  "The keyword Space_Dim has not been found in the file " << filename << "!");
72  hy_assert(equal_sign == "=", "The keyword " << keyword << " has not been followd by = symbol!");
73  hy_assert(epsilon > 0, "Epsilon needs to be larger than zeros, but is " << epsilon << "!");
74 
75  while (keyword != "POINTS:" && std::getline(infile, line))
76  {
77  linestream = std::istringstream(line);
78  linestream >> keyword;
79  }
80 
81  hy_assert(keyword == "POINTS:",
82  "The keyword 'POINTS:' has not been found in the file " << filename << "!");
83 
84  while (std::getline(infile, line))
85  {
86  linestream = std::istringstream(line);
87  for (unsigned int dimension = 0; dimension < dim; ++dimension)
88  linestream >> pt[dimension];
89  points.push_back(pt);
90  }
91 
92  std::sort(points.begin(), points.end());
93  hy_assert(std::adjacent_find(points.begin(), points.end()) == points.end(),
94  "Points must be unique in given file!");
95 
96  vectorT<bool> bool_vec(points.size(), false);
97  search.push_back(0);
98  bool_vec[0] = true;
99 
100  while (!search.empty())
101  {
102  index = search.front();
103  search.pop_front();
104  for (index_t ind = index;
105  ind >= 0 && ind < points.size() && std::abs(points[index][0] - points[ind][0]) < epsilon;
106  --ind)
107  if (norm_2(points[index] - points[ind]) < epsilon && ind != index &&
108  (!bool_vec[ind] || std::find(search.begin(), search.end(), ind) != search.end()))
109  {
110  if (!bool_vec[ind])
111  search.push_back(ind);
112  bool_vec[ind] = true;
113  connections.push_back(Pair(index, ind));
114  }
115  for (index_t ind = index;
116  ind >= 0 && ind < points.size() && std::abs(points[index][0] - points[ind][0]) < epsilon;
117  ++ind)
118  if (norm_2(points[index] - points[ind]) < epsilon && ind != index &&
119  (!bool_vec[ind] || std::find(search.begin(), search.end(), ind) != search.end()))
120  {
121  if (!bool_vec[ind])
122  search.push_back(ind);
123  bool_vec[ind] = true;
124  connections.push_back(Pair(index, ind));
125  }
126  }
127 
128  infile.close();
129  filename = filename + ".geo";
130  std::ofstream outfile(filename);
131 
132  outfile << "Space_Dim = " << dim << ";" << std::endl;
133  outfile << "HyperEdge_Dim = 1;" << std::endl << std::endl;
134  outfile << "N_Points = " << points.size() << ";" << std::endl;
135  outfile << "N_HyperNodes = " << points.size() << ";" << std::endl;
136  outfile << "N_HyperEdges = " << connections.size() << ";" << std::endl << std::endl;
137  outfile << "POINTS:" << std::endl;
138  for (unsigned int i = 0; i < points.size(); ++i)
139  outfile << points[i];
140  outfile << std::endl << "HYPERNODES_OF_HYPEREDGES:" << std::endl;
141  for (unsigned int i = 0; i < connections.size(); ++i)
142  outfile << connections[i].left << " " << connections[i].right << std::endl;
143  outfile << std::endl << "TYPES_OF_HYPERFACES:" << std::endl;
144  for (unsigned int i = 0; i < connections.size(); ++i)
145  outfile << connections[i].left << " " << connections[i].right << std::endl;
146  outfile << std::endl << "POINTS_OF_HYPEREDGES:" << std::endl;
147  for (unsigned int i = 0; i < connections.size(); ++i)
148  outfile << connections[i].left << " " << connections[i].right << std::endl;
149 
150  outfile.close();
151 
152  for (unsigned int i = 0; i < bool_vec.size(); ++i)
153  hy_assert(bool_vec[i], "All points need to belong to one graph, but " << i << " does not!");
154 }
hy_assert.hxx
This file provides the function hy_assert.
check_push_test.index
index
Definition: check_push_test.py:10
make_epsilon_neighborhood_graph
void make_epsilon_neighborhood_graph(std::string &filename)
Construct epsilon neighborhood graph from a file that contains only points.
Definition: epsilon_neighborhood_graph.hxx:24
norm_2
mat_entry_t norm_2(const SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Euclidean norm of a small/dense vector.
Definition: dense_la.hxx:854
hy_assert
#define hy_assert(Expr, Msg)
The assertion to be used within HyperHDG — deactivate using -DNDEBUG compile flag.
Definition: hy_assert.hxx:38
SmallMat
This class implements a small/dense matrix.
Definition: dense_la.hxx:34