Adapt and use readDeck from EclipseBaseVanguard, too.

This reduces code duplication ad should fix the bad_cast exception
when running ebos in parallel.
This commit is contained in:
Markus Blatt 2020-08-18 12:35:55 +02:00
parent 575245d785
commit c958034d26
4 changed files with 81 additions and 90 deletions

View File

@ -49,6 +49,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/State.hpp>
#include <opm/simulators/utils/readDeck.hpp>
#if HAVE_MPI
#include <mpi.h>
@ -300,77 +301,48 @@ public:
std::transform(caseName_.begin(), caseName_.end(), caseName_.begin(), ::toupper);
}
// create the parser objects for the deck or use their externally specified
// versions (if desired)
if (!externalParseContext_) {
std::unique_ptr<ErrorGuard> errorGuard = nullptr;
// Check that we are in one of the known configurations for external variables
// and move them to internal
if (externalDeck_)
{
deck_ = std::move(externalDeck_);
if (externalParseContext_ && externalErrorGuard_ )
{
parseContext_ = std::move(externalParseContext_);
errorGuard = std::move(externalErrorGuard_);
}
else if(externalEclState_ && externalEclSchedule_ && externalEclSummaryConfig_)
{
eclState_ = std::move(externalEclState_);
eclSchedule_ = std::move(externalEclSchedule_);
eclSummaryConfig_ = std::move(externalEclSummaryConfig_);
}
else
{
OPM_THROW(std::logic_error, "Either parse context and error guard or ECL state, schedule, and summary config need to be"
<< " set externally.");
}
}
else if (externalParseContext_)
{
parseContext_ = std::move(externalParseContext_);
}
else
{
parseContext_ = createParseContext();
}
else
parseContext_ = std::move(externalParseContext_);
if (!externalParseContext_) {
errorGuard_ = std::make_unique<Opm::ErrorGuard>();
}
else
errorGuard_ = std::move(externalErrorGuard_);
readDeck(myRank, fileName, deck_, eclState_, eclSchedule_,
eclSummaryConfig_, std::move(errorGuard), python,
std::move(parseContext_), /* initFromRestart = */ false,
/* checkDeck = */ enableExperiments);
if (!externalDeck_ && !externalDeckSet_) {
if (myRank == 0)
std::cout << "Reading the deck file '" << fileName << "'" << std::endl;
Opm::Parser parser;
deck_ = std::make_unique<Opm::Deck>(parser.parseFile(fileName, *parseContext_, *errorGuard_));
if (enableExperiments && myRank == 0)
Opm::checkDeck(*deck_, parser, *parseContext_, *errorGuard_);
}
else {
deck_ = std::move(externalDeck_);
}
if (!externalEclState_) {
eclState_ = std::make_unique<Opm::EclipseState>(*deck_);
}
else {
assert(externalEclState_);
deck_ = std::move(externalDeck_);
eclState_ = std::move(externalEclState_);
}
if (!externalEclSchedule_) {
// create the schedule object. Note that if eclState is supposed to represent
// the internalized version of the deck, this constitutes a layering
// violation.
eclSchedule_ = std::make_unique<Opm::Schedule>(*deck_, *eclState_, *parseContext_, *errorGuard_, python);
}
else
eclSchedule_ = std::move(externalEclSchedule_);
this->summaryState_ = std::make_unique<Opm::SummaryState>( std::chrono::system_clock::from_time_t(this->eclSchedule_->getStartTime() ));
this->actionState_ = std::make_unique<Opm::Action::State>() ;
if (!externalEclSummaryConfig_) {
// create the schedule object. Note that if eclState is supposed to represent
// the internalized version of the deck, this constitutes a layering
// violation.
eclSummaryConfig_ =
std::make_unique<Opm::SummaryConfig>(*deck_,
*eclSchedule_,
eclState_->getTableManager(),
*parseContext_,
*errorGuard_);
}
else
eclSummaryConfig_ = std::move(externalEclSummaryConfig_);
if (*errorGuard_) {
errorGuard_->dump();
errorGuard_->clear();
throw std::runtime_error("Unrecoverable errors were encountered while loading input.");
}
// Possibly override IOConfig setting for how often RESTART files should get
// written to disk (every N report step)
int outputInterval = EWOMS_GET_PARAM(TypeTag, int, EclOutputInterval);
@ -568,8 +540,11 @@ protected:
asImp_().finalizeInit_();
if (enableExperiments) {
Opm::RelpermDiagnostics relpermDiagnostics;
relpermDiagnostics.diagnosis(*eclState_, asImp_().grid());
if (asImp_().grid().size(0)) //grid not loadbalanced yet for ebos!
{
Opm::RelpermDiagnostics relpermDiagnostics;
relpermDiagnostics.diagnosis(*eclState_, asImp_().grid());
}
}
}
private:

