opm-simulators
FlowBaseVanguard.hpp
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
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 2 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  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
27 #ifndef OPM_FLOW_BASE_VANGUARD_HPP
28 #define OPM_FLOW_BASE_VANGUARD_HPP
29 
30 #include <dune/grid/common/partitionset.hh>
31 
32 #include <opm/grid/common/GridEnums.hpp>
33 #include <opm/grid/common/CartesianIndexMapper.hpp>
34 #include <opm/grid/LookUpCellCentroid.hh>
35 
36 #include <opm/input/eclipse/EclipseState/Aquifer/NumericalAquifer/NumericalAquiferCell.hpp>
37 #include <opm/input/eclipse/EclipseState/EclipseState.hpp>
38 
44 
45 #include <opm/simulators/flow/BlackoilModelParameters.hpp>
47 
48 #include <array>
49 #include <cstddef>
50 #include <optional>
51 #include <unordered_map>
52 #include <vector>
53 
54 namespace Opm {
55 template <class TypeTag>
57 template<typename Grid, typename GridView> struct LookUpCellCentroid;
58 }
59 
60 namespace Opm::Properties {
61 
62 namespace TTag {
63 
64 struct FlowBaseVanguard {};
65 
66 }
67 
68 // declare the properties required by the for the ecl simulator vanguard
69 template<class TypeTag, class MyTypeTag>
70 struct EquilGrid { using type = UndefinedProperty; };
71 
72 } // namespace Opm::Properties
73 
74 namespace Opm {
75 
81 template <class TypeTag>
82 class FlowBaseVanguard : public BaseVanguard<TypeTag>,
83  public FlowGenericVanguard
84 {
85  using ParentType = BaseVanguard<TypeTag>;
86  using Implementation = GetPropType<TypeTag, Properties::Vanguard>;
90 
91  enum { enableExperiments = getPropValue<TypeTag, Properties::EnableExperiments>() };
92 
93 public:
94  using Grid = GetPropType<TypeTag, Properties::Grid>;
95  using GridView = GetPropType<TypeTag, Properties::GridView>;
96 
97 protected:
98  static const int dimension = Grid::dimension;
99  static const int dimensionworld = Grid::dimensionworld;
100  using Element = typename GridView::template Codim<0>::Entity;
101  using CartesianIndexMapper = Dune::CartesianIndexMapper<Grid>;
102 
103 public:
105  virtual ~FlowBaseVanguard() = default;
106 
110  static void registerParameters()
111  {
112  FlowGenericVanguard::registerParameters_<Scalar>();
113  }
114 
121  explicit FlowBaseVanguard(Simulator& simulator)
122  : ParentType(simulator)
123  {
124 #if HAVE_MPI
125  imbalanceTol_ = Parameters::Get<Parameters::ImbalanceTol<Scalar>>();
126 
127  zoltanImbalanceTolSet_ = Parameters::IsSet<Parameters::ZoltanImbalanceTol<Scalar>>();
128  zoltanImbalanceTol_ = Parameters::Get<Parameters::ZoltanImbalanceTol<Scalar>>();
129 #endif
130  enableExperiments_ = enableExperiments;
131 
132  init();
133  }
134 
135  const CartesianIndexMapper& cartesianMapper() const
136  { return asImp_().cartesianIndexMapper(); }
137 
141  const std::array<int, dimension>& cartesianDimensions() const
142  { return asImp_().cartesianIndexMapper().cartesianDimensions(); }
143 
147  int cartesianSize() const
148  { return asImp_().cartesianIndexMapper().cartesianSize(); }
149 
153  int equilCartesianSize() const
154  { return asImp_().equilCartesianIndexMapper().cartesianSize(); }
155 
159  unsigned cartesianIndex(unsigned compressedCellIdx) const
160  { return asImp_().cartesianIndexMapper().cartesianIndex(compressedCellIdx); }
161 
165  unsigned cartesianIndex(const std::array<int,dimension>& coords) const
166  {
167  unsigned cartIndex = coords[0];
168  int factor = cartesianDimensions()[0];
169  for (unsigned i = 1; i < dimension; ++i) {
170  cartIndex += coords[i]*factor;
171  factor *= cartesianDimensions()[i];
172  }
173 
174  return cartIndex;
175  }
176 
183  int compressedIndex(int cartesianCellIdx) const
184  {
185  auto index_pair = cartesianToCompressed_.find(cartesianCellIdx);
186  if (index_pair!=cartesianToCompressed_.end())
187  return index_pair->second;
188  else
189  return -1;
190  }
191 
198  int compressedIndexForInterior(int cartesianCellIdx) const
199  {
200  auto index_pair = cartesianToCompressed_.find(cartesianCellIdx);
201  if (index_pair == cartesianToCompressed_.end() ||
202  !is_interior_[index_pair->second])
203  {
204  return -1;
205  }
206  else
207  {
208  return index_pair->second;
209  }
210  }
211 
212  virtual int compressedIndexForInteriorLGR([[maybe_unused]] const std::string& lgr_tag,
213  [[maybe_unused]] const Connection& conn) const
214  {
215  throw std::runtime_error("compressedIndexForInteriorLGR not implemented");
216  }
217 
224  void cartesianCoordinate(unsigned cellIdx, std::array<int,3>& ijk) const
225  { return asImp_().cartesianIndexMapper().cartesianCoordinate(cellIdx, ijk); }
226 
230  unsigned equilCartesianIndex(unsigned compressedEquilCellIdx) const
231  { return asImp_().equilCartesianIndexMapper().cartesianIndex(compressedEquilCellIdx); }
232 
239  void equilCartesianCoordinate(unsigned cellIdx, std::array<int,3>& ijk) const
240  { return asImp_().equilCartesianIndexMapper().cartesianCoordinate(cellIdx, ijk); }
241 
242 
249  Scalar cellCenterDepth(unsigned globalSpaceIdx) const
250  {
251  return cellCenterDepth_[globalSpaceIdx];
252  }
253 
254  const std::vector<Scalar>& cellCenterDepths() const
255  {
256  return cellCenterDepth_;
257  }
258 
266  Scalar cellThickness(unsigned globalSpaceIdx) const
267  {
268  assert(!cellThickness_.empty());
269  return cellThickness_[globalSpaceIdx];
270  }
271 
277  std::size_t globalNumCells() const
278  {
279  const auto& grid = asImp_().grid();
280  if (grid.comm().size() == 1)
281  {
282  return grid.leafGridView().size(0);
283  }
284  const auto& gridView = grid.leafGridView();
285  constexpr int codim = 0;
286  constexpr auto Part = Dune::Interior_Partition;
287  auto local_cells = std::distance(gridView.template begin<codim, Part>(),
288  gridView.template end<codim, Part>());
289  return grid.comm().sum(local_cells);
290  }
291 
292 protected:
303  template<class CartMapper>
304  std::function<std::array<double,dimensionworld>(int)>
305  cellCentroids_(const CartMapper& cartMapper, const bool& isCpGrid) const
306  {
307  return [this, cartMapper, isCpGrid](int elemIdx) {
308  std::array<double,dimensionworld> centroid;
309  const auto rank = this->gridView().comm().rank();
310  const auto maxLevel = this->gridView().grid().maxLevel();
311  bool useEclipse = !isCpGrid || (isCpGrid && (rank == 0) && (maxLevel == 0));
312  if (useEclipse)
313  {
314  centroid = this->eclState().getInputGrid().getCellCenter(cartMapper.cartesianIndex(elemIdx));
315  }
316  else
317  {
318  LookUpCellCentroid<Grid,GridView> lookUpCellCentroid(this->gridView(), cartMapper, nullptr);
319  centroid = lookUpCellCentroid(elemIdx);
320  }
321  return centroid;
322  };
323  }
324 
325  void callImplementationInit()
326  {
327  asImp_().createGrids_();
328  std::string outputDir = Parameters::Get<Parameters::OutputDir>();
329  bool enableEclCompatFile = !Parameters::Get<Parameters::EnableOpmRstFile>();
330  asImp_().updateOutputDir_(outputDir, enableEclCompatFile);
331  const std::string& dryRunString = Parameters::Get<Parameters::EnableDryRun>();
332  asImp_().updateNOSIM_(dryRunString);
333  asImp_().finalizeInit_();
334  }
335 
336  void updateCartesianToCompressedMapping_()
337  {
338  std::size_t num_cells = asImp_().grid().leafGridView().size(0);
339  is_interior_.resize(num_cells);
340 
341  ElementMapper elemMapper(this->gridView(), Dune::mcmgElementLayout());
342  for (const auto& element : elements(this->gridView()))
343  {
344  const auto elemIdx = elemMapper.index(element);
345  unsigned cartesianCellIdx = cartesianIndex(elemIdx);
346  cartesianToCompressed_[cartesianCellIdx] = elemIdx;
347  if (element.partitionType() == Dune::InteriorEntity)
348  {
349  is_interior_[elemIdx] = 1;
350  }
351  else
352  {
353  is_interior_[elemIdx] = 0;
354  }
355  }
356  }
357 
358  void updateCellDepths_()
359  {
360  int numCells = this->gridView().size(/*codim=*/0);
361  cellCenterDepth_.resize(numCells);
362 
363  ElementMapper elemMapper(this->gridView(), Dune::mcmgElementLayout());
364 
365  const auto num_aqu_cells = this->allAquiferCells();
366 
367  for(const auto& element : elements(this->gridView())) {
368  const unsigned int elemIdx = elemMapper.index(element);
369  cellCenterDepth_[elemIdx] = cellCenterDepth(element);
370 
371  if (!num_aqu_cells.empty()) {
372  const unsigned int global_index = cartesianIndex(elemIdx);
373  const auto search = num_aqu_cells.find(global_index);
374  if (search != num_aqu_cells.end()) {
375  // updating the cell depth using aquifer cell depth
376  cellCenterDepth_[elemIdx] = search->second->depth;
377  }
378  }
379  }
380  }
381  void updateCellThickness_()
382  {
383  if (!this->drsdtconEnabled())
384  return;
385 
386  ElementMapper elemMapper(this->gridView(), Dune::mcmgElementLayout());
387 
388  int numElements = this->gridView().size(/*codim=*/0);
389  cellThickness_.resize(numElements);
390 
391  for (const auto& elem : elements(this->gridView())) {
392  const unsigned int elemIdx = elemMapper.index(elem);
393  cellThickness_[elemIdx] = computeCellThickness(elem);
394  }
395  }
396 
397 private:
398  // computed from averaging cell corner depths
399  Scalar cellCenterDepth(const Element& element) const
400  {
401  typedef typename Element::Geometry Geometry;
402  static constexpr int zCoord = Element::dimension - 1;
403  Scalar zz = 0.0;
404 
405  const Geometry& geometry = element.geometry();
406  const int corners = geometry.corners();
407  for (int i=0; i < corners; ++i)
408  zz += geometry.corner(i)[zCoord];
409 
410  return zz/Scalar(corners);
411  }
412 
413  Scalar computeCellThickness(const typename GridView::template Codim<0>::Entity& element) const
414  {
415  typedef typename Element::Geometry Geometry;
416  static constexpr int zCoord = Element::dimension - 1;
417  Scalar zz1 = 0.0;
418  Scalar zz2 = 0.0;
419 
420  const Geometry& geometry = element.geometry();
421  // This code only works with CP-grid where the
422  // number of corners are 8 and
423  // also assumes that the first
424  // 4 corners are the top surface and
425  // the 4 next are the bottomn.
426  assert(geometry.corners() == 8);
427  for (int i=0; i < 4; ++i){
428  zz1 += geometry.corner(i)[zCoord];
429  zz2 += geometry.corner(i+4)[zCoord];
430  }
431  zz1 /=4;
432  zz2 /=4;
433  return zz2-zz1;
434  }
435 
436  Implementation& asImp_()
437  { return *static_cast<Implementation*>(this); }
438 
439  const Implementation& asImp_() const
440  { return *static_cast<const Implementation*>(this); }
441 
442 protected:
446  std::unordered_map<int,int> cartesianToCompressed_;
450  mutable std::optional<std::vector<std::unordered_map<std::size_t, std::size_t>>> lgrMappers_;
453  std::vector<Scalar> cellCenterDepth_;
454 
457  std::vector<Scalar> cellThickness_;
458 
461  std::vector<int> is_interior_;
462 };
463 
464 } // namespace Opm
465 
466 #endif // OPM_FLOW_BASE_VANGUARD_HPP
unsigned cartesianIndex(unsigned compressedCellIdx) const
Returns the Cartesian cell id for identifaction with ECL data.
Definition: FlowBaseVanguard.hpp:159
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(...))
Definition: propertysystem.hh:233
const EclipseState & eclState() const
Return a reference to the internalized ECL deck.
Definition: FlowGenericVanguard.hpp:168
Definition: FlowBaseVanguard.hpp:57
Scalar cellCenterDepth(unsigned globalSpaceIdx) const
Returns the depth of a degree of freedom [m].
Definition: FlowBaseVanguard.hpp:249
std::vector< Scalar > cellCenterDepth_
Cell center depths.
Definition: FlowBaseVanguard.hpp:453
Helper class for grid instantiation of ECL file-format using problems.
This file provides the infrastructure to retrieve run-time parameters.
const GridView & gridView() const
Returns a reference to the grid view to be used.
Definition: basevanguard.hh:70
std::optional< std::vector< std::unordered_map< std::size_t, std::size_t > > > lgrMappers_
Mapping between LGR cartesian and compressed cells.
Definition: FlowBaseVanguard.hpp:450
int equilCartesianSize() const
Returns the overall number of cells of the logically EquilCartesian grid.
Definition: FlowBaseVanguard.hpp:153
a tag to mark properties as undefined
Definition: propertysystem.hh:38
Definition: FlowBaseVanguard.hpp:70
Provides the base class for most (all?) simulator vanguards.
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Declare the properties used by the infrastructure code of the finite volume discretizations.
int compressedIndexForInterior(int cartesianCellIdx) const
Return compressed index from cartesian index only in interior.
Definition: FlowBaseVanguard.hpp:198
std::unordered_map< int, int > cartesianToCompressed_
Mapping between cartesian and compressed cells.
Definition: FlowBaseVanguard.hpp:446
std::vector< int > is_interior_
Whether a cells is in the interior.
Definition: FlowBaseVanguard.hpp:461
int cartesianSize() const
Returns the overall number of cells of the logically Cartesian grid.
Definition: FlowBaseVanguard.hpp:147
Definition: FlowBaseVanguard.hpp:64
void cartesianCoordinate(unsigned cellIdx, std::array< int, 3 > &ijk) const
Extract Cartesian index triplet (i,j,k) of an active cell.
Definition: FlowBaseVanguard.hpp:224
Declare the properties used by the infrastructure code of the finite volume discretizations.
int compressedIndex(int cartesianCellIdx) const
Return compressed index from cartesian index.
Definition: FlowBaseVanguard.hpp:183
unsigned equilCartesianIndex(unsigned compressedEquilCellIdx) const
Returns the Cartesian cell id given an element index for the grid used for equilibration.
Definition: FlowBaseVanguard.hpp:230
static void registerParameters()
Register the common run-time parameters for all ECL simulator vanguards.
Definition: FlowBaseVanguard.hpp:110
std::vector< Scalar > cellThickness_
Cell thickness.
Definition: FlowBaseVanguard.hpp:457
Helper class for grid instantiation of ECL file-format using problems.
Definition: FlowBaseVanguard.hpp:56
unsigned cartesianIndex(const std::array< int, dimension > &coords) const
Return the index of the cells in the logical Cartesian grid.
Definition: FlowBaseVanguard.hpp:165
std::size_t globalNumCells() const
Get the number of cells in the global leaf grid view.
Definition: FlowBaseVanguard.hpp:277
Definition: FlowGenericVanguard.hpp:108
void equilCartesianCoordinate(unsigned cellIdx, std::array< int, 3 > &ijk) const
Extract Cartesian index triplet (i,j,k) of an active cell of the grid used for EQUIL.
Definition: FlowBaseVanguard.hpp:239
The Opm property system, traits with inheritance.
Scalar cellThickness(unsigned globalSpaceIdx) const
Returns the thickness of a degree of freedom [m].
Definition: FlowBaseVanguard.hpp:266
virtual ~FlowBaseVanguard()=default
Empty virtual dtor.
Provides the base class for most (all?) simulator vanguards.
Definition: basevanguard.hh:49
Definition: CollectDataOnIORank.hpp:49
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:83
Definition: blackoilmodel.hh:80
std::function< std::array< double, dimensionworld >int)> cellCentroids_(const CartMapper &cartMapper, const bool &isCpGrid) const
Get function to query cell centroids for a distributed grid.
Definition: FlowBaseVanguard.hpp:305
const std::array< int, dimension > & cartesianDimensions() const
Returns the number of logically Cartesian cells in each direction.
Definition: FlowBaseVanguard.hpp:141
FlowBaseVanguard(Simulator &simulator)
Create the grid for problem data files which use the ECL file format.
Definition: FlowBaseVanguard.hpp:121