KASKADE 7 development version
iluprecond.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2020 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef ILUPRECOND_HH
14#define ILUPRECOND_HH
15
16extern "C"
17{
18#include "protos.h"
19#include "ios.h"
20}
21extern "C" void set_arms_pars(io_t* io, int Dscale, int *ipar, double *tolcoef, int *lfil);
22
23#include <boost/timer/timer.hpp>
24#include "dune/istl/preconditioners.hh"
25#include "linalg/triplet.hh"
26
27//---------------------------------------------------------------------
28//---------------------------------------------------------------------
29
30namespace Kaskade
31{
37 template <class Op>
38 class ILUTPreconditioner: public Dune::Preconditioner<typename Op::Range, typename Op::Range>
39 {
40 typedef typename Op::Range Range;
41 typedef Range Domain;
42 typedef typename Op::field_type field_type;
43
44 public:
45 ILUTPreconditioner(Op& op, int lfil=240, double tol=1.0e-2, int verbosity=2)
46 {
47 static char main[] = "main";
48
49 boost::timer::cpu_timer iluTimer;
50 std::cout << "ilut constructor: ";
51 MatrixAsTriplet<field_type> A = op.template get<MatrixAsTriplet<field_type> >();
52 int n = A.nrows(), nnz = A.nnz(), ierr;
53 FILE *flog = stdout;
54
55 csmat = (csptr)Malloc( sizeof(SparMat), main );
56 ierr = COOcs(n, nnz, &A.data[0], &A.cidx[0], &A.ridx[0], csmat);
57 if( ierr != 0 )
58 {
59 printf(" *** ILU error - COOcs code %d csmat=%p\n", ierr, csmat);
60 throw ierr;
61 }
62
63 lu = (iluptr)Malloc(sizeof(ILUSpar), main);
64 ierr = ilut(csmat, lu, lfil, tol, flog);
65 if( ierr != 0 )
66 {
67 printf(" *** PrecondType::ILUT error - ilut code %d lu=%p\n", ierr, lu);
68 throw ierr;
69 }
70
71 xx = (double *)Malloc(n*sizeof(double), main);
72 yy = (double *)Malloc(n*sizeof(double), main);
73
74 if ( verbosity>=2 )
75 std::cout << "PrecondType::ILUT: n=" << n << ", nnz=" << nnz << " dropTol=" << tol << ", fillfac="
76 << 1.0*nnz_ilu(lu)/(nnz+1.0) << ", lfil=" << lfil << ", time="
77 << (double)(iluTimer.elapsed().user)/1e9 << "s\n";
78 }
79
81 {
82 cleanILU(lu);
83 cleanCS(csmat);
84 free(xx);
85 free(yy);
86 }
87
88 virtual void pre (Domain&, Range&) {}
89 virtual void post (Domain&) {}
90
91 virtual void apply (Domain& x, Range const& y)
92 {
93 y.write(yy);
94 lusolC(yy, xx, lu);
95 x.read(xx);
96 }
97
103 virtual Dune::SolverCategory::Category category() const override
104 {
105 return Dune::SolverCategory::sequential;
106 }
107
108
109 private:
110 csptr csmat;
111 iluptr lu;
112 double *xx, *yy;
113 };
114
115 //---------------------------------------------------------------------
116
122 template <class Op>
123 class ILUKPreconditioner: public Dune::Preconditioner<typename Op::Range, typename Op::Range>
124 {
125 typedef typename Op::Range Range;
126 typedef Range Domain;
127 typedef typename Op::field_type field_type;
128
129 public:
130
131 ILUKPreconditioner(Op& op, int fill_lev=3, int verbosity=2)
132 {
133 static char main[] = "main";
134
135 boost::timer::cpu_timer iluTimer;
136 MatrixAsTriplet<field_type> A = op.template get<MatrixAsTriplet<field_type> >();
137 int n = A.nrows(), nnz = A.nnz(), ierr;
138 FILE *flog = stdout;
139
140 csmat = (csptr)Malloc( sizeof(SparMat), main );
141 ierr = COOcs(n, nnz, &A.data[0], &A.cidx[0], &A.ridx[0], csmat);
142 if( ierr != 0 )
143 {
144 printf(" *** ILU error - COOcs code %d csmat=%p\n", ierr, csmat);
145 throw ierr;
146 }
147
148 lu = (iluptr)Malloc(sizeof(ILUSpar), main);
149 ierr = ilukC(fill_lev, csmat, lu, flog);
150 if( ierr != 0 )
151 {
152 printf(" *** PrecondType::ILUK error - ilut code %d lu=%p\n", ierr, lu);
153 throw ierr;
154 }
155
156 xx = (double *)Malloc(n*sizeof(double), main);
157 yy = (double *)Malloc(n*sizeof(double), main);
158
159 if ( verbosity>=2 )
160 {
161 std::cout << "PrecondType::ILUK: n=" << n << ", nnz=" << nnz << ", fillfac="
162 << 1.0*nnz_ilu(lu)/(nnz+1.0) << ", fill_lev="
163 << fill_lev << ", time=" << (double)(iluTimer.elapsed().user)/1e9 << "s\n";
164 }
165 }
166
168 {
169 cleanILU(lu);
170 cleanCS(csmat);
171 free(xx);
172 free(yy);
173 }
174
175 virtual void pre (Domain&, Range&) {}
176 virtual void post (Domain&) {}
177
178 virtual void apply (Domain& x, Range const& y)
179 {
180 y.write(yy);
181 lusolC(yy, xx, lu);
182 x.read(xx);
183 }
184
190 virtual Dune::SolverCategory::Category category() const override
191 {
192 return Dune::SolverCategory::sequential;
193 }
194
195 private:
196 csptr csmat;
197 iluptr lu;
198 double *xx, *yy;
199 };
200 //---------------------------------------------------------------------
201
207 template <class Op>
208 class ARMSPreconditioner: public Dune::Preconditioner<typename Op::Range, typename Op::Range>
209 {
210 typedef typename Op::Range Range;
211 typedef Range Domain;
212 typedef typename Op::field_type field_type;
213
214 public:
215 ARMSPreconditioner(Op& op, int lfil=4, double tol=1.0e-2, int lev_reord=1, double tolind = 0.2, int verbosity=2)
216 {
217 static char main[] = "main";
218 static char main2[] = "main:ArmsSt";
219
220 boost::timer::cpu_timer iluTimer;
221 MatrixAsTriplet<field_type> A = op.template get<MatrixAsTriplet<field_type> >();
222 int n = A.nrows(), nnz = A.nnz(), ierr, diagscal = 1;
223
224 int lfil_arr[7];
225 double droptol[7], dropcoef[7];
226 int ipar[18];
227 io_t io;
228 FILE *flog = stdout;
229
230 csmat = (csptr)Malloc( sizeof(SparMat), main );
231 ierr = COOcs(n, nnz, &A.data[0], &A.cidx[0], &A.ridx[0], csmat);
232 if( ierr != 0 )
233 {
234 printf(" *** PrecondType::ARMS error - COOcs code %d csmat=%p\n", ierr, csmat);
235 throw ierr;
236 }
237
238 memset(&io,0,sizeof(io));
239 io.perm_type = 0;
240 io.Bsize = 400;
241 set_arms_pars(&io, diagscal, ipar, dropcoef, lfil_arr);
242 for (int j=0; j<7; j++)
243 {
244 lfil_arr[j] = lfil*((int) nnz/n);
245 droptol[j] = tol*dropcoef[j];
246 }
247 ipar[1] = lev_reord;
248 ArmsSt = (arms) Malloc(sizeof(armsMat),main2);
249 setup_arms(ArmsSt);
250
251 ierr = arms2(csmat, ipar, droptol, lfil_arr, tolind, ArmsSt, flog);
252 if (ierr != 0)
253 {
254 printf(" *** PrecondType::ARMS error - arms2 code %d ArmsSt=%p\n", ierr, ArmsSt);
255 throw ierr;
256 }
257
258 yy = (double *)Malloc(n*sizeof(double), main);
259
260 if (verbosity>=2)
261 std::cout << "PrecondType::ARMS: n=" << n << ", nnz=" << nnz << ", dropTol=" << tol
262 << ", lev_reord=" << lev_reord
263 << ", lfil=" << lfil << ", time=" << (double)(iluTimer.elapsed().user)/1e9 << "s\n";
264 }
265
267 {
268 cleanARMS(ArmsSt);
269 cleanCS(csmat);
270 free(yy);
271 }
272
273 virtual void pre (Domain&, Range&) {}
274 virtual void post (Domain&) {}
275
276 virtual void apply (Domain& x, Range const& y)
277 {
278 y.write(yy);
279 armsol2(yy, ArmsSt);
280 x.read(yy);
281 }
282
288 virtual Dune::SolverCategory::Category category() const override
289 {
290 return Dune::SolverCategory::sequential;
291 }
292
293 private:
294 csptr csmat;
295 arms ArmsSt;
296 double *yy;
297 };
298
299} // namespace Kaskade
300#endif
virtual void apply(Domain &x, Range const &y)
Definition: iluprecond.hh:276
virtual Dune::SolverCategory::Category category() const override
returns the category of the operator
Definition: iluprecond.hh:288
virtual void post(Domain &)
Definition: iluprecond.hh:274
ARMSPreconditioner(Op &op, int lfil=4, double tol=1.0e-2, int lev_reord=1, double tolind=0.2, int verbosity=2)
Definition: iluprecond.hh:215
virtual void pre(Domain &, Range &)
Definition: iluprecond.hh:273
virtual void post(Domain &)
Definition: iluprecond.hh:176
ILUKPreconditioner(Op &op, int fill_lev=3, int verbosity=2)
Definition: iluprecond.hh:131
virtual void pre(Domain &, Range &)
Definition: iluprecond.hh:175
virtual Dune::SolverCategory::Category category() const override
returns the category of the operator
Definition: iluprecond.hh:190
virtual void apply(Domain &x, Range const &y)
Definition: iluprecond.hh:178
virtual void apply(Domain &x, Range const &y)
Definition: iluprecond.hh:91
virtual void pre(Domain &, Range &)
Definition: iluprecond.hh:88
virtual void post(Domain &)
Definition: iluprecond.hh:89
virtual Dune::SolverCategory::Category category() const override
returns the category of the operator
Definition: iluprecond.hh:103
ILUTPreconditioner(Op &op, int lfil=240, double tol=1.0e-2, int verbosity=2)
Definition: iluprecond.hh:45
size_t nnz() const
Definition: triplet.hh:254
SparseIndexInt nrows() const
Returns number of rows (computes them, if not known)
Definition: triplet.hh:202
std::vector< SparseIndexInt > ridx
row indices
Definition: triplet.hh:669
std::vector< SparseIndexInt > cidx
column indices
Definition: triplet.hh:671
std::vector< Scalar > data
data
Definition: triplet.hh:673
void set_arms_pars(io_t *io, int Dscale, int *ipar, double *tolcoef, int *lfil)