mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-11-26 19:20:17 -06:00
cd681c6445
this is part of the release maintainance. in this context "core headers" means the ones which do not include the well model headers, and only those which are concerned with non-exotic functionality, e.g., the PolyhedralGrid and ALUGrid vanguards are not changed.
254 lines
8.1 KiB
C++
254 lines
8.1 KiB
C++
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
// vi: set et ts=4 sw=4 sts=4:
|
|
/*
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
OPM is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
OPM is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
Consult the COPYING file in the top-level source directory of this
|
|
module for the precise wording of the license and the list of
|
|
copyright holders.
|
|
*/
|
|
/*!
|
|
* \file
|
|
*
|
|
* \copydoc Ewoms::AluCartesianIndexMapper
|
|
*/
|
|
#ifndef EWOMS_ALU_CARTESIAN_INDEX_MAPPER_HH
|
|
#define EWOMS_ALU_CARTESIAN_INDEX_MAPPER_HH
|
|
|
|
#include <dune/grid/common/datahandleif.hh>
|
|
#include <dune/grid/utility/persistentcontainer.hh>
|
|
|
|
#include <array>
|
|
#include <memory>
|
|
#include <exception>
|
|
#include <vector>
|
|
#include <cassert>
|
|
|
|
namespace Ewoms {
|
|
|
|
/*!
|
|
* \brief Interface class to access the logical Cartesian grid as used in industry
|
|
* standard simulator decks.
|
|
*/
|
|
template <class Grid>
|
|
class AluCartesianIndexMapper
|
|
{
|
|
public:
|
|
// data handle for communicating global ids during load balance and communication
|
|
template <class GridView>
|
|
class GlobalIndexDataHandle : public Dune::CommDataHandleIF<GlobalIndexDataHandle<GridView>, int>
|
|
{
|
|
// global id
|
|
class GlobalCellIndex
|
|
{
|
|
public:
|
|
GlobalCellIndex()
|
|
: idx_(-1)
|
|
{}
|
|
|
|
GlobalCellIndex& operator=(const int index)
|
|
{
|
|
idx_ = index;
|
|
return *this;
|
|
}
|
|
|
|
int index() const
|
|
{ return idx_; }
|
|
|
|
private:
|
|
int idx_;
|
|
};
|
|
|
|
typedef typename Dune::PersistentContainer<Grid, GlobalCellIndex> GlobalIndexContainer;
|
|
|
|
public:
|
|
// constructor copying cartesian index to persistent container
|
|
GlobalIndexDataHandle(const GridView& gridView,
|
|
std::vector<int>& cartesianIndex)
|
|
: gridView_(gridView)
|
|
, globalIndex_(gridView.grid(), 0)
|
|
, cartesianIndex_(cartesianIndex)
|
|
{
|
|
globalIndex_.resize();
|
|
initialize();
|
|
}
|
|
|
|
// constructor copying cartesian index to persistent container
|
|
GlobalIndexDataHandle(const GlobalIndexDataHandle& other) = delete ;
|
|
|
|
// destrcutor writing load balanced cartesian index back to vector
|
|
~GlobalIndexDataHandle()
|
|
{ finalize(); }
|
|
|
|
bool contains(int dim, int codim) const
|
|
{ return codim == 0; }
|
|
|
|
bool fixedsize(int dim, int codim) const
|
|
{ return true; }
|
|
|
|
//! \brief loop over all internal data handlers and call gather for
|
|
//! given entity
|
|
template<class MessageBufferImp, class EntityType>
|
|
void gather(MessageBufferImp& buff, const EntityType& element) const
|
|
{
|
|
int globalIdx = globalIndex_[element].index();
|
|
buff.write(globalIdx);
|
|
}
|
|
|
|
//! \brief loop over all internal data handlers and call scatter for
|
|
//! given entity
|
|
template<class MessageBufferImp, class EntityType>
|
|
void scatter(MessageBufferImp& buff, const EntityType& element, size_t n)
|
|
{
|
|
int globalIdx = -1;
|
|
buff.read(globalIdx);
|
|
if (globalIdx >= 0)
|
|
{
|
|
globalIndex_.resize();
|
|
globalIndex_[element] = globalIdx;
|
|
}
|
|
}
|
|
|
|
//! \brief loop over all internal data handlers and return sum of data
|
|
//! size of given entity
|
|
template<class EntityType>
|
|
size_t size(const EntityType& en) const
|
|
{ return 1; }
|
|
|
|
protected:
|
|
// initialize persistent container from given vector
|
|
void initialize()
|
|
{
|
|
auto idx = cartesianIndex_.begin();
|
|
auto it = gridView_.template begin<0>();
|
|
const auto& endIt = gridView_.template end<0>();
|
|
|
|
for (; it != endIt; ++it, ++idx)
|
|
globalIndex_[*it] = *idx;
|
|
}
|
|
|
|
// update vector from given persistent container
|
|
void finalize()
|
|
{
|
|
std::vector<int> newIndex ;
|
|
newIndex.reserve(gridView_.indexSet().size(0));
|
|
|
|
auto it = gridView_.template begin<0>();
|
|
const auto& endIt = gridView_.template end<0>();
|
|
for (; it != endIt; ++it)
|
|
newIndex.push_back(globalIndex_[*it].index()) ;
|
|
|
|
cartesianIndex_.swap(newIndex);
|
|
}
|
|
|
|
GridView gridView_;
|
|
GlobalIndexContainer globalIndex_;
|
|
std::vector<int>& cartesianIndex_;
|
|
};
|
|
|
|
public:
|
|
/** \brief dimension of the grid */
|
|
static const int dimension = Grid::dimension ;
|
|
|
|
/** \brief constructor taking grid */
|
|
AluCartesianIndexMapper(const Grid& grid,
|
|
const std::array<int, dimension>& cartDims,
|
|
const std::vector<int>& cartesianIndex)
|
|
: grid_(grid)
|
|
, cartesianDimensions_(cartDims)
|
|
, cartesianIndex_(cartesianIndex)
|
|
, cartesianSize_(computeCartesianSize())
|
|
{}
|
|
|
|
/** \brief return Cartesian dimensions, i.e. number of cells in each direction */
|
|
const std::array<int, dimension>& cartesianDimensions() const
|
|
{ return cartesianDimensions_; }
|
|
|
|
/** \brief return total number of cells in the logical Cartesian grid */
|
|
int cartesianSize() const
|
|
{ return cartesianSize_; }
|
|
|
|
/** \brief return number of cells in the active grid */
|
|
int compressedSize() const
|
|
{ return cartesianIndex_.size(); }
|
|
|
|
/** \brief return index of the cells in the logical Cartesian grid */
|
|
int cartesianIndex(const int compressedElementIndex) const
|
|
{
|
|
assert(compressedElementIndex < compressedSize());
|
|
return cartesianIndex_[compressedElementIndex];
|
|
}
|
|
|
|
/** \brief return index of the cells in the logical Cartesian grid */
|
|
int cartesianIndex(const std::array<int, dimension>& coords) const
|
|
{
|
|
int cartIndex = coords[0];
|
|
int factor = cartesianDimensions()[0];
|
|
for (int i=1; i < dimension; ++i) {
|
|
cartIndex += coords[i] * factor;
|
|
factor *= cartesianDimensions()[i];
|
|
}
|
|
|
|
return cartIndex;
|
|
}
|
|
|
|
/** \brief return Cartesian coordinate, i.e. IJK, for a given cell */
|
|
void cartesianCoordinate(const int compressedElementIndex, std::array<int, dimension>& coords) const
|
|
{
|
|
int gc = cartesianIndex(compressedElementIndex);
|
|
if (dimension == 3) {
|
|
coords[0] = gc % cartesianDimensions()[0];
|
|
gc /= cartesianDimensions()[0];
|
|
coords[1] = gc % cartesianDimensions()[1];
|
|
coords[2] = gc / cartesianDimensions()[1];
|
|
}
|
|
else if (dimension == 2) {
|
|
coords[0] = gc % cartesianDimensions()[0];
|
|
coords[1] = gc / cartesianDimensions()[0];
|
|
}
|
|
else if (dimension == 1)
|
|
coords[0] = gc ;
|
|
else
|
|
throw std::invalid_argument("cartesianCoordinate not implemented for dimension " + std::to_string(dimension));
|
|
}
|
|
|
|
template <class GridView>
|
|
std::unique_ptr<GlobalIndexDataHandle<GridView> > dataHandle(const GridView& gridView)
|
|
{
|
|
typedef GlobalIndexDataHandle<GridView> DataHandle ;
|
|
assert(&grid_ == &gridView.grid());
|
|
return std::unique_ptr<DataHandle>(new DataHandle(gridView, cartesianIndex_));
|
|
}
|
|
|
|
protected:
|
|
int computeCartesianSize() const
|
|
{
|
|
int size = cartesianDimensions()[0];
|
|
for (int d=1; d<dimension; ++d)
|
|
size *= cartesianDimensions()[d];
|
|
return size ;
|
|
}
|
|
|
|
const Grid& grid_;
|
|
const std::array<int, dimension> cartesianDimensions_;
|
|
std::vector<int> cartesianIndex_;
|
|
const int cartesianSize_ ;
|
|
};
|
|
|
|
} // end namespace Ewoms
|
|
|
|
#endif
|