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
47
48#include <array>
49#include <cstddef>
50#include <optional>
51#include <unordered_map>
52#include <vector>
53
54namespace Opm {
55template <class TypeTag>
56class FlowBaseVanguard;
57template<typename Grid, typename GridView> struct LookUpCellCentroid;
58}
59
60namespace Opm::Properties {
61
62namespace TTag {
63
65
66}
67
68// declare the properties required by the for the ecl simulator vanguard
69template<class TypeTag, class MyTypeTag>
70struct EquilGrid { using type = UndefinedProperty; };
71
72} // namespace Opm::Properties
73
74namespace Opm {
75
81template <class TypeTag>
82class FlowBaseVanguard : public BaseVanguard<TypeTag>,
84{
86 using Implementation = GetPropType<TypeTag, Properties::Vanguard>;
90
91 enum { enableExperiments = getPropValue<TypeTag, Properties::EnableExperiments>() };
92
93public:
96
97protected:
98 static const int dimension = Grid::dimension;
99 static const int dimensionworld = Grid::dimensionworld;
100 using Element = typename GridView::template Codim<0>::Entity;
102
103public:
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
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
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
257 bool cellDepthsEdited() const
258 {
259 const auto& comm = this->gridView().comm();
260 int depthEdited = (comm.rank() == 0)
261 && this->eclState().globalFieldProps().depth_edited();
262 return comm.max(depthEdited) != 0;
263 }
264
265 const std::vector<Scalar>& cellCenterDepths() const
266 {
267 return cellCenterDepth_;
268 }
269
277 Scalar cellThickness(unsigned globalSpaceIdx) const
278 {
279 assert(!cellThickness_.empty());
280 return cellThickness_[globalSpaceIdx];
281 }
282
288 std::size_t globalNumCells() const
289 {
290 const auto& grid = asImp_().grid();
291 if (grid.comm().size() == 1)
292 {
293 return grid.leafGridView().size(0);
294 }
295 const auto& gridView = grid.leafGridView();
296 constexpr int codim = 0;
297 constexpr auto Part = Dune::Interior_Partition;
298 auto local_cells = std::distance(gridView.template begin<codim, Part>(),
299 gridView.template end<codim, Part>());
300 return grid.comm().sum(local_cells);
301 }
302
303protected:
314 template<class CartMapper>
315 std::function<std::array<double,dimensionworld>(int)>
316 cellCentroids_(const CartMapper& cartMapper, const bool& isCpGrid) const
317 {
318 return [this, cartMapper, isCpGrid](int elemIdx) {
319 std::array<double,dimensionworld> centroid;
320 const auto rank = this->gridView().comm().rank();
321 const auto maxLevel = this->gridView().grid().maxLevel();
322 bool useEclipse = !isCpGrid || (isCpGrid && (rank == 0) && (maxLevel == 0));
323 if (useEclipse)
324 {
325 centroid = this->eclState().getInputGrid().getCellCenter(cartMapper.cartesianIndex(elemIdx));
326 }
327 else
328 {
329 LookUpCellCentroid<Grid,GridView> lookUpCellCentroid(this->gridView(), cartMapper, nullptr);
330 centroid = lookUpCellCentroid(elemIdx);
331 }
332 return centroid;
333 };
334 }
335
337 {
338 asImp_().createGrids_();
339 std::string outputDir = Parameters::Get<Parameters::OutputDir>();
340 bool enableEclCompatFile = !Parameters::Get<Parameters::EnableOpmRstFile>();
341 asImp_().updateOutputDir_(outputDir, enableEclCompatFile);
342 const std::string& dryRunString = Parameters::Get<Parameters::EnableDryRun>();
343 asImp_().updateNOSIM_(dryRunString);
344 asImp_().finalizeInit_();
345 }
346
348 {
349 std::size_t num_cells = asImp_().grid().leafGridView().size(0);
350 is_interior_.resize(num_cells);
351
352 ElementMapper elemMapper(this->gridView(), Dune::mcmgElementLayout());
353 for (const auto& element : elements(this->gridView()))
354 {
355 const auto elemIdx = elemMapper.index(element);
356 unsigned cartesianCellIdx = cartesianIndex(elemIdx);
357 cartesianToCompressed_[cartesianCellIdx] = elemIdx;
358 if (element.partitionType() == Dune::InteriorEntity)
359 {
360 is_interior_[elemIdx] = 1;
361 }
362 else
363 {
364 is_interior_[elemIdx] = 0;
365 }
366 }
367 }
368
370 {
371 int numCells = this->gridView().size(/*codim=*/0);
372 cellCenterDepth_.resize(numCells);
373
374 ElementMapper elemMapper(this->gridView(), Dune::mcmgElementLayout());
375
376 const auto num_aqu_cells = this->allAquiferCells();
377 const auto* depthEdits = this->editedCellDepths_(numCells);
378
379 for (const auto& element : elements(this->gridView())) {
380 const unsigned int elemIdx = elemMapper.index(element);
381 cellCenterDepth_[elemIdx] = depthEdits != nullptr
382 ? (*depthEdits)[elemIdx]
383 : cellCenterDepth(element);
384
385 if (!num_aqu_cells.empty()) {
386 const unsigned int global_index = cartesianIndex(elemIdx);
387 const auto search = num_aqu_cells.find(global_index);
388 if (search != num_aqu_cells.end()) {
389 // updating the cell depth using aquifer cell depth
390 cellCenterDepth_[elemIdx] = search->second->depth;
391 }
392 }
393 }
394 }
395
404 const std::vector<double>* editedCellDepths_(const int numCells) const
405 {
406 const auto& comm = this->gridView().comm();
407
408 int depthEdited = (comm.rank() == 0)
409 && this->eclState().globalFieldProps().depth_edited();
410 depthEdited = comm.max(depthEdited);
411
412 if (!depthEdited) {
413 return nullptr;
414 }
415
416 const auto& depth = this->eclState().fieldProps().get_double("DEPTH");
417
418 // The field properties are given on the level zero grid, so they cannot be
419 // indexed by leaf element index when the grid has been refined.
420 if (static_cast<int>(depth.size()) != numCells) {
421 throw std::runtime_error("DEPTH assigned in the EDIT section is not "
422 "supported in combination with LGR");
423 }
424
425 return &depth;
426 }
428 {
429 if (!this->drsdtconEnabled())
430 return;
431
432 ElementMapper elemMapper(this->gridView(), Dune::mcmgElementLayout());
433
434 int numElements = this->gridView().size(/*codim=*/0);
435 cellThickness_.resize(numElements);
436
437 for (const auto& elem : elements(this->gridView())) {
438 const unsigned int elemIdx = elemMapper.index(elem);
439 cellThickness_[elemIdx] = computeCellThickness(elem);
440 }
441 }
442
443private:
444 Scalar cellCenterDepth(const Element& element) const
445 {
446 typedef typename Element::Geometry Geometry;
447 static constexpr int zCoord = Element::dimension - 1;
448 Scalar zz = 0.0;
449
450 const Geometry& geometry = element.geometry();
451 const int corners = geometry.corners();
452 for (int i = 0; i < corners; ++i)
453 zz += geometry.corner(i)[zCoord];
454
455 return zz / Scalar(corners);
456 }
457
458 Scalar computeCellThickness(const typename GridView::template Codim<0>::Entity& element) const
459 {
460 typedef typename Element::Geometry Geometry;
461 static constexpr int zCoord = Element::dimension - 1;
462 Scalar zz1 = 0.0;
463 Scalar zz2 = 0.0;
464
465 const Geometry& geometry = element.geometry();
466 // This code only works with CP-grid where the
467 // number of corners are 8 and
468 // also assumes that the first
469 // 4 corners are the top surface and
470 // the 4 next are the bottomn.
471 assert(geometry.corners() == 8);
472 for (int i=0; i < 4; ++i){
473 zz1 += geometry.corner(i)[zCoord];
474 zz2 += geometry.corner(i+4)[zCoord];
475 }
476 zz1 /=4;
477 zz2 /=4;
478 return zz2-zz1;
479 }
480
481 Implementation& asImp_()
482 { return *static_cast<Implementation*>(this); }
483
484 const Implementation& asImp_() const
485 { return *static_cast<const Implementation*>(this); }
486
487protected:
491 std::unordered_map<int,int> cartesianToCompressed_;
495 mutable std::optional<std::vector<std::unordered_map<std::size_t, std::size_t>>> lgrMappers_;
498 std::vector<Scalar> cellCenterDepth_;
499
502 std::vector<Scalar> cellThickness_;
503
506 std::vector<int> is_interior_;
507};
508
509} // namespace Opm
510
511#endif // OPM_FLOW_BASE_VANGUARD_HPP
Definition: CollectDataOnIORank.hpp:50
Provides the base class for most (all?) simulator vanguards.
Definition: basevanguard.hh:50
const GridView & gridView() const
Returns a reference to the grid view to be used.
Definition: basevanguard.hh:70
Helper class for grid instantiation of ECL file-format using problems.
Definition: FlowBaseVanguard.hpp:84
unsigned cartesianIndex(const std::array< int, dimension > &coords) const
Return the index of the cells in the logical Cartesian grid.
Definition: FlowBaseVanguard.hpp:165
void updateCartesianToCompressedMapping_()
Definition: FlowBaseVanguard.hpp:347
virtual ~FlowBaseVanguard()=default
Empty virtual dtor.
int cartesianSize() const
Returns the overall number of cells of the logically Cartesian grid.
Definition: FlowBaseVanguard.hpp:147
int compressedIndex(int cartesianCellIdx) const
Return compressed index from cartesian index.
Definition: FlowBaseVanguard.hpp:183
const std::vector< double > * editedCellDepths_(const int numCells) const
Cell depths from a DEPTH assignment in the EDIT section, or nullptr.
Definition: FlowBaseVanguard.hpp:404
void updateCellThickness_()
Definition: FlowBaseVanguard.hpp:427
std::vector< Scalar > cellCenterDepth_
Cell center depths.
Definition: FlowBaseVanguard.hpp:498
const std::array< int, dimension > & cartesianDimensions() const
Returns the number of logically Cartesian cells in each direction.
Definition: FlowBaseVanguard.hpp:141
unsigned equilCartesianIndex(unsigned compressedEquilCellIdx) const
Returns the Cartesian cell id given an element index for the grid used for equilibration.
Definition: FlowBaseVanguard.hpp:230
FlowBaseVanguard(Simulator &simulator)
Create the grid for problem data files which use the ECL file format.
Definition: FlowBaseVanguard.hpp:121
int compressedIndexForInterior(int cartesianCellIdx) const
Return compressed index from cartesian index only in interior.
Definition: FlowBaseVanguard.hpp:198
const std::vector< Scalar > & cellCenterDepths() const
Definition: FlowBaseVanguard.hpp:265
bool cellDepthsEdited() const
Whether DEPTH was assigned in the EDIT section (same on all ranks).
Definition: FlowBaseVanguard.hpp:257
unsigned cartesianIndex(unsigned compressedCellIdx) const
Returns the Cartesian cell id for identifaction with ECL data.
Definition: FlowBaseVanguard.hpp:159
static const int dimension
Definition: FlowBaseVanguard.hpp:98
std::vector< int > is_interior_
Whether a cells is in the interior.
Definition: FlowBaseVanguard.hpp:506
void updateCellDepths_()
Definition: FlowBaseVanguard.hpp:369
void callImplementationInit()
Definition: FlowBaseVanguard.hpp:336
const CartesianIndexMapper & cartesianMapper() const
Definition: FlowBaseVanguard.hpp:135
static const int dimensionworld
Definition: FlowBaseVanguard.hpp:99
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
std::unordered_map< int, int > cartesianToCompressed_
Mapping between cartesian and compressed cells. It is initialized the first time it is called.
Definition: FlowBaseVanguard.hpp:491
std::vector< Scalar > cellThickness_
Cell thickness.
Definition: FlowBaseVanguard.hpp:502
std::optional< std::vector< std::unordered_map< std::size_t, std::size_t > > > lgrMappers_
Mapping between LGR cartesian and compressed cells. It is initialized as it is called.
Definition: FlowBaseVanguard.hpp:495
Scalar cellCenterDepth(unsigned globalSpaceIdx) const
Returns the depth of a degree of freedom [m].
Definition: FlowBaseVanguard.hpp:249
virtual int compressedIndexForInteriorLGR(const std::string &lgr_tag, const Connection &conn) const
Definition: FlowBaseVanguard.hpp:212
std::size_t globalNumCells() const
Get the number of cells in the global leaf grid view. \warn This is a collective operation that needs...
Definition: FlowBaseVanguard.hpp:288
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
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:316
Scalar cellThickness(unsigned globalSpaceIdx) const
Returns the thickness of a degree of freedom [m].
Definition: FlowBaseVanguard.hpp:277
typename GridView::template Codim< 0 >::Entity Element
Definition: FlowBaseVanguard.hpp:100
static void registerParameters()
Register the common run-time parameters for all ECL simulator vanguards.
Definition: FlowBaseVanguard.hpp:110
int equilCartesianSize() const
Returns the overall number of cells of the logically EquilCartesian grid.
Definition: FlowBaseVanguard.hpp:153
Definition: FlowGenericVanguard.hpp:108
static Parallel::Communication & comm()
Obtain global communicator.
Definition: FlowGenericVanguard.hpp:330
std::unordered_map< std::size_t, const NumericalAquiferCell * > allAquiferCells() const
bool zoltanImbalanceTolSet_
Definition: FlowGenericVanguard.hpp:383
bool enableExperiments_
Definition: FlowGenericVanguard.hpp:400
const EclipseState & eclState() const
Return a reference to the internalized ECL deck.
Definition: FlowGenericVanguard.hpp:168
bool drsdtconEnabled() const
double zoltanImbalanceTol_
Definition: FlowGenericVanguard.hpp:384
double imbalanceTol_
Definition: FlowGenericVanguard.hpp:381
Declare the properties used by the infrastructure code of the finite volume discretizations.
Declare the properties used by the infrastructure code of the finite volume discretizations.
Definition: blackoilmodel.hh:74
Definition: blackoilbioeffectsmodules.hh:45
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
This file provides the infrastructure to retrieve run-time parameters.
The Opm property system, traits with inheritance.
Definition: FlowBaseVanguard.hpp:57
Definition: FlowBaseVanguard.hpp:70
Definition: FlowBaseVanguard.hpp:64
a tag to mark properties as undefined
Definition: propertysystem.hh:38