Merge pull request #3545 from blattms/fix-parallel-try-catch

[bugfix] Fix deadlocks because of parallel try-catch for some CO2 storage cases
This commit is contained in:
Markus Blatt 2021-09-27 13:02:34 +02:00 committed by GitHub
commit 88ae5b5963
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 177 additions and 147 deletions

View File

@ -68,6 +68,8 @@
#include <opm/core/props/satfunc/RelpermDiagnostics.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <opm/models/utils/pffgridvector.hh>
#include <opm/models/blackoil/blackoilmodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
@ -2027,6 +2029,7 @@ private:
const auto& simulator = this->simulator();
int episodeIdx = this->episodeIndex();
OPM_BEGIN_PARALLEL_TRY_CATCH();
if (this->drsdtConvective_(episodeIdx)) {
// This implements the convective DRSDT as described in
// Sandve et al. "Convective dissolution in field scale CO2 storage simulations using the OPM Flow simulator"
@ -2118,6 +2121,7 @@ private:
Scalar>(fs, iq.pvtRegionIndex());
}
}
OPM_END_PARALLEL_TRY_CATCH("EclProblem::_updateCompositionLayers() failed: ");
}
bool updateMaxOilSaturation_()
@ -2131,6 +2135,7 @@ private:
const auto& vanguard = simulator.vanguard();
auto elemIt = vanguard.gridView().template begin</*codim=*/0>();
const auto& elemEndIt = vanguard.gridView().template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (; elemIt != elemEndIt; ++elemIt) {
const Element& elem = *elemIt;
@ -2145,7 +2150,7 @@ private:
this->maxOilSaturation_[compressedDofIdx] = std::max(this->maxOilSaturation_[compressedDofIdx], So);
}
OPM_END_PARALLEL_TRY_CATCH("EclProblem::updateMayOilSaturation() failed:");
// we need to invalidate the intensive quantities cache here because the
// derivatives of Rs and Rv will most likely have changed
return true;
@ -2165,6 +2170,7 @@ private:
const auto& vanguard = this->simulator().vanguard();
auto elemIt = vanguard.gridView().template begin</*codim=*/0>();
const auto& elemEndIt = vanguard.gridView().template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (; elemIt != elemEndIt; ++elemIt) {
const Element& elem = *elemIt;
@ -2178,6 +2184,7 @@ private:
Scalar Sw = decay<Scalar>(fs.saturation(waterPhaseIdx));
this->maxWaterSaturation_[compressedDofIdx] = std::max(this->maxWaterSaturation_[compressedDofIdx], Sw);
}
OPM_END_PARALLEL_TRY_CATCH("EclProblem::updateMayWaterSaturation() failed: ");
return true;
}
@ -2188,6 +2195,7 @@ private:
if (this->minOilPressure_.empty())
return false;
OPM_BEGIN_PARALLEL_TRY_CATCH();
ElementContext elemCtx(this->simulator());
const auto& vanguard = this->simulator().vanguard();
auto elemIt = vanguard.gridView().template begin</*codim=*/0>();
@ -2207,6 +2215,7 @@ private:
getValue(fs.pressure(oilPhaseIdx)));
}
OPM_END_PARALLEL_TRY_CATCH("EclProblem::updateMinPressure_() failed: ");
return true;
}
@ -2638,6 +2647,7 @@ private:
const auto& vanguard = simulator.vanguard();
auto elemIt = vanguard.gridView().template begin</*codim=*/0>();
const auto& elemEndIt = vanguard.gridView().template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (; elemIt != elemEndIt; ++elemIt) {
const Element& elem = *elemIt;
@ -2648,6 +2658,7 @@ private:
const auto& intQuants = elemCtx.intensiveQuantities(/*spaceIdx=*/0, /*timeIdx=*/0);
materialLawManager_->updateHysteresis(intQuants.fluidState(), compressedDofIdx);
}
OPM_END_PARALLEL_TRY_CATCH("EclProblem::updateHyteresis_(): ");
return true;
}
@ -2659,6 +2670,7 @@ private:
const auto& vanguard = simulator.vanguard();
auto elemIt = vanguard.gridView().template begin</*codim=*/0>();
const auto& elemEndIt = vanguard.gridView().template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (; elemIt != elemEndIt; ++elemIt) {
const Element& elem = *elemIt;
@ -2671,6 +2683,7 @@ private:
this->maxPolymerAdsorption_[compressedDofIdx] = std::max(this->maxPolymerAdsorption_[compressedDofIdx],
scalarValue(intQuants.polymerAdsorption()));
}
OPM_END_PARALLEL_TRY_CATCH("EclProblem::updateMaxPolymerAdsorption_(): ");
}
struct PffDofData_

