00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef OPM_ISTLSOLVER_HEADER_INCLUDED
00021 #define OPM_ISTLSOLVER_HEADER_INCLUDED
00022
00023 #include <opm/autodiff/AdditionalObjectDeleter.hpp>
00024 #include <opm/autodiff/CPRPreconditioner.hpp>
00025 #include <opm/autodiff/NewtonIterationBlackoilInterleaved.hpp>
00026 #include <opm/autodiff/NewtonIterationUtilities.hpp>
00027 #include <opm/autodiff/ParallelRestrictedAdditiveSchwarz.hpp>
00028 #include <opm/autodiff/ParallelOverlappingILU0.hpp>
00029 #include <opm/autodiff/AutoDiffHelpers.hpp>
00030
00031 #include <opm/common/Exceptions.hpp>
00032 #include <opm/core/linalg/ParallelIstlInformation.hpp>
00033 #include <opm/common/utility/platform_dependent/disable_warnings.h>
00034
00035 #include <dune/istl/scalarproducts.hh>
00036 #include <dune/istl/operators.hh>
00037 #include <dune/istl/preconditioners.hh>
00038 #include <dune/istl/solvers.hh>
00039 #include <dune/istl/owneroverlapcopy.hh>
00040 #include <dune/istl/paamg/amg.hh>
00041
00042 #include <opm/common/utility/platform_dependent/reenable_warnings.h>
00043
00044 namespace Dune
00045 {
00046 namespace FMatrixHelp {
00048 template <typename K>
00049 static inline K invertMatrix (const FieldMatrix<K,4,4> &matrix, FieldMatrix<K,4,4> &inverse)
00050 {
00051 inverse[0][0] = matrix[1][1] * matrix[2][2] * matrix[3][3] -
00052 matrix[1][1] * matrix[2][3] * matrix[3][2] -
00053 matrix[2][1] * matrix[1][2] * matrix[3][3] +
00054 matrix[2][1] * matrix[1][3] * matrix[3][2] +
00055 matrix[3][1] * matrix[1][2] * matrix[2][3] -
00056 matrix[3][1] * matrix[1][3] * matrix[2][2];
00057
00058 inverse[1][0] = -matrix[1][0] * matrix[2][2] * matrix[3][3] +
00059 matrix[1][0] * matrix[2][3] * matrix[3][2] +
00060 matrix[2][0] * matrix[1][2] * matrix[3][3] -
00061 matrix[2][0] * matrix[1][3] * matrix[3][2] -
00062 matrix[3][0] * matrix[1][2] * matrix[2][3] +
00063 matrix[3][0] * matrix[1][3] * matrix[2][2];
00064
00065 inverse[2][0] = matrix[1][0] * matrix[2][1] * matrix[3][3] -
00066 matrix[1][0] * matrix[2][3] * matrix[3][1] -
00067 matrix[2][0] * matrix[1][1] * matrix[3][3] +
00068 matrix[2][0] * matrix[1][3] * matrix[3][1] +
00069 matrix[3][0] * matrix[1][1] * matrix[2][3] -
00070 matrix[3][0] * matrix[1][3] * matrix[2][1];
00071
00072 inverse[3][0] = -matrix[1][0] * matrix[2][1] * matrix[3][2] +
00073 matrix[1][0] * matrix[2][2] * matrix[3][1] +
00074 matrix[2][0] * matrix[1][1] * matrix[3][2] -
00075 matrix[2][0] * matrix[1][2] * matrix[3][1] -
00076 matrix[3][0] * matrix[1][1] * matrix[2][2] +
00077 matrix[3][0] * matrix[1][2] * matrix[2][1];
00078
00079 inverse[0][1]= -matrix[0][1] * matrix[2][2] * matrix[3][3] +
00080 matrix[0][1] * matrix[2][3] * matrix[3][2] +
00081 matrix[2][1] * matrix[0][2] * matrix[3][3] -
00082 matrix[2][1] * matrix[0][3] * matrix[3][2] -
00083 matrix[3][1] * matrix[0][2] * matrix[2][3] +
00084 matrix[3][1] * matrix[0][3] * matrix[2][2];
00085
00086 inverse[1][1] = matrix[0][0] * matrix[2][2] * matrix[3][3] -
00087 matrix[0][0] * matrix[2][3] * matrix[3][2] -
00088 matrix[2][0] * matrix[0][2] * matrix[3][3] +
00089 matrix[2][0] * matrix[0][3] * matrix[3][2] +
00090 matrix[3][0] * matrix[0][2] * matrix[2][3] -
00091 matrix[3][0] * matrix[0][3] * matrix[2][2];
00092
00093 inverse[2][1] = -matrix[0][0] * matrix[2][1] * matrix[3][3] +
00094 matrix[0][0] * matrix[2][3] * matrix[3][1] +
00095 matrix[2][0] * matrix[0][1] * matrix[3][3] -
00096 matrix[2][0] * matrix[0][3] * matrix[3][1] -
00097 matrix[3][0] * matrix[0][1] * matrix[2][3] +
00098 matrix[3][0] * matrix[0][3] * matrix[2][1];
00099
00100 inverse[3][1] = matrix[0][0] * matrix[2][1] * matrix[3][2] -
00101 matrix[0][0] * matrix[2][2] * matrix[3][1] -
00102 matrix[2][0] * matrix[0][1] * matrix[3][2] +
00103 matrix[2][0] * matrix[0][2] * matrix[3][1] +
00104 matrix[3][0] * matrix[0][1] * matrix[2][2] -
00105 matrix[3][0] * matrix[0][2] * matrix[2][1];
00106
00107 inverse[0][2] = matrix[0][1] * matrix[1][2] * matrix[3][3] -
00108 matrix[0][1] * matrix[1][3] * matrix[3][2] -
00109 matrix[1][1] * matrix[0][2] * matrix[3][3] +
00110 matrix[1][1] * matrix[0][3] * matrix[3][2] +
00111 matrix[3][1] * matrix[0][2] * matrix[1][3] -
00112 matrix[3][1] * matrix[0][3] * matrix[1][2];
00113
00114 inverse[1][2] = -matrix[0][0] * matrix[1][2] * matrix[3][3] +
00115 matrix[0][0] * matrix[1][3] * matrix[3][2] +
00116 matrix[1][0] * matrix[0][2] * matrix[3][3] -
00117 matrix[1][0] * matrix[0][3] * matrix[3][2] -
00118 matrix[3][0] * matrix[0][2] * matrix[1][3] +
00119 matrix[3][0] * matrix[0][3] * matrix[1][2];
00120
00121 inverse[2][2] = matrix[0][0] * matrix[1][1] * matrix[3][3] -
00122 matrix[0][0] * matrix[1][3] * matrix[3][1] -
00123 matrix[1][0] * matrix[0][1] * matrix[3][3] +
00124 matrix[1][0] * matrix[0][3] * matrix[3][1] +
00125 matrix[3][0] * matrix[0][1] * matrix[1][3] -
00126 matrix[3][0] * matrix[0][3] * matrix[1][1];
00127
00128 inverse[3][2] = -matrix[0][0] * matrix[1][1] * matrix[3][2] +
00129 matrix[0][0] * matrix[1][2] * matrix[3][1] +
00130 matrix[1][0] * matrix[0][1] * matrix[3][2] -
00131 matrix[1][0] * matrix[0][2] * matrix[3][1] -
00132 matrix[3][0] * matrix[0][1] * matrix[1][2] +
00133 matrix[3][0] * matrix[0][2] * matrix[1][1];
00134
00135 inverse[0][3] = -matrix[0][1] * matrix[1][2] * matrix[2][3] +
00136 matrix[0][1] * matrix[1][3] * matrix[2][2] +
00137 matrix[1][1] * matrix[0][2] * matrix[2][3] -
00138 matrix[1][1] * matrix[0][3] * matrix[2][2] -
00139 matrix[2][1] * matrix[0][2] * matrix[1][3] +
00140 matrix[2][1] * matrix[0][3] * matrix[1][2];
00141
00142 inverse[1][3] = matrix[0][0] * matrix[1][2] * matrix[2][3] -
00143 matrix[0][0] * matrix[1][3] * matrix[2][2] -
00144 matrix[1][0] * matrix[0][2] * matrix[2][3] +
00145 matrix[1][0] * matrix[0][3] * matrix[2][2] +
00146 matrix[2][0] * matrix[0][2] * matrix[1][3] -
00147 matrix[2][0] * matrix[0][3] * matrix[1][2];
00148
00149 inverse[2][3] = -matrix[0][0] * matrix[1][1] * matrix[2][3] +
00150 matrix[0][0] * matrix[1][3] * matrix[2][1] +
00151 matrix[1][0] * matrix[0][1] * matrix[2][3] -
00152 matrix[1][0] * matrix[0][3] * matrix[2][1] -
00153 matrix[2][0] * matrix[0][1] * matrix[1][3] +
00154 matrix[2][0] * matrix[0][3] * matrix[1][1];
00155
00156 inverse[3][3] = matrix[0][0] * matrix[1][1] * matrix[2][2] -
00157 matrix[0][0] * matrix[1][2] * matrix[2][1] -
00158 matrix[1][0] * matrix[0][1] * matrix[2][2] +
00159 matrix[1][0] * matrix[0][2] * matrix[2][1] +
00160 matrix[2][0] * matrix[0][1] * matrix[1][2] -
00161 matrix[2][0] * matrix[0][2] * matrix[1][1];
00162
00163 K det = matrix[0][0] * inverse[0][0] + matrix[0][1] * inverse[1][0] + matrix[0][2] * inverse[2][0] + matrix[0][3] * inverse[3][0];
00164
00165
00166 if (std::abs(det) < 1e-40) {
00167 for (int i = 0; i < 4; ++i){
00168 inverse[i][i] = 1.0;
00169 }
00170 return 1.0;
00171 }
00172 K inv_det = 1.0 / det;
00173 inverse *= inv_det;
00174
00175 return det;
00176 }
00177 }
00178
00179 namespace ISTLUtility {
00180
00182 template <typename K>
00183 static inline void invertMatrix (FieldMatrix<K,1,1> &matrix)
00184 {
00185 FieldMatrix<K,1,1> A ( matrix );
00186 FMatrixHelp::invertMatrix(A, matrix );
00187 }
00188
00190 template <typename K>
00191 static inline void invertMatrix (FieldMatrix<K,2,2> &matrix)
00192 {
00193 FieldMatrix<K,2,2> A ( matrix );
00194 FMatrixHelp::invertMatrix(A, matrix );
00195 }
00196
00198 template <typename K>
00199 static inline void invertMatrix (FieldMatrix<K,3,3> &matrix)
00200 {
00201 FieldMatrix<K,3,3> A ( matrix );
00202 FMatrixHelp::invertMatrix(A, matrix );
00203 }
00204
00206 template <typename K>
00207 static inline void invertMatrix (FieldMatrix<K,4,4> &matrix)
00208 {
00209 FieldMatrix<K,4,4> A ( matrix );
00210 FMatrixHelp::invertMatrix(A, matrix );
00211 }
00212
00214 template <typename K, int n>
00215 static inline void invertMatrix (FieldMatrix<K,n,n> &matrix)
00216 {
00217 matrix.invert();
00218 }
00219
00220 }
00221
00222 template <class Scalar, int n, int m>
00223 class MatrixBlock : public Dune::FieldMatrix<Scalar, n, m>
00224 {
00225 public:
00226 typedef Dune::FieldMatrix<Scalar, n, m> BaseType;
00227
00228 using BaseType :: operator= ;
00229 using BaseType :: rows;
00230 using BaseType :: cols;
00231 explicit MatrixBlock( const Scalar scalar = 0 ) : BaseType( scalar ) {}
00232 void invert()
00233 {
00234 ISTLUtility::invertMatrix( *this );
00235 }
00236 const BaseType& asBase() const { return static_cast< const BaseType& > (*this); }
00237 BaseType& asBase() { return static_cast< BaseType& > (*this); }
00238 };
00239
00240 template<class K, int n, int m>
00241 void
00242 print_row (std::ostream& s, const MatrixBlock<K,n,m>& A,
00243 typename FieldMatrix<K,n,m>::size_type I,
00244 typename FieldMatrix<K,n,m>::size_type J,
00245 typename FieldMatrix<K,n,m>::size_type therow, int width,
00246 int precision)
00247 {
00248 print_row(s, A.asBase(), I, J, therow, width, precision);
00249 }
00250
00251 template<class K, int n, int m>
00252 K& firstmatrixelement (MatrixBlock<K,n,m>& A)
00253 {
00254 return firstmatrixelement( A.asBase() );
00255 }
00256
00257
00258
00259 template<typename Scalar, int n, int m>
00260 struct MatrixDimension< MatrixBlock< Scalar, n, m > >
00261 : public MatrixDimension< typename MatrixBlock< Scalar, n, m >::BaseType >
00262 {
00263 };
00264
00265
00266 #if HAVE_UMFPACK
00267
00271 template<typename T, typename A, int n, int m>
00272 class UMFPack<BCRSMatrix<MatrixBlock<T,n,m>, A> >
00273 : public UMFPack<BCRSMatrix<FieldMatrix<T,n,m>, A> >
00274 {
00275 typedef UMFPack<BCRSMatrix<FieldMatrix<T,n,m>, A> > Base;
00276 typedef BCRSMatrix<FieldMatrix<T,n,m>, A> Matrix;
00277
00278 public:
00279 typedef BCRSMatrix<MatrixBlock<T,n,m>, A> RealMatrix;
00280
00281 UMFPack(const RealMatrix& matrix, int verbose, bool)
00282 : Base(reinterpret_cast<const Matrix&>(matrix), verbose)
00283 {}
00284 };
00285 #endif
00286
00287 #if HAVE_SUPERLU
00288
00292 template<typename T, typename A, int n, int m>
00293 class SuperLU<BCRSMatrix<MatrixBlock<T,n,m>, A> >
00294 : public SuperLU<BCRSMatrix<FieldMatrix<T,n,m>, A> >
00295 {
00296 typedef SuperLU<BCRSMatrix<FieldMatrix<T,n,m>, A> > Base;
00297 typedef BCRSMatrix<FieldMatrix<T,n,m>, A> Matrix;
00298
00299 public:
00300 typedef BCRSMatrix<MatrixBlock<T,n,m>, A> RealMatrix;
00301
00302 SuperLU(const RealMatrix& matrix, int verbose, bool reuse=true)
00303 : Base(reinterpret_cast<const Matrix&>(matrix), verbose, reuse)
00304 {}
00305 };
00306 #endif
00307
00308
00309 }
00310
00311 namespace Opm
00312 {
00322 template < class MatrixBlockType, class VectorBlockType, int pressureIndex=0 >
00323 class ISTLSolver : public NewtonIterationBlackoilInterface
00324 {
00325 typedef typename MatrixBlockType :: field_type Scalar;
00326
00327 typedef Dune::BCRSMatrix <MatrixBlockType> Matrix;
00328 typedef Dune::BlockVector<VectorBlockType> Vector;
00329
00330 public:
00331 typedef Dune::AssembledLinearOperator< Matrix, Vector, Vector > AssembledLinearOperatorType;
00332
00333 typedef NewtonIterationBlackoilInterface :: SolutionVector SolutionVector;
00338 ISTLSolver(const NewtonIterationBlackoilInterleavedParameters& param,
00339 const boost::any& parallelInformation_arg=boost::any())
00340 : iterations_( 0 ),
00341 parallelInformation_(parallelInformation_arg),
00342 isIORank_(isIORank(parallelInformation_arg)),
00343 parameters_( param )
00344 {
00345 }
00346
00351 ISTLSolver(const ParameterGroup& param,
00352 const boost::any& parallelInformation_arg=boost::any())
00353 : iterations_( 0 ),
00354 parallelInformation_(parallelInformation_arg),
00355 isIORank_(isIORank(parallelInformation_arg)),
00356 parameters_( param )
00357 {
00358 }
00359
00360
00361 SolutionVector computeNewtonIncrement(const LinearisedBlackoilResidual&) const
00362 {
00363 OPM_THROW(std::logic_error,"This method is not implemented");
00364 return SolutionVector();
00365 }
00366
00372
00374 int iterations () const { return iterations_; }
00375
00377 const boost::any& parallelInformation() const { return parallelInformation_; }
00378
00379 public:
00383 template<int category=Dune::SolverCategory::sequential, class LinearOperator, class POrComm>
00384 void constructPreconditionerAndSolve(LinearOperator& linearOperator,
00385 Vector& x, Vector& istlb,
00386 const POrComm& parallelInformation_arg,
00387 Dune::InverseOperatorResult& result) const
00388 {
00389
00390 typedef Dune::ScalarProductChooser<Vector, POrComm, category> ScalarProductChooser;
00391 typedef std::unique_ptr<typename ScalarProductChooser::ScalarProduct> SPPointer;
00392 SPPointer sp(ScalarProductChooser::construct(parallelInformation_arg));
00393
00394
00395 parallelInformation_arg.copyOwnerToAll(istlb, istlb);
00396
00397 #if FLOW_SUPPORT_AMG // activate AMG if either flow_ebos is used or UMFPack is not available
00398 if( parameters_.linear_solver_use_amg_ )
00399 {
00400 typedef ISTLUtility::CPRSelector< Matrix, Vector, Vector, POrComm> CPRSelectorType;
00401 typedef typename CPRSelectorType::AMG AMG;
00402 typedef typename CPRSelectorType::Operator MatrixOperator;
00403
00404 std::unique_ptr< AMG > amg;
00405 std::unique_ptr< MatrixOperator > opA;
00406
00407 if( ! std::is_same< LinearOperator, MatrixOperator > :: value )
00408 {
00409
00410 opA.reset( CPRSelectorType::makeOperator( linearOperator.getmat(), parallelInformation_arg ) );
00411 }
00412
00413 const double relax = 1.0;
00414
00415
00416 constructAMGPrecond( linearOperator, parallelInformation_arg, amg, opA, relax );
00417
00418
00419 solve(linearOperator, x, istlb, *sp, *amg, result);
00420 }
00421 else
00422 #endif
00423 {
00424
00425 auto precond = constructPrecond(linearOperator, parallelInformation_arg);
00426
00427
00428 solve(linearOperator, x, istlb, *sp, *precond, result);
00429 }
00430 }
00431
00432 #if DUNE_VERSION_NEWER(DUNE_ISTL, 2 , 5)
00433 typedef ParallelOverlappingILU0<Matrix,Vector,Vector> SeqPreconditioner;
00434 #else
00435 typedef ParallelOverlappingILU0<Dune::BCRSMatrix<Dune::MatrixBlock<typename Matrix::field_type,
00436 Matrix::block_type::rows,
00437 Matrix::block_type::cols> >,
00438 Vector, Vector> SeqPreconditioner;
00439 #endif
00440
00441 template <class Operator>
00442 std::unique_ptr<SeqPreconditioner> constructPrecond(Operator& opA, const Dune::Amg::SequentialInformation&) const
00443 {
00444 const double relax = parameters_.ilu_relaxation_;
00445 const int ilu_fillin = parameters_.ilu_fillin_level_;
00446 std::unique_ptr<SeqPreconditioner> precond(new SeqPreconditioner(opA.getmat(), ilu_fillin, relax));
00447 return precond;
00448 }
00449
00450 #if HAVE_MPI
00451 typedef Dune::OwnerOverlapCopyCommunication<int, int> Comm;
00452 #if DUNE_VERSION_NEWER(DUNE_ISTL, 2 , 5)
00453 typedef ParallelOverlappingILU0<Matrix,Vector,Vector,Comm> ParPreconditioner;
00454 #else
00455 typedef ParallelOverlappingILU0<Dune::BCRSMatrix<Dune::MatrixBlock<typename Matrix::field_type,
00456 Matrix::block_type::rows,
00457 Matrix::block_type::cols> >,
00458 Vector, Vector, Comm> ParPreconditioner;
00459 #endif
00460 template <class Operator>
00461 std::unique_ptr<ParPreconditioner>
00462 constructPrecond(Operator& opA, const Comm& comm) const
00463 {
00464 typedef std::unique_ptr<ParPreconditioner> Pointer;
00465 const double relax = parameters_.ilu_relaxation_;
00466 return Pointer(new ParPreconditioner(opA.getmat(), comm, relax));
00467 }
00468 #endif
00469
00470 template <class LinearOperator, class MatrixOperator, class POrComm, class AMG >
00471 void
00472 constructAMGPrecond(LinearOperator& , const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >& opA, const double relax ) const
00473 {
00474 ISTLUtility::template createAMGPreconditionerPointer<pressureIndex>( *opA, relax, comm, amg );
00475 }
00476
00477
00478 template <class MatrixOperator, class POrComm, class AMG >
00479 void
00480 constructAMGPrecond(MatrixOperator& opA, const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >&, const double relax ) const
00481 {
00482 ISTLUtility::template createAMGPreconditionerPointer<pressureIndex>( opA, relax, comm, amg );
00483 }
00484
00486 template <class Operator, class ScalarProd, class Precond>
00487 void solve(Operator& opA, Vector& x, Vector& istlb, ScalarProd& sp, Precond& precond, Dune::InverseOperatorResult& result) const
00488 {
00489
00490
00491
00492 int verbosity = ( isIORank_ ) ? parameters_.linear_solver_verbosity_ : 0;
00493
00494 if ( parameters_.newton_use_gmres_ ) {
00495 Dune::RestartedGMResSolver<Vector> linsolve(opA, sp, precond,
00496 parameters_.linear_solver_reduction_,
00497 parameters_.linear_solver_restart_,
00498 parameters_.linear_solver_maxiter_,
00499 verbosity);
00500
00501 linsolve.apply(x, istlb, result);
00502 }
00503 else {
00504 Dune::BiCGSTABSolver<Vector> linsolve(opA, sp, precond,
00505 parameters_.linear_solver_reduction_,
00506 parameters_.linear_solver_maxiter_,
00507 verbosity);
00508
00509 linsolve.apply(x, istlb, result);
00510 }
00511 }
00512
00513
00520 void solve(Matrix& A, Vector& x, Vector& b ) const
00521 {
00522
00523 #if HAVE_MPI
00524 if (parallelInformation_.type() == typeid(ParallelISTLInformation))
00525 {
00526 typedef Dune::OwnerOverlapCopyCommunication<int,int> Comm;
00527 const ParallelISTLInformation& info =
00528 boost::any_cast<const ParallelISTLInformation&>( parallelInformation_);
00529 Comm istlComm(info.communicator());
00530
00531
00532 typedef Dune::OverlappingSchwarzOperator<Matrix, Vector, Vector,Comm> Operator;
00533 Operator opA(A, istlComm);
00534 solve( opA, x, b, istlComm );
00535 }
00536 else
00537 #endif
00538 {
00539
00540 Dune::MatrixAdapter< Matrix, Vector, Vector> opA( A );
00541 solve( opA, x, b );
00542 }
00543 }
00544
00551 template <class Operator, class Comm >
00552 void solve(Operator& opA, Vector& x, Vector& b, Comm& comm) const
00553 {
00554 Dune::InverseOperatorResult result;
00555
00556 #if HAVE_MPI
00557 if (parallelInformation_.type() == typeid(ParallelISTLInformation))
00558 {
00559 const size_t size = opA.getmat().N();
00560 const ParallelISTLInformation& info =
00561 boost::any_cast<const ParallelISTLInformation&>( parallelInformation_);
00562
00563
00564
00565 info.copyValuesTo(comm.indexSet(), comm.remoteIndices(),
00566 size, 1);
00567
00568 constructPreconditionerAndSolve<Dune::SolverCategory::overlapping>(opA, x, b, comm, result);
00569 }
00570 else
00571 #endif
00572 {
00573 OPM_THROW(std::logic_error,"this method if for parallel solve only");
00574 }
00575
00576 checkConvergence( result );
00577 }
00578
00585 template <class Operator>
00586 void solve(Operator& opA, Vector& x, Vector& b ) const
00587 {
00588 Dune::InverseOperatorResult result;
00589
00590 Dune::Amg::SequentialInformation info;
00591 constructPreconditionerAndSolve(opA, x, b, info, result);
00592 checkConvergence( result );
00593 }
00594
00595 void checkConvergence( const Dune::InverseOperatorResult& result ) const
00596 {
00597
00598 iterations_ = result.iterations;
00599
00600
00601 if (!parameters_.ignoreConvergenceFailure_ && !result.converged) {
00602 const std::string msg("Convergence failure for linear solver.");
00603 OPM_THROW_NOLOG(LinearSolverProblem, msg);
00604 }
00605 }
00606 protected:
00607 mutable int iterations_;
00608 boost::any parallelInformation_;
00609 bool isIORank_;
00610
00611 NewtonIterationBlackoilInterleavedParameters parameters_;
00612 };
00613
00614 }
00615 #endif