1#ifndef DUNE_FEM_UMFPACKSOLVER_HH
2#define DUNE_FEM_UMFPACKSOLVER_HH
21#if HAVE_SUITESPARSE_UMFPACK
38template<
class DiscreteFunction,
class Matrix>
39class UMFPACKInverseOperator;
41template<
class DiscreteFunction,
class Matrix>
42struct UMFPACKInverseOperatorTraits
44 typedef DiscreteFunction DiscreteFunctionType;
45 typedef AdaptiveDiscreteFunction< typename DiscreteFunction::DiscreteFunctionSpaceType > SolverDiscreteFunctionType;
48 typedef OperatorType PreconditionerType;
50 typedef Fem::SparseRowLinearOperator< DiscreteFunction, DiscreteFunction, Matrix > AssembledOperatorType;
52 typedef UMFPACKInverseOperator< DiscreteFunction,Matrix> InverseOperatorType;
53 typedef SolverParameter SolverParameterType;
63template<
class DiscreteFunction,
64 class Matrix = SparseRowMatrix< typename DiscreteFunction::DiscreteFunctionSpaceType::RangeFieldType > >
65class UMFPACKInverseOperator :
66 public InverseOperatorInterface< UMFPACKInverseOperatorTraits< DiscreteFunction, Matrix > >
69 typedef UMFPACKInverseOperatorTraits< DiscreteFunction, Matrix > Traits;
70 typedef InverseOperatorInterface< Traits > BaseType;
72 typedef typename BaseType :: SolverDiscreteFunctionType
73 SolverDiscreteFunctionType;
75 typedef typename BaseType :: OperatorType OperatorType;
76 typedef typename BaseType :: AssembledOperatorType AssembledOperatorType;
78 typedef UMFPACKInverseOperator< DiscreteFunction,Matrix> ThisType;
80 typedef DiscreteFunction DiscreteFunctionType;
84 typedef ColCompMatrix<typename AssembledOperatorType::MatrixType::MatrixBaseType, SuiteSparse_long> CCSMatrixType;
85 typedef typename DiscreteFunctionType::DofType DofType;
86 typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
88 using BaseType :: parameter_;
89 using BaseType :: bind;
92 static const bool preconditioningAvailable =
false;
97 UMFPACKInverseOperator(
const SolverParameter ¶meter = SolverParameter(Parameter::container()) )
98 : BaseType(parameter),
100 UMF_Symbolic( nullptr ),
101 UMF_Numeric( nullptr )
103 Caller::defaults(UMF_Control);
104 UMF_Control[UMFPACK_PRL] = 4;
108 ~UMFPACKInverseOperator()
113 void bind(
const OperatorType& op )
117 BaseType::bind( op );
118 assert( assembledOperator_ );
128 template<
typename... A>
129 void prepare(A... )
const
131 if(assembledOperator_ && !ccsmat_)
139 virtual void finalize()
143 getCCSMatrix().free();
145 Caller::free_symbolic(&UMF_Symbolic); UMF_Symbolic =
nullptr;
146 Caller::free_numeric(&UMF_Numeric); UMF_Numeric =
nullptr;
156 int apply(
const DofType* arg, DofType* dest)
const
160 double UMF_Apply_Info[UMFPACK_INFO];
161 Caller::solve(UMFPACK_A, getCCSMatrix().getColStart(), getCCSMatrix().getRowIndex(), getCCSMatrix().getValues(),
162 dest,
const_cast<DofType*
>(arg), UMF_Numeric, UMF_Control, UMF_Apply_Info);
163 if( Parameter::verbose( Parameter::solverStatistics ) && parameter_->verbose() )
165 Caller::report_status(UMF_Control, UMF_Apply_Info[UMFPACK_STATUS]);
167 std::cout <<
"Wallclock Time: " << UMF_Apply_Info[UMFPACK_SOLVE_WALLTIME]
168 <<
" (CPU Time: " << UMF_Apply_Info[UMFPACK_SOLVE_TIME] <<
")" <<
std::endl;
170 std::cout <<
"Iterative Refinement steps taken: " << UMF_Apply_Info[UMFPACK_IR_TAKEN] <<
std::endl;
171 std::cout <<
"Error Estimate: " << UMF_Apply_Info[UMFPACK_OMEGA1] <<
" resp. " << UMF_Apply_Info[UMFPACK_OMEGA2] <<
std::endl;
174 const_cast<ThisType*
>(
this)->finalize();
185 int apply(
const SolverDiscreteFunctionType& arg, SolverDiscreteFunctionType& dest)
const
187 return apply(arg.leakPointer(), dest.leakPointer());
196 template<
typename... DFs>
197 int apply(
const TupleDiscreteFunction<DFs...>& arg,TupleDiscreteFunction<DFs...>& dest)
const
201 auto vecArgIt(vecArg.begin());
206 apply(vecArg.data(),vecDest.data());
208 auto vecDestIt(vecDest.begin());
218 void setMaxIterations (
int ) {}
223 CCSMatrixType& getCCSMatrix()
const
230 void printDecompositionInfo()
const
232 Caller::report_info(UMF_Control,UMF_Decomposition_Info);
235 UMFPACKInverseOperator(
const UMFPACKInverseOperator &other)
238 UMF_Symbolic(other.UMF_Symbolic),
239 UMF_Numeric(other.UMF_Numeric)
241 for (
int i=0;i<UMFPACK_CONTROL;++i) UMF_Control[i] = other.UMF_Control[i];
242 for (
int i=0;i<UMFPACK_INFO;++i) UMF_Decomposition_Info[i] = other.UMF_Decomposition_Info[i];
246 using BaseType::assembledOperator_;
248 mutable void *UMF_Symbolic;
249 mutable void *UMF_Numeric;
250 mutable double UMF_Control[UMFPACK_CONTROL];
251 mutable double UMF_Decomposition_Info[UMFPACK_INFO];
256 void decompose()
const
259 Caller::symbolic(
static_cast<int>(dimMat),
static_cast<int>(dimMat), getCCSMatrix().getColStart(), getCCSMatrix().getRowIndex(),
260 reinterpret_cast<double*
>(getCCSMatrix().getValues()), &UMF_Symbolic, UMF_Control, UMF_Decomposition_Info);
261 Caller::numeric(getCCSMatrix().getColStart(), getCCSMatrix().getRowIndex(),
reinterpret_cast<double*
>(getCCSMatrix().getValues()),
262 UMF_Symbolic, &UMF_Numeric, UMF_Control, UMF_Decomposition_Info);
263 if( Parameter::verbose( Parameter::solverStatistics ) && parameter_->verbose() )
265 Caller::report_status(UMF_Control,UMF_Decomposition_Info[UMFPACK_STATUS]);
267 std::cout <<
"Wallclock Time taken: " << UMF_Decomposition_Info[UMFPACK_NUMERIC_WALLTIME]
268 <<
" (CPU Time: " << UMF_Decomposition_Info[UMFPACK_NUMERIC_TIME] <<
")" <<
std::endl;
270 std::cout <<
"Peak Memory Usage: " << UMF_Decomposition_Info[UMFPACK_PEAK_MEMORY]*UMF_Decomposition_Info[UMFPACK_SIZE_OF_UNIT]
272 std::cout <<
"Condition number estimate: " << 1./UMF_Decomposition_Info[UMFPACK_RCOND] <<
std::endl;
273 std::cout <<
"Numbers of non-zeroes in decomposition: L: " << UMF_Decomposition_Info[UMFPACK_LNZ]
274 <<
" U: " << UMF_Decomposition_Info[UMFPACK_UNZ] <<
std::endl;
Dune::BCRSMatrix< FieldMatrix< T, n, m >, TA > Matrix
static TupleAccessTraits< typenameAtType< N, Tuple >::Type >::NonConstType get(Tuple &t)
static constexpr size_type N()
IteratorRange< typename DF::DofIteratorType > dofs(DF &df)
Iterates over all DOFs.
Definition rangegenerators.hh:76