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:257
 
Dune namespace.
Definition: alignedallocator.hh:13