Merge pull request #2222 from dr-robertk/PR/ebos-polyhedralgrid2

Make ebos compile with PolyhedralGrid again.
This commit is contained in:
Markus Blatt 2019-12-18 23:57:38 +01:00 committed by GitHub
commit 2511121a84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 51 deletions

View File

@ -28,6 +28,7 @@
#define EWOMS_ECL_POLYHEDRAL_GRID_VANGUARD_HH #define EWOMS_ECL_POLYHEDRAL_GRID_VANGUARD_HH
#include "eclbasevanguard.hh" #include "eclbasevanguard.hh"
#include "ecltransmissibility.hh"
#include <opm/grid/polyhedralgrid.hh> #include <opm/grid/polyhedralgrid.hh>
@ -78,7 +79,8 @@ private:
public: public:
EclPolyhedralGridVanguard(Simulator& simulator) EclPolyhedralGridVanguard(Simulator& simulator)
: EclBaseVanguard<TypeTag>(simulator) : EclBaseVanguard<TypeTag>(simulator),
simulator_( simulator )
{ {
this->callImplementationInit(); this->callImplementationInit();
} }
@ -147,6 +149,24 @@ public:
const CartesianIndexMapper& equilCartesianIndexMapper() const const CartesianIndexMapper& equilCartesianIndexMapper() const
{ return *cartesianIndexMapper_; } { return *cartesianIndexMapper_; }
/*!
* \brief Free the memory occupied by the global transmissibility object.
*
* After writing the initial solution, this array should not be necessary anymore.
*/
void releaseGlobalTransmissibilities()
{
}
std::unordered_set<std::string> defunctWellNames() const
{ return defunctWellNames_; }
const EclTransmissibility<TypeTag>& globalTransmissibility() const
{
return simulator_.problem().eclTransmissibilities();
}
protected: protected:
void createGrids_() void createGrids_()
{ {
@ -162,8 +182,12 @@ protected:
// not handling the removal of completions for this type of grid yet. // not handling the removal of completions for this type of grid yet.
} }
Simulator& simulator_;
GridPointer grid_; GridPointer grid_;
CartesianIndexMapperPointer cartesianIndexMapper_; CartesianIndexMapperPointer cartesianIndexMapper_;
std::unordered_set<std::string> defunctWellNames_;
}; };
} // namespace Opm } // namespace Opm

View File

