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 PetscErrorCode ierr; 21a2fc1e05SToby Isaac 22a2fc1e05SToby Isaac PetscFunctionBegin; 2365f45395SPierre Jolivet ierr = PetscObjectTypeCompare((PetscObject)A, MATNORMALHERMITIAN, &flg);CHKERRQ(ierr); 2465f45395SPierre Jolivet if (flg) { 2565f45395SPierre Jolivet ierr = MatNormalHermitianGetMat(A, &A);CHKERRQ(ierr); 2665f45395SPierre Jolivet } else if (!PetscDefined(USE_COMPLEX)) { 2702ef7dfaSPierre Jolivet ierr = PetscObjectTypeCompare((PetscObject)A, MATNORMAL, &flg);CHKERRQ(ierr); 2802ef7dfaSPierre Jolivet if (flg) { 2902ef7dfaSPierre Jolivet ierr = MatNormalGetMat(A, &A);CHKERRQ(ierr); 3002ef7dfaSPierre Jolivet } 3165f45395SPierre Jolivet } 32a2fc1e05SToby Isaac /* cholmod_sparse is compressed sparse column */ 3302ef7dfaSPierre Jolivet ierr = MatGetOption(A, MAT_SYMMETRIC, &flg);CHKERRQ(ierr); 3402ef7dfaSPierre Jolivet if (flg) { 35a2fc1e05SToby Isaac ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 36a2fc1e05SToby Isaac AT = A; 37a2fc1e05SToby Isaac } else { 38a2fc1e05SToby Isaac ierr = MatTranspose(A, MAT_INITIAL_MATRIX, &AT);CHKERRQ(ierr); 39a2fc1e05SToby Isaac } 40a2fc1e05SToby Isaac aij = (Mat_SeqAIJ*)AT->data; 41a2fc1e05SToby Isaac ai = aij->j; 42a2fc1e05SToby Isaac aj = aij->i; 43a2fc1e05SToby Isaac for (j=0,nz=0; j<n; j++) nz += aj[j+1] - aj[j]; 44a2fc1e05SToby Isaac ierr = PetscMalloc2(n+1,&cj,nz,&ci);CHKERRQ(ierr); 45a2fc1e05SToby Isaac if (values) { 46a2fc1e05SToby Isaac vain = PETSC_TRUE; 47a2fc1e05SToby Isaac ierr = PetscMalloc1(nz,&ca);CHKERRQ(ierr); 48a2fc1e05SToby Isaac ierr = MatSeqAIJGetArrayRead(AT,&aa);CHKERRQ(ierr); 49a2fc1e05SToby Isaac } 50a2fc1e05SToby Isaac for (j=0,k=0; j<n; j++) { 51a2fc1e05SToby Isaac cj[j] = k; 52a2fc1e05SToby Isaac for (i=aj[j]; i<aj[j+1]; i++,k++) { 53a2fc1e05SToby Isaac ci[k] = ai[i]; 54a2fc1e05SToby Isaac if (values) ca[k] = aa[i]; 55a2fc1e05SToby Isaac } 56a2fc1e05SToby Isaac } 57a2fc1e05SToby Isaac cj[j] = k; 58a2fc1e05SToby Isaac *aijalloc = PETSC_TRUE; 59a2fc1e05SToby Isaac *valloc = vain; 60a2fc1e05SToby Isaac if (values) { 61b2397800SPierre Jolivet ierr = MatSeqAIJRestoreArrayRead(AT,&aa);CHKERRQ(ierr); 62a2fc1e05SToby Isaac } 63a2fc1e05SToby Isaac 64a2fc1e05SToby Isaac ierr = PetscMemzero(C,sizeof(*C));CHKERRQ(ierr); 65a2fc1e05SToby Isaac 6602ef7dfaSPierre Jolivet C->nrow = (size_t)AT->cmap->n; 6702ef7dfaSPierre Jolivet C->ncol = (size_t)AT->rmap->n; 68a2fc1e05SToby Isaac C->nzmax = (size_t)nz; 69a2fc1e05SToby Isaac C->p = cj; 70a2fc1e05SToby Isaac C->i = ci; 71a2fc1e05SToby Isaac C->x = values ? ca : 0; 72a2fc1e05SToby Isaac C->stype = 0; 73a2fc1e05SToby Isaac C->itype = CHOLMOD_LONG; 74a2fc1e05SToby Isaac C->xtype = values ? CHOLMOD_SCALAR_TYPE : CHOLMOD_PATTERN; 75a2fc1e05SToby Isaac C->dtype = CHOLMOD_DOUBLE; 76a2fc1e05SToby Isaac C->sorted = 1; 77a2fc1e05SToby Isaac C->packed = 1; 78a2fc1e05SToby Isaac 79a2fc1e05SToby Isaac ierr = MatDestroy(&AT);CHKERRQ(ierr); 80a2fc1e05SToby Isaac PetscFunctionReturn(0); 81a2fc1e05SToby Isaac } 82a2fc1e05SToby Isaac 83a2fc1e05SToby Isaac static PetscErrorCode MatFactorGetSolverType_seqaij_SPQR(Mat A,MatSolverType *type) 84a2fc1e05SToby Isaac { 85a2fc1e05SToby Isaac PetscFunctionBegin; 86a2fc1e05SToby Isaac *type = MATSOLVERSPQR; 87a2fc1e05SToby Isaac PetscFunctionReturn(0); 88a2fc1e05SToby Isaac } 89a2fc1e05SToby Isaac 90a2fc1e05SToby Isaac #define GET_ARRAY_READ 0 91a2fc1e05SToby Isaac #define GET_ARRAY_WRITE 1 92a2fc1e05SToby Isaac 93a2fc1e05SToby Isaac static PetscErrorCode MatSolve_SPQR_Internal(Mat F, cholmod_dense *cholB, cholmod_dense **_Y_handle) 94a2fc1e05SToby Isaac { 95a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 9602ef7dfaSPierre Jolivet cholmod_dense *Y_handle = NULL, *QTB_handle = NULL, *Z_handle = NULL; 97a2fc1e05SToby Isaac PetscErrorCode ierr; 98a2fc1e05SToby Isaac 99a2fc1e05SToby Isaac PetscFunctionBegin; 10002ef7dfaSPierre Jolivet if (!chol->normal) { 101a2fc1e05SToby Isaac QTB_handle = SuiteSparseQR_C_qmult(SPQR_QTX, chol->spqrfact, cholB, chol->common); 102*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!QTB_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_qmult failed"); 103a2fc1e05SToby Isaac Y_handle = SuiteSparseQR_C_solve(SPQR_RETX_EQUALS_B, chol->spqrfact, QTB_handle, chol->common); 104*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!Y_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_solve failed"); 10502ef7dfaSPierre Jolivet } else { 10602ef7dfaSPierre Jolivet Z_handle = SuiteSparseQR_C_solve(SPQR_RTX_EQUALS_ETB, chol->spqrfact, cholB, chol->common); 107*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!Z_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_solve failed"); 10802ef7dfaSPierre Jolivet Y_handle = SuiteSparseQR_C_solve(SPQR_RETX_EQUALS_B, chol->spqrfact, Z_handle, chol->common); 109*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!Y_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_solve failed"); 11002ef7dfaSPierre Jolivet ierr = !cholmod_l_free_dense(&Z_handle, chol->common);CHKERRQ(ierr); 11102ef7dfaSPierre Jolivet } 112a2fc1e05SToby Isaac *_Y_handle = Y_handle; 113a2fc1e05SToby Isaac ierr = !cholmod_l_free_dense(&QTB_handle, chol->common);CHKERRQ(ierr); 114a2fc1e05SToby Isaac PetscFunctionReturn(0); 115a2fc1e05SToby Isaac } 116a2fc1e05SToby Isaac 117a2fc1e05SToby Isaac static PetscErrorCode MatSolve_SPQR(Mat F,Vec B,Vec X) 118a2fc1e05SToby Isaac { 119a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 120a2fc1e05SToby Isaac cholmod_dense cholB,*Y_handle = NULL; 121a2fc1e05SToby Isaac PetscInt n; 122a2fc1e05SToby Isaac PetscScalar *v; 123a2fc1e05SToby Isaac PetscErrorCode ierr; 124a2fc1e05SToby Isaac 125a2fc1e05SToby Isaac PetscFunctionBegin; 126a2fc1e05SToby Isaac ierr = VecWrapCholmod(B,GET_ARRAY_READ,&cholB);CHKERRQ(ierr); 127a2fc1e05SToby Isaac ierr = MatSolve_SPQR_Internal(F, &cholB, &Y_handle);CHKERRQ(ierr); 128a2fc1e05SToby Isaac ierr = VecGetLocalSize(X, &n);CHKERRQ(ierr); 129a2fc1e05SToby Isaac ierr = VecGetArrayWrite(X, &v);CHKERRQ(ierr); 130a2fc1e05SToby Isaac ierr = PetscArraycpy(v, (PetscScalar *) (Y_handle->x), n);CHKERRQ(ierr); 131a2fc1e05SToby Isaac ierr = VecRestoreArrayWrite(X, &v);CHKERRQ(ierr); 132a2fc1e05SToby Isaac ierr = !cholmod_l_free_dense(&Y_handle, chol->common);CHKERRQ(ierr); 133a2fc1e05SToby Isaac ierr = VecUnWrapCholmod(B,GET_ARRAY_READ,&cholB);CHKERRQ(ierr); 134a2fc1e05SToby Isaac PetscFunctionReturn(0); 135a2fc1e05SToby Isaac } 136a2fc1e05SToby Isaac 137a2fc1e05SToby Isaac static PetscErrorCode MatMatSolve_SPQR(Mat F,Mat B,Mat X) 138a2fc1e05SToby Isaac { 139a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 140a2fc1e05SToby Isaac cholmod_dense cholB,*Y_handle = NULL; 141a2fc1e05SToby Isaac PetscScalar *v; 142a2fc1e05SToby Isaac PetscInt lda; 143a2fc1e05SToby Isaac PetscErrorCode ierr; 144a2fc1e05SToby Isaac 145a2fc1e05SToby Isaac PetscFunctionBegin; 146a2fc1e05SToby Isaac ierr = MatDenseWrapCholmod(B,GET_ARRAY_READ,&cholB);CHKERRQ(ierr); 147a2fc1e05SToby Isaac ierr = MatSolve_SPQR_Internal(F, &cholB, &Y_handle);CHKERRQ(ierr); 148a2fc1e05SToby Isaac ierr = MatDenseGetArrayWrite(X, &v);CHKERRQ(ierr); 149a2fc1e05SToby Isaac ierr = MatDenseGetLDA(X, &lda);CHKERRQ(ierr); 150a2fc1e05SToby Isaac if ((size_t) lda == Y_handle->d) { 151a2fc1e05SToby Isaac ierr = PetscArraycpy(v, (PetscScalar *) (Y_handle->x), lda * Y_handle->ncol);CHKERRQ(ierr); 152a2fc1e05SToby Isaac } else { 153a2fc1e05SToby Isaac for (size_t j = 0; j < Y_handle->ncol; j++) { 154a2fc1e05SToby Isaac ierr = PetscArraycpy(&v[j*lda], &(((PetscScalar *) Y_handle->x)[j*Y_handle->d]), Y_handle->nrow);CHKERRQ(ierr); 155a2fc1e05SToby Isaac } 156a2fc1e05SToby Isaac } 157a2fc1e05SToby Isaac ierr = MatDenseRestoreArrayWrite(X, &v);CHKERRQ(ierr); 158a2fc1e05SToby Isaac ierr = !cholmod_l_free_dense(&Y_handle, chol->common);CHKERRQ(ierr); 159a2fc1e05SToby Isaac ierr = MatDenseUnWrapCholmod(B,GET_ARRAY_READ,&cholB);CHKERRQ(ierr); 160a2fc1e05SToby Isaac PetscFunctionReturn(0); 161a2fc1e05SToby Isaac } 162a2fc1e05SToby Isaac 163a2fc1e05SToby Isaac static PetscErrorCode MatSolveTranspose_SPQR_Internal(Mat F, cholmod_dense *cholB, cholmod_dense **_Y_handle) 164a2fc1e05SToby Isaac { 165a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 166a2fc1e05SToby Isaac cholmod_dense *Y_handle = NULL, *RTB_handle = NULL; 167a2fc1e05SToby Isaac PetscErrorCode ierr; 168a2fc1e05SToby Isaac 169a2fc1e05SToby Isaac PetscFunctionBegin; 170a2fc1e05SToby Isaac RTB_handle = SuiteSparseQR_C_solve(SPQR_RTX_EQUALS_ETB, chol->spqrfact, cholB, chol->common); 171*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!RTB_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_solve failed"); 172a2fc1e05SToby Isaac Y_handle = SuiteSparseQR_C_qmult(SPQR_QX, chol->spqrfact, RTB_handle, chol->common); 173*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!Y_handle,PetscObjectComm((PetscObject)F), PETSC_ERR_LIB, "SuiteSparseQR_C_qmult failed"); 174a2fc1e05SToby Isaac *_Y_handle = Y_handle; 175a2fc1e05SToby Isaac ierr = !cholmod_l_free_dense(&RTB_handle, chol->common);CHKERRQ(ierr); 176a2fc1e05SToby Isaac PetscFunctionReturn(0); 177a2fc1e05SToby Isaac } 178a2fc1e05SToby Isaac 179a2fc1e05SToby Isaac static PetscErrorCode MatSolveTranspose_SPQR(Mat F,Vec B,Vec X) 180a2fc1e05SToby Isaac { 181a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 182a2fc1e05SToby Isaac cholmod_dense cholB,*Y_handle = NULL; 183a2fc1e05SToby Isaac PetscInt n; 184a2fc1e05SToby Isaac PetscScalar *v; 185a2fc1e05SToby Isaac PetscErrorCode ierr; 186a2fc1e05SToby Isaac 187a2fc1e05SToby Isaac PetscFunctionBegin; 188a2fc1e05SToby Isaac ierr = VecWrapCholmod(B,GET_ARRAY_READ,&cholB);CHKERRQ(ierr); 189a2fc1e05SToby Isaac ierr = MatSolveTranspose_SPQR_Internal(F, &cholB, &Y_handle);CHKERRQ(ierr); 190a2fc1e05SToby Isaac ierr = VecGetLocalSize(X, &n);CHKERRQ(ierr); 191a2fc1e05SToby Isaac ierr = VecGetArrayWrite(X, &v);CHKERRQ(ierr); 192a2fc1e05SToby Isaac ierr = PetscArraycpy(v, (PetscScalar *) Y_handle->x, n);CHKERRQ(ierr); 193a2fc1e05SToby Isaac ierr = VecRestoreArrayWrite(X, &v);CHKERRQ(ierr); 194a2fc1e05SToby Isaac ierr = !cholmod_l_free_dense(&Y_handle, chol->common);CHKERRQ(ierr); 195a2fc1e05SToby Isaac ierr = VecUnWrapCholmod(B,GET_ARRAY_READ,&cholB);CHKERRQ(ierr); 196a2fc1e05SToby Isaac PetscFunctionReturn(0); 197a2fc1e05SToby Isaac } 198a2fc1e05SToby Isaac 199a2fc1e05SToby Isaac static PetscErrorCode MatMatSolveTranspose_SPQR(Mat F,Mat B,Mat X) 200a2fc1e05SToby Isaac { 201a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 202a2fc1e05SToby Isaac cholmod_dense cholB,*Y_handle = NULL; 203a2fc1e05SToby Isaac PetscScalar *v; 204a2fc1e05SToby Isaac PetscInt lda; 205a2fc1e05SToby Isaac PetscErrorCode ierr; 206a2fc1e05SToby Isaac 207a2fc1e05SToby Isaac PetscFunctionBegin; 208a2fc1e05SToby Isaac ierr = MatDenseWrapCholmod(B,GET_ARRAY_READ,&cholB);CHKERRQ(ierr); 209a2fc1e05SToby Isaac ierr = MatSolveTranspose_SPQR_Internal(F, &cholB, &Y_handle);CHKERRQ(ierr); 210a2fc1e05SToby Isaac ierr = MatDenseGetArrayWrite(X, &v);CHKERRQ(ierr); 211a2fc1e05SToby Isaac ierr = MatDenseGetLDA(X, &lda);CHKERRQ(ierr); 212a2fc1e05SToby Isaac if ((size_t) lda == Y_handle->d) { 213a2fc1e05SToby Isaac ierr = PetscArraycpy(v, (PetscScalar *) Y_handle->x, lda * Y_handle->ncol);CHKERRQ(ierr); 214a2fc1e05SToby Isaac } else { 215a2fc1e05SToby Isaac for (size_t j = 0; j < Y_handle->ncol; j++) { 216a2fc1e05SToby Isaac ierr = PetscArraycpy(&v[j*lda], &(((PetscScalar *) Y_handle->x)[j*Y_handle->d]), Y_handle->nrow);CHKERRQ(ierr); 217a2fc1e05SToby Isaac } 218a2fc1e05SToby Isaac } 219a2fc1e05SToby Isaac ierr = MatDenseRestoreArrayWrite(X, &v);CHKERRQ(ierr); 220a2fc1e05SToby Isaac ierr = !cholmod_l_free_dense(&Y_handle, chol->common);CHKERRQ(ierr); 221a2fc1e05SToby Isaac ierr = MatDenseUnWrapCholmod(B,GET_ARRAY_READ,&cholB);CHKERRQ(ierr); 222a2fc1e05SToby Isaac PetscFunctionReturn(0); 223a2fc1e05SToby Isaac } 224a2fc1e05SToby Isaac 225a2fc1e05SToby Isaac static PetscErrorCode MatQRFactorNumeric_SPQR(Mat F,Mat A,const MatFactorInfo *info) 226a2fc1e05SToby Isaac { 227a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 228a2fc1e05SToby Isaac cholmod_sparse cholA; 22965f45395SPierre Jolivet PetscBool aijalloc,valloc; 230a2fc1e05SToby Isaac PetscErrorCode ierr; 231a2fc1e05SToby Isaac 232a2fc1e05SToby Isaac PetscFunctionBegin; 23365f45395SPierre Jolivet ierr = PetscObjectTypeCompare((PetscObject)A, MATNORMALHERMITIAN, &chol->normal);CHKERRQ(ierr); 23465f45395SPierre Jolivet if (!chol->normal && !PetscDefined(USE_COMPLEX)) { 23565f45395SPierre Jolivet ierr = PetscObjectTypeCompare((PetscObject)A, MATNORMAL, &chol->normal);CHKERRQ(ierr); 23665f45395SPierre Jolivet } 237a2fc1e05SToby Isaac ierr = (*chol->Wrap)(A,PETSC_TRUE,&cholA,&aijalloc,&valloc);CHKERRQ(ierr); 238d0f82a0bSPierre Jolivet ierr = !SuiteSparseQR_C_numeric(PETSC_SMALL, &cholA, chol->spqrfact, chol->common); 239*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(ierr,PetscObjectComm((PetscObject)F),PETSC_ERR_LIB,"SPQR factorization failed with status %d",chol->common->status); 240a2fc1e05SToby Isaac 241a2fc1e05SToby Isaac if (aijalloc) {ierr = PetscFree2(cholA.p,cholA.i);CHKERRQ(ierr);} 242a2fc1e05SToby Isaac if (valloc) {ierr = PetscFree(cholA.x);CHKERRQ(ierr);} 243a2fc1e05SToby Isaac 244a2fc1e05SToby Isaac F->ops->solve = MatSolve_SPQR; 245a2fc1e05SToby Isaac F->ops->matsolve = MatMatSolve_SPQR; 24602ef7dfaSPierre Jolivet if (chol->normal) { 24702ef7dfaSPierre Jolivet F->ops->solvetranspose = MatSolve_SPQR; 24802ef7dfaSPierre Jolivet F->ops->matsolvetranspose = MatMatSolve_SPQR; 24902ef7dfaSPierre Jolivet } else if (A->cmap->n == A->rmap->n) { 250a2fc1e05SToby Isaac F->ops->solvetranspose = MatSolveTranspose_SPQR; 251a2fc1e05SToby Isaac F->ops->matsolvetranspose = MatMatSolveTranspose_SPQR; 252a2fc1e05SToby Isaac } 253a2fc1e05SToby Isaac PetscFunctionReturn(0); 254a2fc1e05SToby Isaac } 255a2fc1e05SToby Isaac 256a2fc1e05SToby Isaac PETSC_INTERN PetscErrorCode MatQRFactorSymbolic_SPQR(Mat F,Mat A,IS perm,const MatFactorInfo *info) 257a2fc1e05SToby Isaac { 258a2fc1e05SToby Isaac Mat_CHOLMOD *chol = (Mat_CHOLMOD*)F->data; 259a2fc1e05SToby Isaac PetscErrorCode ierr; 260a2fc1e05SToby Isaac cholmod_sparse cholA; 26165f45395SPierre Jolivet PetscBool aijalloc,valloc; 262a2fc1e05SToby Isaac 263a2fc1e05SToby Isaac PetscFunctionBegin; 26465f45395SPierre Jolivet ierr = PetscObjectTypeCompare((PetscObject)A, MATNORMALHERMITIAN, &chol->normal);CHKERRQ(ierr); 26565f45395SPierre Jolivet if (!chol->normal && !PetscDefined(USE_COMPLEX)) { 26665f45395SPierre Jolivet ierr = PetscObjectTypeCompare((PetscObject)A, MATNORMAL, &chol->normal);CHKERRQ(ierr); 26765f45395SPierre Jolivet } 268a2fc1e05SToby Isaac ierr = (*chol->Wrap)(A,PETSC_TRUE,&cholA,&aijalloc,&valloc);CHKERRQ(ierr); 269a2fc1e05SToby Isaac if (PetscDefined(USE_DEBUG)) { 270a2fc1e05SToby Isaac ierr = !cholmod_l_check_sparse(&cholA, chol->common);CHKERRQ(ierr); 271a2fc1e05SToby Isaac } 272a2fc1e05SToby Isaac if (chol->spqrfact) { 273a2fc1e05SToby Isaac ierr = !SuiteSparseQR_C_free(&chol->spqrfact, chol->common);CHKERRQ(ierr); 274a2fc1e05SToby Isaac } 275d0f82a0bSPierre Jolivet chol->spqrfact = SuiteSparseQR_C_symbolic(SPQR_ORDERING_DEFAULT, 1, &cholA, chol->common); 276*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!chol->spqrfact,PetscObjectComm((PetscObject)F),PETSC_ERR_LIB,"CHOLMOD analysis failed using internal ordering with status %d",chol->common->status); 277a2fc1e05SToby Isaac 278a2fc1e05SToby Isaac if (aijalloc) {ierr = PetscFree2(cholA.p,cholA.i);CHKERRQ(ierr);} 279a2fc1e05SToby Isaac if (valloc) {ierr = PetscFree(cholA.x);CHKERRQ(ierr);} 280a2fc1e05SToby Isaac 2811e1ea65dSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)F,"MatQRFactorNumeric_C", MatQRFactorNumeric_SPQR);CHKERRQ(ierr); 282a2fc1e05SToby Isaac PetscFunctionReturn(0); 283a2fc1e05SToby Isaac } 284a2fc1e05SToby Isaac 285a2fc1e05SToby Isaac /*MC 286a2fc1e05SToby Isaac MATSOLVERSPQR 287a2fc1e05SToby Isaac 288a2fc1e05SToby Isaac A matrix type providing direct solvers (QR factorizations) for sequential matrices 289a2fc1e05SToby Isaac via the external package SPQR. 290a2fc1e05SToby Isaac 291a2fc1e05SToby Isaac Use ./configure --download-suitesparse to install PETSc to use CHOLMOD 292a2fc1e05SToby Isaac 293a2fc1e05SToby Isaac Consult SPQR documentation for more information about the Common parameters 294a2fc1e05SToby Isaac which correspond to the options database keys below. 295a2fc1e05SToby Isaac 296a2fc1e05SToby Isaac Level: beginner 297a2fc1e05SToby Isaac 298a2fc1e05SToby Isaac Note: SPQR is part of SuiteSparse http://faculty.cse.tamu.edu/davis/suitesparse.html 299a2fc1e05SToby Isaac 300a2fc1e05SToby Isaac .seealso: PCQR, PCFactorSetMatSolverType(), MatSolverType 301a2fc1e05SToby Isaac M*/ 302a2fc1e05SToby Isaac 303a2fc1e05SToby Isaac PETSC_INTERN PetscErrorCode MatGetFactor_seqaij_spqr(Mat A,MatFactorType ftype,Mat *F) 304a2fc1e05SToby Isaac { 305a2fc1e05SToby Isaac Mat B; 306a2fc1e05SToby Isaac Mat_CHOLMOD *chol; 307a2fc1e05SToby Isaac PetscErrorCode ierr; 308a2fc1e05SToby Isaac PetscInt m=A->rmap->n,n=A->cmap->n; 309a2fc1e05SToby Isaac const char *prefix; 310a2fc1e05SToby Isaac 311a2fc1e05SToby Isaac PetscFunctionBegin; 312a2fc1e05SToby Isaac /* Create the factorization matrix F */ 313a2fc1e05SToby Isaac ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 314a2fc1e05SToby Isaac ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr); 315a2fc1e05SToby Isaac ierr = PetscStrallocpy("spqr",&((PetscObject)B)->type_name);CHKERRQ(ierr); 316a2fc1e05SToby Isaac ierr = MatGetOptionsPrefix(A,&prefix);CHKERRQ(ierr); 317a2fc1e05SToby Isaac ierr = MatSetOptionsPrefix(B,prefix);CHKERRQ(ierr); 318a2fc1e05SToby Isaac ierr = MatSetUp(B);CHKERRQ(ierr); 319a2fc1e05SToby Isaac ierr = PetscNewLog(B,&chol);CHKERRQ(ierr); 320a2fc1e05SToby Isaac 321a2fc1e05SToby Isaac chol->Wrap = MatWrapCholmod_SPQR_seqaij; 322a2fc1e05SToby Isaac B->data = chol; 323a2fc1e05SToby Isaac 324a2fc1e05SToby Isaac B->ops->getinfo = MatGetInfo_CHOLMOD; 325a2fc1e05SToby Isaac B->ops->view = MatView_CHOLMOD; 326a2fc1e05SToby Isaac B->ops->destroy = MatDestroy_CHOLMOD; 327a2fc1e05SToby Isaac 328a2fc1e05SToby Isaac ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_seqaij_SPQR);CHKERRQ(ierr); 3291e1ea65dSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactorSymbolic_C", MatQRFactorSymbolic_SPQR);CHKERRQ(ierr); 330a2fc1e05SToby Isaac 331a2fc1e05SToby Isaac B->factortype = MAT_FACTOR_QR; 332a2fc1e05SToby Isaac B->assembled = PETSC_TRUE; 333a2fc1e05SToby Isaac B->preallocated = PETSC_TRUE; 334a2fc1e05SToby Isaac 335a2fc1e05SToby Isaac ierr = PetscFree(B->solvertype);CHKERRQ(ierr); 336a2fc1e05SToby Isaac ierr = PetscStrallocpy(MATSOLVERCHOLMOD,&B->solvertype);CHKERRQ(ierr); 337a2fc1e05SToby Isaac B->canuseordering = PETSC_FALSE; 338a2fc1e05SToby Isaac ierr = CholmodStart(B);CHKERRQ(ierr); 339a2fc1e05SToby Isaac chol->common->itype = CHOLMOD_LONG; 340a2fc1e05SToby Isaac *F = B; 341a2fc1e05SToby Isaac PetscFunctionReturn(0); 342a2fc1e05SToby Isaac } 343a2fc1e05SToby Isaac 344