Dune Core Modules (2.7.1)

superlu.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_ISTL_SUPERLU_HH
4 #define DUNE_ISTL_SUPERLU_HH
5 
6 #if HAVE_SUPERLU
7 
8 #include "superlufunctions.hh"
9 #include "solvers.hh"
10 #include "supermatrix.hh"
11 #include <algorithm>
12 #include <functional>
13 #include "bcrsmatrix.hh"
14 #include "bvector.hh"
15 #include "istlexception.hh"
16 #include <dune/common/fmatrix.hh>
17 #include <dune/common/fvector.hh>
19 #include <dune/istl/solvertype.hh>
20 #include <dune/istl/solverfactory.hh>
21 
22 namespace Dune
23 {
24 
35  template<class M, class T, class TM, class TD, class TA>
36  class SeqOverlappingSchwarz;
37 
38  template<class T, bool tag>
39  struct SeqOverlappingSchwarzAssemblerHelper;
40 
41  template<class T>
42  struct SuperLUSolveChooser
43  {};
44 
45  template<class T>
46  struct SuperLUDenseMatChooser
47  {};
48 
49  template<class T>
50  struct SuperLUQueryChooser
51  {};
52 
53  template<class T>
54  struct QuerySpaceChooser
55  {};
56 
57 #if HAVE_SLU_SDEFS_H
58  template<>
59  struct SuperLUDenseMatChooser<float>
60  {
61  static void create(SuperMatrix *mat, int n, int m, float *dat, int n1,
62  Stype_t stype, Dtype_t dtype, Mtype_t mtype)
63  {
64  sCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);
65 
66  }
67 
68  static void destroy(SuperMatrix*)
69  {}
70 
71  };
72  template<>
73  struct SuperLUSolveChooser<float>
74  {
75  static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
76  char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,
77  void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
78  float *rpg, float *rcond, float *ferr, float *berr,
79  mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
80  {
81 #if SUPERLU_MIN_VERSION_5
82  GlobalLU_t gLU;
83  sgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
84  L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
85  &gLU, memusage, stat, info);
86 #else
87  sgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
88  L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
89  memusage, stat, info);
90 #endif
91  }
92  };
93 
94  template<>
95  struct QuerySpaceChooser<float>
96  {
97  static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
98  {
99  sQuerySpace(L,U,memusage);
100  }
101  };
102 
103 #endif
104 
105 #if HAVE_SLU_DDEFS_H
106 
107  template<>
108  struct SuperLUDenseMatChooser<double>
109  {
110  static void create(SuperMatrix *mat, int n, int m, double *dat, int n1,
111  Stype_t stype, Dtype_t dtype, Mtype_t mtype)
112  {
113  dCreate_Dense_Matrix(mat, n, m, dat, n1, stype, dtype, mtype);
114 
115  }
116 
117  static void destroy(SuperMatrix * /* mat */)
118  {}
119  };
120  template<>
121  struct SuperLUSolveChooser<double>
122  {
123  static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
124  char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,
125  void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
126  double *rpg, double *rcond, double *ferr, double *berr,
127  mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
128  {
129 #if SUPERLU_MIN_VERSION_5
130  GlobalLU_t gLU;
131  dgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
132  L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
133  &gLU, memusage, stat, info);
134 #else
135  dgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
136  L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
137  memusage, stat, info);
138 #endif
139  }
140  };
141 
142  template<>
143  struct QuerySpaceChooser<double>
144  {
145  static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
146  {
147  dQuerySpace(L,U,memusage);
148  }
149  };
150 #endif
151 
152 #if HAVE_SLU_ZDEFS_H
153  template<>
154  struct SuperLUDenseMatChooser<std::complex<double> >
155  {
156  static void create(SuperMatrix *mat, int n, int m, std::complex<double> *dat, int n1,
157  Stype_t stype, Dtype_t dtype, Mtype_t mtype)
158  {
159  zCreate_Dense_Matrix(mat, n, m, reinterpret_cast<doublecomplex*>(dat), n1, stype, dtype, mtype);
160 
161  }
162 
163  static void destroy(SuperMatrix*)
164  {}
165  };
166 
167  template<>
168  struct SuperLUSolveChooser<std::complex<double> >
169  {
170  static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
171  char *equed, double *R, double *C, SuperMatrix *L, SuperMatrix *U,
172  void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
173  double *rpg, double *rcond, double *ferr, double *berr,
174  mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
175  {
176 #if SUPERLU_MIN_VERSION_5
177  GlobalLU_t gLU;
178  zgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
179  L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
180  &gLU, memusage, stat, info);
181 #else
182  zgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
183  L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
184  memusage, stat, info);
185 #endif
186  }
187  };
188 
189  template<>
190  struct QuerySpaceChooser<std::complex<double> >
191  {
192  static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
193  {
194  zQuerySpace(L,U,memusage);
195  }
196  };
197 #endif
198 
199 #if HAVE_SLU_CDEFS_H
200  template<>
201  struct SuperLUDenseMatChooser<std::complex<float> >
202  {
203  static void create(SuperMatrix *mat, int n, int m, std::complex<float> *dat, int n1,
204  Stype_t stype, Dtype_t dtype, Mtype_t mtype)
205  {
206  cCreate_Dense_Matrix(mat, n, m, reinterpret_cast< ::complex*>(dat), n1, stype, dtype, mtype);
207 
208  }
209 
210  static void destroy(SuperMatrix* /* mat */)
211  {}
212  };
213 
214  template<>
215  struct SuperLUSolveChooser<std::complex<float> >
216  {
217  static void solve(superlu_options_t *options, SuperMatrix *mat, int *perm_c, int *perm_r, int *etree,
218  char *equed, float *R, float *C, SuperMatrix *L, SuperMatrix *U,
219  void *work, int lwork, SuperMatrix *B, SuperMatrix *X,
220  float *rpg, float *rcond, float *ferr, float *berr,
221  mem_usage_t *memusage, SuperLUStat_t *stat, int *info)
222  {
223 #if SUPERLU_MIN_VERSION_5
224  GlobalLU_t gLU;
225  cgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
226  L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
227  &gLU, memusage, stat, info);
228 #else
229  cgssvx(options, mat, perm_c, perm_r, etree, equed, R, C,
230  L, U, work, lwork, B, X, rpg, rcond, ferr, berr,
231  memusage, stat, info);
232 #endif
233  }
234  };
235 
236  template<>
237  struct QuerySpaceChooser<std::complex<float> >
238  {
239  static void querySpace(SuperMatrix* L, SuperMatrix* U, mem_usage_t* memusage)
240  {
241  cQuerySpace(L,U,memusage);
242  }
243  };
244 #endif
245 
246  namespace Impl
247  {
248  template<class M>
249  struct SuperLUVectorChooser
250  {};
251 
252  template<typename T, typename A, int n, int m>
253  struct SuperLUVectorChooser<BCRSMatrix<FieldMatrix<T,n,m>,A > >
254  {
256  using domain_type = BlockVector<
257  FieldVector<T,m>,
258  typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,m> > >;
260  using range_type = BlockVector<
261  FieldVector<T,n>,
262  typename std::allocator_traits<A>::template rebind_alloc<FieldVector<T,n> > >;
263  };
264 
265  template<typename T, typename A>
266  struct SuperLUVectorChooser<BCRSMatrix<T,A> >
267  {
269  using domain_type = BlockVector<T, A>;
271  using range_type = BlockVector<T, A>;
272  };
273  }
274 
288  template<typename M>
289  class SuperLU
290  : public InverseOperator<
291  typename Impl::SuperLUVectorChooser<M>::domain_type,
292  typename Impl::SuperLUVectorChooser<M>::range_type >
293  {
294  using T = typename M::field_type;
295  public:
297  using Matrix = M;
298  using matrix_type = M;
302  typedef SuperMatrixInitializer<Matrix> MatrixInitializer;
304  using domain_type = typename Impl::SuperLUVectorChooser<M>::domain_type;
306  using range_type = typename Impl::SuperLUVectorChooser<M>::range_type;
307 
310  {
311  return SolverCategory::Category::sequential;
312  }
313 
328  explicit SuperLU(const Matrix& mat, bool verbose=false,
329  bool reusevector=true);
336  SuperLU();
337 
338  ~SuperLU();
339 
344 
348  void apply (domain_type& x, range_type& b, double reduction, InverseOperatorResult& res)
349  {
350  DUNE_UNUSED_PARAMETER(reduction);
351  apply(x,b,res);
352  }
353 
357  void apply(T* x, T* b);
358 
360  void setMatrix(const Matrix& mat);
361 
362  typename SuperLUMatrix::size_type nnz() const
363  {
364  return mat.nnz();
365  }
366 
367  template<class S>
368  void setSubMatrix(const Matrix& mat, const S& rowIndexSet);
369 
370  void setVerbosity(bool v);
371 
376  void free();
377 
378  const char* name() { return "SuperLU"; }
379  private:
380  template<class Mat,class X, class TM, class TD, class T1>
381  friend class SeqOverlappingSchwarz;
382  friend struct SeqOverlappingSchwarzAssemblerHelper<SuperLU<Matrix>,true>;
383 
384  SuperLUMatrix& getInternalMatrix() { return mat; }
385 
387  void decompose();
388 
389  SuperLUMatrix mat;
390  SuperMatrix L, U, B, X;
391  int *perm_c, *perm_r, *etree;
392  typename GetSuperLUType<T>::float_type *R, *C;
393  T *bstore;
394  superlu_options_t options;
395  char equed;
396  void *work;
397  int lwork;
398  bool first, verbose, reusevector;
399  };
400 
401  template<typename M>
402  SuperLU<M>
403  ::~SuperLU()
404  {
405  if(mat.N()+mat.M()>0)
406  free();
407  }
408 
409  template<typename M>
411  {
412  delete[] perm_c;
413  delete[] perm_r;
414  delete[] etree;
415  delete[] R;
416  delete[] C;
417  if(lwork>=0) {
418  Destroy_SuperNode_Matrix(&L);
419  Destroy_CompCol_Matrix(&U);
420  }
421  lwork=0;
422  if(!first && reusevector) {
423  SUPERLU_FREE(B.Store);
424  SUPERLU_FREE(X.Store);
425  }
426  mat.free();
427  }
428 
429  template<typename M>
430  SuperLU<M>
431  ::SuperLU(const Matrix& mat_, bool verbose_, bool reusevector_)
432  : work(0), lwork(0), first(true), verbose(verbose_),
433  reusevector(reusevector_)
434  {
435  setMatrix(mat_);
436 
437  }
438  template<typename M>
440  : work(0), lwork(0),verbose(false),
441  reusevector(false)
442  {}
443  template<typename M>
444  void SuperLU<M>::setVerbosity(bool v)
445  {
446  verbose=v;
447  }
448 
449  template<typename M>
450  void SuperLU<M>::setMatrix(const Matrix& mat_)
451  {
452  if(mat.N()+mat.M()>0) {
453  free();
454  }
455  lwork=0;
456  work=0;
457  //a=&mat_;
458  mat=mat_;
459  decompose();
460  }
461 
462  template<typename M>
463  template<class S>
464  void SuperLU<M>::setSubMatrix(const Matrix& mat_,
465  const S& mrs)
466  {
467  if(mat.N()+mat.M()>0) {
468  free();
469  }
470  lwork=0;
471  work=0;
472  //a=&mat_;
473  mat.setMatrix(mat_,mrs);
474  decompose();
475  }
476 
477  template<typename M>
478  void SuperLU<M>::decompose()
479  {
480 
481  first = true;
482  perm_c = new int[mat.M()];
483  perm_r = new int[mat.N()];
484  etree = new int[mat.M()];
485  R = new typename GetSuperLUType<T>::float_type[mat.N()];
486  C = new typename GetSuperLUType<T>::float_type[mat.M()];
487 
488  set_default_options(&options);
489  // Do the factorization
490  B.ncol=0;
491  B.Stype=SLU_DN;
492  B.Dtype=GetSuperLUType<T>::type;
493  B.Mtype= SLU_GE;
494  DNformat fakeFormat;
495  fakeFormat.lda=mat.N();
496  B.Store=&fakeFormat;
497  X.Stype=SLU_DN;
498  X.Dtype=GetSuperLUType<T>::type;
499  X.Mtype= SLU_GE;
500  X.ncol=0;
501  X.Store=&fakeFormat;
502 
503  typename GetSuperLUType<T>::float_type rpg, rcond, ferr=1e10, berr=1e10;
504  int info;
505  mem_usage_t memusage;
506  SuperLUStat_t stat;
507 
508  StatInit(&stat);
509  SuperLUSolveChooser<T>::solve(&options, &static_cast<SuperMatrix&>(mat), perm_c, perm_r, etree, &equed, R, C,
510  &L, &U, work, lwork, &B, &X, &rpg, &rcond, &ferr,
511  &berr, &memusage, &stat, &info);
512 
513  if(verbose) {
514  dinfo<<"LU factorization: dgssvx() returns info "<< info<<std::endl;
515 
516  auto nSuperLUCol = static_cast<SuperMatrix&>(mat).ncol;
517 
518  if ( info == 0 || info == nSuperLUCol+1 ) {
519 
520  if ( options.PivotGrowth )
521  dinfo<<"Recip. pivot growth = "<<rpg<<std::endl;
522  if ( options.ConditionNumber )
523  dinfo<<"Recip. condition number = %e\n"<< rcond<<std::endl;
524  SCformat* Lstore = (SCformat *) L.Store;
525  NCformat* Ustore = (NCformat *) U.Store;
526  dinfo<<"No of nonzeros in factor L = "<< Lstore->nnz<<std::endl;
527  dinfo<<"No of nonzeros in factor U = "<< Ustore->nnz<<std::endl;
528  dinfo<<"No of nonzeros in L+U = "<< Lstore->nnz + Ustore->nnz - nSuperLUCol<<std::endl;
529  QuerySpaceChooser<T>::querySpace(&L, &U, &memusage);
530  dinfo<<"L\\U MB "<<memusage.for_lu/1e6<<" \ttotal MB needed "<<memusage.total_needed/1e6
531  <<" \texpansions ";
532  std::cout<<stat.expansions<<std::endl;
533 
534  } else if ( info > 0 && lwork == -1 ) { // Memory allocation failed
535  dinfo<<"** Estimated memory: "<< info - nSuperLUCol<<std::endl;
536  }
537  if ( options.PrintStat ) StatPrint(&stat);
538  }
539  StatFree(&stat);
540  /*
541  NCformat* Ustore = (NCformat *) U.Store;
542  int k=0;
543  dPrint_CompCol_Matrix("U", &U);
544  for(int i=0; i < U.ncol; ++i, ++k){
545  std::cout<<i<<": ";
546  for(int c=Ustore->colptr[i]; c < Ustore->colptr[i+1]; ++c)
547  //if(Ustore->rowind[c]==i)
548  std::cout<<Ustore->rowind[c]<<"->"<<((double*)Ustore->nzval)[c]<<" ";
549  if(k==0){
550  //
551  k=-1;
552  }std::cout<<std::endl;
553  }
554  dPrint_SuperNode_Matrix("L", &L);
555  for(int i=0; i < U.ncol; ++i, ++k){
556  std::cout<<i<<": ";
557  for(int c=Ustore->colptr[i]; c < Ustore->colptr[i+1]; ++c)
558  //if(Ustore->rowind[c]==i)
559  std::cout<<Ustore->rowind[c]<<"->"<<((double*)Ustore->nzval)[c]<<" ";
560  if(k==0){
561  //
562  k=-1;
563  }std::cout<<std::endl;
564  } */
565  options.Fact = FACTORED;
566  }
567 
568  template<typename M>
569  void SuperLU<M>
571  {
572  if (mat.N() != b.dim())
573  DUNE_THROW(ISTLError, "Size of right-hand-side vector b does not match the number of matrix rows!");
574  if (mat.M() != x.dim())
575  DUNE_THROW(ISTLError, "Size of solution vector x does not match the number of matrix columns!");
576  if (mat.M()+mat.N()==0)
577  DUNE_THROW(ISTLError, "Matrix of SuperLU is null!");
578 
579  SuperMatrix* mB = &B;
580  SuperMatrix* mX = &X;
581  SuperMatrix rB, rX;
582  if (reusevector) {
583  if(first) {
584  SuperLUDenseMatChooser<T>::create(&B, (int)mat.N(), 1, reinterpret_cast<T*>(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
585  SuperLUDenseMatChooser<T>::create(&X, (int)mat.N(), 1, reinterpret_cast<T*>(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
586  first=false;
587  }else{
588  ((DNformat*)B.Store)->nzval=&b[0];
589  ((DNformat*)X.Store)->nzval=&x[0];
590  }
591  } else {
592  SuperLUDenseMatChooser<T>::create(&rB, (int)mat.N(), 1, reinterpret_cast<T*>(&b[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
593  SuperLUDenseMatChooser<T>::create(&rX, (int)mat.N(), 1, reinterpret_cast<T*>(&x[0]), (int)mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
594  mB = &rB;
595  mX = &rX;
596  }
597  typename GetSuperLUType<T>::float_type rpg, rcond, ferr=1e10, berr;
598  int info;
599  mem_usage_t memusage;
600  SuperLUStat_t stat;
601  /* Initialize the statistics variables. */
602  StatInit(&stat);
603  /*
604  range_type d=b;
605  a->usmv(-1, x, d);
606 
607  double def0=d.two_norm();
608  */
609 #ifdef SUPERLU_MIN_VERSION_4_3
610  options.IterRefine=SLU_DOUBLE;
611 #else
612  options.IterRefine=DOUBLE;
613 #endif
614 
615  SuperLUSolveChooser<T>::solve(&options, &static_cast<SuperMatrix&>(mat), perm_c, perm_r, etree, &equed, R, C,
616  &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,
617  &memusage, &stat, &info);
618 
619  res.iterations=1;
620 
621  /*
622  if(options.Equil==YES)
623  // undo scaling of right hand side
624  std::transform(reinterpret_cast<T*>(&b[0]),reinterpret_cast<T*>(&b[0])+mat.M(),
625  C, reinterpret_cast<T*>(&d[0]), std::divides<T>());
626  else
627  d=b;
628  a->usmv(-1, x, d);
629  res.reduction=d.two_norm()/def0;
630  res.conv_rate = res.reduction;
631  res.converged=(res.reduction<1e-10||d.two_norm()<1e-18);
632  */
633  res.converged=true;
634 
635  if(verbose) {
636 
637  dinfo<<"Triangular solve: dgssvx() returns info "<< info<<std::endl;
638 
639  auto nSuperLUCol = static_cast<SuperMatrix&>(mat).ncol;
640 
641  if ( info == 0 || info == nSuperLUCol+1 ) {
642 
643  if ( options.IterRefine ) {
644  std::cout<<"Iterative Refinement: steps="
645  <<stat.RefineSteps<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
646  }else
647  std::cout<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
648  } else if ( info > 0 && lwork == -1 ) { // Memory allocation failed
649  std::cout<<"** Estimated memory: "<< info - nSuperLUCol<<" bytes"<<std::endl;
650  }
651 
652  if ( options.PrintStat ) StatPrint(&stat);
653  }
654  StatFree(&stat);
655  if (!reusevector) {
656  SUPERLU_FREE(rB.Store);
657  SUPERLU_FREE(rX.Store);
658  }
659  }
660 
661  template<typename M>
662  void SuperLU<M>
663  ::apply(T* x, T* b)
664  {
665  if(mat.N()+mat.M()==0)
666  DUNE_THROW(ISTLError, "Matrix of SuperLU is null!");
667 
668  SuperMatrix* mB = &B;
669  SuperMatrix* mX = &X;
670  SuperMatrix rB, rX;
671  if (reusevector) {
672  if(first) {
673  SuperLUDenseMatChooser<T>::create(&B, mat.N(), 1, b, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
674  SuperLUDenseMatChooser<T>::create(&X, mat.N(), 1, x, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
675  first=false;
676  }else{
677  ((DNformat*) B.Store)->nzval=b;
678  ((DNformat*)X.Store)->nzval=x;
679  }
680  } else {
681  SuperLUDenseMatChooser<T>::create(&rB, mat.N(), 1, b, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
682  SuperLUDenseMatChooser<T>::create(&rX, mat.N(), 1, x, mat.N(), SLU_DN, GetSuperLUType<T>::type, SLU_GE);
683  mB = &rB;
684  mX = &rX;
685  }
686 
687  typename GetSuperLUType<T>::float_type rpg, rcond, ferr=1e10, berr;
688  int info;
689  mem_usage_t memusage;
690  SuperLUStat_t stat;
691  /* Initialize the statistics variables. */
692  StatInit(&stat);
693 
694 #ifdef SUPERLU_MIN_VERSION_4_3
695  options.IterRefine=SLU_DOUBLE;
696 #else
697  options.IterRefine=DOUBLE;
698 #endif
699 
700  SuperLUSolveChooser<T>::solve(&options, &static_cast<SuperMatrix&>(mat), perm_c, perm_r, etree, &equed, R, C,
701  &L, &U, work, lwork, mB, mX, &rpg, &rcond, &ferr, &berr,
702  &memusage, &stat, &info);
703 
704  if(verbose) {
705  dinfo<<"Triangular solve: dgssvx() returns info "<< info<<std::endl;
706 
707  auto nSuperLUCol = static_cast<SuperMatrix&>(mat).ncol;
708 
709  if ( info == 0 || info == nSuperLUCol+1 ) { // Factorization has succeeded
710 
711  if ( options.IterRefine ) {
712  dinfo<<"Iterative Refinement: steps="
713  <<stat.RefineSteps<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
714  }else
715  dinfo<<" FERR="<<ferr<<" BERR="<<berr<<std::endl;
716  } else if ( info > 0 && lwork == -1 ) { // Memory allocation failed
717  dinfo<<"** Estimated memory: "<< info - nSuperLUCol<<" bytes"<<std::endl;
718  }
719  if ( options.PrintStat ) StatPrint(&stat);
720  }
721 
722  StatFree(&stat);
723  if (!reusevector) {
724  SUPERLU_FREE(rB.Store);
725  SUPERLU_FREE(rX.Store);
726  }
727  }
730  template<typename T, typename A>
731  struct IsDirectSolver<SuperLU<BCRSMatrix<T,A> > >
732  {
733  enum { value=true};
734  };
735 
736  template<typename T, typename A>
737  struct StoresColumnCompressed<SuperLU<BCRSMatrix<T,A> > >
738  {
739  enum { value = true };
740  };
741 
742  struct SuperLUCreator {
743  template<class> struct isValidBlock : std::false_type{};
744  template<int k> struct isValidBlock<Dune::FieldVector<double,k>> : std::true_type{};
745  template<int k> struct isValidBlock<Dune::FieldVector<std::complex<double>,k>> : std::true_type{};
746  template<typename TL, typename M>
747  std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
748  typename Dune::TypeListElement<2, TL>::type>>
749  operator() (TL /*tl*/, const M& mat, const Dune::ParameterTree& config,
750  std::enable_if_t<isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
751  {
752  int verbose = config.get("verbose", 0);
753  return std::make_shared<Dune::SuperLU<M>>(mat,verbose);
754  }
755 
756  // second version with SFINAE to validate the template parameters of SuperLU
757  template<typename TL, typename M>
758  std::shared_ptr<Dune::InverseOperator<typename Dune::TypeListElement<1, TL>::type,
759  typename Dune::TypeListElement<2, TL>::type>>
760  operator() (TL /*tl*/, const M& /*mat*/, const Dune::ParameterTree& /*config*/,
761  std::enable_if_t<!isValidBlock<typename Dune::TypeListElement<1, TL>::type::block_type>::value,int> = 0) const
762  {
763  DUNE_THROW(UnsupportedType,
764  "Unsupported Type in SuperLU (only double and std::complex<double> supported)");
765  }
766  };
767  template<> struct SuperLUCreator::isValidBlock<double> : std::true_type{};
768  template<> struct SuperLUCreator::isValidBlock<std::complex<double>> : std::true_type{};
769 
770  DUNE_REGISTER_DIRECT_SOLVER("superlu", SuperLUCreator());
771 } // end namespace DUNE
772 
773 // undefine macros from SuperLU's slu_util.h
774 #undef FIRSTCOL_OF_SNODE
775 #undef NO_MARKER
776 #undef NUM_TEMPV
777 #undef USER_ABORT
778 #undef USER_MALLOC
779 #undef SUPERLU_MALLOC
780 #undef USER_FREE
781 #undef SUPERLU_FREE
782 #undef CHECK_MALLOC
783 #undef SUPERLU_MAX
784 #undef SUPERLU_MIN
785 #undef L_SUB_START
786 #undef L_SUB
787 #undef L_NZ_START
788 #undef L_FST_SUPC
789 #undef U_NZ_START
790 #undef U_SUB
791 #undef TRUE
792 #undef FALSE
793 #undef EMPTY
794 #undef NODROP
795 #undef DROP_BASIC
796 #undef DROP_PROWS
797 #undef DROP_COLUMN
798 #undef DROP_AREA
799 #undef DROP_SECONDARY
800 #undef DROP_DYNAMIC
801 #undef DROP_INTERP
802 #undef MILU_ALPHA
803 
804 #endif // HAVE_SUPERLU
805 #endif // DUNE_SUPERLU_HH
Implementation of the BCRSMatrix class.
This file implements a vector space as a tensor product of a given vector space. The number of compon...
A sparse block matrix with compressed row storage.
Definition: bcrsmatrix.hh:426
derive error class from the base class in common
Definition: istlexception.hh:16
Abstract base class for all solvers.
Definition: solver.hh:97
A generic dynamic dense matrix.
Definition: matrix.hh:558
size_type M() const
Return the number of columns.
Definition: matrix.hh:696
size_type N() const
Return the number of rows.
Definition: matrix.hh:691
Hierarchical structure of string parameters.
Definition: parametertree.hh:35
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: parametertree.cc:183
SuperLu Solver.
Definition: superlu.hh:293
void apply(domain_type &x, range_type &b, double reduction, InverseOperatorResult &res)
apply inverse operator, with given convergence criteria.
Definition: superlu.hh:348
typename Impl::SuperLUVectorChooser< M >::range_type range_type
The type of the range of the solver.
Definition: superlu.hh:306
SuperMatrixInitializer< Matrix > MatrixInitializer
Type of an associated initializer class.
Definition: superlu.hh:302
M Matrix
The matrix type.
Definition: superlu.hh:297
typename Impl::SuperLUVectorChooser< M >::domain_type domain_type
The type of the domain of the solver.
Definition: superlu.hh:304
virtual SolverCategory::Category category() const
Category of the solver (see SolverCategory::Category)
Definition: superlu.hh:309
Dune::SuperLUMatrix< Matrix > SuperLUMatrix
The corresponding SuperLU Matrix type.
Definition: superlu.hh:300
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition: unused.hh:25
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
void apply(domain_type &x, range_type &b, InverseOperatorResult &res)
Apply inverse operator,.
Definition: superlu.hh:570
void free()
free allocated space.
Definition: superlu.hh:410
SuperLU()
Empty default constructor.
Definition: superlu.hh:439
void setMatrix(const Matrix &mat)
Initialize data from given matrix.
Definition: superlu.hh:450
DInfoType dinfo(std::cout)
Stream for informative output.
Definition: stdstreams.hh:138
Dune namespace.
Definition: alignedallocator.hh:14
Implementations of the inverse operator interface.
Templates characterizing the type of a solver.
Standard Dune debug streams.
Statistics about the application of an inverse operator.
Definition: solver.hh:46
int iterations
Number of iterations.
Definition: solver.hh:65
bool converged
True if convergence criterion has been met.
Definition: solver.hh:71
Category
Definition: solvercategory.hh:21
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 9, 22:29, 2024)