opm-grid
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/grid/utility/SparseTable.hpp>
41 #include <map>
42 #include <climits>
43 
45 namespace Dune
46 {
47  namespace cpgrid
48  {
49 
50 
53  template <int codim_to>
54  class OrientedEntityRange : private Opm::SparseTable< EntityRep<codim_to> >::row_type
55  {
56  public:
58  typedef ToType* ToTypePtr;
59  typedef typename Opm::SparseTable<ToType>::row_type R;
60 
63  : orientation_(true)
64  {
65  }
69  OrientedEntityRange(const R& r, bool orientation)
70  : R(r), orientation_(orientation)
71  {
72  }
73  int size () const { return R::size(); }
74  using R::empty;
75  using R::begin;
76  using R::end;
80  ToType operator[](int subindex) const
81  {
82  ToType erep = *(this->begin() + subindex);
83  return orientation_ ? erep : erep.opposite();
84  }
85  private:
86  bool orientation_;
87  };
88 
89 
92  template <int codim_to>
93  class MutableOrientedEntityRange : private Opm::SparseTable< EntityRep<codim_to> >::mutable_row_type
94  {
95  public:
97  typedef ToType* ToTypePtr;
98  typedef typename Opm::SparseTable<ToType>::mutable_row_type R;
99 
102  : R(ToTypePtr(0), ToTypePtr(0)), orientation_(true)
103  {
104  }
108  MutableOrientedEntityRange(const R& r, bool orientation)
109  : R(r), orientation_(orientation)
110  {
111  }
112  int size () const { return R::size(); }
113  using R::empty;
114  using R::begin;
115  using R::end;
119  ToType operator[](int subindex) const
120  {
121  ToType erep = R::operator[](subindex);
122  return orientation_ ? erep : erep.opposite();
123  }
124  private:
125  bool orientation_;
126  };
127 
128 
137  template <int codim_from, int codim_to>
138  class OrientedEntityTable : private Opm::SparseTable< EntityRep<codim_to> >
139  {
140  friend class CpGridData;
141  public:
143  typedef EntityRep<codim_to> ToType;
144  typedef OrientedEntityRange<codim_to> row_type; // ??? doxygen henter doc fra Opm::SparseTable
146  typedef typename super_t::mutable_row_type mutable_row_type;
147 
150  {
151  }
152 
164  template <typename DataIter, typename IntegerIter>
165  OrientedEntityTable(DataIter data_beg, DataIter data_end,
166  IntegerIter rowsize_beg, IntegerIter rowsize_end)
167  : super_t(data_beg, data_end, rowsize_beg, rowsize_end)
168  {
169  }
170 
171  using super_t::empty;
172  using super_t::size;
173  using super_t::dataSize;
174  using super_t::clear;
175  using super_t::appendRow;
176  using super_t::allocate;
177 
182  int rowSize(const FromType& e) const
183  {
184  return super_t::rowSize(e.index());
185  }
186 
192  row_type operator[](const FromType& e) const
193  {
194  return row_type(super_t::operator[](e.index()), e.orientation());
195  }
196 
202  mutable_row_type row(const FromType& e)
203  {
204  return super_t::operator[](e.index());
205  }
209  bool operator==(const OrientedEntityTable& other) const
210  {
211  return super_t::operator==(other);
212  }
213 
216  {
217  super_t::swap(other);
218  }
219 
242  void printSparseRelationMatrix(std::ostream& os) const
243  {
244  for (int i = 0; i < size(); ++i) {
245  const FromType from_ent(i, true);
246  const row_type r = operator[](from_ent);
247  const int rsize = r.size();
248  for (int j = 0; j < rsize; ++j) {
249  os << i << ' ' << r[j].index() << ' ' << (r[j].orientation() ? 1 : -1) << '\n';
250  }
251  }
252  os << std::flush;
253  }
254 
272  void printRelationMatrix(std::ostream& os) const
273  {
274  int columns = numberOfColumns();
275  for (int i = 0; i < size(); ++i) {
276  FromType from_ent(i, true);
277  row_type r = operator[](from_ent);
278  int cur_col = 0;
279  int next_ent = 0;
280  ToType to_ent = r[next_ent];
281  int next_print = to_ent.index();
282  while (cur_col < columns) {
283  if (cur_col == next_print) {
284  if (to_ent.orientation()) {
285  os << " 1";
286  } else {
287  os << " -1";
288  }
289  ++next_ent;
290  if (next_ent >= r.size()) {
291  next_print = columns;
292  } else {
293  to_ent = r[next_ent];
294  next_print = to_ent.index();
295  }
296  } else {
297  os << " 0";
298  }
299  ++cur_col;
300  }
301  os << '\n';
302  }
303  }
304 
312  {
313  // Find the maximum index used. This will give (one less than) the size
314  // of the table to be created.
315  int maxind = -1;
316  for (int i = 0; i < size(); ++i) {
317  EntityRep<codim_from> from_ent(i, true);
318  row_type r = operator[](from_ent);
319  for (int j = 0; j < r.size(); ++j) {
320  EntityRep<codim_to> to_ent = r[j];
321  int ind = to_ent.index();
322  maxind = std::max(ind, maxind);
323  }
324  }
325  // Build the new_sizes vector and compute datacount.
326  std::vector<int> new_sizes(maxind + 1);
327  int datacount = 0;
328  for (int i = 0; i < size(); ++i) {
329  EntityRep<codim_from> from_ent(i, true);
330  row_type r = operator[](from_ent);
331  datacount += r.size();
332  for (int j = 0; j < r.size(); ++j) {
333  EntityRep<codim_to> to_ent = r[j];
334  int ind = to_ent.index();
335  ++new_sizes[ind];
336  }
337  }
338  // Compute the cumulative sizes.
339  std::vector<int> cumul_sizes(new_sizes.size() + 1);
340  cumul_sizes[0] = 0;
341  std::partial_sum(new_sizes.begin(), new_sizes.end(), cumul_sizes.begin() + 1);
342  // Using the cumulative sizes array as indices, we populate new_data.
343  // Note that cumul_sizes[ind] is not kept constant, but incremented so that
344  // it always gives the correct index for new data corresponding to index ind.
345  std::vector<EntityRep<codim_from> > new_data(datacount);
346  for (int i = 0; i < size(); ++i) {
347  EntityRep<codim_from> from_ent(i, true);
348  row_type r = operator[](from_ent);
349  for (int j = 0; j < r.size(); ++j) {
350  EntityRep<codim_to> to_ent(r[j]);
351  int ind = to_ent.index();
352  int data_ind = cumul_sizes[ind];
353  new_data[data_ind] = to_ent.orientation() ? from_ent : from_ent.opposite();
354  ++cumul_sizes[ind];
355  }
356  }
357  inv = OrientedEntityTable<codim_to, codim_from>(new_data.begin(),
358  new_data.end(),
359  new_sizes.begin(),
360  new_sizes.end());
361  }
362 
363  private:
364  int numberOfColumns() const
365  {
366  int maxind = 0;
367  for (int i = 0; i < size(); ++i) {
368  FromType from_ent(i, true);
369  row_type r = operator[](from_ent);
370  for (int j = 0; j < r.size(); ++j) {
371  maxind = std::max(maxind, r[j].index());
372  }
373  }
374  return maxind + 1;
375  }
376  };
377 
378 
379  } // namespace cpgrid
380 } // namespace Dune
381 
382 
383 
384 
385 #endif // OPM_ORIENTEDENTITYTABLE_HEADER
mutable_row_type row(const FromType &e)
Given an entity e of codimension codim_from, returns a row (an indirect container) containing its nei...
Definition: OrientedEntityTable.hpp:202
int index() const
The (positive) index of an entity.
Definition: EntityRep.hpp:125
OPM_HOST_DEVICE bool empty() const
True if the table contains no rows.
Definition: SparseTable.hpp:189
bool orientation() const
Returns true if the entity has positive orientation.
Definition: EntityRep.hpp:139
MutableOrientedEntityRange(const R &r, bool orientation)
Constructor taking a row type and an orientation.
Definition: OrientedEntityTable.hpp:108
EntityRep opposite() const
Returns an EntityRep with opposite orientation.
Definition: EntityRep.hpp:146
void printSparseRelationMatrix(std::ostream &os) const
Prints the relation matrix corresponding to the table, sparse format.
Definition: OrientedEntityTable.hpp:242
A SparseTable stores a table with rows of varying size as efficiently as possible.
Definition: SparseTable.hpp:116
The namespace Dune is the main namespace for all Dune code.
Definition: CartesianIndexMapper.hpp:9
ToType operator[](int subindex) const
Random access operator.
Definition: OrientedEntityTable.hpp:119
OPM_HOST_DEVICE int size() const
Returns the number of rows in the table.
Definition: SparseTable.hpp:195
void swap(SparseTable< T > &other)
Swap contents for other SparseTable<T>
Definition: SparseTable.hpp:208
OPM_HOST_DEVICE int dataSize() const
Returns the number of data elements.
Definition: SparseTable.hpp:215
Represents the topological relationships between sets of entities, for example cells and faces...
Definition: OrientedEntityTable.hpp:138
OPM_HOST_DEVICE bool operator==(const SparseTable &other) const
Equality.
Definition: SparseTable.hpp:331
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:182
Struct that hods all the data needed to represent a Cpgrid.
Definition: CpGridData.hpp:117
OrientedEntityTable()
Default constructor.
Definition: OrientedEntityTable.hpp:149
void clear()
Makes the table empty().
Definition: SparseTable.hpp:231
ToType operator[](int subindex) const
Random access operator.
Definition: OrientedEntityTable.hpp:80
OPM_HOST_DEVICE row_type operator[](int row) const
Returns a row of the table.
Definition: SparseTable.hpp:272
MutableOrientedEntityRange()
Default constructor yielding an empty range.
Definition: OrientedEntityTable.hpp:101
OPM_HOST_DEVICE int rowSize(int row) const
Returns the size of a table row.
Definition: SparseTable.hpp:221
void allocate(IntegerIter rowsize_beg, IntegerIter rowsize_end)
Request storage for table of given size.
Definition: SparseTable.hpp:170
OrientedEntityRange()
Default constructor yielding an empty range.
Definition: OrientedEntityTable.hpp:62
void printRelationMatrix(std::ostream &os) const
Prints the full relation matrix corresponding to the table.
Definition: OrientedEntityTable.hpp:272
void swap(OrientedEntityTable &other)
Swap contents for other OrientedEntityTable.
Definition: OrientedEntityTable.hpp:215
A class used as a row type for OrientedEntityTable.
Definition: OrientedEntityTable.hpp:93
OrientedEntityRange(const R &r, bool orientation)
Constructor taking a row type and an orientation.
Definition: OrientedEntityTable.hpp:69
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:192
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:311
Represents an entity of a given codim, with positive or negative orientation.
Definition: CpGridData.hpp:96
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:165
void appendRow(DataIter row_beg, DataIter row_end)
Appends a row to the table.
Definition: SparseTable.hpp:182
bool operator==(const OrientedEntityTable &other) const
Elementwise equality.
Definition: OrientedEntityTable.hpp:209
A class used as a row type for OrientedEntityTable.
Definition: OrientedEntityTable.hpp:54