View File

@ -422,12 +422,15 @@ namespace Opm
outputDir,
EWOMS_GET_PARAM(PreTypeTag, std::string, OutputMode),
outputCout_, "STDOUT_LOGGER");
Opm::ParseContext parseContext({{Opm::ParseContext::PARSE_RANDOM_SLASH, Opm::InputError::IGNORE},
{Opm::ParseContext::PARSE_MISSING_DIMS_KEYWORD, Opm::InputError::WARN},
{Opm::ParseContext::SUMMARY_UNKNOWN_WELL, Opm::InputError::WARN},
{Opm::ParseContext::SUMMARY_UNKNOWN_GROUP, Opm::InputError::WARN}});
auto parseContext =
std::make_unique<Opm::ParseContext>(std::vector<std::pair<std::string , InputError::Action>>
{{Opm::ParseContext::PARSE_RANDOM_SLASH, Opm::InputError::IGNORE},
{Opm::ParseContext::PARSE_MISSING_DIMS_KEYWORD, Opm::InputError::WARN},
{Opm::ParseContext::SUMMARY_UNKNOWN_WELL, Opm::InputError::WARN},
{Opm::ParseContext::SUMMARY_UNKNOWN_GROUP, Opm::InputError::WARN}});
readDeck(mpiRank, deckFilename, deck_, eclipseState_, schedule_,
summaryConfig_, python, parseContext,
summaryConfig_, nullptr, python, std::move(parseContext),
init_from_restart_file, outputCout_);
setupTime_ = externalSetupTimer.elapsed();
outputFiles_ = (outputMode != FileOutputMode::OUTPUT_NONE);

View File