View File

@ -38,6 +38,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/wells/WGState.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/output/eclipse/RestartValue.hpp>
@ -407,6 +408,7 @@ public:
const auto gridView = simulator_.vanguard().gridView();
auto elemIt = gridView.template begin</*codim=*/0>();
const auto& elemEndIt = gridView.template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (; elemIt != elemEndIt; ++elemIt) {
const Element& elem = *elemIt;
if (elem.partitionType() != Dune::InteriorEntity)
@ -418,6 +420,7 @@ public:
for (size_t wellIdx = 0; wellIdx < wellSize; ++wellIdx)
wells_[wellIdx]->beginIterationAccumulate(elemCtx, /*timeIdx=*/0);
}
OPM_END_PARALLEL_TRY_CATCH("EclWellManager::beginIteration() failed: ");
// call the postprocessing routines
for (size_t wellIdx = 0; wellIdx < wellSize; ++wellIdx)

View File

@ -34,6 +34,7 @@
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/simulators/utils/ParallelRestart.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <ebos/eclgenericwriter.hh>
@ -379,6 +380,7 @@ private:
ElementIterator elemIt = gridView.template begin</*codim=*/0>();
const ElementIterator& elemEndIt = gridView.template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (; elemIt != elemEndIt; ++elemIt) {
const Element& elem = *elemIt;
@ -387,6 +389,7 @@ private:
eclOutputModule_->processElement(elemCtx);
}
OPM_END_PARALLEL_TRY_CATCH("EclWriter::prepareLocalCellData() failed: ")
}
Simulator& simulator_;

View File

@ -27,6 +27,8 @@
#include <opm/output/data/Aquifer.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <opm/material/common/MathToolbox.hpp>
#include <opm/material/densead/Evaluation.hpp>
#include <opm/material/densead/Math.hpp>
@ -110,6 +112,8 @@ public:
ElementContext elemCtx(ebos_simulator_);
auto elemIt = ebos_simulator_.gridView().template begin<0>();
const auto& elemEndIt = ebos_simulator_.gridView().template end<0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (; elemIt != elemEndIt; ++elemIt) {
const auto& elem = *elemIt;
@ -124,6 +128,7 @@ public:
const auto& iq = elemCtx.intensiveQuantities(0, 0);
pressure_previous_[idx] = getValue(iq.fluidState().pressure(phaseIdx_()));
}
OPM_END_PARALLEL_TRY_CATCH("AquiferInterface::beginTimeStep() failed: ");
}
template <class Context>

View File

