1a2fc1e05SToby Isaac 2a2fc1e05SToby Isaac #include <petscsys.h> 3a2fc1e05SToby Isaac #include <../src/mat/impls/aij/seq/aij.h> 4a2fc1e05SToby Isaac #include <../src/mat/impls/sbaij/seq/cholmod/cholmodimpl.h> 5a2fc1e05SToby Isaac 6a2fc1e05SToby Isaac EXTERN_C_BEGIN 7a2fc1e05SToby Isaac #include <SuiteSparseQR_C.h> 8a2fc1e05SToby Isaac EXTERN_C_END 9a2fc1e05SToby Isaac 10a2fc1e05SToby Isaac static PetscErrorCode MatWrapCholmod_SPQR_seqaij(Mat A,PetscBool values,cholmod_sparse *C,PetscBool *aijalloc,PetscBool *valloc) 11a2fc1e05SToby Isaac { 12a2fc1e05SToby Isaac Mat_SeqAIJ *aij; 13a2fc1e05SToby Isaac Mat AT; 14a2fc1e05SToby Isaac const PetscScalar *aa; 15a2fc1e05SToby Isaac PetscScalar *ca; 16a2fc1e05SToby Isaac const PetscInt *ai, *aj; 17a2fc1e05SToby Isaac PetscInt n = A->cmap->n, i,j,k,nz; 18a2fc1e05SToby Isaac SuiteSparse_long *ci, *cj; /* SuiteSparse_long is the only choice for SPQR */ 1902ef7dfaSPierre Jolivet PetscBool vain = PETSC_FALSE,flg; 20a2fc1e05SToby Isaac 21a2fc1e05SToby Isaac PetscFunctionBegin; 22*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATNORMALHERMITIAN, &flg)); 2365f45395SPierre Jolivet if (flg) { 24*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatNormalHermitianGetMat(A, &A)); 2565f45395SPierre Jolivet } else if (!PetscDefined(USE_COMPLEX)) { 26*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATNORMAL, &flg)); 2702ef7dfaSPierre Jolivet if (flg) { 28*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatNormalGetMat(A, &A)); 2902ef7dfaSPierre Jolivet } 3065f45395SPierre Jolivet } 31a2fc1e05SToby Isaac /* cholmod_sparse is compressed sparse column */ 32*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetOption(A, MAT_SYMMETRIC, &flg)); 3302ef7dfaSPierre Jolivet if (flg) { 34*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject)A)); 35a2fc1e05SToby Isaac AT = A; 36a2fc1e05SToby Isaac } else { 37*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatTranspose(A, MAT_INITIAL_MATRIX, &AT)); 38a2fc1e05SToby Isaac } 39a2fc1e05SToby Isaac aij = (Mat_SeqAIJ*)AT->data; 40a2fc1e05SToby Isaac ai = aij->j; 41a2fc1e05SToby Isaac aj = aij->i; 42a2fc1e05SToby Isaac for (j=0,nz=0; j<n; j++) nz += aj[j+1] - aj[j]; 43*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc2(n+1,&cj,nz,&ci)); 44a2fc1e05SToby Isaac if (values) { 45a2fc1e05SToby Isaac vain = PETSC_TRUE; 46*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nz,&ca)); 47*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(AT,&aa)); 48a2fc1e05SToby Isaac } 49a2fc1e05SToby Isaac for (j=0,k=0; j<n; j++) { 50a2fc1e05SToby Isaac cj[j] = k; 51a2fc1e05SToby Isaac for (i=aj[j]; i<aj[j+1]; i++,k++) { 52a2fc1e05SToby Isaac ci[k] = ai[i]; 53a2fc1e05SToby Isaac if (values) ca[k] = aa[i]; 54a2fc1e05SToby Isaac } 55a2fc1e05SToby Isaac } 56a2fc1e05SToby Isaac cj[j] = k; 57a2fc1e05SToby Isaac *aijalloc = PETSC_TRUE; 58a2fc1e05SToby Isaac *valloc = vain; 59a2fc1e05SToby Isaac if (values) { 60*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(AT,&aa)); 61a2fc1e05SToby Isaac } 62a2fc1e05SToby Isaac 63*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemzero(C,sizeof(*C))); 64a2fc1e05SToby Isaac 6502ef7dfaSPierre Jolivet C->nrow = (size_t)AT->cmap->n; 6602ef7dfaSPierre Jolivet C->ncol = (size_t)AT->rmap->n; 67a2fc1e05SToby Isaac C->nzmax = (size_t)nz; 68a2fc1e05SToby Isaac C->p = cj; 69a2fc1e05SToby Isaac C->i = ci; 70a2fc1e05SToby Isaac C->x = values ? ca : 0; 71a2fc1e05SToby Isaac C->stype = 0; 72a2fc1e05SToby Isaac C->itype = CHOLMOD_LONG; 73a2fc1e05SToby Isaac C->xtype = values ? CHOLMOD_SCALAR_TYPE : CHOLMOD_PATTERN; 74a2fc1e05SToby Isaac C->dtype = CHOLMOD_DOUBLE; 75a2fc1e05SToby Isaac C->sorted = 1; 76a2fc1e05SToby Isaac C->packed = 1; 77a2fc1e05SToby Isaac 78*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&AT)); 79a2fc1e05SToby Isaac PetscFunctionReturn(0); 80a2fc1e05SToby Isaac } 81a2fc1e05SToby Isaac 82a2fc1e05SToby Isaac static PetscErrorCode MatFactorGetSolverType_seqaij_SPQR(Mat A,MatSolverType *type) 83a2fc1e05SToby Isaac { 84a2fc1e05SToby Isaac PetscFunctionBegin; 85a2fc1e05SToby Isaac *type = MATSOLVERSPQR; 86a2fc1e05SToby Isaac PetscFunctionReturn(0); 87a2fc1e05SToby Isaac } 88a2fc1e05SToby Isaac 89a2fc1e05SToby Isaac #define GET_ARRAY_READ 0 90a2fc1e05SToby Isaac #define GET_ARRAY_WRITE 1 91a2fc1e05SToby Isaac 92a2fc1e05SToby Isaac static PetscErrorCode MatSolve_SPQR_Internal(Mat F, cholmod_dense *cholB, cholmod_dense **_Y_handle) 93a2fc1e05SToby Isaac { 94a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 9502ef7dfaSPierre Jolivet cholmod_dense *Y_handle = NULL, *QTB_handle = NULL, *Z_handle = NULL; 96a2fc1e05SToby Isaac 97a2fc1e05SToby Isaac PetscFunctionBegin; 9802ef7dfaSPierre Jolivet if (!chol->normal) { 99a2fc1e05SToby Isaac QTB_handle = SuiteSparseQR_C_qmult(SPQR_QTX, chol->spqrfact, cholB, chol->common); 1002c71b3e2SJacob Faibussowitsch PetscCheckFalse(!QTB_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_qmult failed"); 101a2fc1e05SToby Isaac Y_handle = SuiteSparseQR_C_solve(SPQR_RETX_EQUALS_B, chol->spqrfact, QTB_handle, chol->common); 1022c71b3e2SJacob Faibussowitsch PetscCheckFalse(!Y_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_solve failed"); 10302ef7dfaSPierre Jolivet } else { 10402ef7dfaSPierre Jolivet Z_handle = SuiteSparseQR_C_solve(SPQR_RTX_EQUALS_ETB, chol->spqrfact, cholB, chol->common); 1052c71b3e2SJacob Faibussowitsch PetscCheckFalse(!Z_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_solve failed"); 10602ef7dfaSPierre Jolivet Y_handle = SuiteSparseQR_C_solve(SPQR_RETX_EQUALS_B, chol->spqrfact, Z_handle, chol->common); 1072c71b3e2SJacob Faibussowitsch PetscCheckFalse(!Y_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_solve failed"); 108*5f80ce2aSJacob Faibussowitsch CHKERRQ(!cholmod_l_free_dense(&Z_handle, chol->common)); 10902ef7dfaSPierre Jolivet } 110a2fc1e05SToby Isaac *_Y_handle = Y_handle; 111*5f80ce2aSJacob Faibussowitsch CHKERRQ(!cholmod_l_free_dense(&QTB_handle, chol->common)); 112a2fc1e05SToby Isaac PetscFunctionReturn(0); 113a2fc1e05SToby Isaac } 114a2fc1e05SToby Isaac 115a2fc1e05SToby Isaac static PetscErrorCode MatSolve_SPQR(Mat F,Vec B,Vec X) 116a2fc1e05SToby Isaac { 117a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 118a2fc1e05SToby Isaac cholmod_dense cholB,*Y_handle = NULL; 119a2fc1e05SToby Isaac PetscInt n; 120a2fc1e05SToby Isaac PetscScalar *v; 121a2fc1e05SToby Isaac 122a2fc1e05SToby Isaac PetscFunctionBegin; 123*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecWrapCholmod(B,GET_ARRAY_READ,&cholB)); 124*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSolve_SPQR_Internal(F, &cholB, &Y_handle)); 125*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(X, &n)); 126*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(X, &v)); 127*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(v, (PetscScalar *) (Y_handle->x), n)); 128*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(X, &v)); 129*5f80ce2aSJacob Faibussowitsch CHKERRQ(!cholmod_l_free_dense(&Y_handle, chol->common)); 130*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecUnWrapCholmod(B,GET_ARRAY_READ,&cholB)); 131a2fc1e05SToby Isaac PetscFunctionReturn(0); 132a2fc1e05SToby Isaac } 133a2fc1e05SToby Isaac 134a2fc1e05SToby Isaac static PetscErrorCode MatMatSolve_SPQR(Mat F,Mat B,Mat X) 135a2fc1e05SToby Isaac { 136a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 137a2fc1e05SToby Isaac cholmod_dense cholB,*Y_handle = NULL; 138a2fc1e05SToby Isaac PetscScalar *v; 139a2fc1e05SToby Isaac PetscInt lda; 140a2fc1e05SToby Isaac 141a2fc1e05SToby Isaac PetscFunctionBegin; 142*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseWrapCholmod(B,GET_ARRAY_READ,&cholB)); 143*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSolve_SPQR_Internal(F, &cholB, &Y_handle)); 144*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseGetArrayWrite(X, &v)); 145*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseGetLDA(X, &lda)); 146a2fc1e05SToby Isaac if ((size_t) lda == Y_handle->d) { 147*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(v, (PetscScalar *) (Y_handle->x), lda * Y_handle->ncol)); 148a2fc1e05SToby Isaac } else { 149a2fc1e05SToby Isaac for (size_t j = 0; j < Y_handle->ncol; j++) { 150*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(&v[j*lda], &(((PetscScalar *) Y_handle->x)[j*Y_handle->d]), Y_handle->nrow)); 151a2fc1e05SToby Isaac } 152a2fc1e05SToby Isaac } 153*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseRestoreArrayWrite(X, &v)); 154*5f80ce2aSJacob Faibussowitsch CHKERRQ(!cholmod_l_free_dense(&Y_handle, chol->common)); 155*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseUnWrapCholmod(B,GET_ARRAY_READ,&cholB)); 156a2fc1e05SToby Isaac PetscFunctionReturn(0); 157a2fc1e05SToby Isaac } 158a2fc1e05SToby Isaac 159a2fc1e05SToby Isaac static PetscErrorCode MatSolveTranspose_SPQR_Internal(Mat F, cholmod_dense *cholB, cholmod_dense **_Y_handle) 160a2fc1e05SToby Isaac { 161a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 162a2fc1e05SToby Isaac cholmod_dense *Y_handle = NULL, *RTB_handle = NULL; 163a2fc1e05SToby Isaac 164a2fc1e05SToby Isaac PetscFunctionBegin; 165a2fc1e05SToby Isaac RTB_handle = SuiteSparseQR_C_solve(SPQR_RTX_EQUALS_ETB, chol->spqrfact, cholB, chol->common); 1662c71b3e2SJacob Faibussowitsch PetscCheckFalse(!RTB_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_solve failed"); 167a2fc1e05SToby Isaac Y_handle = SuiteSparseQR_C_qmult(SPQR_QX, chol->spqrfact, RTB_handle, chol->common); 1682c71b3e2SJacob Faibussowitsch PetscCheckFalse(!Y_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_qmult failed"); 169a2fc1e05SToby Isaac *_Y_handle = Y_handle; 170*5f80ce2aSJacob Faibussowitsch CHKERRQ(!cholmod_l_free_dense(&RTB_handle, chol->common)); 171a2fc1e05SToby Isaac PetscFunctionReturn(0); 172a2fc1e05SToby Isaac } 173a2fc1e05SToby Isaac 174a2fc1e05SToby Isaac static PetscErrorCode MatSolveTranspose_SPQR(Mat F,Vec B,Vec X) 175a2fc1e05SToby Isaac { 176a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 177a2fc1e05SToby Isaac cholmod_dense cholB,*Y_handle = NULL; 178a2fc1e05SToby Isaac PetscInt n; 179a2fc1e05SToby Isaac PetscScalar *v; 180a2fc1e05SToby Isaac 181a2fc1e05SToby Isaac PetscFunctionBegin; 182*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecWrapCholmod(B,GET_ARRAY_READ,&cholB)); 183*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSolveTranspose_SPQR_Internal(F, &cholB, &Y_handle)); 184*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(X, &n)); 185*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(X, &v)); 186*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(v, (PetscScalar *) Y_handle->x, n)); 187*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(X, &v)); 188*5f80ce2aSJacob Faibussowitsch CHKERRQ(!cholmod_l_free_dense(&Y_handle, chol->common)); 189*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecUnWrapCholmod(B,GET_ARRAY_READ,&cholB)); 190a2fc1e05SToby Isaac PetscFunctionReturn(0); 191a2fc1e05SToby Isaac } 192a2fc1e05SToby Isaac 193a2fc1e05SToby Isaac static PetscErrorCode MatMatSolveTranspose_SPQR(Mat F,Mat B,Mat X) 194a2fc1e05SToby Isaac { 195a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 196a2fc1e05SToby Isaac cholmod_dense cholB,*Y_handle = NULL; 197a2fc1e05SToby Isaac PetscScalar *v; 198a2fc1e05SToby Isaac PetscInt lda; 199a2fc1e05SToby Isaac 200a2fc1e05SToby Isaac PetscFunctionBegin; 201*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseWrapCholmod(B,GET_ARRAY_READ,&cholB)); 202*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSolveTranspose_SPQR_Internal(F, &cholB, &Y_handle)); 203*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseGetArrayWrite(X, &v)); 204*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseGetLDA(X, &lda)); 205a2fc1e05SToby Isaac if ((size_t) lda == Y_handle->d) { 206*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(v, (PetscScalar *) Y_handle->x, lda * Y_handle->ncol)); 207a2fc1e05SToby Isaac } else { 208a2fc1e05SToby Isaac for (size_t j = 0; j < Y_handle->ncol; j++) { 209*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(&v[j*lda], &(((PetscScalar *) Y_handle->x)[j*Y_handle->d]), Y_handle->nrow)); 210a2fc1e05SToby Isaac } 211a2fc1e05SToby Isaac } 212*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseRestoreArrayWrite(X, &v)); 213*5f80ce2aSJacob Faibussowitsch CHKERRQ(!cholmod_l_free_dense(&Y_handle, chol->common)); 214*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseUnWrapCholmod(B,GET_ARRAY_READ,&cholB)); 215a2fc1e05SToby Isaac PetscFunctionReturn(0); 216a2fc1e05SToby Isaac } 217a2fc1e05SToby Isaac 218a2fc1e05SToby Isaac static PetscErrorCode MatQRFactorNumeric_SPQR(Mat F,Mat A,const MatFactorInfo *info) 219a2fc1e05SToby Isaac { 220a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 221a2fc1e05SToby Isaac cholmod_sparse cholA; 22265f45395SPierre Jolivet PetscBool aijalloc,valloc; 223a2fc1e05SToby Isaac PetscErrorCode ierr; 224a2fc1e05SToby Isaac 225a2fc1e05SToby Isaac PetscFunctionBegin; 226*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATNORMALHERMITIAN, &chol->normal)); 22765f45395SPierre Jolivet if (!chol->normal && !PetscDefined(USE_COMPLEX)) { 228*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATNORMAL, &chol->normal)); 22965f45395SPierre Jolivet } 230*5f80ce2aSJacob Faibussowitsch CHKERRQ((*chol->Wrap)(A,PETSC_TRUE,&cholA,&aijalloc,&valloc)); 231d0f82a0bSPierre Jolivet ierr = !SuiteSparseQR_C_numeric(PETSC_SMALL, &cholA, chol->spqrfact, chol->common); 2322c71b3e2SJacob Faibussowitsch PetscCheckFalse(ierr,PetscObjectComm((PetscObject)F),PETSC_ERR_LIB,"SPQR factorization failed with status %d",chol->common->status); 233a2fc1e05SToby Isaac 234*5f80ce2aSJacob Faibussowitsch if (aijalloc) CHKERRQ(PetscFree2(cholA.p,cholA.i)); 235*5f80ce2aSJacob Faibussowitsch if (valloc) CHKERRQ(PetscFree(cholA.x)); 236a2fc1e05SToby Isaac 237a2fc1e05SToby Isaac F->ops->solve = MatSolve_SPQR; 238a2fc1e05SToby Isaac F->ops->matsolve = MatMatSolve_SPQR; 23902ef7dfaSPierre Jolivet if (chol->normal) { 24002ef7dfaSPierre Jolivet F->ops->solvetranspose = MatSolve_SPQR; 24102ef7dfaSPierre Jolivet F->ops->matsolvetranspose = MatMatSolve_SPQR; 24202ef7dfaSPierre Jolivet } else if (A->cmap->n == A->rmap->n) { 243a2fc1e05SToby Isaac F->ops->solvetranspose = MatSolveTranspose_SPQR; 244a2fc1e05SToby Isaac F->ops->matsolvetranspose = MatMatSolveTranspose_SPQR; 245a2fc1e05SToby Isaac } 246a2fc1e05SToby Isaac PetscFunctionReturn(0); 247a2fc1e05SToby Isaac } 248a2fc1e05SToby Isaac 249a2fc1e05SToby Isaac PETSC_INTERN PetscErrorCode MatQRFactorSymbolic_SPQR(Mat F,Mat A,IS perm,const MatFactorInfo *info) 250a2fc1e05SToby Isaac { 251a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 252a2fc1e05SToby Isaac cholmod_sparse cholA; 25365f45395SPierre Jolivet PetscBool aijalloc,valloc; 254a2fc1e05SToby Isaac 255a2fc1e05SToby Isaac PetscFunctionBegin; 256*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATNORMALHERMITIAN, &chol->normal)); 25765f45395SPierre Jolivet if (!chol->normal && !PetscDefined(USE_COMPLEX)) { 258*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATNORMAL, &chol->normal)); 25965f45395SPierre Jolivet } 260*5f80ce2aSJacob Faibussowitsch CHKERRQ((*chol->Wrap)(A,PETSC_TRUE,&cholA,&aijalloc,&valloc)); 261a2fc1e05SToby Isaac if (PetscDefined(USE_DEBUG)) { 262*5f80ce2aSJacob Faibussowitsch CHKERRQ(!cholmod_l_check_sparse(&cholA, chol->common)); 263a2fc1e05SToby Isaac } 264a2fc1e05SToby Isaac if (chol->spqrfact) { 265*5f80ce2aSJacob Faibussowitsch CHKERRQ(!SuiteSparseQR_C_free(&chol->spqrfact, chol->common)); 266a2fc1e05SToby Isaac } 267d0f82a0bSPierre Jolivet chol->spqrfact = SuiteSparseQR_C_symbolic(SPQR_ORDERING_DEFAULT, 1, &cholA, chol->common); 2682c71b3e2SJacob Faibussowitsch PetscCheckFalse(!chol->spqrfact,PetscObjectComm((PetscObject)F),PETSC_ERR_LIB,"CHOLMOD analysis failed using internal ordering with status %d",chol->common->status); 269a2fc1e05SToby Isaac 270*5f80ce2aSJacob Faibussowitsch if (aijalloc) CHKERRQ(PetscFree2(cholA.p,cholA.i)); 271*5f80ce2aSJacob Faibussowitsch if (valloc) CHKERRQ(PetscFree(cholA.x)); 272a2fc1e05SToby Isaac 273*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)F,"MatQRFactorNumeric_C", MatQRFactorNumeric_SPQR)); 274a2fc1e05SToby Isaac PetscFunctionReturn(0); 275a2fc1e05SToby Isaac } 276a2fc1e05SToby Isaac 277a2fc1e05SToby Isaac /*MC 278a2fc1e05SToby Isaac MATSOLVERSPQR 279a2fc1e05SToby Isaac 280a2fc1e05SToby Isaac A matrix type providing direct solvers (QR factorizations) for sequential matrices 281a2fc1e05SToby Isaac via the external package SPQR. 282a2fc1e05SToby Isaac 283a2fc1e05SToby Isaac Use ./configure --download-suitesparse to install PETSc to use CHOLMOD 284a2fc1e05SToby Isaac 285a2fc1e05SToby Isaac Consult SPQR documentation for more information about the Common parameters 286a2fc1e05SToby Isaac which correspond to the options database keys below. 287a2fc1e05SToby Isaac 288a2fc1e05SToby Isaac Level: beginner 289a2fc1e05SToby Isaac 290a2fc1e05SToby Isaac Note: SPQR is part of SuiteSparse http://faculty.cse.tamu.edu/davis/suitesparse.html 291a2fc1e05SToby Isaac 292a2fc1e05SToby Isaac .seealso: PCQR, PCFactorSetMatSolverType(), MatSolverType 293a2fc1e05SToby Isaac M*/ 294a2fc1e05SToby Isaac 295a2fc1e05SToby Isaac PETSC_INTERN PetscErrorCode MatGetFactor_seqaij_spqr(Mat A,MatFactorType ftype,Mat *F) 296a2fc1e05SToby Isaac { 297a2fc1e05SToby Isaac Mat B; 298a2fc1e05SToby Isaac Mat_CHOLMOD *chol; 299a2fc1e05SToby Isaac PetscInt m=A->rmap->n,n=A->cmap->n; 300a2fc1e05SToby Isaac const char *prefix; 301a2fc1e05SToby Isaac 302a2fc1e05SToby Isaac PetscFunctionBegin; 303a2fc1e05SToby Isaac /* Create the factorization matrix F */ 304*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PetscObjectComm((PetscObject)A),&B)); 305*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,m,n)); 306*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrallocpy("spqr",&((PetscObject)B)->type_name)); 307*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetOptionsPrefix(A,&prefix)); 308*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetOptionsPrefix(B,prefix)); 309*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetUp(B)); 310*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(B,&chol)); 311a2fc1e05SToby Isaac 312a2fc1e05SToby Isaac chol->Wrap = MatWrapCholmod_SPQR_seqaij; 313a2fc1e05SToby Isaac B->data = chol; 314a2fc1e05SToby Isaac 315a2fc1e05SToby Isaac B->ops->getinfo = MatGetInfo_CHOLMOD; 316a2fc1e05SToby Isaac B->ops->view = MatView_CHOLMOD; 317a2fc1e05SToby Isaac B->ops->destroy = MatDestroy_CHOLMOD; 318a2fc1e05SToby Isaac 319*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_seqaij_SPQR)); 320*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatQRFactorSymbolic_C", MatQRFactorSymbolic_SPQR)); 321a2fc1e05SToby Isaac 322a2fc1e05SToby Isaac B->factortype = MAT_FACTOR_QR; 323a2fc1e05SToby Isaac B->assembled = PETSC_TRUE; 324a2fc1e05SToby Isaac B->preallocated = PETSC_TRUE; 325a2fc1e05SToby Isaac 326*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(B->solvertype)); 327*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrallocpy(MATSOLVERCHOLMOD,&B->solvertype)); 328a2fc1e05SToby Isaac B->canuseordering = PETSC_FALSE; 329*5f80ce2aSJacob Faibussowitsch CHKERRQ(CholmodStart(B)); 330a2fc1e05SToby Isaac chol->common->itype = CHOLMOD_LONG; 331a2fc1e05SToby Isaac *F = B; 332a2fc1e05SToby Isaac PetscFunctionReturn(0); 333a2fc1e05SToby Isaac } 334