@ -148,6 +148,7 @@ class EclWriter
typedef typename GET_PROP_TYPE(TypeTag, Vanguard) Vanguard; typedef typename GET_PROP_TYPE(TypeTag, Vanguard) Vanguard;
typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
typedef typename GET_PROP_TYPE(TypeTag, EquilGrid) EquilGrid;
typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext; typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
@ -180,10 +181,8 @@ public:
, eclOutputModule_(simulator, collectToIORank_) , eclOutputModule_(simulator, collectToIORank_)
{ {
if (collectToIORank_.isIORank()) { if (collectToIORank_.isIORank()) {
globalGrid_ = simulator_.vanguard().grid();
globalGrid_.switchToGlobalView();
eclIO_.reset(new Opm::EclipseIO(simulator_.vanguard().eclState(), eclIO_.reset(new Opm::EclipseIO(simulator_.vanguard().eclState(),
Opm::UgGridHelpers::createEclipseGrid(globalGrid_, simulator_.vanguard().eclState().getInputGrid()), Opm::UgGridHelpers::createEclipseGrid(globalGrid(), simulator_.vanguard().eclState().getInputGrid()),
simulator_.vanguard().schedule(), simulator_.vanguard().schedule(),
simulator_.vanguard().summaryConfig())); simulator_.vanguard().summaryConfig()));
} }
@ -206,14 +205,19 @@ public:
return *eclIO_; return *eclIO_;
} }
const EquilGrid& globalGrid() const
{
return simulator_.vanguard().equilGrid();
}
void writeInit() void writeInit()
{ {
if (collectToIORank_.isIORank()) { if (collectToIORank_.isIORank()) {
std::map<std::string, std::vector<int> > integerVectors; std::map<std::string, std::vector<int> > integerVectors;
if (collectToIORank_.isParallel()) if (collectToIORank_.isParallel())
integerVectors.emplace("MPI_RANK", collectToIORank_.globalRanks()); integerVectors.emplace("MPI_RANK", collectToIORank_.globalRanks());
auto cartMap = Opm::cartesianToCompressed(globalGrid_.size(0), auto cartMap = Opm::cartesianToCompressed(globalGrid().size(0),
Opm::UgGridHelpers::globalCell(globalGrid_)); Opm::UgGridHelpers::globalCell(globalGrid()));
eclIO_->writeInitial(computeTrans_(cartMap), integerVectors, exportNncStructure_(cartMap)); eclIO_->writeInitial(computeTrans_(cartMap), integerVectors, exportNncStructure_(cartMap));
} }
} }
@ -274,13 +278,13 @@ public:
std::map<std::string, double> miscSummaryData; std::map<std::string, double> miscSummaryData;
std::map<std::string, std::vector<double>> regionData; std::map<std::string, std::vector<double>> regionData;
eclOutputModule_.outputFipLog(miscSummaryData, regionData, isSubStep); eclOutputModule_.outputFipLog(miscSummaryData, regionData, isSubStep);
bool forceDisableProdOutput = false; bool forceDisableProdOutput = false;
bool forceDisableInjOutput = false; bool forceDisableInjOutput = false;
bool forceDisableCumOutput = false; bool forceDisableCumOutput = false;
eclOutputModule_.outputProdLog(reportStepNum, isSubStep, forceDisableProdOutput); eclOutputModule_.outputProdLog(reportStepNum, isSubStep, forceDisableProdOutput);
eclOutputModule_.outputInjLog(reportStepNum, isSubStep, forceDisableInjOutput); eclOutputModule_.outputInjLog(reportStepNum, isSubStep, forceDisableInjOutput);
eclOutputModule_.outputCumLog(reportStepNum, isSubStep, forceDisableCumOutput); eclOutputModule_.outputCumLog(reportStepNum, isSubStep, forceDisableCumOutput);
std::vector<char> buffer; std::vector<char> buffer;
if (collectToIORank_.isIORank()) { if (collectToIORank_.isIORank()) {
@ -476,7 +480,7 @@ private:
Opm::data::Solution computeTrans_(const std::unordered_map<int,int>& cartesianToActive) const Opm::data::Solution computeTrans_(const std::unordered_map<int,int>& cartesianToActive) const
{ {
const auto& cartMapper = simulator_.vanguard().cartesianIndexMapper(); const auto& cartMapper = simulator_.vanguard().equilCartesianIndexMapper();
const auto& cartDims = cartMapper.cartesianDimensions(); const auto& cartDims = cartMapper.cartesianDimensions();
const int globalSize = cartDims[0]*cartDims[1]*cartDims[2]; const int globalSize = cartDims[0]*cartDims[1]*cartDims[2];
@ -490,8 +494,8 @@ private:
tranz.data[0] = 0.0; tranz.data[0] = 0.0;
} }
typedef typename Grid :: LeafGridView GlobalGridView; typedef typename EquilGrid :: LeafGridView GlobalGridView;
const GlobalGridView& globalGridView = globalGrid_.leafGridView(); const GlobalGridView& globalGridView = globalGrid().leafGridView();
#if DUNE_VERSION_NEWER(DUNE_GRID, 2,6) #if DUNE_VERSION_NEWER(DUNE_GRID, 2,6)
typedef Dune::MultipleCodimMultipleGeomTypeMapper<GlobalGridView> ElementMapper; typedef Dune::MultipleCodimMultipleGeomTypeMapper<GlobalGridView> ElementMapper;
ElementMapper globalElemMapper(globalGridView, Dune::mcmgElementLayout()); ElementMapper globalElemMapper(globalGridView, Dune::mcmgElementLayout());
@ -500,7 +504,6 @@ private:
ElementMapper globalElemMapper(globalGridView); ElementMapper globalElemMapper(globalGridView);
#endif #endif
const auto& cartesianCellIdx = globalGrid_.globalCell();
const EclTransmissibility<TypeTag>* globalTrans; const EclTransmissibility<TypeTag>* globalTrans;
if (!collectToIORank_.isParallel()) if (!collectToIORank_.isParallel())
@ -538,9 +541,12 @@ private:
continue; // we only need to handle each connection once, thank you. continue; // we only need to handle each connection once, thank you.
// Ordering of compressed and uncompressed index should be the same // Ordering of compressed and uncompressed index should be the same
assert(cartesianCellIdx[c1] <= cartesianCellIdx[c2]); const int cartIdx1 = cartMapper.cartesianIndex( c1 );
int gc1 = std::min(cartesianCellIdx[c1], cartesianCellIdx[c2]); const int cartIdx2 = cartMapper.cartesianIndex( c2 );
int gc2 = std::max(cartesianCellIdx[c1], cartesianCellIdx[c2]); // Ordering of compressed and uncompressed index should be the same
assert(cartIdx1 <= cartIdx2);
int gc1 = std::min(cartIdx1, cartIdx2);
int gc2 = std::max(cartIdx1, cartIdx2);
if (gc2 - gc1 == 1) { if (gc2 - gc1 == 1) {
tranx.data[gc1] = globalTrans->transmissibility(c1, c2); tranx.data[gc1] = globalTrans->transmissibility(c1, c2);
@ -595,8 +601,8 @@ private:
// Checked when writing NNC transmissibilities from the simulation. // Checked when writing NNC transmissibilities from the simulation.
std::sort(nncData.begin(), nncData.end(), nncCompare); std::sort(nncData.begin(), nncData.end(), nncCompare);
typedef typename Grid :: LeafGridView GlobalGridView; typedef typename EquilGrid :: LeafGridView GlobalGridView;
const GlobalGridView& globalGridView = globalGrid_.leafGridView(); const GlobalGridView& globalGridView = globalGrid().leafGridView();
#if DUNE_VERSION_NEWER(DUNE_GRID, 2,6) #if DUNE_VERSION_NEWER(DUNE_GRID, 2,6)
typedef Dune::MultipleCodimMultipleGeomTypeMapper<GlobalGridView> ElementMapper; typedef Dune::MultipleCodimMultipleGeomTypeMapper<GlobalGridView> ElementMapper;
ElementMapper globalElemMapper(globalGridView, Dune::mcmgElementLayout()); ElementMapper globalElemMapper(globalGridView, Dune::mcmgElementLayout());
@ -621,7 +627,10 @@ private:
globalTrans = &(simulator_.vanguard().globalTransmissibility()); globalTrans = &(simulator_.vanguard().globalTransmissibility());
} }
auto cartDims = simulator_.vanguard().cartesianIndexMapper().cartesianDimensions(); // Cartesian index mapper for the serial I/O grid
const auto& equilCartMapper = simulator_.vanguard().equilCartesianIndexMapper();
const auto& cartDims = simulator_.vanguard().cartesianIndexMapper().cartesianDimensions();
auto elemIt = globalGridView.template begin</*codim=*/0>(); auto elemIt = globalGridView.template begin</*codim=*/0>();
const auto& elemEndIt = globalGridView.template end</*codim=*/0>(); const auto& elemEndIt = globalGridView.template end</*codim=*/0>();
for (; elemIt != elemEndIt; ++ elemIt) { for (; elemIt != elemEndIt; ++ elemIt) {
@ -641,11 +650,8 @@ private:
if (c1 > c2) if (c1 > c2)
continue; // we only need to handle each connection once, thank you. continue; // we only need to handle each connection once, thank you.
// TODO (?): use the cartesian index mapper to make this code work std::size_t cc1 = equilCartMapper.cartesianIndex( c1 ); //globalIOGrid_.globalCell()[c1];
// with grids other than Dune::CpGrid. The problem is that we need std::size_t cc2 = equilCartMapper.cartesianIndex( c2 ); //globalIOGrid_.globalCell()[c2];
// the a mapper for the sequential grid, not for the distributed one.
std::size_t cc1 = globalGrid_.globalCell()[c1];
std::size_t cc2 = globalGrid_.globalCell()[c2];
if ( cc2 < cc1 ) if ( cc2 < cc1 )
std::swap(cc1, cc2); std::swap(cc1, cc2);
@ -733,7 +739,6 @@ private:
CollectDataToIORankType collectToIORank_; CollectDataToIORankType collectToIORank_;
EclOutputBlackOilModule<TypeTag> eclOutputModule_; EclOutputBlackOilModule<TypeTag> eclOutputModule_;
std::unique_ptr<Opm::EclipseIO> eclIO_; std::unique_ptr<Opm::EclipseIO> eclIO_;
Grid globalGrid_;
std::unique_ptr<TaskletRunner> taskletRunner_; std::unique_ptr<TaskletRunner> taskletRunner_;
Scalar restartTimeStepSize_; Scalar restartTimeStepSize_;

View File

@ -39,6 +39,11 @@ namespace Opm
void extractParallelGridInformationToISTL(const Dune::CpGrid& grid, boost::any& anyComm); void extractParallelGridInformationToISTL(const Dune::CpGrid& grid, boost::any& anyComm);
// Grid is not CpGrid --> do nothing.
template <class Grid>
void extractParallelGridInformationToISTL(const Grid&, boost::any&)
{}
} // end namespace Opm } // end namespace Opm
#endif //defined(HAVE_OPM_GRID) #endif //defined(HAVE_OPM_GRID)
#endif // OPM_EXTRACTPARALLELGRIDINFORMATIONTOISTL_HEADER_INCLUDED #endif // OPM_EXTRACTPARALLELGRIDINFORMATIONTOISTL_HEADER_INCLUDED

View File

@ -240,7 +240,7 @@ protected:
{ {
parameters_.template init<TypeTag>(); parameters_.template init<TypeTag>();
extractParallelGridInformationToISTL(simulator_.vanguard().grid(), parallelInformation_); extractParallelGridInformationToISTL(simulator_.vanguard().grid(), parallelInformation_);
auto gridForConn = simulator_.vanguard().grid(); const auto& gridForConn = simulator_.vanguard().grid();
const auto wellsForConn = simulator_.vanguard().schedule().getWellsatEnd(); const auto wellsForConn = simulator_.vanguard().schedule().getWellsatEnd();
const bool useWellConn = EWOMS_GET_PARAM(TypeTag, bool, MatrixAddWellContributions); const bool useWellConn = EWOMS_GET_PARAM(TypeTag, bool, MatrixAddWellContributions);
@ -648,21 +648,21 @@ protected:
/// Create sparsity pattern of matrix without off-diagonal ghost entries. /// Create sparsity pattern of matrix without off-diagonal ghost entries.
void noGhostAdjacency() void noGhostAdjacency()
{ {
auto grid = simulator_.vanguard().grid(); const auto& grid = simulator_.vanguard().grid();
typedef typename Matrix::size_type size_type; typedef typename Matrix::size_type size_type;
size_type numCells = grid.numCells(); size_type numCells = grid.size( 0 );
noGhostMat_.reset(new Matrix(numCells, numCells, Matrix::random)); noGhostMat_.reset(new Matrix(numCells, numCells, Matrix::random));
std::vector<std::set<size_type>> pattern; std::vector<std::set<size_type>> pattern;
pattern.resize(grid.numCells()); pattern.resize(numCells);
auto lid = grid.localIdSet(); const auto& lid = grid.localIdSet();
const auto& gridView = grid.leafGridView(); const auto& gridView = grid.leafGridView();
auto elemIt = gridView.template begin<0>(); auto elemIt = gridView.template begin<0>();
const auto& elemEndIt = gridView.template end<0>(); const auto& elemEndIt = gridView.template end<0>();
//Loop over cells //Loop over cells
for (; elemIt != elemEndIt; ++elemIt) for (; elemIt != elemEndIt; ++elemIt)
{ {
const auto& elem = *elemIt; const auto& elem = *elemIt;
size_type idx = lid.id(elem); size_type idx = lid.id(elem);
@ -679,7 +679,7 @@ protected:
} }
else { else {
auto isend = gridView.iend(elem); auto isend = gridView.iend(elem);
for (auto is = gridView.ibegin(elem); is!=isend; ++is) for (auto is = gridView.ibegin(elem); is!=isend; ++is)
{ {
//check if face has neighbor //check if face has neighbor
if (is->neighbor()) if (is->neighbor())
@ -725,7 +725,7 @@ protected:
/// Copy interior rows to noghost matrix /// Copy interior rows to noghost matrix
void copyJacToNoGhost(const Matrix& jac, Matrix& ng) void copyJacToNoGhost(const Matrix& jac, Matrix& ng)
{ {
//Loop over precalculated interior rows. //Loop over precalculated interior rows.
for (auto row = interiorRows_.begin(); row != interiorRows_.end(); row++ ) for (auto row = interiorRows_.begin(); row != interiorRows_.end(); row++ )
{ {
//Copy row //Copy row

View File

@ -30,7 +30,7 @@ namespace detail
{ {
/// \brief Find cell IDs for wells contained in local grid. /// \brief Find cell IDs for wells contained in local grid.
/// ///
/// Cell IDs of wells stored in a graph, so it can be used to create /// Cell IDs of wells stored in a graph, so it can be used to create
/// an adjacency pattern. Only relevant when the UseWellContribusion option is set to true /// an adjacency pattern. Only relevant when the UseWellContribusion option is set to true
/// \tparam The type of the DUNE grid. /// \tparam The type of the DUNE grid.
/// \tparam Well vector type /// \tparam Well vector type
@ -41,17 +41,19 @@ namespace detail
template<class Grid, class W> template<class Grid, class W>
void setWellConnections(const Grid& grid, const W& wells, bool useWellConn, std::vector<std::set<int>>& wellGraph) void setWellConnections(const Grid& grid, const W& wells, bool useWellConn, std::vector<std::set<int>>& wellGraph)
{ {
if ( grid.comm().size() > 1) if ( grid.comm().size() > 1)
{ {
wellGraph.resize(grid.numCells()); Dune::CartesianIndexMapper< Grid > cartMapper( grid );
const int numCells = cartMapper.compressedSize(); // grid.numCells()
wellGraph.resize(numCells);
if (useWellConn) { if (useWellConn) {
const auto& cpgdim = grid.logicalCartesianSize(); const auto& cpgdim = cartMapper.cartesianDimensions();
std::vector<int> cart(cpgdim[0]*cpgdim[1]*cpgdim[2], -1); std::vector<int> cart(cpgdim[0]*cpgdim[1]*cpgdim[2], -1);
for( int i=0; i < grid.numCells(); ++i ) for( int i=0; i < numCells; ++i )
cart[grid.globalCell()[i]] = i; cart[ cartMapper.cartesianIndex( i ) ] = i;
Dune::cpgrid::WellConnections well_indices; Dune::cpgrid::WellConnections well_indices;
well_indices.init(wells, cpgdim, cart); well_indices.init(wells, cpgdim, cart);
@ -66,7 +68,7 @@ namespace detail
wellGraph[*perf].insert(*perf2); wellGraph[*perf].insert(*perf2);
wellGraph[*perf2].insert(*perf); wellGraph[*perf2].insert(*perf);
} }
} }
} }
} }
} }
@ -81,27 +83,27 @@ namespace detail
/// \param overlapRows List where overlap rows are stored. /// \param overlapRows List where overlap rows are stored.
/// \param interiorRows List where overlap rows are stored. /// \param interiorRows List where overlap rows are stored.
template<class Grid> template<class Grid>
void findOverlapAndInterior(const Grid& grid, std::vector<int>& overlapRows, void findOverlapAndInterior(const Grid& grid, std::vector<int>& overlapRows,
std::vector<int>& interiorRows) std::vector<int>& interiorRows)
{ {
//only relevant in parallel case. //only relevant in parallel case.
if ( grid.comm().size() > 1) if ( grid.comm().size() > 1)
{ {
//Numbering of cells //Numbering of cells
auto lid = grid.localIdSet(); const auto& lid = grid.localIdSet();
const auto& gridView = grid.leafGridView(); const auto& gridView = grid.leafGridView();
auto elemIt = gridView.template begin<0>(); auto elemIt = gridView.template begin<0>();
const auto& elemEndIt = gridView.template end<0>(); const auto& elemEndIt = gridView.template end<0>();
//loop over cells in mesh //loop over cells in mesh
for (; elemIt != elemEndIt; ++elemIt) for (; elemIt != elemEndIt; ++elemIt)
{ {
const auto& elem = *elemIt; const auto& elem = *elemIt;
int lcell = lid.id(elem); int lcell = lid.id(elem);
if (elem.partitionType() != Dune::InteriorEntity) if (elem.partitionType() != Dune::InteriorEntity)
{ {
//add row to list //add row to list
overlapRows.push_back(lcell); overlapRows.push_back(lcell);
} else { } else {

View File

@ -293,7 +293,7 @@ namespace Opm {
// Compute reservoir volumes for RESV controls. // Compute reservoir volumes for RESV controls.
rateConverter_.reset(new RateConverterType (phase_usage_, rateConverter_.reset(new RateConverterType (phase_usage_,
std::vector<int>(number_of_cells_, 0))); std::vector<int>(number_of_cells_, 0)));
rateConverter_->template defineState<ElementContext>(ebosSimulator_); rateConverter_->template defineState<ElementContext>(ebosSimulator_);
// update VFP properties // update VFP properties
@ -558,7 +558,7 @@ namespace Opm {
// for ecl compatible restart the current controls are not written // for ecl compatible restart the current controls are not written
const auto& ioCfg = eclState().getIOConfig(); const auto& ioCfg = eclState().getIOConfig();
const auto ecl_compatible_rst = ioCfg.getEclCompatibleRST(); const auto ecl_compatible_rst = ioCfg.getEclCompatibleRST();
if (true || ecl_compatible_rst) { // always set the control from the schedule if (true || ecl_compatible_rst) { // always set the control from the schedule
for (int w = 0; w <nw; ++w) { for (int w = 0; w <nw; ++w) {
const auto& well = wells_ecl_[w]; const auto& well = wells_ecl_[w];
@ -1508,8 +1508,7 @@ namespace Opm {
depth_.resize(numCells); depth_.resize(numCells);
for (unsigned cellIdx = 0; cellIdx < numCells; ++cellIdx) { for (unsigned cellIdx = 0; cellIdx < numCells; ++cellIdx) {
depth_[cellIdx] = depth_[cellIdx] = Opm::UgGridHelpers::cellCenterDepth( grid, cellIdx );
grid.cellCenterDepth(cellIdx);
} }
} }
@ -1897,7 +1896,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
actionOnBrokenConstraints(const Group& group, const Group::ExceedAction& exceed_action, const Group::ProductionCMode& newControl, const int reportStepIdx, Opm::DeferredLogger& deferred_logger) { actionOnBrokenConstraints(const Group& group, const Group::ExceedAction& exceed_action, const Group::ProductionCMode& newControl, const int reportStepIdx, Opm::DeferredLogger& deferred_logger) {
auto& well_state = well_state_; auto& well_state = well_state_;
const Group::ProductionCMode& oldControl = well_state.currentProductionGroupControl(group.name()); const Group::ProductionCMode& oldControl = well_state.currentProductionGroupControl(group.name());
std::ostringstream ss; std::ostringstream ss;