DUNE PDELab (2.7)

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"
20#include <dune/istl/solverfactory.hh>
21
22namespace 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>
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);
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>
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>
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
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
Sequential overlapping Schwarz preconditioner.
Definition: overlappingschwarz.hh:752
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
SuperLU(const Matrix &mat, bool verbose=false, bool reusevector=true)
Constructs the SuperLU solver.
Definition: superlu.hh:431
void apply(T *x, T *b)
Apply SuperLu to C arrays.
Definition: superlu.hh:663
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
STL namespace.
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.111.3 (Jul 15, 22:36, 2024)