@ -162,11 +162,13 @@ void setupMessageLimiter(const Opm::MessageLimits msgLimits, const std::string&
void readDeck(int rank, std::string& deckFilename, std::unique_ptr<Opm::Deck>& deck, std::unique_ptr<Opm::EclipseState>& eclipseState,
std::unique_ptr<Opm::Schedule>& schedule, std::unique_ptr<Opm::SummaryConfig>& summaryConfig,
std::shared_ptr<Opm::Python>& python, const ParseContext& parseContext,
std::unique_ptr<ErrorGuard> errorGuard, std::shared_ptr<Opm::Python>& python, std::unique_ptr<ParseContext> parseContext,
bool initFromRestart, bool checkDeck)
{
Opm::Parser parser;
Opm::ErrorGuard errorGuard;
if (!errorGuard)
{
errorGuard = std::make_unique<ErrorGuard>();
}
#if HAVE_MPI
int parseSuccess = 0;
@ -176,14 +178,22 @@ void readDeck(int rank, std::string& deckFilename, std::unique_ptr<Opm::Deck>& d
if (rank==0) {
try
{
if ( (!deck || !schedule || !summaryConfig ) && !parseContext)
{
OPM_THROW(std::logic_error, "We need a parse context if deck, schedule, or summaryConfig are not initialized");
}
if (!deck)
deck.reset( new Opm::Deck( parser.parseFile(deckFilename , parseContext, errorGuard)));
Opm::MissingFeatures::checkKeywords(*deck, parseContext, errorGuard);
if ( checkDeck )
Opm::checkDeck(*deck, parser, parseContext, errorGuard);
{
Opm::Parser parser;
deck.reset( new Opm::Deck( parser.parseFile(deckFilename , *parseContext, *errorGuard)));
Opm::MissingFeatures::checkKeywords(*deck, *parseContext, *errorGuard);
if ( checkDeck )
Opm::checkDeck(*deck, parser, *parseContext, *errorGuard);
}
if (!eclipseState) {
#if HAVEMPI
#if HAVE_MPI
eclipseState.reset(new Opm::ParallelEclipseState(*deck));
#else
eclipseState.reset(new Opm::EclipseState(*deck));
@ -201,15 +211,15 @@ void readDeck(int rank, std::string& deckFilename, std::unique_ptr<Opm::Deck>& d
Opm::EclIO::ERst rst_file(rst_filename);
const auto& rst_state = Opm::RestartIO::RstState::load(rst_file, report_step);
if (!schedule)
schedule.reset(new Opm::Schedule(*deck, *eclipseState, parseContext, errorGuard, python, &rst_state) );
schedule.reset(new Opm::Schedule(*deck, *eclipseState, *parseContext, *errorGuard, python, &rst_state) );
}
else {
if (!schedule)
schedule.reset(new Opm::Schedule(*deck, *eclipseState, parseContext, errorGuard, python));
schedule.reset(new Opm::Schedule(*deck, *eclipseState, *parseContext, *errorGuard, python));
}
setupMessageLimiter(schedule->getMessageLimits(), "STDOUT_LOGGER");
if (!summaryConfig)
summaryConfig.reset( new Opm::SummaryConfig(*deck, *schedule, eclipseState->getTableManager(), parseContext, errorGuard));
summaryConfig.reset( new Opm::SummaryConfig(*deck, *schedule, eclipseState->getTableManager(), *parseContext, *errorGuard));
#if HAVE_MPI
parseSuccess = 1;
#endif
@ -233,9 +243,9 @@ void readDeck(int rank, std::string& deckFilename, std::unique_ptr<Opm::Deck>& d
parseSuccess = comm.max(parseSuccess);
if (!parseSuccess)
{
if (errorGuard) {
errorGuard.dump();
errorGuard.clear();
if (*errorGuard) {
errorGuard->dump();
errorGuard->clear();
}
MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
}
@ -243,11 +253,11 @@ void readDeck(int rank, std::string& deckFilename, std::unique_ptr<Opm::Deck>& d
Opm::eclStateBroadcast(*eclipseState, *schedule, *summaryConfig);
#endif
Opm::checkConsistentArrayDimensions(*eclipseState, *schedule, parseContext, errorGuard);
Opm::checkConsistentArrayDimensions(*eclipseState, *schedule, *parseContext, *errorGuard);
if (errorGuard) {
errorGuard.dump();
errorGuard.clear();
if (*errorGuard) {
errorGuard->dump();
errorGuard->clear();
throw std::runtime_error("Unrecoverable errors were encountered while loading input.");
}

View File

@ -53,9 +53,12 @@ FileOutputMode setupLogging(int mpi_rank_, const std::string& deck_filename, con
void setupMessageLimiter(const Opm::MessageLimits msgLimits, const std::string& stdout_log_id);
/// \brief Reads the deck and creates all necessary objects if needed
///
/// If pointers already contains objects then they are used otherwise they are created and can be used outside later.
void readDeck(int rank, std::string& deckFilename, std::unique_ptr<Opm::Deck>& deck, std::unique_ptr<Opm::EclipseState>& eclipseState,
std::unique_ptr<Opm::Schedule>& schedule, std::unique_ptr<Opm::SummaryConfig>& summaryConfig,
std::shared_ptr<Opm::Python>& python, const ParseContext& parseContext,
std::unique_ptr<ErrorGuard> errorGuard, std::shared_ptr<Opm::Python>& python, std::unique_ptr<ParseContext> parseContext,
bool initFromRestart, bool checkDeck);
} // end namespace Opm