flow_ebos*: make it build and (the sequential part) work if dune-fem is available

in particular, this implied some changes to the MPI initialization
code. since dune-fem's GridPart class currently has issues with
CpGrid's implementation of loadBalance(), parallel computations still
do not work if dune-fem is around, but at least sequential ones now
do even if MPI is enabled.
This commit is contained in:
Andreas Lauser 2017-10-05 16:55:26 +02:00
parent 64d7366de2
commit 0c92c24dcb
6 changed files with 128 additions and 40 deletions

View File

@ -27,6 +27,8 @@
#include <opm/core/utility/parameters/ParameterGroup.hpp>
#include <opm/common/ResetLocale.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
@ -38,7 +40,6 @@
// Define making clear that the simulator supports AMG
#define FLOW_SUPPORT_AMG 1
#include <opm/material/densead/Evaluation.hpp>
#include <ewoms/models/blackoil/blackoiltwophaseindices.hh>
#include <opm/autodiff/DuneMatrix.hpp>
@ -116,18 +117,31 @@ namespace detail
int main(int argc, char** argv)
{
// MPI setup.
// Must ensure an instance of the helper is created to initialise MPI.
// For a build without MPI the Dune::FakeMPIHelper is used, so rank will
// be 0 and size 1.
const Dune::MPIHelper& mpi_helper = Dune::MPIHelper::instance(argc, argv);
const bool outputCout = mpi_helper.rank() == 0;
#if HAVE_DUNE_FEM
Dune::Fem::MPIManager::initialize(argc, argv);
int mpiRank = Dune::Fem::MPIManager::rank();
#else
// the design of the plain dune MPIHelper class is quite flawed: there is no way to
// get the instance without having the argc and argv parameters available and it is
// not possible to determine the MPI rank and size without an instance. (IOW: the
// rank() and size() methods are supposed to be static.)
const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
int mpiRank = mpiHelper.rank();
#endif
const bool outputCout = (mpiRank == 0);
// we always want to use the default locale, and thus spare us the trouble
// with incorrect locale settings.
Opm::resetLocale();
Opm::ParameterGroup param(argc, argv, false, outputCout);
// See if a deck was specified on the command line.
if (!param.unhandledArguments().empty()) {
if (param.unhandledArguments().size() != 1) {
std::cerr << "You can only specify a single input deck on the command line.\n";
if (outputCout)
std::cerr << "You can only specify a single input deck on the command line.\n";
return EXIT_FAILURE;
} else {
const auto casename = detail::simulationCaseName( param.unhandledArguments()[ 0 ] );
@ -137,11 +151,12 @@ int main(int argc, char** argv)
// We must have an input deck. Grid and props will be read from that.
if (!param.has("deck_filename")) {
std::cerr << "This program must be run with an input deck.\n"
"Specify the deck filename either\n"
" a) as a command line argument by itself\n"
" b) as a command line parameter with the syntax deck_filename=<path to your deck>, or\n"
" c) as a parameter in a parameter file (.param or .xml) passed to the program.\n";
if (outputCout)
std::cerr << "This program must be run with an input deck.\n"
"Specify the deck filename either\n"
" a) as a command line argument by itself\n"
" b) as a command line parameter with the syntax deck_filename=<path to your deck>, or\n"
" c) as a parameter in a parameter file (.param or .xml) passed to the program.\n";
return EXIT_FAILURE;
}
@ -160,8 +175,8 @@ int main(int argc, char** argv)
Opm::ParseContext parseContext(tmp);
std::shared_ptr<Opm::Deck> deck = std::make_shared< Opm::Deck >( parser.parseFile(deckFilename , parseContext) );
Opm::checkDeck(*deck, parser);
if ( outputCout ) {
Opm::checkDeck(*deck, parser);
Opm::MissingFeatures::checkKeywords(*deck);
}
@ -171,7 +186,7 @@ int main(int argc, char** argv)
Opm::Runspec runspec( *deck );
const auto& phases = runspec.phases();
// Twophase case
// Twophase cases
if( phases.size() == 2 ) {
// oil-gas
if (phases.active( Opm::Phase::GAS ))
@ -186,7 +201,8 @@ int main(int argc, char** argv)
return mainfunc.execute(argc, argv, deck, eclipseState );
}
else {
std::cerr << "No suitable configuration found, valid are Twophase (oilwater and oilgas), polymer, solvent, or blackoil" << std::endl;
if (outputCout)
std::cerr << "No suitable configuration found, valid are Twophase (oilwater and oilgas), polymer, solvent, or blackoil" << std::endl;
return EXIT_FAILURE;
}
}
@ -209,14 +225,17 @@ int main(int argc, char** argv)
}
else
{
std::cerr << "No suitable configuration found, valid are Twophase, polymer, solvent, or blackoil" << std::endl;
if (outputCout)
std::cerr << "No suitable configuration found, valid are Twophase, polymer, solvent, or blackoil" << std::endl;
return EXIT_FAILURE;
}
}
catch (const std::invalid_argument& e)
{
std::cerr << "Failed to create valid EclipseState object." << std::endl;
std::cerr << "Exception caught: " << e.what() << std::endl;
if (outputCout) {
std::cerr << "Failed to create valid EclipseState object." << std::endl;
std::cerr << "Exception caught: " << e.what() << std::endl;
}
throw;
}