@ -25,6 +25,8 @@
#include <opm/parser/eclipse/EclipseState/Aquifer/NumericalAquifer/SingleNumericalAquifer.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <algorithm>
#include <cassert>
#include <cstddef>
@ -193,6 +195,8 @@ private:
const auto& gridView = this->ebos_simulator_.gridView();
auto elemIt = gridView.template begin</*codim=*/0>();
const auto& elemEndIt = gridView.template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (; elemIt != elemEndIt; ++elemIt) {
const auto& elem = *elemIt;
if (elem.partitionType() != Dune::InteriorEntity) {
@ -225,6 +229,7 @@ private:
cell_pressure[idx] = water_pressure_reservoir;
}
OPM_END_PARALLEL_TRY_CATCH("AquiferNumerical::calculateAquiferPressure() failed: ");
const auto& comm = this->ebos_simulator_.vanguard().grid().comm();
comm.sum(&sum_pressure_watervolume, 1);
comm.sum(&sum_watervolume, 1);

View File

@ -35,6 +35,7 @@
#include <opm/simulators/aquifers/BlackoilAquiferModel.hpp>
#include <opm/simulators/wells/WellConnectionAuxiliaryModule.hpp>
#include <opm/simulators/flow/countGlobalCells.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <opm/grid/UnstructuredGrid.h>
#include <opm/simulators/timestepping/SimulatorReport.hpp>
@ -643,6 +644,7 @@ namespace Opm {
ElementContext elemCtx(ebosSimulator_);
const auto& gridView = ebosSimulator().gridView();
const auto& elemEndIt = gridView.template end</*codim=*/0, Dune::Interior_Partition>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (auto elemIt = gridView.template begin</*codim=*/0, Dune::Interior_Partition>();
elemIt != elemEndIt;
@ -725,6 +727,8 @@ namespace Opm {
}
OPM_END_PARALLEL_TRY_CATCH("BlackoilModelEbos::localConvergenceData() failed: ");
// compute local average in terms of global number of elements
const int bSize = B_avg.size();
for ( int i = 0; i<bSize; ++i )
@ -744,6 +748,8 @@ namespace Opm {
const auto& gridView = ebosSimulator().gridView();
ElementContext elemCtx(ebosSimulator_);
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (const auto& elem: elements(gridView, Dune::Partitions::interiorBorder))
{
elemCtx.updatePrimaryStencil(elem);
@ -766,6 +772,8 @@ namespace Opm {
}
}
OPM_END_PARALLEL_TRY_CATCH("BlackoilModelEbos::ComputeCnvError() failed: ");
return grid_.comm().sum(errorPV);
}

View File

@ -22,6 +22,8 @@
#include <dune/common/fvector.hh>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <algorithm>
#include <cmath>
@ -100,6 +102,7 @@ namespace Amg
int index = 0;
auto elemIt = gridView.template begin</*codim=*/0>();
const auto& elemEndIt = gridView.template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (; elemIt != elemEndIt; ++elemIt) {
elemCtx.updatePrimaryStencil(*elemIt);
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
@ -125,6 +128,7 @@ namespace Amg
weights[index] = bweights;
++index;
}
OPM_END_PARALLEL_TRY_CATCH("getTrueImpesWeights() failed: ");
}
} // namespace Amg

View File

@ -100,4 +100,60 @@ inline void logAndCheckForExceptionsAndThrow(Opm::DeferredLogger& deferred_logge
_throw(exc_type, message);
}
/// \brief Macro to setup the try of a parallel try-catch
///
/// Use OPM_END_PARALLEL_TRY_CATCH or OPM_END_PARALLEL_TRY_CATCH_LOG
/// fot the catch part.
#define OPM_BEGIN_PARALLEL_TRY_CATCH() \
std::string obptc_exc_msg; \
auto obptc_exc_type = Opm::ExceptionType::NONE; \
try {
/// \brief Inserts catch classes for the parallel try-catch
///
/// There is a clause that will catch anything
#define OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, \
obptc_exc_msg) \
catch (const Opm::NumericalIssue& e){ \
obptc_exc_type = Opm::ExceptionType::NUMERICAL_ISSUE; \
obptc_exc_msg = e.what(); \
} catch (const std::runtime_error& e) { \
obptc_exc_type = Opm::ExceptionType::RUNTIME_ERROR; \
obptc_exc_msg = e.what(); \
} catch (const std::invalid_argument& e) { \
obptc_exc_type = Opm::ExceptionType::INVALID_ARGUMENT; \
obptc_exc_msg = e.what(); \
} catch (const std::logic_error& e) { \
obptc_exc_type = Opm::ExceptionType::LOGIC_ERROR; \
obptc_exc_msg = e.what(); \
} catch (const std::exception& e) { \
obptc_exc_type = Opm::ExceptionType::DEFAULT; \
obptc_exc_msg = e.what(); \
} catch (...) { \
obptc_exc_type = Opm::ExceptionType::DEFAULT; \
obptc_exc_msg = "Unknown exception was thrown"; \
}
/// \brief Catch exception and throw in a parallel try-catch clause
///
/// Assumes that OPM_BEGIN_PARALLEL_TRY_CATCH() was called to initiate
/// the try-catch clause
#define OPM_END_PARALLEL_TRY_CATCH(prefix) \
} \
OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, obptc_exc_msg);\
checkForExceptionsAndThrow(obptc_exc_type, \
prefix + obptc_exc_msg);
/// \brief Catch exception, log, and throw in a parallel try-catch clause
///
/// Assumes that OPM_BEGIN_PARALLEL_TRY_CATCH() was called to initiate
/// the try-catch clause
#define OPM_END_PARALLEL_TRY_CATCH_LOG(obptc_logger, \
obptc_prefix, \
obptc_output) \
} \
OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, obptc_exc_msg); \
logAndCheckForExceptionsAndThrow(obptc_logger, obptc_exc_type, \
obptc_prefix + obptc_exc_msg, obptc_output);
#endif // OPM_DEFERREDLOGGINGERRORHELPERS_HPP

