mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Added various other variants of MILU.
These versions are inspired by the ones used in SuperLU and the enums to choose them have simuilar names, but without leading S (MILU_1-MILU_3). The following variants are supported (chosen by the enum MILU_VARIANT): ILU: plain ILU MILU_1: lump diagonal with dropped row entries. MILU_2: lump diagonal with the sum of the absolute values of the dropped row entries. MILU_3: if diagonal is positive add sum of dropped row entrires. Otherwise substract them. MILU_4: if diagonal is positive add sum of dropped row entrires. Otherwise do nothing
This commit is contained in:
parent
59b99d9ef9
commit
63058559bc
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <opm/common/utility/platform_dependent/disable_warnings.h>
|
#include <opm/common/utility/platform_dependent/disable_warnings.h>
|
||||||
#include <opm/common/utility/parameters/ParameterGroup.hpp>
|
#include <opm/common/utility/parameters/ParameterGroup.hpp>
|
||||||
|
#include <opm/autodiff/ParallelOverlappingILU0.hpp>
|
||||||
|
|
||||||
#include <dune/istl/bvector.hh>
|
#include <dune/istl/bvector.hh>
|
||||||
#include <dune/istl/bcrsmatrix.hh>
|
#include <dune/istl/bcrsmatrix.hh>
|
||||||
@ -64,7 +65,7 @@ struct CPRParameter
|
|||||||
double cpr_relax_;
|
double cpr_relax_;
|
||||||
double cpr_solver_tol_;
|
double cpr_solver_tol_;
|
||||||
int cpr_ilu_n_;
|
int cpr_ilu_n_;
|
||||||
bool cpr_ilu_milu_;
|
MILU_VARIANT cpr_ilu_milu_;
|
||||||
int cpr_max_ell_iter_;
|
int cpr_max_ell_iter_;
|
||||||
bool cpr_use_amg_;
|
bool cpr_use_amg_;
|
||||||
bool cpr_use_bicgstab_;
|
bool cpr_use_bicgstab_;
|
||||||
@ -81,12 +82,14 @@ struct CPRParameter
|
|||||||
cpr_relax_ = param.getDefault("cpr_relax", cpr_relax_);
|
cpr_relax_ = param.getDefault("cpr_relax", cpr_relax_);
|
||||||
cpr_solver_tol_ = param.getDefault("cpr_solver_tol", cpr_solver_tol_);
|
cpr_solver_tol_ = param.getDefault("cpr_solver_tol", cpr_solver_tol_);
|
||||||
cpr_ilu_n_ = param.getDefault("cpr_ilu_n", cpr_ilu_n_);
|
cpr_ilu_n_ = param.getDefault("cpr_ilu_n", cpr_ilu_n_);
|
||||||
cpr_ilu_milu_ = param.getDefault("ilu_milu", cpr_ilu_milu_);
|
|
||||||
cpr_max_ell_iter_ = param.getDefault("cpr_max_elliptic_iter",cpr_max_ell_iter_);
|
cpr_max_ell_iter_ = param.getDefault("cpr_max_elliptic_iter",cpr_max_ell_iter_);
|
||||||
cpr_use_amg_ = param.getDefault("cpr_use_amg", cpr_use_amg_);
|
cpr_use_amg_ = param.getDefault("cpr_use_amg", cpr_use_amg_);
|
||||||
cpr_use_bicgstab_ = param.getDefault("cpr_use_bicgstab", cpr_use_bicgstab_);
|
cpr_use_bicgstab_ = param.getDefault("cpr_use_bicgstab", cpr_use_bicgstab_);
|
||||||
cpr_solver_verbose_ = param.getDefault("cpr_solver_verbose", cpr_solver_verbose_);
|
cpr_solver_verbose_ = param.getDefault("cpr_solver_verbose", cpr_solver_verbose_);
|
||||||
cpr_pressure_aggregation_ = param.getDefault("cpr_pressure_aggregation", cpr_pressure_aggregation_);
|
cpr_pressure_aggregation_ = param.getDefault("cpr_pressure_aggregation", cpr_pressure_aggregation_);
|
||||||
|
|
||||||
|
std::string milu("ILU");
|
||||||
|
cpr_ilu_milu_ = convertString2Milu(param.getDefault("ilu_milu", milu));
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
@ -94,7 +97,7 @@ struct CPRParameter
|
|||||||
cpr_relax_ = 1.0;
|
cpr_relax_ = 1.0;
|
||||||
cpr_solver_tol_ = 1e-2;
|
cpr_solver_tol_ = 1e-2;
|
||||||
cpr_ilu_n_ = 0;
|
cpr_ilu_n_ = 0;
|
||||||
cpr_ilu_milu_ = false;
|
cpr_ilu_milu_ = MILU_VARIANT::ILU;
|
||||||
cpr_max_ell_iter_ = 25;
|
cpr_max_ell_iter_ = 25;
|
||||||
cpr_use_amg_ = true;
|
cpr_use_amg_ = true;
|
||||||
cpr_use_bicgstab_ = true;
|
cpr_use_bicgstab_ = true;
|
||||||
@ -117,7 +120,7 @@ void setILUParameters(Opm::ParallelOverlappingILU0Args<T>& args,
|
|||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void setILUParameters(Opm::ParallelOverlappingILU0Args<T>& args,
|
void setILUParameters(Opm::ParallelOverlappingILU0Args<T>& args,
|
||||||
bool milu, int n=0)
|
MILU_VARIANT milu, int n=0)
|
||||||
{
|
{
|
||||||
args.setN(n);
|
args.setN(n);
|
||||||
args.setMilu(milu);
|
args.setMilu(milu);
|
||||||
@ -195,7 +198,7 @@ struct CPRSelector<M,X,Y,Dune::Amg::SequentialInformation>
|
|||||||
//! \param relax The relaxation factor to use.
|
//! \param relax The relaxation factor to use.
|
||||||
template<class M, class X, class C>
|
template<class M, class X, class C>
|
||||||
std::shared_ptr<ParallelOverlappingILU0<M,X,X,C> >
|
std::shared_ptr<ParallelOverlappingILU0<M,X,X,C> >
|
||||||
createILU0Ptr(const M& A, const C& comm, double relax, bool milu)
|
createILU0Ptr(const M& A, const C& comm, double relax, MILU_VARIANT milu)
|
||||||
{
|
{
|
||||||
return std::make_shared<ParallelOverlappingILU0<M,X,X,C> >(A, comm, relax, milu);
|
return std::make_shared<ParallelOverlappingILU0<M,X,X,C> >(A, comm, relax, milu);
|
||||||
}
|
}
|
||||||
@ -205,7 +208,7 @@ createILU0Ptr(const M& A, const C& comm, double relax, bool milu)
|
|||||||
//! \param relax The relaxation factor to use.
|
//! \param relax The relaxation factor to use.
|
||||||
template<class M, class X, class C>
|
template<class M, class X, class C>
|
||||||
std::shared_ptr<ParallelOverlappingILU0<M,X,X,C> >
|
std::shared_ptr<ParallelOverlappingILU0<M,X,X,C> >
|
||||||
createILUnPtr(const M& A, const C& comm, int ilu_n, double relax, bool milu)
|
createILUnPtr(const M& A, const C& comm, int ilu_n, double relax, MILU_VARIANT milu)
|
||||||
{
|
{
|
||||||
return std::make_shared<ParallelOverlappingILU0<M,X,X,C> >( A, comm, ilu_n, relax, milu );
|
return std::make_shared<ParallelOverlappingILU0<M,X,X,C> >( A, comm, ilu_n, relax, milu );
|
||||||
}
|
}
|
||||||
@ -219,7 +222,7 @@ createILUnPtr(const M& A, const C& comm, int ilu_n, double relax, bool milu)
|
|||||||
template<class M, class X=typename M::range_type, class P>
|
template<class M, class X=typename M::range_type, class P>
|
||||||
typename CPRSelector<M,X,X,P>::EllipticPreconditionerPointer
|
typename CPRSelector<M,X,X,P>::EllipticPreconditionerPointer
|
||||||
createEllipticPreconditionerPointer(const M& Ae, double relax,
|
createEllipticPreconditionerPointer(const M& Ae, double relax,
|
||||||
bool milu, const P& comm)
|
MILU_VARIANT milu, const P& comm)
|
||||||
{
|
{
|
||||||
typedef typename CPRSelector<M,X,X,P >
|
typedef typename CPRSelector<M,X,X,P >
|
||||||
::EllipticPreconditioner ParallelPreconditioner;
|
::EllipticPreconditioner ParallelPreconditioner;
|
||||||
@ -258,7 +261,7 @@ createAMGPreconditionerPointer(Op& opA, const double relax, const P& comm,
|
|||||||
|
|
||||||
template < class C, class Op, class P, class AMG >
|
template < class C, class Op, class P, class AMG >
|
||||||
inline void
|
inline void
|
||||||
createAMGPreconditionerPointer(Op& opA, const double relax, const bool milu, const P& comm, std::unique_ptr< AMG >& amgPtr)
|
createAMGPreconditionerPointer(Op& opA, const double relax, const MILU_VARIANT milu, const P& comm, std::unique_ptr< AMG >& amgPtr)
|
||||||
{
|
{
|
||||||
// TODO: revise choice of parameters
|
// TODO: revise choice of parameters
|
||||||
int coarsenTarget=1200;
|
int coarsenTarget=1200;
|
||||||
@ -287,7 +290,7 @@ createAMGPreconditionerPointer(Op& opA, const double relax, const bool milu, con
|
|||||||
// \param amgPtr The unique_ptr to be filled (return)
|
// \param amgPtr The unique_ptr to be filled (return)
|
||||||
template < int pressureIndex=0, class Op, class P, class AMG >
|
template < int pressureIndex=0, class Op, class P, class AMG >
|
||||||
inline void
|
inline void
|
||||||
createAMGPreconditionerPointer( Op& opA, const double relax, const bool milu, const P& comm, std::unique_ptr< AMG >& amgPtr )
|
createAMGPreconditionerPointer( Op& opA, const double relax, const MILU_VARIANT milu, const P& comm, std::unique_ptr< AMG >& amgPtr )
|
||||||
{
|
{
|
||||||
// type of matrix
|
// type of matrix
|
||||||
typedef typename Op::matrix_type M;
|
typedef typename Op::matrix_type M;
|
||||||
|
@ -440,7 +440,7 @@ namespace Detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
const double relax = parameters_.ilu_relaxation_;
|
const double relax = parameters_.ilu_relaxation_;
|
||||||
const bool ilu_milu = parameters_.ilu_milu_;
|
const MILU_VARIANT ilu_milu = parameters_.ilu_milu_;
|
||||||
if ( parameters_.use_cpr_ )
|
if ( parameters_.use_cpr_ )
|
||||||
{
|
{
|
||||||
using Matrix = typename MatrixOperator::matrix_type;
|
using Matrix = typename MatrixOperator::matrix_type;
|
||||||
@ -496,7 +496,7 @@ namespace Detail
|
|||||||
{
|
{
|
||||||
const double relax = parameters_.ilu_relaxation_;
|
const double relax = parameters_.ilu_relaxation_;
|
||||||
const int ilu_fillin = parameters_.ilu_fillin_level_;
|
const int ilu_fillin = parameters_.ilu_fillin_level_;
|
||||||
const bool ilu_milu = parameters_.ilu_milu_;
|
const MILU_VARIANT ilu_milu = parameters_.ilu_milu_;
|
||||||
std::unique_ptr<SeqPreconditioner> precond(new SeqPreconditioner(opA.getmat(), ilu_fillin, relax, ilu_milu));
|
std::unique_ptr<SeqPreconditioner> precond(new SeqPreconditioner(opA.getmat(), ilu_fillin, relax, ilu_milu));
|
||||||
return precond;
|
return precond;
|
||||||
}
|
}
|
||||||
@ -519,14 +519,14 @@ namespace Detail
|
|||||||
{
|
{
|
||||||
typedef std::unique_ptr<ParPreconditioner> Pointer;
|
typedef std::unique_ptr<ParPreconditioner> Pointer;
|
||||||
const double relax = parameters_.ilu_relaxation_;
|
const double relax = parameters_.ilu_relaxation_;
|
||||||
const bool ilu_milu = parameters_.ilu_milu_;
|
const MILU_VARIANT ilu_milu = parameters_.ilu_milu_;
|
||||||
return Pointer(new ParPreconditioner(opA.getmat(), comm, relax, ilu_milu));
|
return Pointer(new ParPreconditioner(opA.getmat(), comm, relax, ilu_milu));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class LinearOperator, class MatrixOperator, class POrComm, class AMG >
|
template <class LinearOperator, class MatrixOperator, class POrComm, class AMG >
|
||||||
void
|
void
|
||||||
constructAMGPrecond(LinearOperator& /* linearOperator */, const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >& opA, const double relax, const bool milu) const
|
constructAMGPrecond(LinearOperator& /* linearOperator */, const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >& opA, const double relax, const MILU_VARIANT milu) const
|
||||||
{
|
{
|
||||||
ISTLUtility::template createAMGPreconditionerPointer<pressureIndex>( *opA, relax, milu, comm, amg );
|
ISTLUtility::template createAMGPreconditionerPointer<pressureIndex>( *opA, relax, milu, comm, amg );
|
||||||
}
|
}
|
||||||
@ -535,7 +535,7 @@ namespace Detail
|
|||||||
template <class MatrixOperator, class POrComm, class AMG >
|
template <class MatrixOperator, class POrComm, class AMG >
|
||||||
void
|
void
|
||||||
constructAMGPrecond(MatrixOperator& opA, const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >&, const double relax,
|
constructAMGPrecond(MatrixOperator& opA, const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >&, const double relax,
|
||||||
const bool milu) const
|
const MILU_VARIANT milu) const
|
||||||
{
|
{
|
||||||
ISTLUtility::template createAMGPreconditionerPointer<pressureIndex>( opA, relax,
|
ISTLUtility::template createAMGPreconditionerPointer<pressureIndex>( opA, relax,
|
||||||
milu, comm, amg );
|
milu, comm, amg );
|
||||||
@ -544,7 +544,7 @@ namespace Detail
|
|||||||
template <class C, class LinearOperator, class MatrixOperator, class POrComm, class AMG >
|
template <class C, class LinearOperator, class MatrixOperator, class POrComm, class AMG >
|
||||||
void
|
void
|
||||||
constructAMGPrecond(LinearOperator& /* linearOperator */, const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >& opA, const double relax,
|
constructAMGPrecond(LinearOperator& /* linearOperator */, const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >& opA, const double relax,
|
||||||
const bool milu ) const
|
const MILU_VARIANT milu ) const
|
||||||
{
|
{
|
||||||
ISTLUtility::template createAMGPreconditionerPointer<C>( *opA, relax,
|
ISTLUtility::template createAMGPreconditionerPointer<C>( *opA, relax,
|
||||||
comm, amg, parameters_ );
|
comm, amg, parameters_ );
|
||||||
@ -553,7 +553,7 @@ namespace Detail
|
|||||||
|
|
||||||
template <class C, class MatrixOperator, class POrComm, class AMG >
|
template <class C, class MatrixOperator, class POrComm, class AMG >
|
||||||
void
|
void
|
||||||
constructAMGPrecond(MatrixOperator& opA, const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >&, const double relax, const bool milu ) const
|
constructAMGPrecond(MatrixOperator& opA, const POrComm& comm, std::unique_ptr< AMG >& amg, std::unique_ptr< MatrixOperator >&, const double relax, const MILU_VARIANT milu ) const
|
||||||
{
|
{
|
||||||
ISTLUtility::template createAMGPreconditionerPointer<C>( opA, relax, milu,
|
ISTLUtility::template createAMGPreconditionerPointer<C>( opA, relax, milu,
|
||||||
comm, amg, parameters_ );
|
comm, amg, parameters_ );
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <opm/autodiff/CPRPreconditioner.hpp>
|
#include <opm/autodiff/CPRPreconditioner.hpp>
|
||||||
#include <opm/autodiff/NewtonIterationBlackoilInterface.hpp>
|
#include <opm/autodiff/NewtonIterationBlackoilInterface.hpp>
|
||||||
#include <opm/common/utility/parameters/ParameterGroup.hpp>
|
#include <opm/common/utility/parameters/ParameterGroup.hpp>
|
||||||
|
#include <opm/autodiff/ParallelOverlappingILU0.hpp>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -44,7 +45,7 @@ namespace Opm
|
|||||||
int linear_solver_restart_;
|
int linear_solver_restart_;
|
||||||
int linear_solver_verbosity_;
|
int linear_solver_verbosity_;
|
||||||
int ilu_fillin_level_;
|
int ilu_fillin_level_;
|
||||||
bool ilu_milu_;
|
Opm::MILU_VARIANT ilu_milu_;
|
||||||
bool newton_use_gmres_;
|
bool newton_use_gmres_;
|
||||||
bool require_full_sparsity_pattern_;
|
bool require_full_sparsity_pattern_;
|
||||||
bool ignoreConvergenceFailure_;
|
bool ignoreConvergenceFailure_;
|
||||||
@ -70,7 +71,8 @@ namespace Opm
|
|||||||
linear_solver_use_amg_ = param.getDefault("linear_solver_use_amg", linear_solver_use_amg_ );
|
linear_solver_use_amg_ = param.getDefault("linear_solver_use_amg", linear_solver_use_amg_ );
|
||||||
ilu_relaxation_ = param.getDefault("ilu_relaxation", ilu_relaxation_ );
|
ilu_relaxation_ = param.getDefault("ilu_relaxation", ilu_relaxation_ );
|
||||||
ilu_fillin_level_ = param.getDefault("ilu_fillin_level", ilu_fillin_level_ );
|
ilu_fillin_level_ = param.getDefault("ilu_fillin_level", ilu_fillin_level_ );
|
||||||
ilu_milu_ = param.getDefault("ilu_milu", ilu_milu_);
|
std::string milu("ILU");
|
||||||
|
ilu_milu_ = convertString2Milu(param.getDefault("ilu_milu", milu));
|
||||||
|
|
||||||
// Check whether to use cpr approach
|
// Check whether to use cpr approach
|
||||||
const std::string cprSolver = "cpr";
|
const std::string cprSolver = "cpr";
|
||||||
@ -91,7 +93,7 @@ namespace Opm
|
|||||||
linear_solver_use_amg_ = false;
|
linear_solver_use_amg_ = false;
|
||||||
ilu_fillin_level_ = 0;
|
ilu_fillin_level_ = 0;
|
||||||
ilu_relaxation_ = 0.9;
|
ilu_relaxation_ = 0.9;
|
||||||
ilu_milu_ = false;
|
ilu_milu_ = MILU_VARIANT::ILU;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <dune/istl/paamg/pinfo.hh>
|
#include <dune/istl/paamg/pinfo.hh>
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm
|
||||||
{
|
{
|
||||||
@ -37,19 +38,49 @@ namespace Opm
|
|||||||
template<class Matrix, class Domain, class Range, class ParallelInfo = Dune::Amg::SequentialInformation>
|
template<class Matrix, class Domain, class Range, class ParallelInfo = Dune::Amg::SequentialInformation>
|
||||||
class ParallelOverlappingILU0;
|
class ParallelOverlappingILU0;
|
||||||
|
|
||||||
|
enum class MILU_VARIANT{
|
||||||
|
/// \brief Do not perform modified ILU
|
||||||
|
ILU = 0,
|
||||||
|
/// \brief \f$U_{ii} = U_{ii} +\f$ sum(dropped entries)
|
||||||
|
MILU_1 = 1,
|
||||||
|
/// \brief \f$U_{ii} = U_{ii} + sign(U_{ii}) * \f$ sum(dropped entries)
|
||||||
|
MILU_2 = 2,
|
||||||
|
/// \brief \f$U_{ii} = U_{ii} sign(U_{ii}) * \f$ sum(|dropped entries|)
|
||||||
|
MILU_3 = 3,
|
||||||
|
/// \brief \f$U_{ii} = U_{ii} + (U_{ii}>0?1:0) * \f$ sum(dropped entries)
|
||||||
|
MILU_4 = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
inline MILU_VARIANT convertString2Milu(std::string milu)
|
||||||
|
{
|
||||||
|
if( 0 == milu.compare("MILU_1") )
|
||||||
|
{
|
||||||
|
return MILU_VARIANT::MILU_1;
|
||||||
|
}
|
||||||
|
if ( 0 == milu.compare("MILU_2") )
|
||||||
|
{
|
||||||
|
return MILU_VARIANT::MILU_2;
|
||||||
|
}
|
||||||
|
if ( 0 == milu.compare("MILU_3") )
|
||||||
|
{
|
||||||
|
return MILU_VARIANT::MILU_3;
|
||||||
|
}
|
||||||
|
return MILU_VARIANT::ILU;
|
||||||
|
}
|
||||||
|
|
||||||
template<class F>
|
template<class F>
|
||||||
class ParallelOverlappingILU0Args
|
class ParallelOverlappingILU0Args
|
||||||
: public Dune::Amg::DefaultSmootherArgs<F>
|
: public Dune::Amg::DefaultSmootherArgs<F>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ParallelOverlappingILU0Args(bool milu = false)
|
ParallelOverlappingILU0Args(MILU_VARIANT milu = MILU_VARIANT::ILU )
|
||||||
: milu_(milu)
|
: milu_(milu)
|
||||||
{}
|
{}
|
||||||
void setMilu(bool milu)
|
void setMilu(MILU_VARIANT milu)
|
||||||
{
|
{
|
||||||
milu_ = milu;
|
milu_ = milu;
|
||||||
}
|
}
|
||||||
bool getMilu() const
|
MILU_VARIANT getMilu() const
|
||||||
{
|
{
|
||||||
return milu_;
|
return milu_;
|
||||||
}
|
}
|
||||||
@ -62,7 +93,7 @@ class ParallelOverlappingILU0Args
|
|||||||
return n_;
|
return n_;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool milu_;
|
MILU_VARIANT milu_;
|
||||||
int n_;
|
int n_;
|
||||||
};
|
};
|
||||||
} // end namespace Opm
|
} // end namespace Opm
|
||||||
@ -118,12 +149,68 @@ namespace Opm
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<class M>
|
struct IdentityFunctor
|
||||||
void milu0_decomposition(M& A,
|
{
|
||||||
|
template<class T>
|
||||||
|
T operator()(const T& t)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OneFunctor
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
T operator()(const T&)
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct SignFunctor
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
double operator()(const T& t)
|
||||||
|
{
|
||||||
|
if ( t < 0.0 )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IsPositiveFunctor
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
double operator()(const T& t)
|
||||||
|
{
|
||||||
|
if ( t < 0.0 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct AbsFunctor
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
T operator()(const T& t)
|
||||||
|
{
|
||||||
|
using std::abs;
|
||||||
|
return abs(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class M, class F1=detail::IdentityFunctor, class F2=detail::OneFunctor >
|
||||||
|
void milu0_decomposition(M& A, F1 absFunctor = F1(), F2 signFunctor = F2(),
|
||||||
std::vector<typename M::block_type>* diagonal = nullptr)
|
std::vector<typename M::block_type>* diagonal = nullptr)
|
||||||
{
|
{
|
||||||
using block = typename M::block_type;
|
|
||||||
|
|
||||||
if( diagonal )
|
if( diagonal )
|
||||||
{
|
{
|
||||||
diagonal->reserve(A.N());
|
diagonal->reserve(A.N());
|
||||||
@ -134,8 +221,7 @@ namespace Opm
|
|||||||
auto a_i_end = irow->end();
|
auto a_i_end = irow->end();
|
||||||
auto a_ik = irow->begin();
|
auto a_ik = irow->begin();
|
||||||
|
|
||||||
block sum_dropped;
|
std::array<typename M::field_type, M::block_type::rows> sum_dropped{};
|
||||||
sum_dropped = 0.0;
|
|
||||||
|
|
||||||
// Eliminate entries in lower triangular matrix
|
// Eliminate entries in lower triangular matrix
|
||||||
// and store factors for L
|
// and store factors for L
|
||||||
@ -170,7 +256,15 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sum_dropped += modifier;
|
auto entry = sum_dropped.begin();
|
||||||
|
for( const auto& row: modifier )
|
||||||
|
{
|
||||||
|
for( const auto& colEntry: row )
|
||||||
|
{
|
||||||
|
*entry += absFunctor(-colEntry);
|
||||||
|
}
|
||||||
|
++entry;
|
||||||
|
}
|
||||||
++a_kj;
|
++a_kj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,12 +274,12 @@ namespace Opm
|
|||||||
OPM_THROW(std::logic_error, "Matrix is missing diagonal for row " << irow.index());
|
OPM_THROW(std::logic_error, "Matrix is missing diagonal for row " << irow.index());
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for(const auto& row: sum_dropped)
|
for(const auto& entry: sum_dropped)
|
||||||
{
|
{
|
||||||
for(const auto& val: row)
|
auto& bdiag = (*a_ik)[index][index];
|
||||||
{
|
if(entry<0)
|
||||||
(*a_ik)[index][index]-=val;
|
std::cout << entry << std::endl;
|
||||||
}
|
bdiag += signFunctor(bdiag) * entry;
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,6 +291,13 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class M>
|
||||||
|
void milu0_decomposition(M& A,
|
||||||
|
std::vector<typename M::block_type>* diagonal)
|
||||||
|
{
|
||||||
|
milu0_decomposition(A, detail::IdentityFunctor(), detail::OneFunctor(),
|
||||||
|
diagonal);
|
||||||
|
}
|
||||||
|
|
||||||
//! compute ILU decomposition of A. A is overwritten by its decomposition
|
//! compute ILU decomposition of A. A is overwritten by its decomposition
|
||||||
template<class M, class CRS, class InvVector>
|
template<class M, class CRS, class InvVector>
|
||||||
@ -271,6 +372,7 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
} // end namespace detail
|
} // end namespace detail
|
||||||
|
|
||||||
|
|
||||||
/// \brief A two-step version of an overlapping Schwarz preconditioner using one step ILU0 as
|
/// \brief A two-step version of an overlapping Schwarz preconditioner using one step ILU0 as
|
||||||
///
|
///
|
||||||
/// This preconditioner differs from a ParallelRestrictedOverlappingSchwarz with
|
/// This preconditioner differs from a ParallelRestrictedOverlappingSchwarz with
|
||||||
@ -374,14 +476,12 @@ public:
|
|||||||
\param A The matrix to operate on.
|
\param A The matrix to operate on.
|
||||||
\param n ILU fill in level (for testing). This does not work in parallel.
|
\param n ILU fill in level (for testing). This does not work in parallel.
|
||||||
\param w The relaxation factor.
|
\param w The relaxation factor.
|
||||||
\param milu If true, the modified ilu approach is used. Dropped elements
|
\param milu The modified ILU variant to use. 0 means traditional ILU. \see MILU_VARIANT.
|
||||||
will get added to the diagonal of U to preserve the row sum
|
|
||||||
for constant vectors (Ae = LUe).
|
|
||||||
*/
|
*/
|
||||||
template<class BlockType, class Alloc>
|
template<class BlockType, class Alloc>
|
||||||
ParallelOverlappingILU0 (const Dune::BCRSMatrix<BlockType,Alloc>& A,
|
ParallelOverlappingILU0 (const Dune::BCRSMatrix<BlockType,Alloc>& A,
|
||||||
const int n, const field_type w,
|
const int n, const field_type w,
|
||||||
bool milu)
|
MILU_VARIANT milu)
|
||||||
: lower_(),
|
: lower_(),
|
||||||
upper_(),
|
upper_(),
|
||||||
inv_(),
|
inv_(),
|
||||||
@ -398,14 +498,12 @@ public:
|
|||||||
\param comm communication object, e.g. Dune::OwnerOverlapCopyCommunication
|
\param comm communication object, e.g. Dune::OwnerOverlapCopyCommunication
|
||||||
\param n ILU fill in level (for testing). This does not work in parallel.
|
\param n ILU fill in level (for testing). This does not work in parallel.
|
||||||
\param w The relaxation factor.
|
\param w The relaxation factor.
|
||||||
\param milu If true, the modified ilu approach is used. Dropped elements
|
\param milu The modified ILU variant to use. 0 means traditional ILU. \see MILU_VARIANT.
|
||||||
will get added to the diagonal of U to preserve the row sum
|
|
||||||
for constant vectors (Ae = LUe).
|
|
||||||
*/
|
*/
|
||||||
template<class BlockType, class Alloc>
|
template<class BlockType, class Alloc>
|
||||||
ParallelOverlappingILU0 (const Dune::BCRSMatrix<BlockType,Alloc>& A,
|
ParallelOverlappingILU0 (const Dune::BCRSMatrix<BlockType,Alloc>& A,
|
||||||
const ParallelInfo& comm, const int n, const field_type w,
|
const ParallelInfo& comm, const int n, const field_type w,
|
||||||
bool milu)
|
MILU_VARIANT milu)
|
||||||
: lower_(),
|
: lower_(),
|
||||||
upper_(),
|
upper_(),
|
||||||
inv_(),
|
inv_(),
|
||||||
@ -422,13 +520,11 @@ public:
|
|||||||
Constructor gets all parameters to operate the prec.
|
Constructor gets all parameters to operate the prec.
|
||||||
\param A The matrix to operate on.
|
\param A The matrix to operate on.
|
||||||
\param w The relaxation factor.
|
\param w The relaxation factor.
|
||||||
\param milu If true, the modified ilu approach is used. Dropped elements
|
\param milu The modified ILU variant to use. 0 means traditional ILU. \see MILU_VARIANT.
|
||||||
will get added to the diagonal of U to preserve the row sum
|
|
||||||
for constant vectors (Ae = LUe).
|
|
||||||
*/
|
*/
|
||||||
template<class BlockType, class Alloc>
|
template<class BlockType, class Alloc>
|
||||||
ParallelOverlappingILU0 (const Dune::BCRSMatrix<BlockType,Alloc>& A,
|
ParallelOverlappingILU0 (const Dune::BCRSMatrix<BlockType,Alloc>& A,
|
||||||
const field_type w, bool milu)
|
const field_type w, MILU_VARIANT milu)
|
||||||
: ParallelOverlappingILU0( A, 0, w, milu )
|
: ParallelOverlappingILU0( A, 0, w, milu )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -439,14 +535,12 @@ public:
|
|||||||
\param A The matrix to operate on.
|
\param A The matrix to operate on.
|
||||||
\param comm communication object, e.g. Dune::OwnerOverlapCopyCommunication
|
\param comm communication object, e.g. Dune::OwnerOverlapCopyCommunication
|
||||||
\param w The relaxation factor.
|
\param w The relaxation factor.
|
||||||
\param milu If true, the modified ilu approach is used. Dropped elements
|
\param milu The modified ILU variant to use. 0 means traditional ILU. \see MILU_VARIANT.
|
||||||
will get added to the diagonal of U to preserve the row sum
|
|
||||||
for constant vectors (Ae = LUe).
|
|
||||||
*/
|
*/
|
||||||
template<class BlockType, class Alloc>
|
template<class BlockType, class Alloc>
|
||||||
ParallelOverlappingILU0 (const Dune::BCRSMatrix<BlockType,Alloc>& A,
|
ParallelOverlappingILU0 (const Dune::BCRSMatrix<BlockType,Alloc>& A,
|
||||||
const ParallelInfo& comm, const field_type w,
|
const ParallelInfo& comm, const field_type w,
|
||||||
bool milu)
|
MILU_VARIANT milu)
|
||||||
: lower_(),
|
: lower_(),
|
||||||
upper_(),
|
upper_(),
|
||||||
inv_(),
|
inv_(),
|
||||||
@ -549,7 +643,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init( const Matrix& A, const int iluIteration, bool milu )
|
void init( const Matrix& A, const int iluIteration, MILU_VARIANT milu )
|
||||||
{
|
{
|
||||||
// (For older DUNE versions the communicator might be
|
// (For older DUNE versions the communicator might be
|
||||||
// invalid if redistribution in AMG happened on the coarset level.
|
// invalid if redistribution in AMG happened on the coarset level.
|
||||||
@ -578,18 +672,32 @@ protected:
|
|||||||
if( iluIteration == 0 ) {
|
if( iluIteration == 0 ) {
|
||||||
// create ILU-0 decomposition
|
// create ILU-0 decomposition
|
||||||
ILU.reset( new Matrix( A ) );
|
ILU.reset( new Matrix( A ) );
|
||||||
if ( milu )
|
switch ( milu )
|
||||||
{
|
|
||||||
detail::milu0_decomposition ( *ILU );
|
|
||||||
}else
|
|
||||||
{
|
{
|
||||||
|
case MILU_VARIANT::MILU_1:
|
||||||
|
detail::milu0_decomposition ( *ILU);
|
||||||
|
break;
|
||||||
|
case MILU_VARIANT::MILU_2:
|
||||||
|
detail::milu0_decomposition ( *ILU, detail::IdentityFunctor(),
|
||||||
|
detail::SignFunctor() );
|
||||||
|
break;
|
||||||
|
case MILU_VARIANT::MILU_3:
|
||||||
|
detail::milu0_decomposition ( *ILU, detail::AbsFunctor(),
|
||||||
|
detail::SignFunctor() );
|
||||||
|
break;
|
||||||
|
case MILU_VARIANT::MILU_4:
|
||||||
|
detail::milu0_decomposition ( *ILU, detail::IdentityFunctor(),
|
||||||
|
detail::IsPositiveFunctor() );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
bilu0_decomposition( *ILU );
|
bilu0_decomposition( *ILU );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// create ILU-n decomposition
|
// create ILU-n decomposition
|
||||||
ILU.reset( new Matrix( A.N(), A.M(), Matrix::row_wise) );
|
ILU.reset( new Matrix( A.N(), A.M(), Matrix::row_wise) );
|
||||||
if ( milu )
|
if ( milu > MILU_VARIANT::ILU )
|
||||||
{
|
{
|
||||||
OpmLog::warning("MILU_N_NOT_SUPPORTED", "MILU variant only supported for zero fill-in");
|
OpmLog::warning("MILU_N_NOT_SUPPORTED", "MILU variant only supported for zero fill-in");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user