xref: /petsc/src/mat/impls/baij/seq/aijbaij.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
161e22dc2SBarry Smith 
2c6db04a5SJed Brown #include <../src/mat/impls/baij/seq/baij.h>
361e22dc2SBarry Smith 
4*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqBAIJ_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
5*d71ae5a4SJacob Faibussowitsch {
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;
17ad540459SPierre Jolivet     for (i = 0; i < n; i++) maxlen = PetscMax(maxlen, (ai[i + 1] - ai[i]));
180f6d62edSLisandro Dalcin   } else {
199566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n * bs, &rowlengths));
2061e22dc2SBarry Smith     for (i = 0; i < n; i++) {
21b9b97703SBarry Smith       maxlen = PetscMax(maxlen, (ai[i + 1] - ai[i]));
22ad540459SPierre Jolivet       for (j = 0; j < bs; j++) rowlengths[i * bs + j] = bs * (ai[i + 1] - ai[i]);
2361e22dc2SBarry Smith     }
249566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
259566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQAIJ));
269566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N));
279566063dSJacob Faibussowitsch     PetscCall(MatSetBlockSizes(B, A->rmap->bs, A->cmap->bs));
289566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B, 0, rowlengths));
299566063dSJacob Faibussowitsch     PetscCall(PetscFree(rowlengths));
300f6d62edSLisandro Dalcin   }
310f6d62edSLisandro Dalcin   b           = (Mat_SeqAIJ *)B->data;
320f6d62edSLisandro Dalcin   roworiented = b->roworiented;
3361e22dc2SBarry Smith 
349566063dSJacob Faibussowitsch   PetscCall(MatSetOption(B, MAT_ROW_ORIENTED, PETSC_FALSE));
359566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(bs, &rows));
369566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(bs * maxlen, &cols));
37b9b97703SBarry Smith   for (i = 0; i < n; i++) {
38ad540459SPierre Jolivet     for (j = 0; j < bs; j++) rows[j] = i * bs + j;
39b9b97703SBarry Smith     ncols = ai[i + 1] - ai[i];
40b9b97703SBarry Smith     for (k = 0; k < ncols; k++) {
41ad540459SPierre Jolivet       for (j = 0; j < bs; j++) cols[k * bs + j] = bs * (*aj) + j;
42b9b97703SBarry Smith       aj++;
43b9b97703SBarry Smith     }
449566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B, bs, rows, bs * ncols, cols, aa, INSERT_VALUES));
45b9b97703SBarry Smith     aa += ncols * bs * bs;
46b9b97703SBarry Smith   }
479566063dSJacob Faibussowitsch   PetscCall(PetscFree(cols));
489566063dSJacob Faibussowitsch   PetscCall(PetscFree(rows));
499566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
509566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
519566063dSJacob Faibussowitsch   PetscCall(MatSetOption(B, MAT_ROW_ORIENTED, roworiented));
52521d7252SBarry Smith 
53511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
549566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
55ae8d29abSPierre Jolivet   } else *newmat = B;
5661e22dc2SBarry Smith   PetscFunctionReturn(0);
5761e22dc2SBarry Smith }
5861e22dc2SBarry Smith 
59c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>
6085fc7724SBarry Smith 
61*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqBAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
62*d71ae5a4SJacob Faibussowitsch {
63676c34cdSKris Buschelman   Mat          B;
6485fc7724SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ *)A->data;
6585fc7724SBarry Smith   Mat_SeqBAIJ *b;
66ae8d29abSPierre Jolivet   PetscInt    *ai = a->i, m = A->rmap->N, n = A->cmap->N, i, *rowlengths, bs = PetscAbs(A->rmap->bs);
6785fc7724SBarry Smith 
6885fc7724SBarry Smith   PetscFunctionBegin;
69345dab1aSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
709566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m / bs, &rowlengths));
71ad540459SPierre Jolivet     for (i = 0; i < m / bs; i++) rowlengths[i] = (ai[i * bs + 1] - ai[i * bs]) / bs;
729566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
739566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, m, n));
749566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQBAIJ));
759566063dSJacob Faibussowitsch     PetscCall(MatSeqBAIJSetPreallocation(B, bs, 0, rowlengths));
769566063dSJacob Faibussowitsch     PetscCall(PetscFree(rowlengths));
77345dab1aSStefano Zampini   } else B = *newmat;
7885fc7724SBarry Smith 
79ae8d29abSPierre Jolivet   if (bs == 1) {
80676c34cdSKris Buschelman     b = (Mat_SeqBAIJ *)(B->data);
8185fc7724SBarry Smith 
829566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(b->i, a->i, m + 1));
839566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(b->ilen, a->ilen, m));
849566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(b->j, a->j, a->nz));
859566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(b->a, a->a, a->nz));
8685fc7724SBarry Smith 
879566063dSJacob Faibussowitsch     PetscCall(MatSetOption(B, MAT_ROW_ORIENTED, PETSC_TRUE));
889566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
899566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
90ae8d29abSPierre Jolivet   } else {
91ae8d29abSPierre 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 */
92ae8d29abSPierre Jolivet     /* if reuse is equal to MAT_INITIAL_MATRIX, it has been appropriately preallocated before                                          */
93ae8d29abSPierre Jolivet     /*                      MAT_INPLACE_MATRIX, it will be replaced with MatHeaderReplace below                                        */
949566063dSJacob Faibussowitsch     PetscCall(MatConvert_Basic(A, newtype, MAT_REUSE_MATRIX, &B));
95ae8d29abSPierre Jolivet   }
96676c34cdSKris Buschelman 
97511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
989566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
99ae8d29abSPierre Jolivet   } else *newmat = B;
10085fc7724SBarry Smith   PetscFunctionReturn(0);
10185fc7724SBarry Smith }
102