PETSC_INTERN PetscErrorCode MatConvert_SeqBAIJ_SeqSBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) { Mat B; Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; Mat_SeqSBAIJ *b; PetscErrorCode ierr; PetscInt *ai=a->i,*aj,m=A->rmap->N,n=A->cmap->n,i,j,k,*bi,*bj,*browlengths; PetscInt bs =A->rmap->bs,bs2=bs*bs,mbs=m/bs,dd; MatScalar *av,*bv; PetscBool flg; PetscFunctionBegin; if (!A->symmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_USER,"Matrix must be symmetric. Call MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)"); if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Matrix must be square"); ierr = MatMissingDiagonal_SeqBAIJ(A,&flg,&dd); CHKERRQ(ierr); /* check for missing diagonals, then mark diag */ if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal %D",dd); ierr = PetscMalloc1(mbs,&browlengths); CHKERRQ(ierr); for (i=0; i<mbs; i++) { browlengths[i] = ai[i+1] - a->diag[i]; } ierr = MatCreate(PetscObjectComm((PetscObject)A),&B); CHKERRQ(ierr); ierr = MatSetSizes(B,m,n,m,n); CHKERRQ(ierr); ierr = MatSetType(B,MATSEQSBAIJ); CHKERRQ(ierr); ierr = MatSeqSBAIJSetPreallocation(B,bs,0,browlengths); CHKERRQ(ierr); ierr = MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE); CHKERRQ(ierr); b = (Mat_SeqSBAIJ*)(B->data); bi = b->i; bj = b->j; bv = b->a; bi[0] = 0; for (i=0; i<mbs; i++) { aj = a->j + a->diag[i]; av = a->a + (a->diag[i])*bs2; for (j=0; j<browlengths[i]; j++) { *bj = *aj; bj++; aj++; for (k=0; k<bs2; k++) { *bv = *av; bv++; av++; } } bi[i+1] = bi[i] + browlengths[i]; b->ilen[i] = browlengths[i]; } ierr = PetscFree(browlengths); CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); if (reuse == MAT_INPLACE_MATRIX) { ierr = MatHeaderReplace(A,&B); CHKERRQ(ierr); } else { *newmat = B; } PetscFunctionReturn(0); }
EXTERN_C_END EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatConvert_SeqBAIJ_SeqSBAIJ" PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqBAIJ_SeqSBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) { Mat B; Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; Mat_SeqSBAIJ *b; PetscErrorCode ierr; PetscInt *ai=a->i,*aj,m=A->rmap->N,n=A->cmap->n,i,j,k,*bi,*bj,*browlengths; PetscInt bs=A->rmap->bs,bs2=bs*bs,mbs=m/bs,dd; MatScalar *av,*bv; PetscTruth flg; PetscFunctionBegin; if (n != m) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square"); ierr = MatMissingDiagonal_SeqBAIJ(A,&flg,&dd);CHKERRQ(ierr); /* check for missing diagonals, then mark diag */ if (flg) SETERRQ1(PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal %D",dd); ierr = PetscMalloc(mbs*sizeof(PetscInt),&browlengths);CHKERRQ(ierr); for (i=0; i<mbs; i++) { browlengths[i] = ai[i+1] - a->diag[i]; } ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr); ierr = MatSetType(B,newtype);CHKERRQ(ierr); ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(B,bs,0,browlengths);CHKERRQ(ierr); ierr = MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); b = (Mat_SeqSBAIJ*)(B->data); bi = b->i; bj = b->j; bv = b->a; bi[0] = 0; for (i=0; i<mbs; i++) { aj = a->j + a->diag[i]; av = a->a + (a->diag[i])*bs2; for (j=0; j<browlengths[i]; j++){ *bj = *aj; bj++; aj++; for (k=0; k<bs2; k++){ *bv = *av; bv++; av++; } } bi[i+1] = bi[i] + browlengths[i]; b->ilen[i] = browlengths[i]; } ierr = PetscFree(browlengths);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (reuse == MAT_REUSE_MATRIX) { ierr = MatHeaderReplace(A,B);CHKERRQ(ierr); } else { *newmat = B; } PetscFunctionReturn(0); }