xref: /petsc/src/mat/impls/sbaij/seq/aijsbaij.c (revision 4e5e7fe449b7c11ceb24afe5a5284bb8387e21ce)
159557b74SHong Zhang /*$Id: aijsbaij.c,v 1.9 2001/08/07 03:02:55 balay Exp $*/
259557b74SHong Zhang 
359557b74SHong Zhang #include "src/mat/impls/aij/seq/aij.h"
4861ba921SHong Zhang #include "src/mat/impls/sbaij/seq/sbaij.h"
559557b74SHong Zhang 
659557b74SHong Zhang EXTERN_C_BEGIN
759557b74SHong Zhang #undef __FUNCT__
8*4e5e7fe4SHong Zhang #define __FUNCT__ "MatConvert_SeqSBAI_SeqAIJ"
9*4e5e7fe4SHong Zhang int MatConvert_SeqSBAIJ_SeqAIJ(Mat A,const MatType newtype,Mat *newmat)
10*4e5e7fe4SHong Zhang {
11*4e5e7fe4SHong Zhang   Mat          B;
12*4e5e7fe4SHong Zhang   Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data;
13*4e5e7fe4SHong Zhang   Mat_SeqAIJ   *b;
14*4e5e7fe4SHong Zhang   int          ierr,bs = a->bs,*ai=a->i,*aj=a->j,m=A->M/bs,*bi,*bj,
15*4e5e7fe4SHong Zhang                i,*rowlengths,nz,*rowstart;
16*4e5e7fe4SHong Zhang   PetscScalar  *av,*bv;
17*4e5e7fe4SHong Zhang 
18*4e5e7fe4SHong Zhang   PetscFunctionBegin;
19*4e5e7fe4SHong Zhang   /* compute rowlengths of newmat */
20*4e5e7fe4SHong Zhang   ierr = PetscMalloc(m*bs*sizeof(int),&rowlengths);CHKERRQ(ierr);
21*4e5e7fe4SHong Zhang   for (i=0; i<m; i++) rowlengths[i] = 0;
22*4e5e7fe4SHong Zhang   aj = a->j;
23*4e5e7fe4SHong Zhang   for (i=0; i<m; i++) {
24*4e5e7fe4SHong Zhang     nz = ai[i+1] - ai[i];
25*4e5e7fe4SHong Zhang     rowlengths[i] += nz; /* upper triangular part */
26*4e5e7fe4SHong Zhang     aj++; nz--;          /* skip diagonal */
27*4e5e7fe4SHong Zhang     while (nz--) { rowlengths[*aj++]++; }  /* lower triangular part */
28*4e5e7fe4SHong Zhang   }
29*4e5e7fe4SHong Zhang 
30*4e5e7fe4SHong Zhang   ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,m,m,0,rowlengths,&B);CHKERRQ(ierr);
31*4e5e7fe4SHong Zhang   ierr = MatSetOption(B,MAT_ROW_ORIENTED);CHKERRQ(ierr);
32*4e5e7fe4SHong Zhang   ierr = MatSetOption(B,MAT_ROWS_SORTED);CHKERRQ(ierr);
33*4e5e7fe4SHong Zhang   ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr);
34*4e5e7fe4SHong Zhang 
35*4e5e7fe4SHong Zhang   b  = (Mat_SeqAIJ*)(B->data);
36*4e5e7fe4SHong Zhang   bi = b->i;
37*4e5e7fe4SHong Zhang   bj = b->j;
38*4e5e7fe4SHong Zhang   bv = b->a;
39*4e5e7fe4SHong Zhang 
40*4e5e7fe4SHong Zhang   /* set b->i */
41*4e5e7fe4SHong Zhang   rowstart = rowlengths; /* rowstart renames rowlengths for code understanding */
42*4e5e7fe4SHong Zhang   bi[0] = 0;
43*4e5e7fe4SHong Zhang   for (i=0; i<m; i++){
44*4e5e7fe4SHong Zhang     b->ilen[i]  = rowlengths[i];
45*4e5e7fe4SHong Zhang     bi[i+1]     = bi[i] + rowlengths[i];
46*4e5e7fe4SHong Zhang     rowstart[i] = bi[i];
47*4e5e7fe4SHong Zhang   }
48*4e5e7fe4SHong Zhang   if (bi[m] != 2*a->nz - m) SETERRQ2(1,"bi[m]: %d != 2*a->nz-m: %d\n",bi[m],2*a->nz - m);
49*4e5e7fe4SHong Zhang 
50*4e5e7fe4SHong Zhang   /* set b->j and b->a */
51*4e5e7fe4SHong Zhang   aj = a->j; av = a->a;
52*4e5e7fe4SHong Zhang   for (i=0; i<m; i++) {
53*4e5e7fe4SHong Zhang     /* diagonal */
54*4e5e7fe4SHong Zhang     *(bj + rowstart[i]) = *aj; aj++;
55*4e5e7fe4SHong Zhang     *(bv + rowstart[i]) = *av; av++;
56*4e5e7fe4SHong Zhang     rowstart[i]++;
57*4e5e7fe4SHong Zhang     nz = ai[i+1] - ai[i] - 1;
58*4e5e7fe4SHong Zhang     while (nz--){
59*4e5e7fe4SHong Zhang       /* lower triangular part */
60*4e5e7fe4SHong Zhang       *(bj + rowstart[*aj]) = i;
61*4e5e7fe4SHong Zhang       *(bv + rowstart[*aj]) = *av;
62*4e5e7fe4SHong Zhang       rowstart[*aj]++;
63*4e5e7fe4SHong Zhang       /* upper triangular part */
64*4e5e7fe4SHong Zhang       *(bj + rowstart[i]) = *aj; aj++;
65*4e5e7fe4SHong Zhang       *(bv + rowstart[i]) = *av; av++;
66*4e5e7fe4SHong Zhang       rowstart[i]++;
67*4e5e7fe4SHong Zhang     }
68*4e5e7fe4SHong Zhang   }
69*4e5e7fe4SHong Zhang   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
70*4e5e7fe4SHong Zhang   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
71*4e5e7fe4SHong Zhang   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
72*4e5e7fe4SHong Zhang 
73*4e5e7fe4SHong Zhang   /* Fake support for "inplace" convert. */
74*4e5e7fe4SHong Zhang   if (*newmat == A) {
75*4e5e7fe4SHong Zhang     ierr = MatDestroy(A);CHKERRQ(ierr);
76*4e5e7fe4SHong Zhang   }
77*4e5e7fe4SHong Zhang   *newmat = B;
78*4e5e7fe4SHong Zhang 
79*4e5e7fe4SHong Zhang   PetscFunctionReturn(0);
80*4e5e7fe4SHong Zhang }
81*4e5e7fe4SHong Zhang #undef __FUNCT__
8259557b74SHong Zhang #define __FUNCT__ "MatConvert_SeqAIJ_SeqSBAIJ"
838e9aea5cSBarry Smith int MatConvert_SeqAIJ_SeqSBAIJ(Mat A,const MatType newtype,Mat *newmat) {
84676c34cdSKris Buschelman   Mat          B;
8559557b74SHong Zhang   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
86861ba921SHong Zhang   Mat_SeqSBAIJ *b;
87861ba921SHong Zhang   int          ierr,*ai=a->i,*aj,m=A->M,n=A->N,i,j,
882d9a3abdSHong Zhang                *bi,*bj,*rowlengths;
89861ba921SHong Zhang   PetscScalar  *av,*bv;
9059557b74SHong Zhang 
9159557b74SHong Zhang   PetscFunctionBegin;
922d9a3abdSHong Zhang   if (n != m) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
9359557b74SHong Zhang   if (!a->diag){
9459557b74SHong Zhang     ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
9559557b74SHong Zhang   }
9659557b74SHong Zhang 
9759557b74SHong Zhang   ierr = PetscMalloc(m*sizeof(int),&rowlengths);CHKERRQ(ierr);
9859557b74SHong Zhang   for (i=0; i<m; i++) {
9959557b74SHong Zhang     rowlengths[i] = ai[i+1] - a->diag[i];
10059557b74SHong Zhang   }
101676c34cdSKris Buschelman   ierr = MatCreateSeqSBAIJ(PETSC_COMM_SELF,1,m,n,0,rowlengths,&B);CHKERRQ(ierr);
10259557b74SHong Zhang 
103676c34cdSKris Buschelman   ierr = MatSetOption(B,MAT_ROW_ORIENTED);CHKERRQ(ierr);
104676c34cdSKris Buschelman   ierr = MatSetOption(B,MAT_ROWS_SORTED);CHKERRQ(ierr);
105676c34cdSKris Buschelman   ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr);
10659557b74SHong Zhang 
107676c34cdSKris Buschelman   b  = (Mat_SeqSBAIJ*)(B->data);
108861ba921SHong Zhang   bi = b->i;
109861ba921SHong Zhang   bj = b->j;
110861ba921SHong Zhang   bv = b->a;
111861ba921SHong Zhang 
112861ba921SHong Zhang   bi[0] = 0;
11359557b74SHong Zhang   for (i=0; i<m; i++) {
11459557b74SHong Zhang     aj = a->j + a->diag[i];
11559557b74SHong Zhang     av = a->a + a->diag[i];
116861ba921SHong Zhang     for (j=0; j<rowlengths[i]; j++){
117861ba921SHong Zhang       *bj = *aj; bj++; aj++;
118861ba921SHong Zhang       *bv = *av; bv++; av++;
119861ba921SHong Zhang     }
120861ba921SHong Zhang     bi[i+1]    = bi[i] + rowlengths[i];
121861ba921SHong Zhang     b->ilen[i] = rowlengths[i];
12259557b74SHong Zhang   }
12359557b74SHong Zhang 
12459557b74SHong Zhang   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
125676c34cdSKris Buschelman   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
126676c34cdSKris Buschelman   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
127676c34cdSKris Buschelman 
128676c34cdSKris Buschelman   /* Fake support for "inplace" convert. */
129676c34cdSKris Buschelman   if (*newmat == A) {
130676c34cdSKris Buschelman     ierr = MatDestroy(A);CHKERRQ(ierr);
131676c34cdSKris Buschelman   }
132676c34cdSKris Buschelman   *newmat = B;
133676c34cdSKris Buschelman 
13459557b74SHong Zhang   PetscFunctionReturn(0);
13559557b74SHong Zhang }
13659557b74SHong Zhang EXTERN_C_END
13759557b74SHong Zhang 
138