My Project
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;
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
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 
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 
236  void printSparseRelationMatrix(std::ostream& os) const
237  {
238  for (int i = 0; i < size(); ++i) {
239  const FromType from_ent(i, true);
240  const row_type r = operator[](from_ent);
241  const int rsize = r.size();
242  for (int j = 0; j < rsize; ++j) {
243  os << i << ' ' << r[j].index() << ' ' << (r[j].orientation() ? 1 : -1) << '\n';
244  }
245  }
246  os << std::flush;
247  }
248 
266  void printRelationMatrix(std::ostream& os) const
267  {
268  int columns = numberOfColumns();
269  for (int i = 0; i < size(); ++i) {
270  FromType from_ent(i, true);
271  row_type r = operator[](from_ent);
272  int cur_col = 0;
273  int next_ent = 0;
274  ToType to_ent = r[next_ent];
275  int next_print = to_ent.index();
276  while (cur_col < columns) {
277  if (cur_col == next_print) {
278  if (to_ent.orientation()) {
279  os << " 1";
280  } else {
281  os << " -1";
282  }
283  ++next_ent;
284  if (next_ent >= r.size()) {
285  next_print = columns;
286  } else {
287  to_ent = r[next_ent];
288  next_print = to_ent.index();
289  }
290  } else {
291  os << " 0";
292  }
293  ++cur_col;
294  }
295  os << '\n';
296  }
297  }
298 
306  {
307  // Find the maximum index used. This will give (one less than) the size
308  // of the table to be created.
309  int maxind = -1;
310  for (int i = 0; i < size(); ++i) {
311  EntityRep<codim_from> from_ent(i, true);
312  row_type r = operator[](from_ent);
313  for (int j = 0; j < r.size(); ++j) {
314  EntityRep<codim_to> to_ent = r[j];
315  int ind = to_ent.index();
316  maxind = std::max(ind, maxind);
317  }
318  }
319  // Build the new_sizes vector and compute datacount.
320  std::vector<int> new_sizes(maxind + 1);
321  int datacount = 0;
322  for (int i = 0; i < size(); ++i) {
323  EntityRep<codim_from> from_ent(i, true);
324  row_type r = operator[](from_ent);
325  datacount += r.size();
326  for (int j = 0; j < r.size(); ++j) {
327  EntityRep<codim_to> to_ent = r[j];
328  int ind = to_ent.index();
329  ++new_sizes[ind];
330  }
331  }
332  // Compute the cumulative sizes.
333  std::vector<int> cumul_sizes(new_sizes.size() + 1);
334  cumul_sizes[0] = 0;
335  std::partial_sum(new_sizes.begin(), new_sizes.end(), cumul_sizes.begin() + 1);
336  // Using the cumulative sizes array as indices, we populate new_data.
337  // Note that cumul_sizes[ind] is not kept constant, but incremented so that
338  // it always gives the correct index for new data corresponding to index ind.
339  std::vector<EntityRep<codim_from> > new_data(datacount);
340  for (int i = 0; i < size(); ++i) {
341  EntityRep<codim_from> from_ent(i, true);
342  row_type r = operator[](from_ent);
343  for (int j = 0; j < r.size(); ++j) {
344  EntityRep<codim_to> to_ent(r[j]);
345  int ind = to_ent.index();
346  int data_ind = cumul_sizes[ind];
347  new_data[data_ind] = to_ent.orientation() ? from_ent : from_ent.opposite();
348  ++cumul_sizes[ind];
349  }
350  }
351  inv = OrientedEntityTable<codim_to, codim_from>(new_data.begin(),
352  new_data.end(),
353  new_sizes.begin(),
354  new_sizes.end());
355  }
356 
357  private:
358  int numberOfColumns() const
359  {
360  int maxind = 0;
361  for (int i = 0; i < size(); ++i) {
362  FromType from_ent(i, true);
363  row_type r = operator[](from_ent);
364  for (int j = 0; j < r.size(); ++j) {
365  maxind = std::max(maxind, r[j].index());
366  }
367  }
368  return maxind + 1;
369  }
370  };
371 
372 
373  } // namespace cpgrid
374 } // namespace Dune
375 
376 
377 
378 
379 #endif // OPM_ORIENTEDENTITYTABLE_HEADER
Struct that hods all the data needed to represent a Cpgrid.
Definition: CpGridData.hpp:123
Represents an entity of a given codim, with positive or negative orientation.
Definition: EntityRep.hpp:98
bool orientation() const
Returns true if the entity has positive orientation.
Definition: EntityRep.hpp:139
EntityRep opposite() const
Returns an EntityRep with opposite orientation.
Definition: EntityRep.hpp:146
int index() const
The (positive) index of an entity.
Definition: EntityRep.hpp:125
A class used as a row type for OrientedEntityTable.
Definition: OrientedEntityTable.hpp:94
MutableOrientedEntityRange()
Default constructor yielding an empty range.
Definition: OrientedEntityTable.hpp:101
MutableOrientedEntityRange(const R &r, bool orientation)
Constructor taking a row type and an orientation.
Definition: OrientedEntityTable.hpp:108
ToType operator[](int subindex) const
Random access operator.
Definition: OrientedEntityTable.hpp:119
A class used as a row type for OrientedEntityTable.
Definition: OrientedEntityTable.hpp:55
OrientedEntityRange(const R &r, bool orientation)
Constructor taking a row type and an orientation.
Definition: OrientedEntityTable.hpp:69
OrientedEntityRange()
Default constructor yielding an empty range.
Definition: OrientedEntityTable.hpp:62
ToType operator[](int subindex) const
Random access operator.
Definition: OrientedEntityTable.hpp:80
Represents the topological relationships between sets of entities, for example cells and faces.
Definition: OrientedEntityTable.hpp:139
int size() const
Returns the number of rows in the table.
Definition: SparseTable.hpp:121
void printRelationMatrix(std::ostream &os) const
Prints the full relation matrix corresponding to the table.
Definition: OrientedEntityTable.hpp:266
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
OrientedEntityTable()
Default constructor.
Definition: OrientedEntityTable.hpp:149
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
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
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
bool operator==(const OrientedEntityTable &other) const
Elementwise equality.
Definition: OrientedEntityTable.hpp:209
void printSparseRelationMatrix(std::ostream &os) const
Prints the relation matrix corresponding to the table, sparse format.
Definition: OrientedEntityTable.hpp:236
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:305
A SparseTable stores a table with rows of varying size as efficiently as possible.
Definition: SparseTable.hpp:55
bool empty() const
True if the table contains no rows.
Definition: SparseTable.hpp:115
void appendRow(DataIter row_beg, DataIter row_end)
Appends a row to the table.
Definition: SparseTable.hpp:108
int size() const
Returns the number of rows in the table.
Definition: SparseTable.hpp:121
row_type operator[](int row) const
Returns a row of the table.
Definition: SparseTable.hpp:167
int rowSize(int row) const
Returns the size of a table row.
Definition: SparseTable.hpp:147
int dataSize() const
Returns the number of data elements.
Definition: SparseTable.hpp:141
void allocate(IntegerIter rowsize_beg, IntegerIter rowsize_end)
Request storage for table of given size.
Definition: SparseTable.hpp:96
void clear()
Makes the table empty().
Definition: SparseTable.hpp:156
bool operator==(const SparseTable &other) const
Equality.
Definition: SparseTable.hpp:226
Copyright 2019 Equinor AS.
Definition: CartesianIndexMapper.hpp:10
Definition: IteratorRange.hpp:50
Definition: IteratorRange.hpp:70