RegionMapping.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2014 SINTEF ICT, Applied Mathematics.
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef OPM_REGIONMAPPING_HEADER_INCLUDED
21 #define OPM_REGIONMAPPING_HEADER_INCLUDED
22 
23 #include <boost/range.hpp>
24 
25 #include <unordered_map>
26 #include <vector>
27 
28 namespace Opm
29 {
30 
42  template < class Region = std::vector<int> >
43  class RegionMapping {
44  public:
51  explicit
52  RegionMapping(const Region& reg)
53  : reg_(reg)
54  {
55  rev_.init(reg_);
56  }
57 
62  typedef typename Region::value_type RegionId;
63 
68  typedef typename Region::size_type CellId;
69 
74  typedef typename std::vector<CellId>::const_iterator CellIter;
75 
76  typedef boost::iterator_range<CellIter> Range;
77 
84  RegionId
85  region(const CellId c) const { return reg_[c]; }
86 
87  const std::vector<RegionId>&
88  activeRegions() const
89  {
90  return rev_.active;
91  }
92 
101  Range
102  cells(const RegionId r) const {
103  const auto id = rev_.binid.find(r);
104 
105  if (id == rev_.binid.end()) {
106  // Region 'r' not an active region. Return empty.
107  return Range(rev_.c.end(), rev_.c.end());
108  }
109 
110  const auto i = id->second;
111 
112  return Range(rev_.c.begin() + rev_.p[i + 0],
113  rev_.c.begin() + rev_.p[i + 1]);
114  }
115 
116  private:
120  Region reg_;
121 
125  struct {
126  typedef typename std::vector<CellId>::size_type Pos;
127 
128  std::unordered_map<RegionId, Pos> binid;
129  std::vector<RegionId> active;
130 
131  std::vector<Pos> p;
132  std::vector<CellId> c;
138  void
139  init(const Region& reg)
140  {
141  binid.clear();
142  for (const auto& r : reg) {
143  ++binid[r];
144  }
145 
146  p .clear(); p.emplace_back(0);
147  active.clear();
148  {
149  Pos n = 0;
150  for (auto& id : binid) {
151  active.push_back(id.first);
152  p .push_back(id.second);
153 
154  id.second = n++;
155  }
156  }
157 
158  for (decltype(p.size()) i = 1, sz = p.size(); i < sz; ++i) {
159  p[0] += p[i];
160  p[i] = p[0] - p[i];
161  }
162 
163  assert (p[0] == static_cast<Pos>(reg.size()));
164 
165  c.resize(reg.size());
166  {
167  CellId i = 0;
168  for (const auto& r : reg) {
169  auto& pos = p[ binid[r] + 1 ];
170  c[ pos++ ] = i++;
171  }
172  }
173 
174  p[0] = 0;
175  }
176  } rev_;
177  };
178 
179 } // namespace Opm
180 
181 #endif // OPM_REGIONMAPPING_HEADER_INCLUDED
const std::vector< RegionId > & activeRegions() const
Definition: RegionMapping.hpp:88
boost::iterator_range< CellIter > Range
Definition: RegionMapping.hpp:76
Definition: AnisotropicEikonal.hpp:43
std::vector< CellId >::const_iterator CellIter
Definition: RegionMapping.hpp:74
RegionId region(const CellId c) const
Definition: RegionMapping.hpp:85
const double second
Definition: Units.hpp:93
std::vector< Pos > p
Definition: RegionMapping.hpp:131
std::unordered_map< RegionId, Pos > binid
Definition: RegionMapping.hpp:128
Range cells(const RegionId r) const
Definition: RegionMapping.hpp:102
RegionMapping(const Region &reg)
Definition: RegionMapping.hpp:52
Definition: RegionMapping.hpp:43
Region::size_type CellId
Definition: RegionMapping.hpp:68
std::vector< CellId >::size_type Pos
Definition: RegionMapping.hpp:126
std::vector< RegionId > active
Definition: RegionMapping.hpp:129
std::vector< CellId > c
Definition: RegionMapping.hpp:132
Region::value_type RegionId
Definition: RegionMapping.hpp:62