View File

@ -27,16 +27,30 @@
// Define making clear that the simulator supports AMG
#define FLOW_SUPPORT_AMG 1
#include <opm/material/densead/Evaluation.hpp>
#include <opm/autodiff/DuneMatrix.hpp>
#include <opm/common/ResetLocale.hpp>
#include <dune/grid/CpGrid.hpp>
#include <opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp>
#include <opm/autodiff/FlowMainEbos.hpp>
#if HAVE_DUNE_FEM
#include <dune/fem/misc/mpimanager.hh>
#else
#include <dune/common/parallel/mpihelper.hh>
#endif
// ----------------- Main program -----------------
int main(int argc, char** argv)
{
// we always want to use the default locale, and thus spare us the trouble
// with incorrect locale settings.
Opm::resetLocale();
#if HAVE_DUNE_FEM
Dune::Fem::MPIManager::initialize(argc, argv);
#else
Dune::MPIHelper::instance(argc, argv);
#endif
Opm::FlowMainEbos<TTAG(EclFlowProblem)> mainfunc;
return mainfunc.execute(argc, argv);
}

View File

@ -25,14 +25,19 @@
// Define making clear that the simulator supports AMG
#define FLOW_SUPPORT_AMG 1
#include <opm/material/densead/Evaluation.hpp>
#include <opm/common/ResetLocale.hpp>
#include <ewoms/models/blackoil/blackoiltwophaseindices.hh>
#include <opm/autodiff/DuneMatrix.hpp>
#include <dune/grid/CpGrid.hpp>
#include <opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp>
#include <opm/autodiff/FlowMainEbos.hpp>
#if HAVE_DUNE_FEM
#include <dune/fem/misc/mpimanager.hh>
#else
#include <dune/common/parallel/mpihelper.hh>
#endif
namespace Ewoms {
namespace Properties {
NEW_TYPE_TAG(EclFlowTwoPhaseProblem, INHERITS_FROM(EclFlowProblem));
@ -44,6 +49,16 @@ SET_TYPE_PROP(EclFlowTwoPhaseProblem, Indices,
// ----------------- Main program -----------------
int main(int argc, char** argv)
{
// we always want to use the default locale, and thus spare us the trouble
// with incorrect locale settings.
Opm::resetLocale();
#if HAVE_DUNE_FEM
Dune::Fem::MPIManager::initialize(argc, argv);
#else
Dune::MPIHelper::instance(argc, argv);
#endif
Opm::FlowMainEbos<TTAG(EclFlowTwoPhaseProblem)> mainfunc;
return mainfunc.execute(argc, argv);
}

View File

@ -22,12 +22,17 @@
#include "config.h"
#endif // HAVE_CONFIG_H
#include <opm/material/densead/Evaluation.hpp>
#include <opm/autodiff/DuneMatrix.hpp>
#include <opm/common/ResetLocale.hpp>
#include <dune/grid/CpGrid.hpp>
#include <opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp>
#include <opm/autodiff/FlowMainEbos.hpp>
#if HAVE_DUNE_FEM
#include <dune/fem/misc/mpimanager.hh>
#else
#include <dune/common/parallel/mpihelper.hh>
#endif
namespace Ewoms {
namespace Properties {
NEW_TYPE_TAG(EclFlowPolymerProblem, INHERITS_FROM(EclFlowProblem));
@ -37,6 +42,18 @@ SET_BOOL_PROP(EclFlowPolymerProblem, EnablePolymer, true);
// ----------------- Main program -----------------
int main(int argc, char** argv)
{
// we always want to use the default locale, and thus spare us the trouble
// with incorrect locale settings.
Opm::resetLocale();
// initialize MPI, finalize is done automatically on exit
#if HAVE_DUNE_FEM
Dune::Fem::MPIManager::initialize(argc, argv);
const int myRank = Dune::Fem::MPIManager::rank();
#else
const int myRank = Dune::MPIHelper::instance(argc, argv).rank();
#endif
Opm::FlowMainEbos<TTAG(EclFlowPolymerProblem)> mainfunc;
return mainfunc.execute(argc, argv);
}

View File

@ -22,12 +22,17 @@
#include "config.h"
#endif // HAVE_CONFIG_H
#include <opm/material/densead/Evaluation.hpp>
#include <opm/autodiff/DuneMatrix.hpp>
#include <opm/common/ResetLocale.hpp>
#include <dune/grid/CpGrid.hpp>
#include <opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp>
#include <opm/autodiff/FlowMainEbos.hpp>
#if HAVE_DUNE_FEM
#include <dune/fem/misc/mpimanager.hh>
#else
#include <dune/common/parallel/mpihelper.hh>
#endif
namespace Ewoms {
namespace Properties {
NEW_TYPE_TAG(EclFlowSolventProblem, INHERITS_FROM(EclFlowProblem));
@ -37,6 +42,18 @@ SET_BOOL_PROP(EclFlowSolventProblem, EnableSolvent, true);
// ----------------- Main program -----------------
int main(int argc, char** argv)
{
// we always want to use the default locale, and thus spare us the trouble
// with incorrect locale settings.
Opm::resetLocale();
// initialize MPI, finalize is done automatically on exit
#if HAVE_DUNE_FEM
Dune::Fem::MPIManager::initialize(argc, argv);
const int myRank = Dune::Fem::MPIManager::rank();
#else
const int myRank = Dune::MPIHelper::instance(argc, argv).rank();
#endif
Opm::FlowMainEbos<TTAG(EclFlowSolventProblem)> mainfunc;
return mainfunc.execute(argc, argv);
}

View File

@ -45,7 +45,6 @@
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/common/OpmLog/EclipsePRTLog.hpp>
#include <opm/common/OpmLog/LogUtil.hpp>
#include <opm/common/ResetLocale.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
@ -55,7 +54,11 @@
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
#include <opm/parser/eclipse/EclipseState/checkDeck.hpp>
#include <ewoms/version.hh>
#if HAVE_DUNE_FEM
#include <dune/fem/misc/mpimanager.hh>
#else
#include <dune/common/parallel/mpihelper.hh>
#endif
namespace Opm
{
@ -76,8 +79,8 @@ namespace Opm
typedef typename GET_PROP(TypeTag, MaterialLaw)::EclMaterialLawManager MaterialLawManager;
typedef typename GET_PROP_TYPE(TypeTag, Simulator) EbosSimulator;
typedef typename GET_PROP_TYPE(TypeTag, SimulatorParameter) EbosSimulatorParameter;
typedef typename GET_PROP_TYPE(TypeTag, ElementMapper) ElementMapper;
typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
@ -96,10 +99,6 @@ namespace Opm
std::shared_ptr<Opm::EclipseState> eclipseState = std::shared_ptr<Opm::EclipseState>() )
{
try {
// we always want to use the default locale, and thus spare us the trouble
// with incorrect locale settings.
resetLocale();
setupParallelism(argc, argv);
printStartupMessage();
const bool ok = setupParameters(argc, argv);
@ -149,13 +148,16 @@ namespace Opm
protected:
void setupParallelism(int argc, char** argv)
{
// MPI setup.
// Must ensure an instance of the helper is created to initialise MPI.
// For a build without MPI the Dune::FakeMPIHelper is used, so rank will
// be 0 and size 1.
const Dune::MPIHelper& mpi_helper = Dune::MPIHelper::instance(argc, argv);
mpi_rank_ = mpi_helper.rank();
const int mpi_size = mpi_helper.size();
// determine the rank of the current process and the number of processes
// involved in the simulation. MPI must have already been initialized here.
#if HAVE_MPI
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank_);
int mpi_size;
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
#else
mpi_rank_ = 0;
const int mpi_size = 1;
#endif
output_cout_ = ( mpi_rank_ == 0 );
must_distribute_ = ( mpi_size > 1 );
@ -808,6 +810,8 @@ namespace Opm
const Grid& globalGrid = this->globalGrid();
const auto& globalGridView = globalGrid.leafGridView();
typedef typename Grid::LeafGridView GridView;
typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGElementLayout> ElementMapper;
ElementMapper globalElemMapper(globalGridView);
const auto& cartesianCellIdx = globalGrid.globalCell();
@ -881,6 +885,8 @@ namespace Opm
const Grid& globalGrid = this->globalGrid();
const auto& globalGridView = globalGrid.leafGridView();
typedef typename Grid::LeafGridView GridView;
typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGElementLayout> ElementMapper;
ElementMapper globalElemMapper(globalGridView);
const auto* globalTrans = &(ebosSimulator_->gridManager().globalTransmissibility());