opm-common
NNC.hpp
1 /*
2  Copyright 2015 IRIS
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_PARSER_NNC_HPP
21 #define OPM_PARSER_NNC_HPP
22 
23 #include <opm/common/OpmLog/KeywordLocation.hpp>
24 
25 #include <cstddef>
26 #include <map>
27 #include <optional>
28 #include <tuple>
29 #include <vector>
30 
31 namespace Opm
32 {
33 
34 class GridDims;
35 
36 struct NNCdata {
37  NNCdata(std::size_t c1, std::size_t c2, double t)
38  : cell1(c1), cell2(c2), trans(t)
39  {}
40  NNCdata() = default;
41 
42  bool operator==(const NNCdata& data) const
43  {
44  return cell1 == data.cell1 &&
45  cell2 == data.cell2 &&
46  trans == data.trans;
47  }
48 
49  template<class Serializer>
50  void serializeOp(Serializer& serializer)
51  {
52  serializer(cell1);
53  serializer(cell2);
54  serializer(trans);
55  }
56 
57  // Observe that the operator< is only for cell ordering and does not consider the
58  // trans member
59  bool operator<(const NNCdata& other) const
60  {
61  return std::tie(this->cell1, this->cell2) < std::tie(other.cell1, other.cell2);
62  }
63 
64  std::size_t cell1{};
65  std::size_t cell2{};
66  double trans{};
67 };
68 
69 class Deck;
70 class EclipseGrid;
71 
72 /*
73  This class is an internalization of the NNC and EDITNNC keywords. Because the
74  opm-common codebase does not itself manage the simulation grid the purpose of
75  the NNC class is mainly to hold on to the NNC/EDITNNC input and pass it on to
76  the grid construction proper.
77 
78  The EDITNNC keywords can operate on two different types of NNCs.
79 
80  1. NNCs which have been explicitly entered using the NNC keyword.
81  2. NNCs which are inderectly inferred from the grid - e.g. due to faults.
82 
83  When processing the EDITNNC keyword the class will search through the NNCs
84  configured explicitly with the NNC keyword and apply the edit transformation
85  on those NNCs, EDITNNCs which affect NNCs which are not configured explicitly
86  are stored for later use by the simulator.
87 
88  The class guarantees the following ordering:
89 
90  1. For all NNC / EDITNNC records we will have cell1 <= cell2
91  2. The vectors NNC::input() and NNC::edit() will be ordered in ascending
92  order.
93 
94  While constructing from a deck NNCs connected to inactive cells will be
95  silently ignored. Do observe though that the addNNC() function does not check
96  the arguments and alas there is no guarantee that only active cells are
97  involved.
98 */
99 
100 class NNC
101 {
102 public:
103  NNC() = default;
104  virtual ~NNC() = default;
106  NNC(const EclipseGrid& grid, const Deck& deck);
107 
108  static NNC serializationTestObject();
109 
110  virtual bool addNNC(const std::size_t cell1, const std::size_t cell2, const double trans);
111 
113  virtual void merge(const std::vector<NNCdata>& nncs);
115  const std::vector<NNCdata>& input() const { return m_input; }
117  const std::vector<NNCdata>& edit() const { return m_edit; }
119  const std::vector<NNCdata>& editr() const { return m_editr; }
120  KeywordLocation input_location(const NNCdata& nnc) const;
121  KeywordLocation edit_location(const NNCdata& nnc) const;
122  KeywordLocation editr_location(const NNCdata& nnc) const;
123 
124  bool operator==(const NNC& data) const;
125 
126  template<class Serializer>
127  void serializeOp(Serializer& serializer)
128  {
129  serializer(m_input);
130  serializer(m_edit);
131  serializer(m_editr);
132  serializer(m_nnc_location);
133  serializer(m_edit_location);
134  serializer(m_editr_location);
135  }
136 
137 private:
138 
139  void load_input(const EclipseGrid& grid, const Deck& deck);
140  void load_edit(const EclipseGrid& grid, const Deck& deck);
141  void load_editr(const EclipseGrid& grid, const Deck& deck);
142  void add_edit(const NNCdata& edit_node);
143 
145  std::vector<NNCdata> m_input;
147  std::vector<NNCdata> m_edit;
149  std::vector<NNCdata> m_editr;
150  std::optional<KeywordLocation> m_nnc_location;
151  std::optional<KeywordLocation> m_edit_location;
152  std::optional<KeywordLocation> m_editr_location;
153 
154  friend class NNCDiffGrid;
155 };
156 
158 {
159  public:
160  NNCDataContainer() = default;
161  virtual ~NNCDataContainer() = default;
162 
163  virtual bool addNNC(const std::size_t cell1, const std::size_t cell2, const double trans);
164  bool addNNC(const NNCdata nnc_data);
165 
166  const std::vector<NNCdata>& input() const { return nnc_container; }
167 
168  bool operator==(const NNCDataContainer& other) const;
169 
170  protected:
171  std::vector<NNCdata> nnc_container;
172 };
173 
174 /*
175  NNCDiffGrid is derived class of NNC. NNC Class as it does not preserve the
176  order of NNC, therefore not suitable for storing NNC data from different grids.
177 */
179 {
180 public:
181  NNCDataContainerDiffGrid() = default;
182  ~NNCDataContainerDiffGrid() override = default;
183 
184  bool addNNC(const std::size_t cell1, const std::size_t cell2,
185  const double trans) override;
186 
187  void swap_adj(std::size_t grid1, std::size_t grid2);
188 
189  bool operator==(const NNCDataContainerDiffGrid& other) const;
190 };
191 
193 {
194 public:
195  NNCCollection();
196  explicit NNCCollection(NNCDataContainer nnc_global);
197 
198  // ---- insertion --------------------------------------------------------
199 
201  void addNNC(std::size_t grid1, std::size_t grid2, NNCDataContainerDiffGrid nnc);
202 
204  void addNNC(std::size_t grid, NNCDataContainer nnc);
205 
207  void addNNC(NNCDataContainer nnc);
208 
209  // ---- cross-grid access ------------------------------------------------
210 
211  const NNCDataContainerDiffGrid& getNNC(std::size_t grid1, std::size_t grid2) const;
212  NNCDataContainerDiffGrid& getNNC(std::size_t grid1, std::size_t grid2);
213 
214  bool hasCrossGridNNC(std::size_t grid1, std::size_t grid2) const;
215 
220  bool empty() const
221  {
222  for (const auto& [grid, nnc] : m_sameGridNNCs)
223  if (!nnc.input().empty()) return false;
224  for (const auto& [grids, nnc] : m_diffGridNNCs)
225  if (!nnc.input().empty()) return false;
226  return true;
227  }
228  // ---- same-grid access -------------------------------------------------
229 
230  const NNCDataContainer& getNNC(std::size_t grid) const;
231  NNCDataContainer& getNNC(std::size_t grid);
232 
233  bool hasSameGridNNC(std::size_t grid) const;
234 
235  // ---- global (grid 0) access -------------------------------------------
236 
237  const NNCDataContainer& getGlobalNNC() const;
239 
243  bool hasGlobalNNC() const { return !getGlobalNNC().input().empty(); }
244 
247  bool hasNNCForGrid(std::size_t grid_index) const
248  {
249  if (((grid_index == 0) && hasGlobalNNC()) || ((grid_index != 0) && hasSameGridNNC(grid_index)))
250  {
251  return true;
252  }
253  for (const auto& [grid, nnc] : m_diffGridNNCs) {
254  if (const auto& [g1, g2] = grid;
255  ((g1 == grid_index) || (g2 == grid_index)) && !nnc.input().empty())
256  {
257  return true;
258  }
259  }
260  return false;
261  }
262 
264  const std::map<std::size_t, NNCDataContainer>& same_grid_nnc() const
265  {
266  return m_sameGridNNCs;
267  }
268 
270  const std::map<std::pair<std::size_t,std::size_t>, NNCDataContainerDiffGrid>& diff_grid_nnc() const
271  {
272  return m_diffGridNNCs;
273  }
274 
275  // ---- factory ----------------------------------------------------------
276 
296  const std::vector<std::vector<NNCdata>>& outputNnc,
297  const std::vector<std::vector<NNCdata>>& outputNncGlobalLocal,
298  const std::vector<std::vector<std::vector<NNCdata>>>& outputAmalgamatedNnc);
299 
300  bool operator==(const NNCCollection& other) const
301  {
302  return m_sameGridNNCs == other.m_sameGridNNCs &&
303  m_diffGridNNCs == other.m_diffGridNNCs;
304  }
305 
306 private:
307 
309  std::map<std::size_t, NNCDataContainer> m_sameGridNNCs;
310 
312  std::map<std::pair<std::size_t,std::size_t>, NNCDataContainerDiffGrid> m_diffGridNNCs;
313 };
314 
315 } // namespace Opm
316 
317 #endif // OPM_PARSER_NNC_HPP
const NNCDataContainerDiffGrid & getNNC(std::size_t grid1, std::size_t grid2) const
Returns a const reference to the cross-grid NNC for the (grid1, grid2) pair.
Definition: NNC.cpp:465
const std::map< std::pair< std::size_t, std::size_t >, NNCDataContainerDiffGrid > & diff_grid_nnc() const
Returns a view of all cross-grid NNCs keyed by normalised (g1,g2) pairs.
Definition: NNC.hpp:270
void swap_adj(std::size_t grid1, std::size_t grid2)
Swaps cell1 and cell2 in every entry when grid1 > grid2, so that the container is always stored in no...
Definition: NNC.cpp:411
Definition: KeywordLocation.hpp:27
static NNCCollection fromLGROutputContainers(const std::vector< std::vector< NNCdata >> &outputNnc, const std::vector< std::vector< NNCdata >> &outputNncGlobalLocal, const std::vector< std::vector< std::vector< NNCdata >>> &outputAmalgamatedNnc)
Build an NNCCollection from the three output containers produced by EclGenericWriter::exportNncStruct...
Definition: NNC.cpp:566
About cell information and dimension: The actual grid information is held in a pointer to an ERT ecl_...
Definition: EclipseGrid.hpp:63
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
Definition: NNC.hpp:192
virtual bool addNNC(const std::size_t cell1, const std::size_t cell2, const double trans)
Inserts an NNC entry (cell1, cell2, trans) into the container, enforcing cell1 <= cell2...
Definition: NNC.cpp:377
bool hasNNCForGrid(std::size_t grid_index) const
Returns true if the given grid has any NNC involvement: same-grid NNCs with data, or cross-grid NNCs ...
Definition: NNC.hpp:247
Definition: NNC.hpp:178
const std::vector< NNCdata > & edit() const
Get the information from EDITNNC keyword.
Definition: NNC.hpp:117
const std::vector< NNCdata > & input() const
Get the combined information from NNC.
Definition: NNC.hpp:115
bool empty() const
Returns true if the collection holds no NNC data of any kind.
Definition: NNC.hpp:220
Definition: NNC.hpp:157
bool hasGlobalNNC() const
Returns true if the global grid has actual same-grid NNC data.
Definition: NNC.hpp:243
Definition: NNC.hpp:100
const std::map< std::size_t, NNCDataContainer > & same_grid_nnc() const
Returns a view of all same-grid NNCs as (grid_index, NNC) pairs.
Definition: NNC.hpp:264
void addNNC(std::size_t grid1, std::size_t grid2, NNCDataContainerDiffGrid nnc)
Add a cross-grid NNC between grid1 and grid2.
Definition: NNC.cpp:446
NNCCollection()
Default constructor: the global grid (grid 0) always exists, initially with an empty NNC container...
Definition: NNC.cpp:431
bool addNNC(const std::size_t cell1, const std::size_t cell2, const double trans) override
Inserts a cross-grid NNC entry without enforcing any cell ordering, since cell1 and cell2 belong to d...
Definition: NNC.cpp:403
const NNCDataContainer & getGlobalNNC() const
Returns a const reference to the global (grid 0) same-grid NNC.
Definition: NNC.cpp:548
Definition: Deck.hpp:46
const std::vector< NNCdata > & editr() const
Get the information from EDITNNCR keyword.
Definition: NNC.hpp:119
Class for (de-)serializing.
Definition: Serializer.hpp:95
virtual void merge(const std::vector< NNCdata > &nncs)
Merge additional NNCs into sorted NNCs.
Definition: NNC.cpp:290
Definition: NNC.hpp:36