1#ifndef OPM_MIXED_PREC_HEADER_INCLUDED
2#define OPM_MIXED_PREC_HEADER_INCLUDED
14template <
class M,
class X,
class Y>
20 static constexpr auto block_size = domain_type::block_type::dimension;
30 int nnz = A.nonzeroes();
31 double_data_ = &A[0][0][0][0];
39 int *rows = mixed_matrix_->
rowptr;
40 int *cols = mixed_matrix_->
colidx;
45 for(
auto row=A.begin(); row!=A.end(); row++)
47 for(
auto col = row->begin(); col != row->end(); ++col)
49 cols[icol++] = col.index();
83 void apply ([[maybe_unused]] X& x, [[maybe_unused]]
const Y& y)
override;
86 Dune::SolverCategory::Category
category()
const override {
return Dune::SolverCategory::sequential; };
90 void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& y)
override {};
91 void post ([[maybe_unused]] X& x)
override {};
95 double const *double_data_;
107 void matvec_mul(
double *y,
float const *A,
double const * x);
115 void matvec_mulsub(
double *y,
float const *A,
double const * x);
121 void mat_copy(
double *C,
double const * A);
128 void mat_inv(
double *invA,
const double *A);
135 void mat_mulsub(
double *C,
double const *A,
double const * B);
141 void mat_rmul(
double *C,
double const *A);
147 void mat_lmul(
double const *A,
double *C);
158template <
class M,
class X,
class Y>
163 constexpr int N = block_size;
164 constexpr int NN=N*N;
167 for(
int k=0;k<nnz_;k++)
169 for(
int i=0;i<N;i++)
for(
int j=0;j<N;j++) B[N*j+i] = double_data_[NN*k + N*i + j];
170 for(
int i=0;i<NN;i++) mixed_matrix_->dbl[NN*k + i] = B[i];
173 if constexpr(N==1){OPM_THROW(std::invalid_argument,
"MixedMatrixPreconditioner::update does not support block size == 1!\n");}
184 int const nrows = A->
nrows;
188 for(
int i=0;i<nrows;i++)
190 for (
int k=A->
rowptr[i];k<A->rowptr[i+1];k++)
196 mat_copy(L->
dbl + NN*kL, A->
dbl + NN*k);
201 mat_copy(D->
dbl + NN*i, A->
dbl + NN*k);
205 mat_copy(U->
dbl + NN*kU, A->
dbl + NN*k);
216 int next = prec_->offsets[idx][0];
218 for(
int i=0;i<A->nrows;i++)
220 mat_inv(scale,D->
dbl+i*NN);
221 mat_copy(D->
dbl+NN*i, scale);
222 for(
int k=L->
rowptr[i];k<L->rowptr[i+1];k++)
225 mat_rmul(L->
dbl+k*NN,scale);
229 mat_mulsub(D->
dbl+j*NN,L->
dbl+k*NN,U->
dbl+k*NN);
233 while(next<U->rowptr[i+1])
235 int ij = prec_->offsets[idx][0];
236 int ik = prec_->offsets[idx][1];
237 int jk = prec_->offsets[idx][2];
240 mat_mulsub(U->
dbl+jk*NN,L->
dbl+ij*NN,U->
dbl+ik*NN);
241 mat_mulsub(L->
dbl+jk*NN,L->
dbl+ik*NN,U->
dbl+ij*NN);
244 next=prec_->offsets[++idx][0];
247 for(
int k=L->
rowptr[i];k<L->rowptr[i+1];k++)
250 mat_lmul(scale,U->
dbl+k*NN);
267template <
class M,
class X,
class Y>
269apply ([[maybe_unused]] X& x, [[maybe_unused]]
const Y& y)
273 int const b = block_size;
274 if constexpr(b==1){OPM_THROW(std::invalid_argument,
"MixedMatrixPreconditioner::apply does not support block size == 1!\n");}
284 int const N = block_size;
288 for(
int i=0;i<L->
ncols;i++)
290 double *xi = &x[0][0]+N*i;
291 for(
int k=L->
rowptr[i];k<L->rowptr[i+1];k++)
293 const float *A = L->
flt+k*NN;
295 double *xj = &x[0][0]+N*j;
296 matvec_mulsub(xj,A,xi);
300 const float *A = D->
flt+i*NN;
305 for(
int i=U->
ncols;i>0;i--)
307 double *xi = &x[0][0]+N*(i-1);
310 const float *A = U->
flt+k*NN;
312 double const *xj =&x[0][0]+N*j;
313 matvec_mulsub(xi,A,xj);
326template <
class M,
class X,
class Y>
328matvec_mul(
double *y,
float const *A,
double const * x)
330 int const N = block_size;
332 for(
int i=0;i<N;i++) z[i] = 0.0;
336 for(
int i=0;i<N;i++) z[i] += A[i+N*j]*xj;
338 for(
int i=0;i<N;i++) y[i] = z[i];
347template <
class M,
class X,
class Y>
348void MixedPreconditioner<M,X,Y>::
349matvec_mulsub(
double *y,
float const *A,
double const * x)
351 int const N = block_size;
353 for(
int i=0;i<N;i++) z[i] = 0.0;
357 for(
int i=0;i<N;i++) z[i] += A[i+N*j]*xj;
359 for(
int i=0;i<N;i++) y[i] -= z[i];
366template <
class M,
class X,
class Y>
367void MixedPreconditioner<M,X,Y>::
368mat_copy(
double *C,
double const * A)
370 int const N = block_size;
372 for(
int i=0;i<NN;i++) C[i] = A[i];
382template <
class M,
class X,
class Y>
383void MixedPreconditioner<M,X,Y>::
384mat_inv(
double *invA,
const double *A)
386 int const N = block_size;
393 double scale=-1.0/T[(N+1)*k];
394 for(
int i=0;i<N;i++) T[i+N*k] *= i==k?0:scale;
398 for(
int i=0;i<N;i++) T[i+N*j] += i==k?0:T[i+N*k]*T[k+N*j];
401 for(
int j=0;j<N;j++) T[k+N*j] *= scale;
412template <
class M,
class X,
class Y>
413void MixedPreconditioner<M,X,Y>::
414mat_mulsub(
double *C,
double const *A,
double const * B)
416 int const N = block_size;
420 for(
int k=0;k<N;k++) z[k] = 0.0;
423 double xk = B[k+N*j];
424 for(
int i=0;i<N;i++) z[i] += A[i+N*k]*xk;
426 for(
int i=0;i<N;i++) C[i+N*j] -= z[i];
434template <
class M,
class X,
class Y>
435void MixedPreconditioner<M,X,Y>::
436mat_rmul(
double *C,
double const *A)
438 int const N = block_size;
443 for(
int k=0;k<N;k++) T[k+N*j] = 0.0;
446 double xk = A[k+N*j];
447 for(
int i=0;i<N;i++) T[i+N*j] += C[i+N*k]*xk;
457template <
class M,
class X,
class Y>
458void MixedPreconditioner<M,X,Y>::
459mat_lmul(
double const *A,
double *C)
461 int const N = block_size;
465 for(
int k=0;k<N;k++) z[k] = 0.0;
468 double xk = C[k+N*j];
469 for(
int i=0;i<N;i++) z[i] += A[i+N*k]*xk;
471 for(
int i=0;i<N;i++) C[i+N*j] = z[i];
bsr_matrix * bsr_alloc(void)
Create empty bsr matrix.
void bsr_free(bsr_matrix *A)
Delete bsr matrix.
void bsr_init(bsr_matrix *A, int nrows, int nnz, int b)
Initialize bsr matrix.
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:34
Wraps c-implementation of mixed-precision preconditioner.
Definition: PreconditionerWrapper.hpp:16
bool hasPerfectUpdate() const override
Definition: PreconditionerWrapper.hpp:88
Dune::SolverCategory::Category category() const override
Solver category.
Definition: PreconditionerWrapper.hpp:86
void pre(X &x, Y &y) override
Definition: PreconditionerWrapper.hpp:90
MixedPreconditioner(const M &A, bool use_dilu=false)
constructor
Definition: PreconditionerWrapper.hpp:26
void apply(X &x, const Y &y) override
Mixed-precision ilu0/dilu application.
Definition: PreconditionerWrapper.hpp:269
X domain_type
Definition: PreconditionerWrapper.hpp:19
void post(X &x) override
Definition: PreconditionerWrapper.hpp:91
void update() override
Update ilu0/dilu factorization.
Definition: PreconditionerWrapper.hpp:160
~MixedPreconditioner()
destructor
Definition: PreconditionerWrapper.hpp:67
static constexpr auto block_size
Definition: PreconditionerWrapper.hpp:20
Definition: blackoilbioeffectsmodules.hh:45
void prec_ilu0_factorize4(prec_t *P, bsr_matrix *A, bool use_dilu)
void prec_mapply3c(prec_t *P, double *x)
void prec_free(prec_t *P)
Delete preconditioner object.
void prec_mapply4c(prec_t *P, double *x)
void prec_downcast(prec_t *P)
Make single-precision copy of double-precision values.
void prec_ilu0_factorize3(prec_t *P, bsr_matrix *A, bool use_dilu)
prec_t * prec_alloc()
Create empty preconditioner object.
void prec_ilu0_factorize2(prec_t *P, bsr_matrix *A, bool use_dilu)
ILU0/DILU factorization.
void prec_init(prec_t *P, bsr_matrix const *A)
Initialize preconditioner object.
void prec_mapply2c(prec_t *P, double *x)
Preconditioner application in mixed-precision.
Mixed-precision bsr matrix.
Definition: bsr.h:12
float * flt
Definition: bsr.h:29
int * colidx
Definition: bsr.h:25
double * dbl
Definition: bsr.h:27
int ncols
Definition: bsr.h:16
int * rowptr
Definition: bsr.h:23
int nrows
Definition: bsr.h:14
Preconditioner struct.
Definition: prec.h:15