// -*- 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 .
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 Opm::DgfVanguard
*/
#ifndef EWOMS_DGF_GRID_VANGUARD_HH
#define EWOMS_DGF_GRID_VANGUARD_HH
#include
#include
#include
#include
#include
#include
#include
#include
namespace Opm {
/*!
* \brief Provides a simulator vanguard which creates a grid by parsing a Dune Grid
* Format (DGF) file.
*/
template
class DgfVanguard : public BaseVanguard
{
using ParentType = BaseVanguard;
using Scalar = GetPropType;
using Simulator = GetPropType;
using Grid = GetPropType;
using FractureMapper = Opm::FractureMapper;
using GridPointer = std::unique_ptr< Grid >;
public:
/*!
* \brief Register all run-time parameters for the DGF simulator vanguard.
*/
static void registerParameters()
{
Parameters::Register
("The file name of the DGF file to load");
Parameters::Register
("The number of global refinements of the grid "
"executed after it was loaded");
}
/*!
* \brief Load the grid from the file.
*/
DgfVanguard(Simulator& simulator)
: ParentType(simulator)
{
const std::string dgfFileName = Parameters::Get();
unsigned numRefinments = Parameters::Get();
{
// create DGF GridPtr from a dgf file
Dune::GridPtr< Grid > dgfPointer( dgfFileName );
// this is only implemented for 2d currently
addFractures_( dgfPointer );
// store pointer to dune grid
gridPtr_.reset( dgfPointer.release() );
}
if (numRefinments > 0)
gridPtr_->globalRefine(static_cast(numRefinments));
this->finalizeInit_();
}
/*!
* \brief Returns a reference to the grid.
*/
Grid& grid()
{ return *gridPtr_; }
/*!
* \brief Returns a reference to the grid.
*/
const Grid& grid() const
{ return *gridPtr_; }
/*!
* \brief Distributes the grid on all processes of a parallel
* computation.
*
* This grid manager plays nice and also distributes the data of
* the DGF...
*/
void loadBalance()
{ gridPtr_->loadBalance(); }
/*!
* \brief Returns the fracture mapper
*
* The fracture mapper determines the topology of the fractures.
*/
FractureMapper& fractureMapper()
{ return fractureMapper_; }
/*!
* \brief Returns the fracture mapper
*
* The fracture mapper determines the topology of the fractures.
*/
const FractureMapper& fractureMapper() const
{ return fractureMapper_; }
protected:
void addFractures_(Dune::GridPtr& dgfPointer)
{
using LevelGridView = typename Grid::LevelGridView;
// check if fractures are available (only 2d currently)
if (dgfPointer.nofParameters(static_cast(Grid::dimension)) == 0)
return;
LevelGridView gridView = dgfPointer->levelGridView(/*level=*/0);
const unsigned edgeCodim = Grid::dimension - 1;
using VertexMapper = Dune::MultipleCodimMultipleGeomTypeMapper;
VertexMapper vertexMapper(gridView, Dune::mcmgVertexLayout());
// first create a map of the dune to ART vertex indices
auto eIt = gridView.template begin*codim=*/0>();
const auto eEndIt = gridView.template end*codim=*/0>();
for (; eIt != eEndIt; ++eIt) {
const auto& element = *eIt;
const auto& refElem =
Dune::ReferenceElements::general(element.type());
const int edges = refElem.size( edgeCodim );
for (int edge = 0; edge < edges; ++edge) {
const int vertices = refElem.size(edge, edgeCodim, Grid::dimension);
std::vector vertexIndices;
vertexIndices.reserve(Grid::dimension);
for (int vx = 0; vx < vertices; ++vx) {
// get local vertex number from edge
const int localVx = refElem.subEntity(edge, edgeCodim, vx, Grid::dimension);
// get vertex
const auto vertex = element.template subEntity(localVx);
// if vertex has parameter 1 insert as a fracture vertex
if (dgfPointer.parameters( vertex )[ 0 ] > 0)
vertexIndices.push_back(
static_cast(vertexMapper.subIndex(element,
static_cast(localVx),
Grid::dimension)));
}
// if 2 vertices have been found with flag 1 insert a fracture edge
if (static_cast(vertexIndices.size()) == Grid::dimension)
fractureMapper_.addFractureEdge(vertexIndices[0], vertexIndices[1]);
}
}
}
private:
GridPointer gridPtr_;
FractureMapper fractureMapper_;
};
} // namespace Opm
#endif