View File

@ -177,8 +177,6 @@ namespace Opm {
{
DeferredLogger local_deferredLogger;
std::string exc_msg;
auto exc_type = ExceptionType::NONE;
report_step_starts_ = true;
const Grid& grid = ebosSimulator_.vanguard().grid();
@ -190,7 +188,7 @@ namespace Opm {
// at least initializeWellState might be throw
// exception in opm-material (UniformTabulated2DFunction.hpp)
// playing it safe by extending the scope a bit.
try
OPM_BEGIN_PARALLEL_TRY_CATCH();
{
// The well state initialize bhp with the cell pressure in the top cell.
@ -233,24 +231,8 @@ namespace Opm {
}
}
}
catch (const Opm::NumericalIssue& e){
exc_type = ExceptionType::NUMERICAL_ISSUE;
exc_msg = e.what();
} catch (const std::runtime_error& e) {
exc_type = ExceptionType::RUNTIME_ERROR;
exc_msg = e.what();
} catch (const std::invalid_argument& e) {
exc_type = ExceptionType::INVALID_ARGUMENT;
exc_msg = e.what();
} catch (const std::logic_error& e) {
exc_type = ExceptionType::LOGIC_ERROR;
exc_msg = e.what();
} catch (const std::exception& e) {
exc_type = ExceptionType::DEFAULT;
exc_msg = e.what();
}
logAndCheckForExceptionsAndThrow(local_deferredLogger, exc_type, "beginReportStep() failed: " + exc_msg, terminal_output_);
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "beginReportStep() failed: ",
terminal_output_);
// Store the current well state, to be able to recover in the case of failed iterations
this->commitWGState();
}
@ -273,9 +255,8 @@ namespace Opm {
ebosSimulator_.model().newtonMethod().numIterations());
this->wellState().gliftTimeStepInit();
const double simulationTime = ebosSimulator_.time();
std::string exc_msg;
auto exc_type = ExceptionType::NONE;
try {
OPM_BEGIN_PARALLEL_TRY_CATCH();
{
// test wells
wellTesting(reportStepIdx, simulationTime, local_deferredLogger);
@ -302,21 +283,9 @@ namespace Opm {
setRepRadiusPerfLength();
}
}
} catch (const std::runtime_error& e) {
exc_type = ExceptionType::RUNTIME_ERROR;
exc_msg = e.what();
} catch (const std::invalid_argument& e) {
exc_type = ExceptionType::INVALID_ARGUMENT;
exc_msg = e.what();
} catch (const std::logic_error& e) {
exc_type = ExceptionType::LOGIC_ERROR;
exc_msg = e.what();
} catch (const std::exception& e) {
exc_type = ExceptionType::DEFAULT;
exc_msg = e.what();
}
logAndCheckForExceptionsAndThrow(local_deferredLogger, exc_type, "beginTimeStep() failed: " + exc_msg, terminal_output_);
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "beginTimeStep() failed: ",
terminal_output_);
for (auto& well : well_container_) {
well->setVFPProperties(vfp_properties_.get());
@ -358,8 +327,8 @@ namespace Opm {
const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx);
WellGroupHelpers::updateGuideRates(fieldGroup, schedule(), summaryState, this->phase_usage_, reportStepIdx, simulationTime,
this->wellState(), this->groupState(), comm, &this->guideRate_, pot, local_deferredLogger);
std::string exc_msg;
auto exc_type = ExceptionType::NONE;
// update gpmaint targets
if (schedule_[reportStepIdx].has_gpmaint()) {
regionalAveragePressureCalculator_->template defineState<ElementContext>(ebosSimulator_);
@ -391,19 +360,9 @@ namespace Opm {
}
}
}
} catch (const std::runtime_error& e) {
exc_type = ExceptionType::RUNTIME_ERROR;
exc_msg = e.what();
} catch (const std::invalid_argument& e) {
exc_type = ExceptionType::INVALID_ARGUMENT;
exc_msg = e.what();
} catch (const std::logic_error& e) {
exc_type = ExceptionType::LOGIC_ERROR;
exc_msg = e.what();
} catch (const std::exception& e) {
exc_type = ExceptionType::DEFAULT;
exc_msg = e.what();
}
// Catch clauses for all errors setting exc_type and exc_msg
OPM_PARALLEL_CATCH_CLAUSE(exc_type, exc_msg);
if (exc_type != ExceptionType::NONE) {
const std::string msg = "Compute initial well solution for new wells failed. Continue with zero initial rates";
@ -568,6 +527,8 @@ namespace Opm {
const auto& gridView = ebosSimulator_.vanguard().gridView();
const auto& elemEndIt = gridView.template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (auto elemIt = gridView.template begin</*codim=*/0>();
elemIt != elemEndIt;
++elemIt)
@ -590,6 +551,7 @@ namespace Opm {
perf_pressure = fs.pressure(FluidSystem::gasPhaseIdx).value();
}
}
OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::initializeWellState() failed: ");
this->wellState().init(cellPressures, schedule(), wells_ecl_, local_parallel_well_info_, timeStepIdx,
&this->prevWellState(), well_perf_data_,
@ -849,34 +811,31 @@ namespace Opm {
updatePerforationIntensiveQuantities();
auto exc_type = ExceptionType::NONE;
std::string exc_msg;
try {
if (iterationIdx == 0) {
if (iterationIdx == 0) {
// try-catch is needed here as updateWellControls
// contains global communication and has either to
// be reached by all processes or all need to abort
// before.
OPM_BEGIN_PARALLEL_TRY_CATCH();
{
calculateExplicitQuantities(local_deferredLogger);
prepareTimeStep(local_deferredLogger);
}
updateWellControls(local_deferredLogger, /* check group controls */ true);
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "assemble() failed (It=0): ",
terminal_output_);
}
updateWellControls(local_deferredLogger, /* check group controls */ true);
OPM_BEGIN_PARALLEL_TRY_CATCH();
{
// Set the well primary variables based on the value of well solutions
initPrimaryVariablesEvaluation();
maybeDoGasLiftOptimize(local_deferredLogger);
assembleWellEq(dt, local_deferredLogger);
} catch (const std::runtime_error& e) {
exc_type = ExceptionType::RUNTIME_ERROR;
exc_msg = e.what();
} catch (const std::invalid_argument& e) {
exc_type = ExceptionType::INVALID_ARGUMENT;
exc_msg = e.what();
} catch (const std::logic_error& e) {
exc_type = ExceptionType::LOGIC_ERROR;
exc_msg = e.what();
} catch (const std::exception& e) {
exc_type = ExceptionType::DEFAULT;
exc_msg = e.what();
}
logAndCheckForExceptionsAndThrow(local_deferredLogger, exc_type, "assemble() failed: " + exc_msg, terminal_output_);
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "assemble() failed: ",
terminal_output_);
last_report_.converged = true;
last_report_.assemble_time_well += perfTimer.stop();
}
@ -1160,28 +1119,17 @@ namespace Opm {
recoverWellSolutionAndUpdateWellState(const BVector& x)
{
DeferredLogger local_deferredLogger;
auto exc_type = ExceptionType::NONE;
std::string exc_msg;
try {
OPM_BEGIN_PARALLEL_TRY_CATCH();
{
if (localWellsActive()) {
for (auto& well : well_container_) {
well->recoverWellSolutionAndUpdateWellState(x, this->wellState(), local_deferredLogger);
}
}
} catch (const std::runtime_error& e) {
exc_type = ExceptionType::RUNTIME_ERROR;
exc_msg = e.what();
} catch (const std::invalid_argument& e) {
exc_type = ExceptionType::INVALID_ARGUMENT;
exc_msg = e.what();
} catch (const std::logic_error& e) {
exc_type = ExceptionType::LOGIC_ERROR;
exc_msg = e.what();
} catch (const std::exception& e) {
exc_type = ExceptionType::DEFAULT;
exc_msg = e.what();
}
logAndCheckForExceptionsAndThrow(local_deferredLogger, exc_type, "recoverWellSolutionAndUpdateWellState() failed: " + exc_msg, terminal_output_);
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
"recoverWellSolutionAndUpdateWellState() failed: ",
terminal_output_);
}
@ -1390,19 +1338,9 @@ namespace Opm {
const auto& well= well_container_[widx];
try {
well->computeWellPotentials(ebosSimulator_, well_state_copy, potentials, deferred_logger);
} catch (const std::runtime_error& e) {
exc_type = ExceptionType::RUNTIME_ERROR;
exc_msg = e.what();
} catch (const std::invalid_argument& e) {
exc_type = ExceptionType::INVALID_ARGUMENT;
exc_msg = e.what();
} catch (const std::logic_error& e) {
exc_type = ExceptionType::LOGIC_ERROR;
exc_msg = e.what();
} catch (const std::exception& e) {
exc_type = ExceptionType::DEFAULT;
exc_msg = e.what();
}
// catch all possible exception and store type and message.
OPM_PARALLEL_CATCH_CLAUSE(exc_type, exc_msg);
// Store it in the well state
// potentials is resized and set to zero in the beginning of well->ComputeWellPotentials
// and updated only if sucessfull. i.e. the potentials are zero for exceptions
@ -1480,60 +1418,43 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
prepareTimeStep(DeferredLogger& deferred_logger)
{
auto exc_type = ExceptionType::NONE;
std::string exc_msg;
try {
for (const auto& well : well_container_) {
const bool old_well_operable = well->isOperable();
well->checkWellOperability(ebosSimulator_, this->wellState(), deferred_logger);
for (const auto& well : well_container_) {
const bool old_well_operable = well->isOperable();
well->checkWellOperability(ebosSimulator_, this->wellState(), deferred_logger);
if (!well->isOperable() ) continue;
if (!well->isOperable() ) continue;
auto& events = this->wellState().well(well->indexOfWell()).events;
if (events.hasEvent(WellState::event_mask)) {
well->updateWellStateWithTarget(ebosSimulator_, this->groupState(), this->wellState(), deferred_logger);
// There is no new well control change input within a report step,
// so next time step, the well does not consider to have effective events anymore.
events.clearEvent(WellState::event_mask);
}
auto& events = this->wellState().well(well->indexOfWell()).events;
if (events.hasEvent(WellState::event_mask)) {
well->updateWellStateWithTarget(ebosSimulator_, this->groupState(), this->wellState(), deferred_logger);
// There is no new well control change input within a report step,
// so next time step, the well does not consider to have effective events anymore.
events.clearEvent(WellState::event_mask);
}
// solve the well equation initially to improve the initial solution of the well model
if (param_.solve_welleq_initially_) {
well->solveWellEquation(ebosSimulator_, this->wellState(), this->groupState(), deferred_logger);
}
// solve the well equation initially to improve the initial solution of the well model
if (param_.solve_welleq_initially_) {
well->solveWellEquation(ebosSimulator_, this->wellState(), this->groupState(), deferred_logger);
}
const bool well_operable = well->isOperable();
if (!well_operable && old_well_operable) {
const Well& well_ecl = getWellEcl(well->name());
if (well_ecl.getAutomaticShutIn()) {
deferred_logger.info(" well " + well->name() + " gets SHUT at the beginning of the time step ");
} else {
if (!well->wellIsStopped()) {
deferred_logger.info(" well " + well->name() + " gets STOPPED at the beginning of the time step ");
well->stopWell();
}
const bool well_operable = well->isOperable();
if (!well_operable && old_well_operable) {
const Well& well_ecl = getWellEcl(well->name());
if (well_ecl.getAutomaticShutIn()) {
deferred_logger.info(" well " + well->name() + " gets SHUT at the beginning of the time step ");
} else {
if (!well->wellIsStopped()) {
deferred_logger.info(" well " + well->name() + " gets STOPPED at the beginning of the time step ");
well->stopWell();
}
} else if (well_operable && !old_well_operable) {
deferred_logger.info(" well " + well->name() + " gets REVIVED at the beginning of the time step ");
well->openWell();
}
} else if (well_operable && !old_well_operable) {
deferred_logger.info(" well " + well->name() + " gets REVIVED at the beginning of the time step ");
well->openWell();
}
} // end of for (const auto& well : well_container_)
updatePrimaryVariables(deferred_logger);
} catch (const std::runtime_error& e) {
exc_type = ExceptionType::RUNTIME_ERROR;
exc_msg = e.what();
} catch (const std::invalid_argument& e) {
exc_type = ExceptionType::INVALID_ARGUMENT;
exc_msg = e.what();
} catch (const std::logic_error& e) {
exc_type = ExceptionType::LOGIC_ERROR;
exc_msg = e.what();
} catch (const std::exception& e) {
exc_type = ExceptionType::DEFAULT;
exc_msg = e.what();
}
logAndCheckForExceptionsAndThrow(deferred_logger, exc_type, "prepareTimestep() failed: " + exc_msg, terminal_output_);
} // end of for (const auto& well : well_container_)
updatePrimaryVariables(deferred_logger);
}
@ -1576,6 +1497,7 @@ namespace Opm {
const auto& gridView = grid.leafGridView();
ElementContext elemCtx(ebosSimulator_);
const auto& elemEndIt = gridView.template end</*codim=*/0, Dune::Interior_Partition>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (auto elemIt = gridView.template begin</*codim=*/0, Dune::Interior_Partition>();
elemIt != elemEndIt; ++elemIt)
@ -1602,6 +1524,7 @@ namespace Opm {
B += 1 / intQuants.solventInverseFormationVolumeFactor().value();
}
}
OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::updateAverageFormationFactor() failed: ")
// compute global average
grid.comm().sum(B_avg.data(), B_avg.size());
@ -1677,6 +1600,7 @@ namespace Opm {
ElementContext elemCtx(ebosSimulator_);
const auto& gridView = ebosSimulator_.gridView();
const auto& elemEndIt = gridView.template end</*codim=*/0, Dune::Interior_Partition>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (auto elemIt = gridView.template begin</*codim=*/0, Dune::Interior_Partition>();
elemIt != elemEndIt;
++elemIt)
@ -1690,6 +1614,7 @@ namespace Opm {
}
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
}
OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::updatePerforationIntensiveQuantities() failed: ");
}

View File

@ -26,6 +26,7 @@
#include <opm/grid/utility/RegionMapping.hpp>
#include <opm/simulators/linalg/ParallelIstlInformation.hpp>
#include <opm/simulators/wells/RegionAttributeHelpers.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <dune/grid/common/gridenums.hh>
#include <algorithm>
#include <cmath>
@ -121,6 +122,7 @@ namespace Opm {
ElementContext elemCtx( simulator );
const auto& gridView = simulator.gridView();
const auto& comm = gridView.comm();
OPM_BEGIN_PARALLEL_TRY_CATCH();
const auto& elemEndIt = gridView.template end</*codim=*/0>();
for (auto elemIt = gridView.template begin</*codim=*/0>();
@ -194,6 +196,8 @@ namespace Opm {
}
}
OPM_END_PARALLEL_TRY_CATCH("SurfaceToReservoirVoidage::defineState() failed: ");
for (const auto& reg : rmap_.activeRegions()) {
auto& ra = attr_.attributes(reg);
const double hpv_sum = comm.sum(attributes_hpv[reg].pv);

View File

@ -23,6 +23,7 @@
#include <opm/core/props/BlackoilPhases.hpp>
#include <opm/simulators/wells/RegionAttributeHelpers.hpp>
#include <opm/simulators/linalg/ParallelIstlInformation.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <dune/grid/common/gridenums.hh>
#include <algorithm>
@ -116,7 +117,9 @@ namespace Opm {
}
ElementContext elemCtx( simulator );
const auto& elemEndIt = gridView.template end</*codim=*/0>();
const auto& elemEndIt = gridView.template end</*codim=*/0>();
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (auto elemIt = gridView.template begin</*codim=*/0>();
elemIt != elemEndIt;
++elemIt)
@ -172,6 +175,7 @@ namespace Opm {
}
}
}
OPM_END_PARALLEL_TRY_CATCH("AverageRegionalPressure::defineState(): ");
for (int reg = 1; reg <= numRegions ; ++ reg) {
auto& ra = attr_.attributes(reg);