1#ifndef DUNE_FEM_UMFPACKSOLVER_HH
2#define DUNE_FEM_UMFPACKSOLVER_HH
10#include <dune/common/hybridutilities.hh>
11#include <dune/fem/function/adaptivefunction.hh>
12#include <dune/fem/function/blockvectorfunction.hh>
13#include <dune/fem/function/tuplediscretefunction.hh>
14#include <dune/fem/io/parameter.hh>
15#include <dune/fem/operator/common/operator.hh>
16#include <dune/fem/operator/linear/spoperator.hh>
17#include <dune/fem/operator/matrix/colcompspmatrix.hh>
18#include <dune/fem/operator/linear/spoperator.hh>
19#include <dune/fem/solver/inverseoperatorinterface.hh>
21#if HAVE_SUITESPARSE_UMFPACK
22#include <dune/fem/misc/umfpack.hh>
38template<
class DiscreteFunction,
class Matrix>
39class UMFPACKInverseOperator;
41template<
class DiscreteFunction,
class Matrix>
42struct UMFPACKInverseOperatorTraits
45 typedef AdaptiveDiscreteFunction< typename DiscreteFunction::DiscreteFunctionSpaceType > SolverDiscreteFunctionType;
48 typedef OperatorType PreconditionerType;
50 typedef Fem::SparseRowLinearOperator< DiscreteFunction, DiscreteFunction, Matrix > AssembledOperatorType;
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;
84 typedef ColCompMatrix<typename AssembledOperatorType::MatrixType::MatrixBaseType, SuiteSparse_long> CCSMatrixType;
85 typedef typename DiscreteFunctionType::DofType DofType;
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_)
133 ccsmat_ = std::make_unique<CCSMatrixType>(assembledOperator_->exportMatrix());
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);
165 Caller::report_status(UMF_Control, UMF_Apply_Info[UMFPACK_STATUS]);
166 std::cout <<
"[UMFPack Solve]" << std::endl;
167 std::cout <<
"Wallclock Time: " << UMF_Apply_Info[UMFPACK_SOLVE_WALLTIME]
168 <<
" (CPU Time: " << UMF_Apply_Info[UMFPACK_SOLVE_TIME] <<
")" << std::endl;
169 std::cout <<
"Flops Taken: " << UMF_Apply_Info[UMFPACK_SOLVE_FLOPS] << 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
200 std::vector<DofType> vecArg(arg.size());
201 auto vecArgIt(vecArg.begin());
203 [&](
auto i){vecArgIt=std::copy(std::get<i>(arg).dbegin(),std::get<i>(arg).dend(),vecArgIt);});
204 std::vector<DofType> vecDest(dest.size());
206 apply(vecArg.data(),vecDest.data());
208 auto vecDestIt(vecDest.begin());
209 Hybrid::forEach(std::make_index_sequence<
sizeof...(DFs)>{},[&](
auto i){
for(
auto& dof:dofs(std::get<i>(dest))) dof=(*(vecDestIt++));});
213 void printTexInfo(std::ostream& out)
const
215 out<<
"Solver: UMFPACK direct solver"<<std::endl;
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_;
247 mutable std::unique_ptr<CCSMatrixType> ccsmat_;
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];
253 typedef typename Dune::UMFPackMethodChooser<DofType> Caller;
256 void decompose()
const
258 const std::size_t dimMat(getCCSMatrix().N());
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);
265 Caller::report_status(UMF_Control,UMF_Decomposition_Info[UMFPACK_STATUS]);
266 std::cout <<
"[UMFPack Decomposition]" << std::endl;
267 std::cout <<
"Wallclock Time taken: " << UMF_Decomposition_Info[UMFPACK_NUMERIC_WALLTIME]
268 <<
" (CPU Time: " << UMF_Decomposition_Info[UMFPACK_NUMERIC_TIME] <<
")" << std::endl;
269 std::cout <<
"Flops taken: " << UMF_Decomposition_Info[UMFPACK_FLOPS] << std::endl;
270 std::cout <<
"Peak Memory Usage: " << UMF_Decomposition_Info[UMFPACK_PEAK_MEMORY]*UMF_Decomposition_Info[UMFPACK_SIZE_OF_UNIT]
271 <<
" bytes" << std::endl;
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;
Inverse operator base on CG method. Uses a runtime parameter fem.preconditioning which enables diagon...
Definition: cginverseoperator.hh:408
static bool verbose()
obtain the cached value for fem.verbose with default verbosity level 2
Definition: parameter.hh:466
forward declaration
Definition: discretefunction.hh:51
TupleDiscreteFunctionSpace< typename DiscreteFunctions::DiscreteFunctionSpaceType ... > DiscreteFunctionSpaceType
type for the discrete function space this function lives in
Definition: discretefunction.hh:69
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
Dune namespace.
Definition: alignedallocator.hh:13