1#ifndef DUNE_FEM_LDLSOLVER_HH
2#define DUNE_FEM_LDLSOLVER_HH
20#if HAVE_SUITESPARSE_LDL
45template<
class DiscreteFunction,
46 class Matrix = SparseRowMatrix< typename DiscreteFunction::DiscreteFunctionSpaceType::RangeFieldType > >
47class LDLInverseOperator;
49template<
class DiscreteFunction,
class Matrix >
50struct LDLInverseOperatorTraits
52 typedef DiscreteFunction DiscreteFunctionType;
53 typedef AdaptiveDiscreteFunction< typename DiscreteFunction::DiscreteFunctionSpaceType > SolverDiscreteFunctionType;
56 typedef OperatorType PreconditionerType;
58 typedef Fem::SparseRowLinearOperator< DiscreteFunction, DiscreteFunction, Matrix > AssembledOperatorType;
60 typedef LDLInverseOperator< DiscreteFunction, Matrix > InverseOperatorType;
61 typedef SolverParameter SolverParameterType;
73template<
class DF,
class Matrix >
74class LDLInverseOperator :
public InverseOperatorInterface< LDLInverseOperatorTraits< DF, Matrix > >
76 typedef LDLInverseOperatorTraits< DF, Matrix > Traits;
77 typedef InverseOperatorInterface< Traits > BaseType;
79 friend class InverseOperatorInterface< Traits >;
82 static const bool preconditioningAvailable =
false;
84 typedef LDLInverseOperator< DF, Matrix > ThisType;
86 typedef typename BaseType :: SolverDiscreteFunctionType
87 SolverDiscreteFunctionType;
89 typedef typename BaseType :: OperatorType OperatorType;
90 typedef typename BaseType :: AssembledOperatorType AssembledOperatorType;
93 typedef ColCompMatrix<typename AssembledOperatorType::MatrixType::MatrixBaseType,int> CCSMatrixType;
95 typedef typename SolverDiscreteFunctionType::DofType DofType;
96 typedef typename SolverDiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
104 LDLInverseOperator(
const double& redEps,
const double& absLimit,
const int& maxIter,
const bool& verbose,
105 const ParameterReader ¶meter = Parameter::container() ) :
106 verbose_(
verbose && Parameter::
verbose(Parameter::solverStatistics )), ccsmat_()
114 LDLInverseOperator(
const double& redEps,
const double& absLimit,
const int& maxIter,
115 const ParameterReader ¶meter = Parameter::container() ) :
116 verbose_(parameter.getValue<bool>(
"fem.solver.verbose",false) && Parameter::
verbose(Parameter::solverStatistics )),
120 LDLInverseOperator(
const SolverParameter ¶meter = SolverParameter(Parameter::container()) )
121 : BaseType(parameter), verbose_(BaseType::
verbose())
131 LDLInverseOperator(
const OperatorType& op,
const double& redEps,
const double& absLimit,
const int& maxIter,
const bool& verbose,
132 const ParameterReader ¶meter = Parameter::container() ) :
133 verbose_(
verbose), ccsmat_(), isloaded_(false)
144 LDLInverseOperator(
const OperatorType& op,
const double& redEps,
const double& absLimit,
const int& maxIter,
145 const ParameterReader ¶meter = Parameter::container() ) :
146 verbose_(parameter.getValue<bool>(
"fem.solver.verbose",false)), ccsmat_(), isloaded_(false)
151 LDLInverseOperator(
const OperatorType& op,
const ParameterReader ¶meter = Parameter::container() ) :
152 verbose_(parameter.getValue<bool>(
"fem.solver.verbose",false)), ccsmat_(), isloaded_(false)
158 ~LDLInverseOperator()
163 void bind(
const OperatorType& op )
167 BaseType::bind( op );
177 template<
typename... A>
178 void prepare(A... )
const
180 if( ! assembledOperator_ )
181 DUNE_THROW(NotImplemented,
"LDLInverseOperator only works for assembled systems!");
185 ccsmat_ = assembledOperator_->exportMatrix();
192 virtual void finalize()
214 template<
typename... DFs>
215 void apply(
const TupleDiscreteFunction<DFs...>& arg,TupleDiscreteFunction<DFs...>& dest)
const
219 auto vecArgIt(vecArg.begin());
224 apply(vecArg.data(),vecDest.data());
226 auto vecDestIt(vecDest.begin());
237 void printDecompositionInfo()
const
277 CCSMatrixType& getCCSMatrix()
289 void apply(
const DofType* arg, DofType* dest)
const
295 ldl_perm(dimMat, Y_,
const_cast<DofType*
>(arg), P_);
296 ldl_lsolve(dimMat, Y_, Lp_, Li_, Lx_);
297 ldl_dsolve(dimMat, Y_, D_);
298 ldl_ltsolve(dimMat, Y_, Lp_, Li_, Lx_);
299 ldl_permt(dimMat, dest, Y_, P_);
301 const_cast<ThisType*
>(
this)->finalize();
310 int apply(
const SolverDiscreteFunctionType& arg,
311 SolverDiscreteFunctionType& dest)
const
313 apply(arg.leakPointer(),dest.leakPointer());
319 using BaseType :: assembledOperator_;
322 mutable CCSMatrixType ccsmat_;
323 mutable bool isloaded_ =
false;
325 mutable int* Parent_;
328 mutable int* Pattern_;
333 mutable DofType* Lx_;
335 mutable double info_[AMD_INFO];
338 void decompose()
const
342 D_ =
new DofType [dimMat];
343 Y_ =
new DofType [dimMat];
344 Lp_ =
new int [dimMat + 1];
345 Parent_ =
new int [dimMat];
346 Lnz_ =
new int [dimMat];
347 Flag_ =
new int [dimMat];
348 Pattern_ =
new int [dimMat];
349 P_ =
new int [dimMat];
350 Pinv_ =
new int [dimMat];
352 if(amd_order (dimMat, ccsmat_.getColStart(), ccsmat_.getRowIndex(), P_, (DofType *) NULL, info_) < AMD_OK)
353 DUNE_THROW(InvalidStateException,
"LDL Error: AMD failed!");
355 printDecompositionInfo();
357 ldl_symbolic(dimMat, ccsmat_.getColStart(), ccsmat_.getRowIndex(), Lp_, Parent_, Lnz_, Flag_, P_, Pinv_);
359 Lx_ =
new DofType [Lp_[dimMat]];
360 Li_ =
new int [Lp_[dimMat]];
362 const std::size_t k(ldl_numeric(dimMat, ccsmat_.getColStart(), ccsmat_.getRowIndex(), ccsmat_.getValues(),
363 Lp_, Parent_, Lnz_, Li_, Lx_, D_, Y_, Pattern_, Flag_, P_, Pinv_));
373 DUNE_THROW(InvalidStateException,
"LDL Error: factorisation failed!");
379template<
class DF,
class Op,
bool symmetric=false>
380using LDLOp = LDLInverseOperator< DF, typename Op::MatrixType >;
Dune::BCRSMatrix< FieldMatrix< T, n, m >, TA > Matrix
static TupleAccessTraits< typenameAtType< N, Tuple >::Type >::NonConstType get(Tuple &t)
#define DUNE_THROW(E,...)
IteratorRange< typename DF::DofIteratorType > dofs(DF &df)
Iterates over all DOFs.
Definition rangegenerators.hh:76