Heidelberg Educational Numerics Library  Version 0.24 (from 9 September 2011)
sgrid.hh
1 #ifndef HDNUM_SGRID_HH
2 #define HDNUM_SGRID_HH
3 #include <limits>
4 #include <assert.h>
5 
6 namespace hdnum {
13  template<class N, class DF, int dimension>
14  class SGrid
15  {
16  public:
17 
19  typedef std::size_t size_type;
20 
22  typedef N number_type;
23 
25  typedef DF DomainFunction;
26 
27  enum { dim = dimension };
28 
30  static const int positive = 1;
31  static const int negative = -1;
32 
33 
34  private:
35 
36  const Vector<number_type> extent;
37  const Vector<size_type> size;
38  const DomainFunction & df;
40  Vector<size_type> offsets;
41  std::vector<size_type> node_map;
42  std::vector<size_type> grid_map;
43  std::vector<bool> inside_map;
44  std::vector<bool> boundary_map;
45 
46  size_t n_nodes;
47 
48  inline Vector<size_type> index2grid(size_type index) const
49  {
50  Vector<size_type> c(dim);
51  for(int d=dim-1; d>=0; --d){
52  c[d] = index / offsets[d];
53  index -= c[d] * offsets[d];
54  }
55  return c;
56  }
57 
58  inline Vector<number_type> grid2world(const Vector<size_type> & c) const
59  {
60  Vector<number_type> w(dim);
61  for(int d=dim-1; d>=0; --d)
62  w[d] = c[d] * h[d];
63  return w;
64  }
65 
66  inline Vector<number_type> index2world(size_type index) const
67  {
68  Vector<number_type> w(dim);
69  Vector<size_type> c = index2grid(index);
70  return grid2world(c);
71  }
72 
73 
74  public:
75 
77  const size_type invalid_node;
78 
93  SGrid(const Vector<number_type> extent_,
94  const Vector<size_type> size_,
95  const DomainFunction & df_)
96  : extent(extent_), size(size_), df(df_),
97  h(dim), offsets(dim),
98  invalid_node(std::numeric_limits<size_type>::max())
99  {
100  // Determine total number of nodes, increment offsets, and cell
101  // widths.
102  n_nodes = 1;
103  offsets.resize(dim);
104  h.resize(dim);
105  for(int d=0; d<dim; ++d){
106  n_nodes *= size[d];
107  offsets[d] = d==0 ? 1 : size[d-1] * offsets[d-1];
108  h[d] = extent[d] / number_type(size[d]-1);
109  }
110 
111  // Initialize maps.
112  node_map.resize(0);
113  inside_map.resize(n_nodes);
114  grid_map.resize(n_nodes);
115  boundary_map.resize(0);
116  boundary_map.resize(n_nodes,false);
117 
118  for(size_type n=0; n<n_nodes; ++n){
119  Vector<size_type> c = index2grid(n);
120  Vector<number_type> x = grid2world(c);
121 
122  inside_map[n] = df.evaluate(x);
123  if(inside_map[n]){
124  node_map.push_back(n);
125  grid_map[n] = node_map.size()-1;
126  }
127  else
128  grid_map[n] = invalid_node;
129  }
130 
131  // Find boundary nodes
132  for(size_type n=0; n<node_map.size(); ++n){
133  for(int d=0; d<dim; ++d){
134  for(int s=0; s<2; ++s){
135  const int side = s*2-1;
136  const size_type neighbor = getNeighborIndex(n,d,side,1);
137  if(neighbor == invalid_node)
138  boundary_map[node_map[n]] = true;
139  }
140  }
141  }
142 
143  }
144 
164  size_type getNeighborIndex(const size_type ln, const size_type n_dim, const int n_side, const int k = 1) const
165  {
166  const size_type n = node_map[ln];
167  const Vector<size_type> c = index2grid(n);
168  size_type neighbors[2];
169  neighbors[0] = c[n_dim];
170  neighbors[1] = size[n_dim]-c[n_dim]-1;
171 
172  assert(n_side == 1 || n_side == -1);
173  if(size_type(k) > neighbors[(n_side+1)/2])
174  return invalid_node;
175 
176  const size_type neighbor = n + offsets[n_dim] * n_side * k;
177 
178  if(!inside_map[neighbor])
179  return invalid_node;
180 
181  return grid_map[neighbor];
182  }
183 
187  bool isBoundaryNode(const size_type ln) const
188  {
189  return boundary_map[node_map[ln]];
190  }
191 
195  size_type getNumberOfNodes() const
196  {
197  return node_map.size();
198  }
199 
200  Vector<size_type> getGridSize() const
201  {
202  return size;
203  }
204 
208  {
209  return h;
210  }
211 
215  Vector<number_type> getCoordinates(const size_type ln) const
216  {
217  return index2world(node_map[ln]);
218  }
219 
220  std::vector<Vector<number_type> > getNodeCoordinates() const
221  {
222  std::vector<Vector<number_type> > coords;
223  for(size_type n=0; n<node_map.size(); ++n){
224  coords.push_back(Vector<number_type>(dim));
225  coords.back() = index2world(node_map[n]);
226  }
227  return coords;
228  }
229 
230  };
231 
232 };
233 
234 #endif // HDNUM_SGRID_HH
size_type getNeighborIndex(const size_type ln, const size_type n_dim, const int n_side, const int k=1) const
Provides the index of the k-th neighbor of the node with index ln.
Definition: sgrid.hh:164
Structured Grid for Finite Differences.
Definition: sgrid.hh:14
Vector< number_type > getCoordinates(const size_type ln) const
Returns the world coordinates of the node with the given node index.
Definition: sgrid.hh:215
Vector< number_type > getCellWidth() const
Returns the cell width h of the structured grid.
Definition: sgrid.hh:207
bool isBoundaryNode(const size_type ln) const
Returns true if the node is on the boundary of the discrete compuational domain.
Definition: sgrid.hh:187
static const int positive
Side definitions for usage in getNeighborIndex(..)
Definition: sgrid.hh:30
size_type getNumberOfNodes() const
Returns the number of nodes which are in the compuational domain.
Definition: sgrid.hh:195
DF DomainFunction
Type of the function defining the domain.
Definition: sgrid.hh:25
SGrid(const Vector< number_type > extent_, const Vector< size_type > size_, const DomainFunction &df_)
Constructor.
Definition: sgrid.hh:93
std::size_t size_type
Export size type.
Definition: sgrid.hh:19
Definition: densematrix.hh:21
const size_type invalid_node
The value which is returned to indicate an invalid node.
Definition: sgrid.hh:77
N number_type
Export number type.
Definition: sgrid.hh:22