diff --git a/ebos/eclproblem.hh b/ebos/eclproblem.hh index 5917846c8..95d9d44a1 100644 --- a/ebos/eclproblem.hh +++ b/ebos/eclproblem.hh @@ -68,6 +68,8 @@ #include +#include + #include #include #include @@ -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(); const auto& elemEndIt = vanguard.gridView().template end(); + 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(); const auto& elemEndIt = vanguard.gridView().template end(); + OPM_BEGIN_PARALLEL_TRY_CATCH(); for (; elemIt != elemEndIt; ++elemIt) { const Element& elem = *elemIt; @@ -2178,6 +2184,7 @@ private: Scalar Sw = decay(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(); @@ -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(); const auto& elemEndIt = vanguard.gridView().template end(); + 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(); const auto& elemEndIt = vanguard.gridView().template end(); + 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_ diff --git a/ebos/eclwellmanager.hh b/ebos/eclwellmanager.hh index 2db48d23b..be24f64da 100644 --- a/ebos/eclwellmanager.hh +++ b/ebos/eclwellmanager.hh @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -407,6 +408,7 @@ public: const auto gridView = simulator_.vanguard().gridView(); auto elemIt = gridView.template begin(); const auto& elemEndIt = gridView.template end(); + 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) diff --git a/ebos/eclwriter.hh b/ebos/eclwriter.hh index 95de4edc2..232beff62 100644 --- a/ebos/eclwriter.hh +++ b/ebos/eclwriter.hh @@ -34,6 +34,7 @@ #include #include +#include #include @@ -379,6 +380,7 @@ private: ElementIterator elemIt = gridView.template begin(); const ElementIterator& elemEndIt = gridView.template end(); + 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_; diff --git a/opm/simulators/aquifers/AquiferInterface.hpp b/opm/simulators/aquifers/AquiferInterface.hpp index abea05af4..f8e5451b6 100644 --- a/opm/simulators/aquifers/AquiferInterface.hpp +++ b/opm/simulators/aquifers/AquiferInterface.hpp @@ -27,6 +27,8 @@ #include +#include + #include #include #include @@ -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 diff --git a/opm/simulators/aquifers/AquiferNumerical.hpp b/opm/simulators/aquifers/AquiferNumerical.hpp index 087793f1a..05d9e372b 100644 --- a/opm/simulators/aquifers/AquiferNumerical.hpp +++ b/opm/simulators/aquifers/AquiferNumerical.hpp @@ -25,6 +25,8 @@ #include +#include + #include #include #include @@ -193,6 +195,8 @@ private: const auto& gridView = this->ebos_simulator_.gridView(); auto elemIt = gridView.template begin(); const auto& elemEndIt = gridView.template end(); + 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); diff --git a/opm/simulators/flow/BlackoilModelEbos.hpp b/opm/simulators/flow/BlackoilModelEbos.hpp index 712c1725d..e68835608 100644 --- a/opm/simulators/flow/BlackoilModelEbos.hpp +++ b/opm/simulators/flow/BlackoilModelEbos.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -643,6 +644,7 @@ namespace Opm { ElementContext elemCtx(ebosSimulator_); const auto& gridView = ebosSimulator().gridView(); const auto& elemEndIt = gridView.template end(); + OPM_BEGIN_PARALLEL_TRY_CATCH(); for (auto elemIt = gridView.template begin(); 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 +#include + #include #include @@ -100,6 +102,7 @@ namespace Amg int index = 0; auto elemIt = gridView.template begin(); const auto& elemEndIt = gridView.template end(); + 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 diff --git a/opm/simulators/utils/DeferredLoggingErrorHelpers.hpp b/opm/simulators/utils/DeferredLoggingErrorHelpers.hpp index caa02054d..66861f8ec 100644 --- a/opm/simulators/utils/DeferredLoggingErrorHelpers.hpp +++ b/opm/simulators/utils/DeferredLoggingErrorHelpers.hpp @@ -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 diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index c2eb8efca..9c821c6bf 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -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(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(); + OPM_BEGIN_PARALLEL_TRY_CATCH(); + for (auto elemIt = gridView.template begin(); 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:: 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(); + OPM_BEGIN_PARALLEL_TRY_CATCH(); for (auto elemIt = gridView.template begin(); 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(); + OPM_BEGIN_PARALLEL_TRY_CATCH(); for (auto elemIt = gridView.template begin(); elemIt != elemEndIt; ++elemIt) @@ -1690,6 +1614,7 @@ namespace Opm { } elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); } + OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::updatePerforationIntensiveQuantities() failed: "); } diff --git a/opm/simulators/wells/RateConverter.hpp b/opm/simulators/wells/RateConverter.hpp index 2664d81ed..be18a2c21 100644 --- a/opm/simulators/wells/RateConverter.hpp +++ b/opm/simulators/wells/RateConverter.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -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(); for (auto elemIt = gridView.template begin(); @@ -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); diff --git a/opm/simulators/wells/RegionAverageCalculator.hpp b/opm/simulators/wells/RegionAverageCalculator.hpp index 54c35e21b..b766e038e 100644 --- a/opm/simulators/wells/RegionAverageCalculator.hpp +++ b/opm/simulators/wells/RegionAverageCalculator.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -116,7 +117,9 @@ namespace Opm { } ElementContext elemCtx( simulator ); - const auto& elemEndIt = gridView.template end(); + const auto& elemEndIt = gridView.template end(); + OPM_BEGIN_PARALLEL_TRY_CATCH(); + for (auto elemIt = gridView.template begin(); 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);