xref: /petsc/src/mat/impls/baij/seq/baijsolvtran1.c (revision ccb4e88a40f0b86eaeca07ff64c64e4de2fae686)
1 #include <../src/mat/impls/baij/seq/baij.h>
2 #include <petsc/private/kernels/blockinvert.h>
3 
4 PetscErrorCode MatSolveTranspose_SeqBAIJ_1(Mat A,Vec bb,Vec xx)
5 {
6   Mat_SeqBAIJ       *a    = (Mat_SeqBAIJ*)A->data;
7   IS                iscol = a->col,isrow = a->row;
8   PetscErrorCode    ierr;
9   const PetscInt    *rout,*cout,*r,*c,*adiag = a->diag,*ai = a->i,*aj = a->j,*vi;
10   PetscInt          i,n = a->mbs,j;
11   PetscInt          nz;
12   PetscScalar       *x,*tmp,s1;
13   const MatScalar   *aa = a->a,*v;
14   const PetscScalar *b;
15 
16   PetscFunctionBegin;
17   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
18   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
19   tmp  = a->solve_work;
20 
21   ierr = ISGetIndices(isrow,&rout);CHKERRQ(ierr); r = rout;
22   ierr = ISGetIndices(iscol,&cout);CHKERRQ(ierr); c = cout;
23 
24   /* copy the b into temp work space according to permutation */
25   for (i=0; i<n; i++) tmp[i] = b[c[i]];
26 
27   /* forward solve the U^T */
28   for (i=0; i<n; i++) {
29     v   = aa + adiag[i+1] + 1;
30     vi  = aj + adiag[i+1] + 1;
31     nz  = adiag[i] - adiag[i+1] - 1;
32     s1  = tmp[i];
33     s1 *= v[nz];  /* multiply by inverse of diagonal entry */
34     for (j=0; j<nz; j++) tmp[vi[j]] -= s1*v[j];
35     tmp[i] = s1;
36   }
37 
38   /* backward solve the L^T */
39   for (i=n-1; i>=0; i--) {
40     v  = aa + ai[i];
41     vi = aj + ai[i];
42     nz = ai[i+1] - ai[i];
43     s1 = tmp[i];
44     for (j=0; j<nz; j++) tmp[vi[j]] -= s1*v[j];
45   }
46 
47   /* copy tmp into x according to permutation */
48   for (i=0; i<n; i++) x[r[i]] = tmp[i];
49 
50   ierr = ISRestoreIndices(isrow,&rout);CHKERRQ(ierr);
51   ierr = ISRestoreIndices(iscol,&cout);CHKERRQ(ierr);
52   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
53   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
54 
55   ierr = PetscLogFlops(2.0*a->nz-A->cmap->n);CHKERRQ(ierr);
56   PetscFunctionReturn(0);
57 }
58 
59 PetscErrorCode MatSolveTranspose_SeqBAIJ_1_inplace(Mat A,Vec bb,Vec xx)
60 {
61   Mat_SeqBAIJ       *a   =(Mat_SeqBAIJ*)A->data;
62   IS                iscol=a->col,isrow=a->row;
63   PetscErrorCode    ierr;
64   const PetscInt    *r,*c,*rout,*cout;
65   const PetscInt    *diag=a->diag,n=a->mbs,*vi,*ai=a->i,*aj=a->j;
66   PetscInt          i,nz;
67   const MatScalar   *aa=a->a,*v;
68   PetscScalar       s1,*x,*t;
69   const PetscScalar *b;
70 
71   PetscFunctionBegin;
72   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
73   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
74   t    = a->solve_work;
75 
76   ierr = ISGetIndices(isrow,&rout);CHKERRQ(ierr); r = rout;
77   ierr = ISGetIndices(iscol,&cout);CHKERRQ(ierr); c = cout;
78 
79   /* copy the b into temp work space according to permutation */
80   for (i=0; i<n; i++) t[i] = b[c[i]];
81 
82   /* forward solve the U^T */
83   for (i=0; i<n; i++) {
84 
85     v = aa + diag[i];
86     /* multiply by the inverse of the block diagonal */
87     s1 = (*v++)*t[i];
88     vi = aj + diag[i] + 1;
89     nz = ai[i+1] - diag[i] - 1;
90     while (nz--) {
91       t[*vi++] -= (*v++)*s1;
92     }
93     t[i] = s1;
94   }
95   /* backward solve the L^T */
96   for (i=n-1; i>=0; i--) {
97     v  = aa + diag[i] - 1;
98     vi = aj + diag[i] - 1;
99     nz = diag[i] - ai[i];
100     s1 = t[i];
101     while (nz--) {
102       t[*vi--] -=  (*v--)*s1;
103     }
104   }
105 
106   /* copy t into x according to permutation */
107   for (i=0; i<n; i++) x[r[i]] = t[i];
108 
109   ierr = ISRestoreIndices(isrow,&rout);CHKERRQ(ierr);
110   ierr = ISRestoreIndices(iscol,&cout);CHKERRQ(ierr);
111   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
112   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
113   ierr = PetscLogFlops(2.0*(a->nz) - A->cmap->n);CHKERRQ(ierr);
114   PetscFunctionReturn(0);
115 }
116