xref: /petsc/src/mat/impls/baij/seq/aijbaij.c (revision 9566063d113dddea24716c546802770db7481bc0)
161e22dc2SBarry Smith 
2c6db04a5SJed Brown #include <../src/mat/impls/baij/seq/baij.h>
361e22dc2SBarry Smith 
4cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqBAIJ_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
5521d7252SBarry Smith {
6676c34cdSKris Buschelman   Mat            B;
70f6d62edSLisandro Dalcin   Mat_SeqAIJ     *b;
80f6d62edSLisandro Dalcin   PetscBool      roworiented;
961e22dc2SBarry Smith   Mat_SeqBAIJ    *a = (Mat_SeqBAIJ*)A->data;
10d0f46423SBarry Smith   PetscInt       bs = A->rmap->bs,*ai = a->i,*aj = a->j,n = A->rmap->N/bs,i,j,k;
11690b6cddSBarry Smith   PetscInt       *rowlengths,*rows,*cols,maxlen = 0,ncols;
12dd6ea824SBarry Smith   MatScalar      *aa = a->a;
1361e22dc2SBarry Smith 
1461e22dc2SBarry Smith   PetscFunctionBegin;
150f6d62edSLisandro Dalcin   if (reuse == MAT_REUSE_MATRIX) {
160f6d62edSLisandro Dalcin     B = *newmat;
170f6d62edSLisandro Dalcin     for (i=0; i<n; i++) {
180f6d62edSLisandro Dalcin       maxlen = PetscMax(maxlen,(ai[i+1] - ai[i]));
190f6d62edSLisandro Dalcin     }
200f6d62edSLisandro Dalcin   } else {
21*9566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n*bs,&rowlengths));
2261e22dc2SBarry Smith     for (i=0; i<n; i++) {
23b9b97703SBarry Smith       maxlen = PetscMax(maxlen,(ai[i+1] - ai[i]));
2461e22dc2SBarry Smith       for (j=0; j<bs; j++) {
25b9b97703SBarry Smith         rowlengths[i*bs+j] = bs*(ai[i+1] - ai[i]);
2661e22dc2SBarry Smith       }
2761e22dc2SBarry Smith     }
28*9566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
29*9566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,MATSEQAIJ));
30*9566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N));
31*9566063dSJacob Faibussowitsch     PetscCall(MatSetBlockSizes(B,A->rmap->bs,A->cmap->bs));
32*9566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B,0,rowlengths));
33*9566063dSJacob Faibussowitsch     PetscCall(PetscFree(rowlengths));
340f6d62edSLisandro Dalcin   }
350f6d62edSLisandro Dalcin   b = (Mat_SeqAIJ*)B->data;
360f6d62edSLisandro Dalcin   roworiented = b->roworiented;
3761e22dc2SBarry Smith 
38*9566063dSJacob Faibussowitsch   PetscCall(MatSetOption(B,MAT_ROW_ORIENTED,PETSC_FALSE));
39*9566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(bs,&rows));
40*9566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(bs*maxlen,&cols));
41b9b97703SBarry Smith   for (i=0; i<n; i++) {
42b9b97703SBarry Smith     for (j=0; j<bs; j++) {
43b9b97703SBarry Smith       rows[j] = i*bs+j;
44b9b97703SBarry Smith     }
45b9b97703SBarry Smith     ncols = ai[i+1] - ai[i];
46b9b97703SBarry Smith     for (k=0; k<ncols; k++) {
47b9b97703SBarry Smith       for (j=0; j<bs; j++) {
48b9b97703SBarry Smith         cols[k*bs+j] = bs*(*aj) + j;
49b9b97703SBarry Smith       }
50b9b97703SBarry Smith       aj++;
51b9b97703SBarry Smith     }
52*9566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B,bs,rows,bs*ncols,cols,aa,INSERT_VALUES));
53b9b97703SBarry Smith     aa  += ncols*bs*bs;
54b9b97703SBarry Smith   }
55*9566063dSJacob Faibussowitsch   PetscCall(PetscFree(cols));
56*9566063dSJacob Faibussowitsch   PetscCall(PetscFree(rows));
57*9566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
58*9566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
59*9566063dSJacob Faibussowitsch   PetscCall(MatSetOption(B,MAT_ROW_ORIENTED,roworiented));
60521d7252SBarry Smith 
61511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
62*9566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&B));
63ae8d29abSPierre Jolivet   } else *newmat = B;
6461e22dc2SBarry Smith   PetscFunctionReturn(0);
6561e22dc2SBarry Smith }
6661e22dc2SBarry Smith 
67c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>
6885fc7724SBarry Smith 
69cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqBAIJ(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
70521d7252SBarry Smith {
71676c34cdSKris Buschelman   Mat            B;
7285fc7724SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
7385fc7724SBarry Smith   Mat_SeqBAIJ    *b;
74ae8d29abSPierre Jolivet   PetscInt       *ai=a->i,m=A->rmap->N,n=A->cmap->N,i,*rowlengths,bs=PetscAbs(A->rmap->bs);
7585fc7724SBarry Smith 
7685fc7724SBarry Smith   PetscFunctionBegin;
77345dab1aSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
78*9566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m/bs,&rowlengths));
79ae8d29abSPierre Jolivet     for (i=0; i<m/bs; i++) {
80ae8d29abSPierre Jolivet       rowlengths[i] = (ai[i*bs+1] - ai[i*bs])/bs;
8185fc7724SBarry Smith     }
82*9566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
83*9566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,m,n,m,n));
84*9566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,MATSEQBAIJ));
85*9566063dSJacob Faibussowitsch     PetscCall(MatSeqBAIJSetPreallocation(B,bs,0,rowlengths));
86*9566063dSJacob Faibussowitsch     PetscCall(PetscFree(rowlengths));
87345dab1aSStefano Zampini   } else B = *newmat;
8885fc7724SBarry Smith 
89ae8d29abSPierre Jolivet   if (bs == 1) {
90676c34cdSKris Buschelman     b = (Mat_SeqBAIJ*)(B->data);
9185fc7724SBarry Smith 
92*9566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(b->i,a->i,m+1));
93*9566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(b->ilen,a->ilen,m));
94*9566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(b->j,a->j,a->nz));
95*9566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(b->a,a->a,a->nz));
9685fc7724SBarry Smith 
97*9566063dSJacob Faibussowitsch     PetscCall(MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE));
98*9566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
99*9566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
100ae8d29abSPierre Jolivet   } else {
101ae8d29abSPierre Jolivet     /* reuse may not be equal to MAT_REUSE_MATRIX, but the basic converter will reallocate or replace newmat if this value is not used */
102ae8d29abSPierre Jolivet     /* if reuse is equal to MAT_INITIAL_MATRIX, it has been appropriately preallocated before                                          */
103ae8d29abSPierre Jolivet     /*                      MAT_INPLACE_MATRIX, it will be replaced with MatHeaderReplace below                                        */
104*9566063dSJacob Faibussowitsch     PetscCall(MatConvert_Basic(A,newtype,MAT_REUSE_MATRIX,&B));
105ae8d29abSPierre Jolivet   }
106676c34cdSKris Buschelman 
107511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
108*9566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&B));
109ae8d29abSPierre Jolivet   } else *newmat = B;
11085fc7724SBarry Smith   PetscFunctionReturn(0);
11185fc7724SBarry Smith }
112