2015-06-01 06:33:37 -05:00
/*
Copyright 2015 SINTEF ICT , Applied Mathematics .
2015-06-16 04:35:23 -05:00
Copyright 2015 Dr . Blatt - HPC - Simulation - Software & Services
Copyright 2015 NTNU
2015-06-01 06:33:37 -05:00
Copyright 2015 Statoil AS
2015-10-07 10:48:27 -05:00
Copyright 2015 IRIS AS
2015-06-01 06:33:37 -05:00
This file is part of the Open Porous Media project ( OPM ) .
OPM is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
OPM is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with OPM . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <config.h>
# include <opm/autodiff/DuneMatrix.hpp>
2015-10-07 13:49:20 -05:00
# include <opm/autodiff/AdditionalObjectDeleter.hpp>
2016-02-08 07:46:29 -06:00
# include <opm/autodiff/CPRPreconditioner.hpp>
2015-06-01 06:33:37 -05:00
# include <opm/autodiff/NewtonIterationBlackoilInterleaved.hpp>
2015-06-16 03:18:11 -05:00
# include <opm/autodiff/NewtonIterationUtilities.hpp>
2015-12-01 07:56:29 -06:00
# include <opm/autodiff/ParallelRestrictedAdditiveSchwarz.hpp>
# include <opm/autodiff/ParallelOverlappingILU0.hpp>
2015-06-01 06:33:37 -05:00
# include <opm/autodiff/AutoDiffHelpers.hpp>
2015-10-08 04:43:36 -05:00
# include <opm/common/Exceptions.hpp>
2015-06-16 04:35:23 -05:00
# include <opm/core/linalg/ParallelIstlInformation.hpp>
2015-06-01 06:33:37 -05:00
2016-11-02 07:10:44 -05:00
# include <opm/autodiff/ISTLSolver.hpp>
2015-10-07 13:49:20 -05:00
# include <opm/common/utility/platform_dependent/disable_warnings.h>
2015-10-07 10:48:27 -05:00
2015-06-01 06:33:37 -05:00
# if HAVE_UMFPACK
# include <Eigen/UmfPackSupport>
# else
# include <Eigen/SparseLU>
# endif
2015-10-06 05:11:49 -05:00
# include <opm/common/utility/platform_dependent/reenable_warnings.h>
2015-06-01 06:33:37 -05:00
namespace Opm
{
2015-10-07 10:48:27 -05:00
namespace detail {
/**
* Simple binary operator that always returns 0.1
* It is used to get the sparsity pattern for our
* interleaved system , and is marginally faster than using
* operator + = .
*/
template < typename Scalar > struct PointOneOp {
EIGEN_EMPTY_STRUCT_CTOR ( PointOneOp )
2015-10-08 08:24:47 -05:00
Scalar operator ( ) ( const Scalar & , const Scalar & ) const { return 0.1 ; }
2015-10-07 10:48:27 -05:00
} ;
2015-06-01 06:33:37 -05:00
}
2015-10-07 10:48:27 -05:00
/// This class solves the fully implicit black-oil system by
/// solving the reduced system (after eliminating well variables)
/// as a block-structured matrix (one block for all cell variables) for a fixed
/// number of cell variables np .
2016-02-08 06:28:28 -06:00
template < int np , class ScalarT = double >
2015-10-07 10:48:27 -05:00
class NewtonIterationBlackoilInterleavedImpl : public NewtonIterationBlackoilInterface
2015-06-01 06:33:37 -05:00
{
2016-02-08 06:28:28 -06:00
typedef ScalarT Scalar ;
2015-10-09 06:39:02 -05:00
typedef Dune : : FieldVector < Scalar , np > VectorBlockType ;
2016-02-08 06:28:28 -06:00
2016-02-08 07:46:29 -06:00
typedef Dune : : MatrixBlock < Scalar , np , np > MatrixBlockType ;
2016-11-02 07:10:44 -05:00
2015-10-07 10:48:27 -05:00
typedef Dune : : BCRSMatrix < MatrixBlockType > Mat ;
typedef Dune : : BlockVector < VectorBlockType > Vector ;
2016-11-02 07:10:44 -05:00
typedef Opm : : ISTLSolver < MatrixBlockType , VectorBlockType > ISTLSolverType ;
2015-10-07 10:48:27 -05:00
public :
typedef NewtonIterationBlackoilInterface : : SolutionVector SolutionVector ;
/// Construct a system solver.
2015-10-09 05:03:58 -05:00
/// \param[in] param parameters controlling the behaviour of the linear solvers
2015-10-07 10:48:27 -05:00
/// \param[in] parallelInformation In the case of a parallel run
2015-10-09 05:03:58 -05:00
/// with dune-istl the information about the parallelization.
NewtonIterationBlackoilInterleavedImpl ( const NewtonIterationBlackoilInterleavedParameters & param ,
2015-10-07 10:48:27 -05:00
const boost : : any & parallelInformation_arg = boost : : any ( ) )
2016-11-02 07:10:44 -05:00
: istlSolver_ ( param , parallelInformation_arg ) ,
2015-10-09 05:03:58 -05:00
parameters_ ( param )
2015-10-07 10:48:27 -05:00
{
2015-06-01 06:33:37 -05:00
}
2015-10-07 10:48:27 -05:00
/// Solve the system of linear equations Ax = b, with A being the
/// combined derivative matrix of the residual and b
/// being the residual itself.
/// \param[in] residual residual object containing A and b.
/// \return the solution x
/// \copydoc NewtonIterationBlackoilInterface::iterations
2016-11-02 07:10:44 -05:00
int iterations ( ) const { return istlSolver_ . iterations ( ) ; }
2015-10-07 10:48:27 -05:00
/// \copydoc NewtonIterationBlackoilInterface::parallelInformation
2016-11-02 07:10:44 -05:00
const boost : : any & parallelInformation ( ) const { return istlSolver_ . parallelInformation ( ) ; }
2015-10-07 10:48:27 -05:00
public :
void formInterleavedSystem ( const std : : vector < LinearisedBlackoilResidual : : ADB > & eqs ,
Mat & istlA ) const
{
assert ( np = = int ( eqs . size ( ) ) ) ;
// Find sparsity structure as union of basic block sparsity structures,
// corresponding to the jacobians with respect to pressure.
// Use our custom PointOneOp to get to the union structure.
2016-05-11 08:13:52 -05:00
// As default we only iterate over the pressure derivatives.
2015-10-07 10:48:27 -05:00
Eigen : : SparseMatrix < double , Eigen : : ColMajor > col_major = eqs [ 0 ] . derivative ( ) [ 0 ] . getSparse ( ) ;
detail : : PointOneOp < double > point_one ;
for ( int phase = 1 ; phase < np ; + + phase ) {
const AutoDiffMatrix : : SparseRep & mat = eqs [ phase ] . derivative ( ) [ 0 ] . getSparse ( ) ;
col_major = col_major . binaryExpr ( mat , point_one ) ;
}
2016-05-11 08:13:52 -05:00
// For some cases (for instance involving Solvent flow) the reasoning for only adding
// the pressure derivatives fails. As getting the sparsity pattern is non-trivial, in terms
// of work, the full sparsity pattern is only added when required.
if ( parameters_ . require_full_sparsity_pattern_ ) {
for ( int p1 = 0 ; p1 < np ; + + p1 ) {
for ( int p2 = 1 ; p2 < np ; + + p2 ) { // pressure is already added
const AutoDiffMatrix : : SparseRep & mat = eqs [ p1 ] . derivative ( ) [ p2 ] . getSparse ( ) ;
col_major = col_major . binaryExpr ( mat , point_one ) ;
}
}
}
2015-06-01 06:33:37 -05:00
2015-10-07 10:48:27 -05:00
// Automatically convert the column major structure to a row-major structure
Eigen : : SparseMatrix < double , Eigen : : RowMajor > row_major = col_major ;
const int size = row_major . rows ( ) ;
assert ( size = = row_major . cols ( ) ) ;
2015-10-08 08:24:47 -05:00
{
// Create ISTL matrix with interleaved rows and columns (block structured).
istlA . setSize ( row_major . rows ( ) , row_major . cols ( ) , row_major . nonZeros ( ) ) ;
istlA . setBuildMode ( Mat : : row_wise ) ;
const int * ia = row_major . outerIndexPtr ( ) ;
const int * ja = row_major . innerIndexPtr ( ) ;
const typename Mat : : CreateIterator endrow = istlA . createend ( ) ;
for ( typename Mat : : CreateIterator row = istlA . createbegin ( ) ; row ! = endrow ; + + row ) {
const int ri = row . index ( ) ;
for ( int i = ia [ ri ] ; i < ia [ ri + 1 ] ; + + i ) {
row . insert ( ja [ i ] ) ;
}
2015-10-07 10:48:27 -05:00
}
}
2016-02-08 08:52:32 -06:00
/*
// not neeeded since MatrixBlock initially zeros all elements during construction
// Set all blocks to zero.
for ( auto row = istlA . begin ( ) , rowend = istlA . end ( ) ; row ! = rowend ; + + row ) {
for ( auto col = row - > begin ( ) , colend = row - > end ( ) ; col ! = colend ; + + col ) {
* col = 0.0 ;
}
}
*/
2015-10-07 10:48:27 -05:00
/**
* Go through all jacobians , and insert in correct spot
*
* The straight forward way to do this would be to run through each
* element in the output matrix , and set all block entries by gathering
* from all " input matrices " ( derivatives ) .
*
* A faster alternative is to instead run through each " input matrix " and
* insert its elements in the correct spot in the output matrix .
*
*/
2015-10-08 08:24:47 -05:00
for ( int p1 = 0 ; p1 < np ; + + p1 ) {
for ( int p2 = 0 ; p2 < np ; + + p2 ) {
// Note that that since these are CSC and not CSR matrices,
// ja contains row numbers instead of column numbers.
const AutoDiffMatrix : : SparseRep & s = eqs [ p1 ] . derivative ( ) [ p2 ] . getSparse ( ) ;
const int * ia = s . outerIndexPtr ( ) ;
const int * ja = s . innerIndexPtr ( ) ;
const double * sa = s . valuePtr ( ) ;
for ( int col = 0 ; col < size ; + + col ) {
2015-10-07 10:48:27 -05:00
for ( int elem_ix = ia [ col ] ; elem_ix < ia [ col + 1 ] ; + + elem_ix ) {
const int row = ja [ elem_ix ] ;
istlA [ row ] [ col ] [ p1 ] [ p2 ] = sa [ elem_ix ] ;
}
}
}
}
2015-06-01 06:33:37 -05:00
}
2015-10-07 10:48:27 -05:00
/// Solve the linear system Ax = b, with A being the
/// combined derivative matrix of the residual and b
/// being the residual itself.
/// \param[in] residual residual object containing A and b.
/// \return the solution x
SolutionVector computeNewtonIncrement ( const LinearisedBlackoilResidual & residual ) const
{
2015-10-09 06:39:02 -05:00
typedef LinearisedBlackoilResidual : : ADB ADB ;
typedef ADB : : V V ;
2015-10-07 10:48:27 -05:00
// Build the vector of equations.
//const int np = residual.material_balance_eq.size();
assert ( np = = int ( residual . material_balance_eq . size ( ) ) ) ;
std : : vector < ADB > eqs ;
2016-09-12 16:28:44 -05:00
eqs . reserve ( np + 2 ) ;
2015-10-07 10:48:27 -05:00
for ( int phase = 0 ; phase < np ; + + phase ) {
eqs . push_back ( residual . material_balance_eq [ phase ] ) ;
}
2015-06-01 06:33:37 -05:00
2015-10-07 10:48:27 -05:00
// check if wells are present
const bool hasWells = residual . well_flux_eq . size ( ) > 0 ;
std : : vector < ADB > elim_eqs ;
if ( hasWells )
{
eqs . push_back ( residual . well_flux_eq ) ;
2016-09-12 16:28:44 -05:00
eqs . push_back ( residual . well_eq ) ;
2015-10-07 10:48:27 -05:00
// Eliminate the well-related unknowns, and corresponding equations.
2016-09-12 16:28:44 -05:00
elim_eqs . reserve ( 2 ) ;
2015-10-07 10:48:27 -05:00
elim_eqs . push_back ( eqs [ np ] ) ;
eqs = eliminateVariable ( eqs , np ) ; // Eliminate well flux unknowns.
2016-09-12 16:28:44 -05:00
elim_eqs . push_back ( eqs [ np ] ) ;
eqs = eliminateVariable ( eqs , np ) ; // Eliminate well bhp unknowns.
2015-10-07 10:48:27 -05:00
assert ( int ( eqs . size ( ) ) = = np ) ;
}
2015-06-01 06:33:37 -05:00
2015-10-07 10:48:27 -05:00
// Scale material balance equations.
for ( int phase = 0 ; phase < np ; + + phase ) {
eqs [ phase ] = eqs [ phase ] * residual . matbalscale [ phase ] ;
}
2015-09-17 06:46:05 -05:00
2015-10-07 10:48:27 -05:00
// calculating the size for b
int size_b = 0 ;
for ( int elem = 0 ; elem < np ; + + elem ) {
const int loc_size = eqs [ elem ] . size ( ) ;
size_b + = loc_size ;
}
2015-06-01 06:33:37 -05:00
2015-10-07 10:48:27 -05:00
V b ( size_b ) ;
2015-06-19 04:33:30 -05:00
2015-10-07 10:48:27 -05:00
int pos = 0 ;
for ( int elem = 0 ; elem < np ; + + elem ) {
const int loc_size = eqs [ elem ] . size ( ) ;
b . segment ( pos , loc_size ) = eqs [ elem ] . value ( ) ;
pos + = loc_size ;
2015-06-19 04:33:30 -05:00
}
2015-10-07 10:48:27 -05:00
assert ( pos = = size_b ) ;
2015-08-17 06:04:07 -05:00
2015-10-07 10:48:27 -05:00
// Create ISTL matrix with interleaved rows and columns (block structured).
Mat istlA ;
formInterleavedSystem ( eqs , istlA ) ;
// Solve reduced system.
SolutionVector dx ( SolutionVector : : Zero ( b . size ( ) ) ) ;
// Right hand side.
const int size = istlA . N ( ) ;
Vector istlb ( size ) ;
for ( int i = 0 ; i < size ; + + i ) {
for ( int p = 0 , idx = i ; p < np ; + + p , idx + = size ) {
istlb [ i ] [ p ] = b ( idx ) ;
}
2015-09-09 03:22:25 -05:00
}
2015-10-07 10:48:27 -05:00
// System solution
Vector x ( istlA . M ( ) ) ;
x = 0.0 ;
2016-11-02 07:10:44 -05:00
// solve linear system using ISTL methods
istlSolver_ . solve ( istlA , x , istlb ) ;
2015-10-07 10:48:27 -05:00
// Copy solver output to dx.
for ( int i = 0 ; i < size ; + + i ) {
for ( int p = 0 , idx = i ; p < np ; + + p , idx + = size ) {
dx ( idx ) = x [ i ] [ p ] ;
2015-06-19 04:33:30 -05:00
}
}
2015-10-07 10:48:27 -05:00
if ( hasWells ) {
// Compute full solution using the eliminated equations.
// Recovery in inverse order of elimination.
2016-09-12 16:28:44 -05:00
dx = recoverVariable ( elim_eqs [ 1 ] , dx , np ) ;
2015-10-07 10:48:27 -05:00
dx = recoverVariable ( elim_eqs [ 0 ] , dx , np ) ;
}
return dx ;
2015-06-19 04:33:30 -05:00
}
2015-10-07 10:48:27 -05:00
protected :
2016-11-02 07:10:44 -05:00
ISTLSolverType istlSolver_ ;
2015-10-09 05:03:58 -05:00
NewtonIterationBlackoilInterleavedParameters parameters_ ;
2015-10-07 10:48:27 -05:00
} ; // end NewtonIterationBlackoilInterleavedImpl
/// Construct a system solver.
NewtonIterationBlackoilInterleaved : : NewtonIterationBlackoilInterleaved ( const parameter : : ParameterGroup & param ,
const boost : : any & parallelInformation_arg )
2016-02-08 08:52:32 -06:00
: newtonIncrementDoublePrecision_ ( ) ,
newtonIncrementSinglePrecision_ ( ) ,
2015-10-09 05:03:58 -05:00
parameters_ ( param ) ,
2015-10-07 10:48:27 -05:00
parallelInformation_ ( parallelInformation_arg ) ,
iterations_ ( 0 )
{
2015-06-19 04:33:30 -05:00
}
2015-10-08 07:04:05 -05:00
namespace detail {
2015-06-19 04:33:30 -05:00
2016-02-08 06:28:28 -06:00
template < int NP , class Scalar >
2015-10-08 07:04:05 -05:00
struct NewtonIncrement
{
template < class NewtonIncVector >
static const NewtonIterationBlackoilInterface &
get ( NewtonIncVector & newtonIncrements ,
2015-10-09 05:03:58 -05:00
const NewtonIterationBlackoilInterleavedParameters & param ,
2015-10-08 07:04:05 -05:00
const boost : : any & parallelInformation ,
const int np )
{
if ( np = = NP )
{
assert ( np < int ( newtonIncrements . size ( ) ) ) ;
// create NewtonIncrement with fixed np
if ( ! newtonIncrements [ NP ] )
2016-02-08 06:28:28 -06:00
newtonIncrements [ NP ] . reset ( new NewtonIterationBlackoilInterleavedImpl < NP , Scalar > ( param , parallelInformation ) ) ;
2015-10-08 07:04:05 -05:00
return * ( newtonIncrements [ NP ] ) ;
}
else
{
2016-02-08 06:28:28 -06:00
return NewtonIncrement < NP - 1 , Scalar > : : get ( newtonIncrements , param , parallelInformation , np ) ;
2015-10-08 07:04:05 -05:00
}
}
} ;
2015-06-19 04:33:30 -05:00
2016-02-08 06:28:28 -06:00
template < class Scalar >
struct NewtonIncrement < 0 , Scalar >
2015-10-07 10:48:27 -05:00
{
2015-10-08 07:04:05 -05:00
template < class NewtonIncVector >
static const NewtonIterationBlackoilInterface &
2015-10-09 06:49:00 -05:00
get ( NewtonIncVector & ,
2015-10-09 05:03:58 -05:00
const NewtonIterationBlackoilInterleavedParameters & ,
const boost : : any & ,
2015-10-09 06:49:00 -05:00
const int np )
2015-10-08 07:04:05 -05:00
{
2015-10-09 06:49:00 -05:00
OPM_THROW ( std : : runtime_error , " NewtonIncrement::get: number of variables not supported yet. Adjust maxNumberEquations appropriately to cover np = " < < np ) ;
2015-10-08 07:04:05 -05:00
}
} ;
2015-12-01 07:15:35 -06:00
std : : pair < NewtonIterationBlackoilInterleaved : : SolutionVector , Dune : : InverseOperatorResult >
computePressureIncrement ( const LinearisedBlackoilResidual & residual )
{
typedef LinearisedBlackoilResidual : : ADB ADB ;
// Build the vector of equations (should be just a single material balance equation
// in which the pressure equation is stored).
const int np = residual . material_balance_eq . size ( ) ;
assert ( np = = 1 ) ;
std : : vector < ADB > eqs ;
eqs . reserve ( np + 2 ) ;
for ( int phase = 0 ; phase < np ; + + phase ) {
eqs . push_back ( residual . material_balance_eq [ phase ] ) ;
}
// Check if wells are present.
const bool hasWells = residual . well_flux_eq . size ( ) > 0 ;
std : : vector < ADB > elim_eqs ;
if ( hasWells ) {
// Eliminate the well-related unknowns, and corresponding equations.
eqs . push_back ( residual . well_flux_eq ) ;
eqs . push_back ( residual . well_eq ) ;
elim_eqs . reserve ( 2 ) ;
elim_eqs . push_back ( eqs [ np ] ) ;
eqs = eliminateVariable ( eqs , np ) ; // Eliminate well flux unknowns.
elim_eqs . push_back ( eqs [ np ] ) ;
eqs = eliminateVariable ( eqs , np ) ; // Eliminate well bhp unknowns.
assert ( int ( eqs . size ( ) ) = = np ) ;
}
// Solve the linearised oil equation.
Eigen : : SparseMatrix < double , Eigen : : RowMajor > eigenA = eqs [ 0 ] . derivative ( ) [ 0 ] . getSparse ( ) ;
DuneMatrix opA ( eigenA ) ;
const int size = eqs [ 0 ] . size ( ) ;
typedef Dune : : BlockVector < Dune : : FieldVector < double , 1 > > Vector1 ;
Vector1 x ;
x . resize ( size ) ;
x = 0.0 ;
Vector1 b ;
b . resize ( size ) ;
b = 0.0 ;
std : : copy_n ( eqs [ 0 ] . value ( ) . data ( ) , size , b . begin ( ) ) ;
// Solve with AMG solver.
typedef Dune : : BCRSMatrix < Dune : : FieldMatrix < double , 1 , 1 > > Mat ;
typedef Dune : : MatrixAdapter < Mat , Vector1 , Vector1 > Operator ;
Operator sOpA ( opA ) ;
typedef Dune : : Amg : : SequentialInformation ParallelInformation ;
typedef Dune : : SeqILU0 < Mat , Vector1 , Vector1 > EllipticPreconditioner ;
typedef EllipticPreconditioner Smoother ;
typedef Dune : : Amg : : AMG < Operator , Vector1 , Smoother , ParallelInformation > AMG ;
typedef Dune : : Amg : : FirstDiagonal CouplingMetric ;
typedef Dune : : Amg : : SymmetricCriterion < Mat , CouplingMetric > CritBase ;
typedef Dune : : Amg : : CoarsenCriterion < CritBase > Criterion ;
// TODO: revise choice of parameters
const int coarsenTarget = 1200 ;
Criterion criterion ( 15 , coarsenTarget ) ;
criterion . setDebugLevel ( 0 ) ; // no debug information, 1 for printing hierarchy information
criterion . setDefaultValuesIsotropic ( 2 ) ;
criterion . setNoPostSmoothSteps ( 1 ) ;
criterion . setNoPreSmoothSteps ( 1 ) ;
// for DUNE 2.2 we also need to pass the smoother args
typedef typename AMG : : Smoother Smoother ;
typedef typename Dune : : Amg : : SmootherTraits < Smoother > : : Arguments SmootherArgs ;
SmootherArgs smootherArgs ;
smootherArgs . iterations = 1 ;
smootherArgs . relaxationFactor = 1.0 ;
AMG precond ( sOpA , criterion , smootherArgs ) ;
const int verbosity = 0 ;
const int maxit = 30 ;
const double tolerance = 1e-5 ;
// Construct linear solver.
Dune : : BiCGSTABSolver < Vector1 > linsolve ( sOpA , precond , tolerance , maxit , verbosity ) ;
// Solve system.
Dune : : InverseOperatorResult result ;
linsolve . apply ( x , b , result ) ;
// Check for failure of linear solver.
if ( ! result . converged ) {
2016-10-17 06:41:39 -05:00
const std : : string msg ( " Convergence failure for linear solver in computePressureIncrement(). " ) ;
OpmLog : : problem ( msg ) ;
OPM_THROW_NOLOG ( LinearSolverProblem , msg ) ;
2015-12-01 07:15:35 -06:00
}
// Copy solver output to dx.
NewtonIterationBlackoilInterleaved : : SolutionVector dx ( size ) ;
for ( int i = 0 ; i < size ; + + i ) {
dx ( i ) = x [ i ] ;
}
if ( hasWells ) {
// Compute full solution using the eliminated equations.
// Recovery in inverse order of elimination.
dx = recoverVariable ( elim_eqs [ 1 ] , dx , np ) ;
dx = recoverVariable ( elim_eqs [ 0 ] , dx , np ) ;
}
return std : : make_pair ( dx , result ) ;
}
2015-10-08 07:04:05 -05:00
} // end namespace detail
2015-06-19 04:33:30 -05:00
2015-10-07 10:48:27 -05:00
NewtonIterationBlackoilInterleaved : : SolutionVector
2015-10-08 07:04:05 -05:00
NewtonIterationBlackoilInterleaved : : computeNewtonIncrement ( const LinearisedBlackoilResidual & residual ) const
2015-06-16 03:18:11 -05:00
{
2015-10-08 07:04:05 -05:00
// get np and call appropriate template method
const int np = residual . material_balance_eq . size ( ) ;
2015-12-01 07:15:35 -06:00
if ( np = = 1 ) {
auto result = detail : : computePressureIncrement ( residual ) ;
iterations_ = result . second . iterations ;
return result . first ;
}
2016-02-09 09:07:56 -06:00
const NewtonIterationBlackoilInterface & newtonIncrement = residual . singlePrecision ?
2016-02-08 06:28:28 -06:00
detail : : NewtonIncrement < maxNumberEquations_ , float > : : get ( newtonIncrementSinglePrecision_ , parameters_ , parallelInformation_ , np ) :
2016-02-08 08:52:32 -06:00
detail : : NewtonIncrement < maxNumberEquations_ , double > : : get ( newtonIncrementDoublePrecision_ , parameters_ , parallelInformation_ , np ) ;
2015-10-07 10:48:27 -05:00
// compute newton increment
2015-10-08 07:04:05 -05:00
SolutionVector dx = newtonIncrement . computeNewtonIncrement ( residual ) ;
2015-10-07 10:48:27 -05:00
// get number of linear iterations
2015-10-08 07:04:05 -05:00
iterations_ = newtonIncrement . iterations ( ) ;
2016-09-26 02:33:13 -05:00
return dx ;
2015-06-16 03:18:11 -05:00
}
2015-06-01 06:33:37 -05:00
2015-10-07 10:48:27 -05:00
const boost : : any & NewtonIterationBlackoilInterleaved : : parallelInformation ( ) const
{
return parallelInformation_ ;
}
2015-06-01 06:33:37 -05:00
} // namespace Opm