From 6ba21fd4c0632447d50a46574f13e43e0f5a6a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Mon, 26 Sep 2016 16:22:51 +0200 Subject: [PATCH 01/19] Update to interface change in opm-output --- .../SimulatorFullyImplicitBlackoilOutput.hpp | 2 +- .../WellStateFullyImplicitBlackoil.hpp | 66 ++++++++----------- 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp index 68e15beed..5cbdd09df 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp @@ -420,7 +420,7 @@ namespace Opm Opm::UgGridHelpers::numCells(grid) ); solutionToSim( restarted.first, phaseusage, simulatorstate ); - wellsToState( restarted.second, wellstate ); + wellsToState( restarted.second, phaseusage, wellstate ); } diff --git a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp index c2a833edc..e739675f5 100644 --- a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp +++ b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp @@ -196,10 +196,22 @@ namespace Opm data::Wells res = WellState::report(pu); const int nw = this->numWells(); - // If there are now wells numPhases throws a floating point - // exception. const int np = nw ? this->numPhases() : -1; + using rt = data::Rates::opt; + std::vector< rt > phs( np ); + if( pu.phase_used[BlackoilPhases::Aqua] ) { + phs.at( pu.phase_pos[BlackoilPhases::Aqua] ) = rt::wat; + } + + if( pu.phase_used[BlackoilPhases::Liquid] ) { + phs.at( pu.phase_pos[BlackoilPhases::Liquid] ) = rt::oil; + } + + if( pu.phase_used[BlackoilPhases::Vapour] ) { + phs.at( pu.phase_pos[BlackoilPhases::Vapour] ) = rt::gas; + } + /* this is a reference or example on **how** to convert from * WellState to something understood by opm-output. it is intended * to be properly implemented and maintained as a part of @@ -207,47 +219,21 @@ namespace Opm * representations. */ - for( auto w = 0; w < nw; ++w ) { - using rt = data::Rates::opt; - std::map< size_t, data::Completion > completions; + for( const auto& wt : this->wellMap() ) { + const auto w = wt.second[ 0 ]; + auto& well = res.at( wt.first ); - // completions aren't supported yet - //const auto* begin = wells_->well_connpos + w; - //const auto* end = wells_->well_connpos + w + 1; - //for( auto* i = begin; i != end; ++i ) { - // const auto perfrate = this->perfPhaseRates().begin() + *i; - // data::Rates perfrates; - // perfrates.set( rt::wat, *(perfrate + 0) ); - // perfrates.set( rt::oil, *(perfrate + 1) ); - // perfrates.set( rt::gas, *(perfrate + 2) ); + int local_comp_index = 0; + for( auto& cpair : well.completions ) { + const auto rates = this->perfPhaseRates().begin() + + (np * wt.second[ 1 ]) + + (np * local_comp_index); + ++local_comp_index; - // const size_t active_index = wells_->well_cells[ *i ]; - - // completions.emplace( active_index, - // data::Completion{ active_index, perfrates } ); - //} - - const auto wellrate_index = np * w; - const auto& wv = this->wellRates(); - - data::Rates wellrates; - if( pu.phase_used[BlackoilPhases::Aqua] ) { - wellrates.set( rt::wat, wv[ wellrate_index + pu.phase_pos[BlackoilPhases::Aqua] ] ); + for( int i = 0; i < np; ++i ) { + cpair.second.rates.set( phs[ i ], *(rates + i) ); + } } - - if( pu.phase_used[BlackoilPhases::Liquid] ) { - wellrates.set( rt::oil, wv[ wellrate_index + pu.phase_pos[BlackoilPhases::Liquid] ] ); - } - - if( pu.phase_used[BlackoilPhases::Vapour] ) { - wellrates.set( rt::gas, wv[ wellrate_index + pu.phase_pos[BlackoilPhases::Vapour] ] ); - } - - const double bhp = this->bhp()[ w ]; - const double thp = this->thp()[ w ]; - - res.emplace( wells_->name[ w ], - data::Well { wellrates, bhp, thp, std::move( completions ) } ); } return res; From dfb7f8ff63418163e10ac4662c2c7a1f01dd1dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Wed, 28 Sep 2016 10:22:03 +0200 Subject: [PATCH 02/19] Stop report early if there are no wells --- opm/autodiff/WellStateFullyImplicitBlackoil.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp index e739675f5..00cdd60ce 100644 --- a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp +++ b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp @@ -196,7 +196,9 @@ namespace Opm data::Wells res = WellState::report(pu); const int nw = this->numWells(); - const int np = nw ? this->numPhases() : -1; + if( nw == 0 ) return res; + const int np = this->numPhases(); + using rt = data::Rates::opt; std::vector< rt > phs( np ); From df4e163796bebdc081e07f490e7b4aa68b18daa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Wed, 28 Sep 2016 14:27:30 +0200 Subject: [PATCH 03/19] Avoid using buggy wellstate api --- opm/autodiff/WellStateFullyImplicitBlackoil.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp index 00cdd60ce..e06a8acd2 100644 --- a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp +++ b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp @@ -197,7 +197,7 @@ namespace Opm const int nw = this->numWells(); if( nw == 0 ) return res; - const int np = this->numPhases(); + const int np = pu.num_phases; using rt = data::Rates::opt; From 545f55bd3b625743db0ebf56b3d07ce2a2851f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Thu, 29 Sep 2016 12:06:51 +0200 Subject: [PATCH 04/19] Write control to data::Wells. Missing ability to restore. --- opm/autodiff/WellStateFullyImplicitBlackoil.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp index e06a8acd2..2abe32542 100644 --- a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp +++ b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp @@ -224,6 +224,7 @@ namespace Opm for( const auto& wt : this->wellMap() ) { const auto w = wt.second[ 0 ]; auto& well = res.at( wt.first ); + well.control = this->currentControls()[ w ]; int local_comp_index = 0; for( auto& cpair : well.completions ) { From 26f1a69903abe4e15481cde6904e05b0253ec8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Fri, 30 Sep 2016 09:52:45 +0200 Subject: [PATCH 05/19] wellToState reads new opm-output data exchange --- opm/autodiff/Compat.hpp | 60 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/opm/autodiff/Compat.hpp b/opm/autodiff/Compat.hpp index d93d71192..23705c04e 100644 --- a/opm/autodiff/Compat.hpp +++ b/opm/autodiff/Compat.hpp @@ -21,6 +21,9 @@ #ifndef OPM_SIMULATORS_COMPAT_HPP #define OPM_SIMULATORS_COMPAT_HPP +#include +#include + #include #include #include @@ -167,14 +170,59 @@ inline void solutionToSim( const data::Solution& sol, +inline void wellsToState( const data::Wells& wells, + PhaseUsage phases, + WellState& state ) { + using rt = data::Rates::opt; -inline void wellsToState( const data::Wells& wells, WellState& state ) { - state.bhp() = wells.bhp; - state.temperature() = wells.temperature; - state.wellRates() = wells.well_rate; - state.perfPress() = wells.perf_pressure; - state.perfRates() = wells.perf_rate; + const auto np = phases.num_phases; + + std::vector< rt > phs( np ); + if( phases.phase_used[BlackoilPhases::Aqua] ) { + phs.at( phases.phase_pos[BlackoilPhases::Aqua] ) = rt::wat; + } + + if( phases.phase_used[BlackoilPhases::Liquid] ) { + phs.at( phases.phase_pos[BlackoilPhases::Liquid] ) = rt::oil; + } + + if( phases.phase_used[BlackoilPhases::Vapour] ) { + phs.at( phases.phase_pos[BlackoilPhases::Vapour] ) = rt::gas; + } + + for( const auto& wm : state.wellMap() ) { + const auto well_index = wm.second[ 0 ]; + const auto& well = wells.at( wm.first ); + + state.bhp()[ well_index ] = well.bhp; + state.temperature()[ well_index ] = well.temperature; + + const auto wellrate_index = well_index * np; + for( size_t i = 0; i < phs.size(); ++i ) { + assert( well.rates.has( phs[ i ] ) ); + state.wellRates()[ wellrate_index + i ] = well.rates.get( phs[ i ] ); + } + + using PerfPairTypeAlias = decltype( *well.completions.begin() ); + const auto perforation_pressure = []( const PerfPairTypeAlias& p ) { + return p.second.pressure; + }; + + const auto perforation_reservoir_rate = []( const PerfPairTypeAlias& p ) { + return p.second.reservoir_rate; + }; + + std::transform( well.completions.begin(), + well.completions.end(), + state.perfPress().begin() + wm.second[ 1 ], + perforation_pressure ); + + std::transform( well.completions.begin(), + well.completions.end(), + state.perfRates().begin() + wm.second[ 1 ], + perforation_reservoir_rate ); + } } } From 164f74c93c9d3a867a155e0a48880425aabc5405 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Thu, 20 Oct 2016 15:54:02 +0800 Subject: [PATCH 06/19] supprot MESSAGES default vaule. --- opm/autodiff/FlowMain.hpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/opm/autodiff/FlowMain.hpp b/opm/autodiff/FlowMain.hpp index d90da6449..61473ba02 100644 --- a/opm/autodiff/FlowMain.hpp +++ b/opm/autodiff/FlowMain.hpp @@ -141,12 +141,12 @@ namespace Opm return EXIT_FAILURE; } asImpl().setupOutput(); - asImpl().setupLogging(); asImpl().readDeckInput(); asImpl().setupGridAndProps(); + asImpl().setupState(); + asImpl().setupLogging(); asImpl().extractMessages(); asImpl().runDiagnostics(); - asImpl().setupState(); asImpl().writeInit(); asImpl().distributeData(); asImpl().setupOutputWriter(); @@ -423,8 +423,16 @@ namespace Opm OpmLog::addBackend( "STREAMLOG", streamLog); std::shared_ptr debugLog = std::make_shared(debugFile, Log::DefaultMessageTypes, false, output_cout_); OpmLog::addBackend( "DEBUGLOG" , debugLog); + const auto& msgLimits = eclipse_state_->getSchedule()->getMessageLimits(); + const std::maplimits = {{Log::MessageType::Note, msgLimits.getMessagePrintLimit(0)}, + {Log::MessageType::Info, msgLimits.getMessagePrintLimit(0)}, + {Log::MessageType::Warning, msgLimits.getWarningPrintLimit(0)}, + {Log::MessageType::Error, msgLimits.getErrorPrintLimit(0)}, + {Log::MessageType::Problem, msgLimits.getProblemPrintLimit(0)}, + {Log::MessageType::Bug, msgLimits.getBugPrintLimit(0)}}; + prtLog->setMessageLimiter(std::make_shared(-1, limits)); prtLog->setMessageFormatter(std::make_shared(false)); - streamLog->setMessageLimiter(std::make_shared(10)); + streamLog->setMessageLimiter(std::make_shared(10, limits)); streamLog->setMessageFormatter(std::make_shared(true)); // Read parameters. From 0695555a778d87e328dd915e0ef9f53f625d452c Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Thu, 20 Oct 2016 16:27:46 +0800 Subject: [PATCH 07/19] correct function call order and add whitespace. --- opm/autodiff/FlowMain.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/opm/autodiff/FlowMain.hpp b/opm/autodiff/FlowMain.hpp index 61473ba02..10270220d 100644 --- a/opm/autodiff/FlowMain.hpp +++ b/opm/autodiff/FlowMain.hpp @@ -142,11 +142,11 @@ namespace Opm } asImpl().setupOutput(); asImpl().readDeckInput(); - asImpl().setupGridAndProps(); - asImpl().setupState(); asImpl().setupLogging(); asImpl().extractMessages(); + asImpl().setupGridAndProps(); asImpl().runDiagnostics(); + asImpl().setupState(); asImpl().writeInit(); asImpl().distributeData(); asImpl().setupOutputWriter(); @@ -424,12 +424,12 @@ namespace Opm std::shared_ptr debugLog = std::make_shared(debugFile, Log::DefaultMessageTypes, false, output_cout_); OpmLog::addBackend( "DEBUGLOG" , debugLog); const auto& msgLimits = eclipse_state_->getSchedule()->getMessageLimits(); - const std::maplimits = {{Log::MessageType::Note, msgLimits.getMessagePrintLimit(0)}, - {Log::MessageType::Info, msgLimits.getMessagePrintLimit(0)}, - {Log::MessageType::Warning, msgLimits.getWarningPrintLimit(0)}, - {Log::MessageType::Error, msgLimits.getErrorPrintLimit(0)}, - {Log::MessageType::Problem, msgLimits.getProblemPrintLimit(0)}, - {Log::MessageType::Bug, msgLimits.getBugPrintLimit(0)}}; + const std::map limits = {{Log::MessageType::Note, msgLimits.getMessagePrintLimit(0)}, + {Log::MessageType::Info, msgLimits.getMessagePrintLimit(0)}, + {Log::MessageType::Warning, msgLimits.getWarningPrintLimit(0)}, + {Log::MessageType::Error, msgLimits.getErrorPrintLimit(0)}, + {Log::MessageType::Problem, msgLimits.getProblemPrintLimit(0)}, + {Log::MessageType::Bug, msgLimits.getBugPrintLimit(0)}}; prtLog->setMessageLimiter(std::make_shared(-1, limits)); prtLog->setMessageFormatter(std::make_shared(false)); streamLog->setMessageLimiter(std::make_shared(10, limits)); From 7c51158ec43d27a528a4fa373f62f9924416572a Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Thu, 20 Oct 2016 21:00:51 +0800 Subject: [PATCH 08/19] do not set limits for prt log and set correct value for Note. --- opm/autodiff/FlowMain.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/autodiff/FlowMain.hpp b/opm/autodiff/FlowMain.hpp index 10270220d..7a589f67f 100644 --- a/opm/autodiff/FlowMain.hpp +++ b/opm/autodiff/FlowMain.hpp @@ -424,13 +424,13 @@ namespace Opm std::shared_ptr debugLog = std::make_shared(debugFile, Log::DefaultMessageTypes, false, output_cout_); OpmLog::addBackend( "DEBUGLOG" , debugLog); const auto& msgLimits = eclipse_state_->getSchedule()->getMessageLimits(); - const std::map limits = {{Log::MessageType::Note, msgLimits.getMessagePrintLimit(0)}, + const std::map limits = {{Log::MessageType::Note, msgLimits.getCommentPrintLimit(0)}, {Log::MessageType::Info, msgLimits.getMessagePrintLimit(0)}, {Log::MessageType::Warning, msgLimits.getWarningPrintLimit(0)}, {Log::MessageType::Error, msgLimits.getErrorPrintLimit(0)}, {Log::MessageType::Problem, msgLimits.getProblemPrintLimit(0)}, {Log::MessageType::Bug, msgLimits.getBugPrintLimit(0)}}; - prtLog->setMessageLimiter(std::make_shared(-1, limits)); + prtLog->setMessageLimiter(std::make_shared()); prtLog->setMessageFormatter(std::make_shared(false)); streamLog->setMessageLimiter(std::make_shared(10, limits)); streamLog->setMessageFormatter(std::make_shared(true)); From 9e1ba495546ae4c49234e2af785078b96d047160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 17 Oct 2016 13:39:06 +0200 Subject: [PATCH 09/19] Bugfix: missing return. --- opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp index 2becfdd38..b8b524094 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp @@ -277,7 +277,7 @@ namespace Opm /** \brief Whether this process does write to disk */ bool isIORank () const { - parallelOutput_->isIORank(); + return parallelOutput_->isIORank(); } void restore(SimulatorTimerInterface& timer, From 5559fbd233a86a07779bfb385f6904caa1dd5ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 17 Oct 2016 13:40:49 +0200 Subject: [PATCH 10/19] Add isRankZero() utility. --- opm/autodiff/NewtonIterationUtilities.cpp | 20 ++++++++++++++++++++ opm/autodiff/NewtonIterationUtilities.hpp | 3 +++ 2 files changed, 23 insertions(+) diff --git a/opm/autodiff/NewtonIterationUtilities.cpp b/opm/autodiff/NewtonIterationUtilities.cpp index 05bf0dc34..dc870ea99 100644 --- a/opm/autodiff/NewtonIterationUtilities.cpp +++ b/opm/autodiff/NewtonIterationUtilities.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -288,5 +289,24 @@ namespace Opm + + /// Return true if this is a serial run, or rank zero on an MPI run. + bool isRankZero(const boost::any& parallel_info) + { +#if HAVE_MPI + if (parallel_info.type() == typeid(ParallelISTLInformation)) { + const ParallelISTLInformation& info = + boost::any_cast(parallel_info); + return info.communicator().rank() == 0; + } else { + return true; + } +#else + static_cast(parallel_info); // Suppress unused argument warning. + return true; +#endif + } + + } // namespace Opm diff --git a/opm/autodiff/NewtonIterationUtilities.hpp b/opm/autodiff/NewtonIterationUtilities.hpp index 1e383d477..5a99f315f 100644 --- a/opm/autodiff/NewtonIterationUtilities.hpp +++ b/opm/autodiff/NewtonIterationUtilities.hpp @@ -21,6 +21,7 @@ #define OPM_NEWTONITERATIONUTILITIES_HEADER_INCLUDED #include +#include #include namespace Opm @@ -58,6 +59,8 @@ namespace Opm Eigen::SparseMatrix& A, AutoDiffBlock::V& b); + /// Return true if this is a serial run, or rank zero on an MPI run. + bool isRankZero(const boost::any& parallel_info); } // namespace Opm From 8ed3418245b5c5dbc3454a92435d9be1ba6e9ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 17 Oct 2016 13:41:39 +0200 Subject: [PATCH 11/19] Ensure only first-rank logging. Also classify convergence troubles or out-of-bounds residuals as "problem" not "error". --- opm/autodiff/BlackoilModelBase_impl.hpp | 30 +++++++++++++++---- .../NewtonIterationBlackoilInterleaved.cpp | 10 +++++-- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/opm/autodiff/BlackoilModelBase_impl.hpp b/opm/autodiff/BlackoilModelBase_impl.hpp index 452ad5326..692ded2b6 100644 --- a/opm/autodiff/BlackoilModelBase_impl.hpp +++ b/opm/autodiff/BlackoilModelBase_impl.hpp @@ -1939,16 +1939,28 @@ namespace detail { if (std::isnan(mass_balance_residual[idx]) || std::isnan(CNV[idx]) || (idx < np && std::isnan(well_flux_residual[idx]))) { - OPM_THROW(Opm::NumericalProblem, "NaN residual for phase " << materialName(idx)); + const auto msg = std::string("NaN residual for phase ") + materialName(idx); + if (terminal_output_) { + OpmLog::problem(msg); + } + OPM_THROW_NOLOG(Opm::NumericalProblem, msg); } if (mass_balance_residual[idx] > maxResidualAllowed() || CNV[idx] > maxResidualAllowed() || (idx < np && well_flux_residual[idx] > maxResidualAllowed())) { - OPM_THROW(Opm::NumericalProblem, "Too large residual for phase " << materialName(idx)); + const auto msg = std::string("Too large residual for phase ") + materialName(idx); + if (terminal_output_) { + OpmLog::problem(msg); + } + OPM_THROW_NOLOG(Opm::NumericalProblem, msg); } } if (std::isnan(residualWell) || residualWell > maxWellResidualAllowed) { - OPM_THROW(Opm::NumericalProblem, "NaN or too large residual for well control equation"); + const auto msg = std::string("NaN or too large residual for well control equation"); + if (terminal_output_) { + OpmLog::problem(msg); + } + OPM_THROW_NOLOG(Opm::NumericalProblem, msg); } return converged; @@ -2004,10 +2016,18 @@ namespace detail { // if one of the residuals is NaN, throw exception, so that the solver can be restarted for (int idx = 0; idx < np; ++idx) { if (std::isnan(well_flux_residual[idx])) { - OPM_THROW(Opm::NumericalProblem, "NaN residual for phase " << materialName(idx)); + const auto msg = std::string("NaN residual for phase ") + materialName(idx); + if (terminal_output_) { + OpmLog::problem(msg); + } + OPM_THROW_NOLOG(Opm::NumericalProblem, msg); } if (well_flux_residual[idx] > maxResidualAllowed()) { - OPM_THROW(Opm::NumericalProblem, "Too large residual for phase " << materialName(idx)); + const auto msg = std::string("Too large residual for phase ") + materialName(idx); + if (terminal_output_) { + OpmLog::problem(msg); + } + OPM_THROW_NOLOG(Opm::NumericalProblem, msg); } } diff --git a/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp b/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp index c8dd4b254..bd323eec5 100644 --- a/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp +++ b/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp @@ -487,7 +487,11 @@ namespace Opm // Check for failure of linear solver. if (!parameters_.ignoreConvergenceFailure_ && !result.converged) { - OPM_THROW(LinearSolverProblem, "Convergence failure for linear solver."); + const std::string msg("Convergence failure for linear solver."); + if (isRankZero(parallelInformation_)) { + OpmLog::problem(msg); + } + OPM_THROW_NOLOG(LinearSolverProblem, msg); } // Copy solver output to dx. @@ -658,7 +662,9 @@ namespace Opm // Check for failure of linear solver. if (!result.converged) { - OPM_THROW(LinearSolverProblem, "Convergence failure for linear solver in computePressureIncrement()."); + const std::string msg("Convergence failure for linear solver in computePressureIncrement()."); + OpmLog::problem(msg); + OPM_THROW_NOLOG(LinearSolverProblem, msg); } // Copy solver output to dx. From e4731fc14d5f2dcce87c3c2dacd150ab22c1de28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 19 Oct 2016 10:28:57 +0200 Subject: [PATCH 12/19] Rename isRankZero() -> isIORank() for consistency. --- opm/autodiff/NewtonIterationBlackoilInterleaved.cpp | 2 +- opm/autodiff/NewtonIterationUtilities.cpp | 2 +- opm/autodiff/NewtonIterationUtilities.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp b/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp index bd323eec5..45131b1a3 100644 --- a/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp +++ b/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp @@ -488,7 +488,7 @@ namespace Opm // Check for failure of linear solver. if (!parameters_.ignoreConvergenceFailure_ && !result.converged) { const std::string msg("Convergence failure for linear solver."); - if (isRankZero(parallelInformation_)) { + if (isIORank(parallelInformation_)) { OpmLog::problem(msg); } OPM_THROW_NOLOG(LinearSolverProblem, msg); diff --git a/opm/autodiff/NewtonIterationUtilities.cpp b/opm/autodiff/NewtonIterationUtilities.cpp index dc870ea99..7f374ef7e 100644 --- a/opm/autodiff/NewtonIterationUtilities.cpp +++ b/opm/autodiff/NewtonIterationUtilities.cpp @@ -291,7 +291,7 @@ namespace Opm /// Return true if this is a serial run, or rank zero on an MPI run. - bool isRankZero(const boost::any& parallel_info) + bool isIORank(const boost::any& parallel_info) { #if HAVE_MPI if (parallel_info.type() == typeid(ParallelISTLInformation)) { diff --git a/opm/autodiff/NewtonIterationUtilities.hpp b/opm/autodiff/NewtonIterationUtilities.hpp index 5a99f315f..b27106854 100644 --- a/opm/autodiff/NewtonIterationUtilities.hpp +++ b/opm/autodiff/NewtonIterationUtilities.hpp @@ -60,7 +60,7 @@ namespace Opm AutoDiffBlock::V& b); /// Return true if this is a serial run, or rank zero on an MPI run. - bool isRankZero(const boost::any& parallel_info); + bool isIORank(const boost::any& parallel_info); } // namespace Opm From a2c9e64291df4ef02feb88ec81c09d62cf8c8932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 19 Oct 2016 12:45:48 +0200 Subject: [PATCH 13/19] Add isIORank_ member to avoid repeated calls. --- opm/autodiff/NewtonIterationBlackoilInterleaved.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp b/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp index 45131b1a3..6c9a87901 100644 --- a/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp +++ b/opm/autodiff/NewtonIterationBlackoilInterleaved.cpp @@ -174,6 +174,7 @@ namespace Opm const boost::any& parallelInformation_arg=boost::any()) : iterations_( 0 ), parallelInformation_(parallelInformation_arg), + isIORank_(isIORank(parallelInformation_arg)), parameters_( param ) { } @@ -488,7 +489,7 @@ namespace Opm // Check for failure of linear solver. if (!parameters_.ignoreConvergenceFailure_ && !result.converged) { const std::string msg("Convergence failure for linear solver."); - if (isIORank(parallelInformation_)) { + if (isIORank_) { OpmLog::problem(msg); } OPM_THROW_NOLOG(LinearSolverProblem, msg); @@ -513,6 +514,7 @@ namespace Opm protected: mutable int iterations_; boost::any parallelInformation_; + bool isIORank_; NewtonIterationBlackoilInterleavedParameters parameters_; }; // end NewtonIterationBlackoilInterleavedImpl From d527b6862a4771a014e541ab9d723e97795c837e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 19 Oct 2016 13:48:25 +0200 Subject: [PATCH 14/19] Ensure logging only on first rank. --- opm/autodiff/FlowMain.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/autodiff/FlowMain.hpp b/opm/autodiff/FlowMain.hpp index a6564e8f0..c317fa138 100644 --- a/opm/autodiff/FlowMain.hpp +++ b/opm/autodiff/FlowMain.hpp @@ -540,7 +540,7 @@ namespace Opm fluidprops_.reset(new BlackoilPropsAdFromDeck(*deck_, *eclipse_state_, material_law_manager_, grid)); // Rock compressibility. - rock_comp_.reset(new RockCompressibility(*deck_, *eclipse_state_)); + rock_comp_.reset(new RockCompressibility(*deck_, *eclipse_state_, output_cout_)); // Gravity. assert(UgGridHelpers::dimensions(grid) == 3); From 2d15c1ffec4e60e88deedb1b425377f3f2c1059e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 21 Oct 2016 11:21:02 +0200 Subject: [PATCH 15/19] Adapt to API change in opm-parser. --- opm/autodiff/FlowMain.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/autodiff/FlowMain.hpp b/opm/autodiff/FlowMain.hpp index 28994bfcc..860e7a2f7 100644 --- a/opm/autodiff/FlowMain.hpp +++ b/opm/autodiff/FlowMain.hpp @@ -423,7 +423,7 @@ namespace Opm OpmLog::addBackend( "STREAMLOG", streamLog); std::shared_ptr debugLog = std::make_shared(debugFile, Log::DefaultMessageTypes, false, output_cout_); OpmLog::addBackend( "DEBUGLOG" , debugLog); - const auto& msgLimits = eclipse_state_->getSchedule()->getMessageLimits(); + const auto& msgLimits = eclipse_state_->getSchedule().getMessageLimits(); const std::map limits = {{Log::MessageType::Note, msgLimits.getCommentPrintLimit(0)}, {Log::MessageType::Info, msgLimits.getMessagePrintLimit(0)}, {Log::MessageType::Warning, msgLimits.getWarningPrintLimit(0)}, From 17a9f28fb8ea7afdb3924958953e5d2774b7f49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 25 Oct 2016 10:31:02 +0200 Subject: [PATCH 16/19] Update well data output integration. Includes the following changes: - update to match API change in opm-output (vector not map for data::Wells::completions), - restore WellStateFullyImplicitBlackoil::perfPhaseRates() from output, - restore WellStateFullyImplicitBlackoil::currentControls() from output. Remaining non-restored well-related data are: - well potentials, - the dynamic list of econ-limited completions. --- opm/autodiff/Compat.hpp | 23 +++++++++++++------ .../WellStateFullyImplicitBlackoil.hpp | 5 ++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/opm/autodiff/Compat.hpp b/opm/autodiff/Compat.hpp index 23705c04e..9bb208bc1 100644 --- a/opm/autodiff/Compat.hpp +++ b/opm/autodiff/Compat.hpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -172,7 +172,7 @@ inline void solutionToSim( const data::Solution& sol, inline void wellsToState( const data::Wells& wells, PhaseUsage phases, - WellState& state ) { + WellStateFullyImplicitBlackoil& state ) { using rt = data::Rates::opt; @@ -197,6 +197,7 @@ inline void wellsToState( const data::Wells& wells, state.bhp()[ well_index ] = well.bhp; state.temperature()[ well_index ] = well.temperature; + state.currentControls()[ well_index ] = well.control; const auto wellrate_index = well_index * np; for( size_t i = 0; i < phs.size(); ++i ) { @@ -204,13 +205,12 @@ inline void wellsToState( const data::Wells& wells, state.wellRates()[ wellrate_index + i ] = well.rates.get( phs[ i ] ); } - using PerfPairTypeAlias = decltype( *well.completions.begin() ); - const auto perforation_pressure = []( const PerfPairTypeAlias& p ) { - return p.second.pressure; + const auto perforation_pressure = []( const data::Completion& comp ) { + return comp.pressure; }; - const auto perforation_reservoir_rate = []( const PerfPairTypeAlias& p ) { - return p.second.reservoir_rate; + const auto perforation_reservoir_rate = []( const data::Completion& comp ) { + return comp.reservoir_rate; }; std::transform( well.completions.begin(), @@ -222,6 +222,15 @@ inline void wellsToState( const data::Wells& wells, well.completions.end(), state.perfRates().begin() + wm.second[ 1 ], perforation_reservoir_rate ); + + int local_comp_index = 0; + for (const data::Completion& comp : well.completions) { + const int global_comp_index = wm.second[1] + local_comp_index; + for (int phase_index = 0; phase_index < np; ++phase_index) { + state.perfPhaseRates()[global_comp_index*np + phase_index] = comp.rates.get(phs[phase_index]); + } + ++local_comp_index; + } } } diff --git a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp index 2abe32542..7a8e1fd43 100644 --- a/opm/autodiff/WellStateFullyImplicitBlackoil.hpp +++ b/opm/autodiff/WellStateFullyImplicitBlackoil.hpp @@ -227,16 +227,17 @@ namespace Opm well.control = this->currentControls()[ w ]; int local_comp_index = 0; - for( auto& cpair : well.completions ) { + for( auto& comp : well.completions ) { const auto rates = this->perfPhaseRates().begin() + (np * wt.second[ 1 ]) + (np * local_comp_index); ++local_comp_index; for( int i = 0; i < np; ++i ) { - cpair.second.rates.set( phs[ i ], *(rates + i) ); + comp.rates.set( phs[ i ], *(rates + i) ); } } + assert(local_comp_index == this->wells_->well_connpos[ w + 1 ] - this->wells_->well_connpos[ w ]); } return res; From 7da420869be8e2b065be04108a97ea24ef67bf19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 25 Oct 2016 15:27:59 +0200 Subject: [PATCH 17/19] Bugfix: pass both normal and extra data to output. Normal meaning SWAT, PRESSURE, RS etc. Extra meaning KR, VISC etc. as asked for in RPTRST. --- opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp index 77624075b..3c8e010e6 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp @@ -374,10 +374,12 @@ namespace Opm if (initConfig.restartRequested() && ((initConfig.getRestartStep()) == (timer.currentStepNum()))) { std::cout << "Skipping restart write in start of step " << timer.currentStepNum() << std::endl; } else { + data::Solution combined_sol = simToSolution(state, phaseUsage_); // Get "normal" data (SWAT, PRESSURE, ...) + combined_sol.insert(simProps.begin(), simProps.end()); // ... insert "extra" data (KR, VISC, ...) eclWriter_->writeTimeStep(timer.reportStepNum(), substep, timer.simulationTimeElapsed(), - simToSolution( state, phaseUsage_ ), + combined_sol, wellState.report(phaseUsage_)); } } From 1fe610ef5a7d0053f84c5c3735dc241bd27fb6dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 27 Oct 2016 11:02:04 +0200 Subject: [PATCH 18/19] Bugfix: properly handle two-phase cases. Errors were found in FIP handling and output. --- opm/autodiff/BlackoilModelBase_impl.hpp | 10 ++++++---- .../SimulatorFullyImplicitBlackoilOutput.hpp | 20 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/opm/autodiff/BlackoilModelBase_impl.hpp b/opm/autodiff/BlackoilModelBase_impl.hpp index 692ded2b6..cfd777df9 100644 --- a/opm/autodiff/BlackoilModelBase_impl.hpp +++ b/opm/autodiff/BlackoilModelBase_impl.hpp @@ -2413,10 +2413,12 @@ namespace detail { { //Accumulate phases for each region for (int phase = 0; phase < maxnp; ++phase) { - for (int c = 0; c < nc; ++c) { - const int region = fipnum[c] - 1; - if (region != -1) { - values[region][phase] += sd_.fip[phase][c]; + if (active_[ phase ]) { + for (int c = 0; c < nc; ++c) { + const int region = fipnum[c] - 1; + if (region != -1) { + values[region][phase] += sd_.fip[phase][c]; + } } } } diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp index 713ef9cef..4348b9a26 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp @@ -691,24 +691,26 @@ namespace Opm data::TargetType::SUMMARY ); } if (liquid_active) { + const ADB::V& oipl = sd.fip[Model::SimulatorData::FIP_LIQUID]; + const ADB::V& oipg = vapour_active ? sd.fip[Model::SimulatorData::FIP_VAPORIZED_OIL] : ADB::V(); + const ADB::V& oip = vapour_active ? oipl + oipg : oipl; + //Oil in place (liquid phase only) if (hasFRBKeyword(summaryConfig, "OIPL")) { output.insert("OIPL", Opm::UnitSystem::measure::volume, - adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_LIQUID]), + adbVToDoubleVector(oipl), data::TargetType::SUMMARY ); } //Oil in place (gas phase only) if (hasFRBKeyword(summaryConfig, "OIPG")) { output.insert("OIPG", Opm::UnitSystem::measure::volume, - adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_VAPORIZED_OIL]), + adbVToDoubleVector(oipg), data::TargetType::SUMMARY ); } // Oil in place (in liquid and gas phases) if (hasFRBKeyword(summaryConfig, "OIP")) { - ADB::V oip = sd.fip[Model::SimulatorData::FIP_LIQUID] + - sd.fip[Model::SimulatorData::FIP_VAPORIZED_OIL]; output.insert("OIP", Opm::UnitSystem::measure::volume, adbVToDoubleVector(oip), @@ -716,24 +718,26 @@ namespace Opm } } if (vapour_active) { + const ADB::V& gipg = sd.fip[Model::SimulatorData::FIP_VAPOUR]; + const ADB::V& gipl = liquid_active ? sd.fip[Model::SimulatorData::FIP_DISSOLVED_GAS] : ADB::V(); + const ADB::V& gip = liquid_active ? gipg + gipl : gipg; + // Gas in place (gas phase only) if (hasFRBKeyword(summaryConfig, "GIPG")) { output.insert("GIPG", Opm::UnitSystem::measure::volume, - adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_VAPOUR]), + adbVToDoubleVector(gipg), data::TargetType::SUMMARY ); } // Gas in place (liquid phase only) if (hasFRBKeyword(summaryConfig, "GIPL")) { output.insert("GIPL", Opm::UnitSystem::measure::volume, - adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_DISSOLVED_GAS]), + adbVToDoubleVector(gipl), data::TargetType::SUMMARY ); } // Gas in place (in both liquid and gas phases) if (hasFRBKeyword(summaryConfig, "GIP")) { - ADB::V gip = sd.fip[Model::SimulatorData::FIP_VAPOUR] + - sd.fip[Model::SimulatorData::FIP_DISSOLVED_GAS]; output.insert("GIP", Opm::UnitSystem::measure::volume, adbVToDoubleVector(gip), From e762844cdf352fc8f7e85a8aeab6f880461d088b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 27 Oct 2016 13:20:10 +0200 Subject: [PATCH 19/19] Bugfix: use correct object in sequential model. Discovered as a side effect of two-phase fix. --- opm/autodiff/BlackoilSequentialModel.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/autodiff/BlackoilSequentialModel.hpp b/opm/autodiff/BlackoilSequentialModel.hpp index 23f9ec6ab..4c1ec6f8e 100644 --- a/opm/autodiff/BlackoilSequentialModel.hpp +++ b/opm/autodiff/BlackoilSequentialModel.hpp @@ -247,7 +247,7 @@ namespace Opm { /// Return the well model const WellModel& wellModel() const { - return pressure_model_->wellModel(); + return pressure_solver_.model().wellModel(); } @@ -265,7 +265,7 @@ namespace Opm { /// Return reservoir simulation data (for output functionality) const SimulatorData& getSimulatorData() const { - return transport_model_->getSimulatorData(); + return transport_solver_.model().getSimulatorData(); }