OrientedEntityTable.hpp
1 //===========================================================================
2 //
3 // File: OrientedEntityTable.hpp
4 //
5 // Created: Wed Aug 26 11:13:20 2009
6 //
7 // Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8 // Bård Skaflestad <bard.skaflestad@sintef.no>
9 //
10 // $Date$
11 //
12 // $Revision$
13 //
14 //===========================================================================
15 
16 /*
17  Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18  Copyright 2009, 2010 Statoil ASA.
19 
20  This file is part of The Open Porous Media project (OPM).
21 
22  OPM is free software: you can redistribute it and/or modify
23  it under the terms of the GNU General Public License as published by
24  the Free Software Foundation, either version 3 of the License, or
25  (at your option) any later version.
26 
27  OPM is distributed in the hope that it will be useful,
28  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  GNU General Public License for more details.
31 
32  You should have received a copy of the GNU General Public License
33  along with OPM. If not, see <http://www.gnu.org/licenses/>.
34 */
35 
36 #ifndef OPM_ORIENTEDENTITYTABLE_HEADER
37 #define OPM_ORIENTEDENTITYTABLE_HEADER
38 
39 #include "EntityRep.hpp"
40 #include <opm/core/utility/SparseTable.hpp>
41 #include <map>
42 #include <climits>
43 #include <boost/algorithm/minmax_element.hpp>
44 
46 namespace Dune
47 {
48  namespace cpgrid
49  {
50 
51 
54  template <int codim_to>
55  class OrientedEntityRange : private Opm::SparseTable< EntityRep<codim_to> >::row_type
56  {
57  public:
59  typedef ToType* ToTypePtr;
60  typedef typename Opm::SparseTable<ToType>::row_type R;
61 
64  : R(ToTypePtr(0), ToTypePtr(0)), orientation_(true)
65  {
66  }
70  OrientedEntityRange(const R& r, bool orientation)
71  : R(r), orientation_(orientation)
72  {
73  }
74  int size () const { return R::size(); }
75  using R::empty;
76  using R::begin;
77  using R::end;
81  ToType operator[](int subindex) const
82  {
83  ToType erep = R::operator[](subindex);
84  return orientation_ ? erep : erep.opposite();
85  }
86  private:
87  bool orientation_;
88  };
89 
90 
91 
92 
101  template <int codim_from, int codim_to>
102  class OrientedEntityTable : private Opm::SparseTable< EntityRep<codim_to> >
103  {
104  friend class CpGridData;
105  public:
107  typedef EntityRep<codim_to> ToType;
108  typedef OrientedEntityRange<codim_to> row_type; // ??? doxygen henter doc fra Opm::SparseTable
110 
113  {
114  }
115 
127  template <typename DataIter, typename IntegerIter>
128  OrientedEntityTable(DataIter data_beg, DataIter data_end,
129  IntegerIter rowsize_beg, IntegerIter rowsize_end)
130  : super_t(data_beg, data_end, rowsize_beg, rowsize_end)
131  {
132  }
133 
134  using super_t::empty;
135  using super_t::size;
136  using super_t::dataSize;
137  using super_t::clear;
138  using super_t::appendRow;
139 
144  int rowSize(const FromType& e) const
145  {
146  return super_t::rowSize(e.index());
147  }
148 
154  row_type operator[](const FromType& e) const
155  {
156  return row_type(super_t::operator[](e.index()), e.orientation());
157  }
158 
162  bool operator==(const OrientedEntityTable& other) const
163  {
164  return super_t::operator==(other);
165  }
166 
189  void printSparseRelationMatrix(std::ostream& os) const
190  {
191  for (int i = 0; i < size(); ++i) {
192  const FromType from_ent(i, true);
193  const row_type r = operator[](from_ent);
194  const int rsize = r.size();
195  for (int j = 0; j < rsize; ++j) {
196  os << i << ' ' << r[j].index() << ' ' << (r[j].orientation() ? 1 : -1) << '\n';
197  }
198  }
199  os << std::flush;
200  }
201 
219  void printRelationMatrix(std::ostream& os) const
220  {
221  int columns = numberOfColumns();
222  for (int i = 0; i < size(); ++i) {
223  FromType from_ent(i, true);
224  row_type r = operator[](from_ent);
225  int cur_col = 0;
226  int next_ent = 0;
227  ToType to_ent = r[next_ent];
228  int next_print = to_ent.index();
229  while (cur_col < columns) {
230  if (cur_col == next_print) {
231  if (to_ent.orientation()) {
232  os << " 1";
233  } else {
234  os << " -1";
235  }
236  ++next_ent;
237  if (next_ent >= r.size()) {
238  next_print = columns;
239  } else {
240  to_ent = r[next_ent];
241  next_print = to_ent.index();
242  }
243  } else {
244  os << " 0";
245  }
246  ++cur_col;
247  }
248  os << '\n';
249  }
250  }
251 
259  {
260  // Find the maximum index used. This will give (one less than) the size
261  // of the table to be created.
262  int maxind = -1;
263  for (int i = 0; i < size(); ++i) {
264  EntityRep<codim_from> from_ent(i, true);
265  row_type r = operator[](from_ent);
266  for (int j = 0; j < r.size(); ++j) {
267  EntityRep<codim_to> to_ent = r[j];
268  int ind = to_ent.index();
269  maxind = std::max(ind, maxind);
270  }
271  }
272  // Build the new_sizes vector and compute datacount.
273  std::vector<int> new_sizes(maxind + 1);
274  int datacount = 0;
275  for (int i = 0; i < size(); ++i) {
276  EntityRep<codim_from> from_ent(i, true);
277  row_type r = operator[](from_ent);
278  datacount += r.size();
279  for (int j = 0; j < r.size(); ++j) {
280  EntityRep<codim_to> to_ent = r[j];
281  int ind = to_ent.index();
282  ++new_sizes[ind];
283  }
284  }
285  // Compute the cumulative sizes.
286  std::vector<int> cumul_sizes(new_sizes.size() + 1);
287  cumul_sizes[0] = 0;
288  std::partial_sum(new_sizes.begin(), new_sizes.end(), cumul_sizes.begin() + 1);
289  // Using the cumulative sizes array as indices, we populate new_data.
290  // Note that cumul_sizes[ind] is not kept constant, but incremented so that
291  // it always gives the correct index for new data corresponding to index ind.
292  std::vector<EntityRep<codim_from> > new_data(datacount);
293  for (int i = 0; i < size(); ++i) {
294  EntityRep<codim_from> from_ent(i, true);
295  row_type r = operator[](from_ent);
296  for (int j = 0; j < r.size(); ++j) {
297  EntityRep<codim_to> to_ent(r[j]);
298  int ind = to_ent.index();
299  int data_ind = cumul_sizes[ind];
300  new_data[data_ind] = to_ent.orientation() ? from_ent : from_ent.opposite();
301  ++cumul_sizes[ind];
302  }
303  }
304  inv = OrientedEntityTable<codim_to, codim_from>(new_data.begin(),
305  new_data.end(),
306  new_sizes.begin(),
307  new_sizes.end());
308  }
309 
310  private:
311  int numberOfColumns() const
312  {
313  int maxind = 0;
314  for (int i = 0; i < size(); ++i) {
315  FromType from_ent(i, true);
316  row_type r = operator[](from_ent);
317  for (int j = 0; j < r.size(); ++j) {
318  maxind = std::max(maxind, r[j].index());
319  }
320  }
321  return maxind + 1;
322  }
323  };
324 
325 
326  } // namespace cpgrid
327 } // namespace Dune
328 
329 
330 
331 
332 #endif // OPM_ORIENTEDENTITYTABLE_HEADER
int index() const
The (positive) index of an entity.
Definition: EntityRep.hpp:126
bool orientation() const
Returns true if the entity has positive orientation.
Definition: EntityRep.hpp:135
EntityRep opposite() const
Returns an EntityRep with opposite orientation.
Definition: EntityRep.hpp:142
void printSparseRelationMatrix(std::ostream &os) const
Prints the relation matrix corresponding to the table, sparse format.
Definition: OrientedEntityTable.hpp:189
bool operator==(const SparseTable &other) const
Equality.
Definition: SparseTable.hpp:186
A SparseTable stores a table with rows of varying size as efficiently as possible.
Definition: SparseTable.hpp:54
Holds the implementation of the CpGrid as a pimple.
Definition: OpmParserIncludes.hpp:42
void appendRow(DataIter row_beg, DataIter row_end)
Appends a row to the table.
Definition: SparseTable.hpp:107
Represents the topological relationships between sets of entities, for example cells and faces...
Definition: OrientedEntityTable.hpp:102
int rowSize(const FromType &e) const
Given an entity e of codimension codim_from, returns the number of neighbours of codimension codim_to...
Definition: OrientedEntityTable.hpp:144
Struct that hods all the data needed to represent a Cpgrid.
Definition: CpGridData.hpp:105
OrientedEntityTable()
Default constructor.
Definition: OrientedEntityTable.hpp:112
void clear()
Makes the table empty().
Definition: SparseTable.hpp:159
ToType operator[](int subindex) const
Random access operator.
Definition: OrientedEntityTable.hpp:81
bool empty() const
True if the table contains no rows.
Definition: SparseTable.hpp:118
int rowSize(int row) const
Returns the size of a table row.
Definition: SparseTable.hpp:150
int dataSize() const
Returns the number of data elements.
Definition: SparseTable.hpp:144
OrientedEntityRange()
Default constructor yielding an empty range.
Definition: OrientedEntityTable.hpp:63
void printRelationMatrix(std::ostream &os) const
Prints the full relation matrix corresponding to the table.
Definition: OrientedEntityTable.hpp:219
boost::iterator_range< const T * > row_type
Defining the row type, returned by operator[].
Definition: SparseTable.hpp:166
OrientedEntityRange(const R &r, bool orientation)
Constructor taking a row type and an orientation.
Definition: OrientedEntityTable.hpp:70
row_type operator[](const FromType &e) const
Given an entity e of codimension codim_from, returns a row (an indirect container) containing its nei...
Definition: OrientedEntityTable.hpp:154
void makeInverseRelation(OrientedEntityTable< codim_to, codim_from > &inv) const
Makes the inverse relation, mapping codim_to entities to their codim_from neighbours.
Definition: OrientedEntityTable.hpp:258
Represents an entity of a given codim, with positive or negative orientation.
Definition: CpGridData.hpp:94
OrientedEntityTable(DataIter data_beg, DataIter data_end, IntegerIter rowsize_beg, IntegerIter rowsize_end)
Constructor taking iterators to a sequence of table data and a sequence of row size data...
Definition: OrientedEntityTable.hpp:128
bool operator==(const OrientedEntityTable &other) const
Elementwise equality.
Definition: OrientedEntityTable.hpp:162
A class used as a row type for OrientedEntityTable.
Definition: OrientedEntityTable.hpp:55
int size() const
Returns the number of rows in the table.
Definition: SparseTable.hpp:124