1 #ifndef DUNE_FEM_SPQRSOLVER_HH 2 #define DUNE_FEM_SPQRSOLVER_HH 18 #include <SuiteSparseQR.hpp> 41 template<
class DF,
class Op,
bool symmetric=false>
42 class SPQROp:
public Operator<DF, DF>
45 typedef DF DiscreteFunctionType;
46 typedef Op OperatorType;
49 typedef ColCompMatrix<typename OperatorType::MatrixType::MatrixBaseType> CCSMatrixType;
50 typedef typename DiscreteFunctionType::DofType DofType;
51 typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
60 SPQROp(
const OperatorType& op,
const double& redEps,
const double& absLimit,
const int& maxIter,
const bool& verbose,
62 op_(op), verbose_(verbose), ccsmat_(), isloaded_(false)
64 cc_ =
new cholmod_common();
74 SPQROp(
const OperatorType& op,
const double& redEps,
const double& absLimit,
const int& maxIter,
76 op_(op), verbose_(parameter.getValue<bool>(
"fem.solver.verbose",false)), ccsmat_(), isloaded_(false)
78 cc_ =
new cholmod_common();
83 op_(op), verbose_(parameter.getValue<bool>(
"fem.solver.verbose",false)), ccsmat_(), isloaded_(false)
85 cc_ =
new cholmod_common();
91 cholmod_l_finish(cc_);
98 void operator()(
const DiscreteFunctionType& arg, DiscreteFunctionType& dest)
const 106 template<
typename... A>
107 void prepare(A... )
const 111 ccsmat_ = op_.systemMatrix().matrix();
118 inline void finalize()
const 123 cholmod_l_free_sparse(&A_, cc_);
124 cholmod_l_free_dense(&B_, cc_);
125 SuiteSparseQR_free<DofType>(&spqrfactorization_, cc_);
136 void apply(
const DofType*& arg, DofType*& dest)
const 138 const std::size_t dimMat(ccsmat_.N());
140 for(std::size_t k = 0; k != dimMat; ++k)
141 (static_cast<DofType*>(B_->x))[k] = arg[k];
142 cholmod_dense* BTemp = B_;
143 B_ = SuiteSparseQR_qmult<DofType>(0, spqrfactorization_, B_, cc_);
144 cholmod_dense* X = SuiteSparseQR_solve<DofType>(1, spqrfactorization_, B_, cc_);
145 cholmod_l_free_dense(&BTemp, cc_);
147 for(std::size_t k = 0; k != dimMat; ++k)
148 dest[k] = (static_cast<DofType*>(X->x))[k];
149 cholmod_l_free_dense(&X, cc_);
153 std::cout<<std::endl<<
"Solving with SuiteSparseQR"<<std::endl;
154 std::cout<<
"Flops Taken: "<<cc_->SPQR_flopcount<<std::endl;
155 std::cout<<
"Analysis Time: "<<cc_->SPQR_analyze_time<<
" s"<<std::endl;
156 std::cout<<
"Factorize Time: "<<cc_->SPQR_factorize_time<<
" s"<<std::endl;
157 std::cout<<
"Backsolve Time: "<<cc_->SPQR_solve_time<<
" s"<<std::endl;
158 std::cout<<
"Peak Memory Usage: "<<cc_->memory_usage<<
" bytes"<<std::endl;
159 std::cout<<
"Rank Estimate: "<<cc_->SPQR_istat[4]<<std::endl<<std::endl;
169 void apply(
const AdaptiveDiscreteFunction<DiscreteFunctionSpaceType>& arg,
170 AdaptiveDiscreteFunction<DiscreteFunctionSpaceType>& dest)
const 172 const DofType* argPtr(arg.leakPointer());
173 DofType* destPtr(dest.leakPointer());
174 apply(argPtr,destPtr);
183 void apply(
const ISTLBlockVectorDiscreteFunction<DiscreteFunctionSpaceType>& arg,
184 ISTLBlockVectorDiscreteFunction<DiscreteFunctionSpaceType>& dest)
const 187 std::vector<DofType> vecArg(arg.size());
188 std::copy(arg.dbegin(),arg.dend(),vecArg.begin());
189 std::vector<DofType> vecDest(dest.size());
191 const DofType* argDataPtr(vecArg.data());
192 DofType* destDataPtr(vecDest.data());
193 apply(argDataPtr,destDataPtr);
195 std::copy(vecDest.begin(),vecDest.end(),dest.dbegin());
198 inline void printTexInfo(std::ostream& out)
const 200 out<<
"Solver: SPQR direct solver";
204 inline double averageCommTime()
const 209 inline int iterations()
const 217 inline SuiteSparseQR_factorization<DofType>*& getFactorization()
219 return spqrfactorization_;
225 inline CCSMatrixType& getCCSMatrix()
231 const OperatorType& op_;
233 mutable CCSMatrixType ccsmat_;
234 mutable bool isloaded_;
235 mutable cholmod_common* cc_;
236 mutable cholmod_sparse* A_;
237 mutable cholmod_dense* B_;
238 mutable SuiteSparseQR_factorization<DofType>* spqrfactorization_;
241 void decompose()
const 243 const std::size_t dimMat(ccsmat_.N());
244 const int nnz(ccsmat_.getColStart()[dimMat]);
248 bool real(std::is_same<DofType,double>::value);
249 A_ = cholmod_l_allocate_sparse(dimMat, dimMat, nnz, sorted, packed, symmetric,
real, cc_);
251 for(std::size_t k = 0; k != (dimMat+1); ++k)
252 (static_cast<long int *>(A_->p))[k] = ccsmat_.getColStart()[k];
253 for(std::size_t k = 0; k != nnz; ++k)
255 (
static_cast<long int*
>(A_->i))[k] = ccsmat_.getRowIndex()[k];
256 (
static_cast<DofType*
>(A_->x))[k] = ccsmat_.getValues()[k];
259 B_ = cholmod_l_allocate_dense(dimMat, 1, dimMat, A_->xtype, cc_);
261 spqrfactorization_=SuiteSparseQR_factorize<DofType>(SPQR_ORDERING_DEFAULT,SPQR_DEFAULT_TOL,A_,cc_);
268 #endif // #if HAVE_SPQR 270 #endif // #ifndef DUNE_FEM_SPQRSOLVER_HH
BasicParameterReader< std::function< const std::string *(const std::string &, const std::string *) > > ParameterReader
Definition: reader.hh:264
Definition: coordinate.hh:4
static ParameterContainer & container()
Definition: io/parameter.hh:190
double real(const std::complex< Double > &x)
Definition: double.hh:890