1*3bf14a46SMatthew Knepley #define PETSCMAT_DLL 2*3bf14a46SMatthew Knepley 3*3bf14a46SMatthew Knepley /* 4*3bf14a46SMatthew Knepley Provides an interface to the PaStiX sparse solver 5*3bf14a46SMatthew Knepley */ 6*3bf14a46SMatthew Knepley #include "../src/mat/impls/aij/seq/aij.h" 7*3bf14a46SMatthew Knepley #include "../src/mat/impls/aij/mpi/mpiaij.h" 8*3bf14a46SMatthew Knepley #include "../src/mat/impls/sbaij/seq/sbaij.h" 9*3bf14a46SMatthew Knepley #include "../src/mat/impls/sbaij/mpi/mpisbaij.h" 10*3bf14a46SMatthew Knepley 11*3bf14a46SMatthew Knepley EXTERN_C_BEGIN 12*3bf14a46SMatthew Knepley #include "mpi.h" 13*3bf14a46SMatthew Knepley #include "pastix.h" 14*3bf14a46SMatthew Knepley static int iter_print = 0; 15*3bf14a46SMatthew Knepley static int csr_iter_print = 0; 16*3bf14a46SMatthew Knepley EXTERN_C_END 17*3bf14a46SMatthew Knepley 18*3bf14a46SMatthew Knepley typedef struct Mat_Pastix_ { 19*3bf14a46SMatthew Knepley pastix_data_t *pastix_data; /* Pastix data storage structure */ 20*3bf14a46SMatthew Knepley MatStructure matstruc; 21*3bf14a46SMatthew Knepley PetscInt n; /* Number of columns in the matrix */ 22*3bf14a46SMatthew Knepley PetscInt *colptr; /* Index of first element of each column in row and val */ 23*3bf14a46SMatthew Knepley PetscInt *row; /* Row of each element of the matrix */ 24*3bf14a46SMatthew Knepley PetscScalar *val; /* Value of each element of the matrix */ 25*3bf14a46SMatthew Knepley PetscInt *perm; /* Permutation tabular */ 26*3bf14a46SMatthew Knepley PetscInt *invp; /* Reverse permutation tabular */ 27*3bf14a46SMatthew Knepley PetscScalar *rhs; /* Rhight-hand-side member */ 28*3bf14a46SMatthew Knepley PetscInt rhsnbr; /* Rhight-hand-side number (must be 1) */ 29*3bf14a46SMatthew Knepley PetscInt iparm[64]; /* Integer parameters */ 30*3bf14a46SMatthew Knepley double dparm[64]; /* Floating point parameters */ 31*3bf14a46SMatthew Knepley MPI_Comm pastix_comm; /* PaStiX MPI communicator */ 32*3bf14a46SMatthew Knepley PetscMPIInt commRank; /* MPI rank */ 33*3bf14a46SMatthew Knepley PetscMPIInt commSize; /* MPI communicator size */ 34*3bf14a46SMatthew Knepley PetscTruth CleanUpPastix; /* Boolean indicating if we call PaStiX clean step */ 35*3bf14a46SMatthew Knepley VecScatter scat_rhs; 36*3bf14a46SMatthew Knepley VecScatter scat_sol; 37*3bf14a46SMatthew Knepley Vec b_seq,x_seq; 38*3bf14a46SMatthew Knepley PetscTruth isAIJ; 39*3bf14a46SMatthew Knepley PetscInt nSolve; /* Number of consecutive solve */ 40*3bf14a46SMatthew Knepley PetscErrorCode (*MatDestroy)(Mat); 41*3bf14a46SMatthew Knepley } Mat_Pastix; 42*3bf14a46SMatthew Knepley 43*3bf14a46SMatthew Knepley EXTERN PetscErrorCode MatDuplicate_Pastix(Mat,MatDuplicateOption,Mat*); 44*3bf14a46SMatthew Knepley 45*3bf14a46SMatthew Knepley /* 46*3bf14a46SMatthew Knepley convert Petsc seqaij matrix to CSC: colptr[n], row[nz], val[nz] 47*3bf14a46SMatthew Knepley 48*3bf14a46SMatthew Knepley input: 49*3bf14a46SMatthew Knepley A - matrix in seqaij or mpisbaij (bs=1) format 50*3bf14a46SMatthew Knepley valOnly - FALSE: spaces are allocated and values are set for the CSC 51*3bf14a46SMatthew Knepley TRUE: Only fill values 52*3bf14a46SMatthew Knepley output: 53*3bf14a46SMatthew Knepley n - Size of the matrix 54*3bf14a46SMatthew Knepley colptr - Index of first element of each column in row and val 55*3bf14a46SMatthew Knepley row - Row of each element of the matrix 56*3bf14a46SMatthew Knepley values - Value of each element of the matrix 57*3bf14a46SMatthew Knepley */ 58*3bf14a46SMatthew Knepley PetscErrorCode MatConvertToCSC(Mat A, 59*3bf14a46SMatthew Knepley PetscTruth valOnly, 60*3bf14a46SMatthew Knepley PetscInt *n, 61*3bf14a46SMatthew Knepley PetscInt **colptr, 62*3bf14a46SMatthew Knepley PetscInt **row, 63*3bf14a46SMatthew Knepley PetscScalar **values) { 64*3bf14a46SMatthew Knepley Mat_SeqAIJ *aa = (Mat_SeqAIJ*)A->data; 65*3bf14a46SMatthew Knepley PetscInt *rowptr = aa->i; 66*3bf14a46SMatthew Knepley PetscInt *col = aa->j; 67*3bf14a46SMatthew Knepley PetscScalar *rvalues = aa->a; 68*3bf14a46SMatthew Knepley PetscInt m = A->rmap->N; 69*3bf14a46SMatthew Knepley PetscInt nnz = aa->nz; 70*3bf14a46SMatthew Knepley PetscInt i,j, k; 71*3bf14a46SMatthew Knepley PetscInt base = 1; 72*3bf14a46SMatthew Knepley PetscInt idx; 73*3bf14a46SMatthew Knepley PetscErrorCode ierr; 74*3bf14a46SMatthew Knepley PetscInt colidx; 75*3bf14a46SMatthew Knepley PetscInt *colcount; 76*3bf14a46SMatthew Knepley 77*3bf14a46SMatthew Knepley 78*3bf14a46SMatthew Knepley PetscFunctionBegin; 79*3bf14a46SMatthew Knepley /* Allocate the CSC */ 80*3bf14a46SMatthew Knepley 81*3bf14a46SMatthew Knepley *n = A->cmap->N; 82*3bf14a46SMatthew Knepley { 83*3bf14a46SMatthew Knepley int rank; 84*3bf14a46SMatthew Knepley MPI_Comm_rank(MPI_COMM_WORLD,&rank); 85*3bf14a46SMatthew Knepley char toto[30]; 86*3bf14a46SMatthew Knepley FILE * plop; 87*3bf14a46SMatthew Knepley 88*3bf14a46SMatthew Knepley sprintf(toto, "csr_ijv_%d_%d",rank, csr_iter_print); 89*3bf14a46SMatthew Knepley plop = fopen(toto,"w"); 90*3bf14a46SMatthew Knepley for (i = 0; i <*n ; i++) 91*3bf14a46SMatthew Knepley for (j = rowptr[i]; j < rowptr[i+1]; j++) 92*3bf14a46SMatthew Knepley fprintf(plop,"%ld\t%ld\t%lg\n", i+1, col[j]+1, rvalues[j]); 93*3bf14a46SMatthew Knepley fclose(plop); 94*3bf14a46SMatthew Knepley csr_iter_print++; 95*3bf14a46SMatthew Knepley } 96*3bf14a46SMatthew Knepley 97*3bf14a46SMatthew Knepley ierr = PetscMalloc((*n)*sizeof(PetscInt) ,&colcount);CHKERRQ(ierr); 98*3bf14a46SMatthew Knepley if (!valOnly){ 99*3bf14a46SMatthew Knepley ierr = PetscMalloc(((*n)+1) *sizeof(PetscInt) ,colptr );CHKERRQ(ierr); 100*3bf14a46SMatthew Knepley ierr = PetscMalloc( nnz *sizeof(PetscInt) ,row);CHKERRQ(ierr); 101*3bf14a46SMatthew Knepley ierr = PetscMalloc( nnz *sizeof(PetscScalar),values);CHKERRQ(ierr); 102*3bf14a46SMatthew Knepley 103*3bf14a46SMatthew Knepley for (i = 0; i < m; i++) 104*3bf14a46SMatthew Knepley colcount[i] = 0; 105*3bf14a46SMatthew Knepley /* Fill-in colptr */ 106*3bf14a46SMatthew Knepley for (i = 0; i < m; i++) 107*3bf14a46SMatthew Knepley for (j = rowptr[i]; j < rowptr[i+1]; j++) 108*3bf14a46SMatthew Knepley colcount[col[j]]++; 109*3bf14a46SMatthew Knepley (*colptr)[0] = base; 110*3bf14a46SMatthew Knepley for (j = 0; j < *n; j++) { 111*3bf14a46SMatthew Knepley (*colptr)[j+1] = (*colptr)[j] + colcount[j]; 112*3bf14a46SMatthew Knepley colcount[j] = -base; 113*3bf14a46SMatthew Knepley } 114*3bf14a46SMatthew Knepley 115*3bf14a46SMatthew Knepley /* Fill-in rows and values */ 116*3bf14a46SMatthew Knepley for (i = 0; i < m; i++) { 117*3bf14a46SMatthew Knepley for (j = rowptr[i]; j < rowptr[i+1]; j++) { 118*3bf14a46SMatthew Knepley colidx = col[j]; 119*3bf14a46SMatthew Knepley idx = (*colptr)[colidx] + colcount[colidx]; 120*3bf14a46SMatthew Knepley (*row)[idx] = i + base; 121*3bf14a46SMatthew Knepley (*values)[idx] = rvalues[j]; 122*3bf14a46SMatthew Knepley colcount[colidx]++; 123*3bf14a46SMatthew Knepley } 124*3bf14a46SMatthew Knepley } 125*3bf14a46SMatthew Knepley } 126*3bf14a46SMatthew Knepley else { 127*3bf14a46SMatthew Knepley /* Fill-in rows and values */ 128*3bf14a46SMatthew Knepley for (i = 0; i < m; i++) { 129*3bf14a46SMatthew Knepley for (j = rowptr[i]; j < rowptr[i+1]; j++) { 130*3bf14a46SMatthew Knepley colidx = col[j]; 131*3bf14a46SMatthew Knepley for (k = (*colptr)[colidx] - base; k < (*colptr)[colidx + 1] - base; k++) { 132*3bf14a46SMatthew Knepley if ((*row)[k] == i) { 133*3bf14a46SMatthew Knepley (*values)[k] = rvalues[j]; 134*3bf14a46SMatthew Knepley break; 135*3bf14a46SMatthew Knepley } 136*3bf14a46SMatthew Knepley } 137*3bf14a46SMatthew Knepley if (k == (*colptr)[colidx + 1] - base) 138*3bf14a46SMatthew Knepley PetscFunctionReturn(1); 139*3bf14a46SMatthew Knepley } 140*3bf14a46SMatthew Knepley } 141*3bf14a46SMatthew Knepley } 142*3bf14a46SMatthew Knepley ierr = PetscFree(colcount);CHKERRQ(ierr); 143*3bf14a46SMatthew Knepley 144*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 145*3bf14a46SMatthew Knepley } 146*3bf14a46SMatthew Knepley 147*3bf14a46SMatthew Knepley 148*3bf14a46SMatthew Knepley 149*3bf14a46SMatthew Knepley #undef __FUNCT__ 150*3bf14a46SMatthew Knepley #define __FUNCT__ "MatDestroy_Pastix" 151*3bf14a46SMatthew Knepley /* 152*3bf14a46SMatthew Knepley Call clean step of PaStiX if lu->CleanUpPastix == true. 153*3bf14a46SMatthew Knepley Free the CSC matrix. 154*3bf14a46SMatthew Knepley */ 155*3bf14a46SMatthew Knepley PetscErrorCode MatDestroy_Pastix(Mat A) 156*3bf14a46SMatthew Knepley { 157*3bf14a46SMatthew Knepley Mat_Pastix *lu=(Mat_Pastix*)A->spptr; 158*3bf14a46SMatthew Knepley PetscErrorCode ierr; 159*3bf14a46SMatthew Knepley PetscMPIInt size=lu->commSize; 160*3bf14a46SMatthew Knepley ierr = PetscPrintf(lu->pastix_comm,"MatDestroy_Pastix\n");CHKERRQ(ierr); 161*3bf14a46SMatthew Knepley PetscFunctionBegin; 162*3bf14a46SMatthew Knepley if (lu->CleanUpPastix) { 163*3bf14a46SMatthew Knepley /* Terminate instance, deallocate memories */ 164*3bf14a46SMatthew Knepley if (size > 1){ 165*3bf14a46SMatthew Knepley ierr = VecScatterDestroy(lu->scat_rhs);CHKERRQ(ierr); 166*3bf14a46SMatthew Knepley ierr = VecDestroy(lu->b_seq);CHKERRQ(ierr); 167*3bf14a46SMatthew Knepley if (lu->nSolve && lu->scat_sol){ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr);} 168*3bf14a46SMatthew Knepley if (lu->nSolve && lu->x_seq){ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr);} 169*3bf14a46SMatthew Knepley } 170*3bf14a46SMatthew Knepley 171*3bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK]=API_TASK_CLEAN; 172*3bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK]=API_TASK_CLEAN; 173*3bf14a46SMatthew Knepley 174*3bf14a46SMatthew Knepley fprintf(stdout, "lu->pastix_data before clean %x\n", lu->pastix_data); 175*3bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 176*3bf14a46SMatthew Knepley lu->pastix_comm, 177*3bf14a46SMatthew Knepley (pastix_int_t) lu->n, 178*3bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 179*3bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 180*3bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 181*3bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 182*3bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 183*3bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 184*3bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 185*3bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 186*3bf14a46SMatthew Knepley lu->dparm); 187*3bf14a46SMatthew Knepley fprintf(stdout, "lu->pastix_data after clean %x\n", lu->pastix_data); 188*3bf14a46SMatthew Knepley 189*3bf14a46SMatthew Knepley ierr = PetscFree(lu->colptr);CHKERRQ(ierr); 190*3bf14a46SMatthew Knepley ierr = PetscFree(lu->row); CHKERRQ(ierr); 191*3bf14a46SMatthew Knepley ierr = PetscFree(lu->val); CHKERRQ(ierr); 192*3bf14a46SMatthew Knepley ierr = PetscFree(lu->perm); CHKERRQ(ierr); 193*3bf14a46SMatthew Knepley ierr = PetscFree(lu->invp); CHKERRQ(ierr); 194*3bf14a46SMatthew Knepley /* ierr = PetscFree(lu->rhs); CHKERRQ(ierr); */ 195*3bf14a46SMatthew Knepley ierr = MPI_Comm_free(&(lu->pastix_comm));CHKERRQ(ierr); 196*3bf14a46SMatthew Knepley 197*3bf14a46SMatthew Knepley } 198*3bf14a46SMatthew Knepley ierr = (lu->MatDestroy)(A);CHKERRQ(ierr); 199*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 200*3bf14a46SMatthew Knepley } 201*3bf14a46SMatthew Knepley 202*3bf14a46SMatthew Knepley #undef __FUNCT__ 203*3bf14a46SMatthew Knepley #define __FUNCT__ "MatSolve_PaStiX" 204*3bf14a46SMatthew Knepley /* 205*3bf14a46SMatthew Knepley Gather right-hand-side. 206*3bf14a46SMatthew Knepley Call for Solve step. 207*3bf14a46SMatthew Knepley Scatter solution. 208*3bf14a46SMatthew Knepley */ 209*3bf14a46SMatthew Knepley PetscErrorCode MatSolve_PaStiX(Mat A,Vec b,Vec x) 210*3bf14a46SMatthew Knepley { 211*3bf14a46SMatthew Knepley Mat_Pastix *lu=(Mat_Pastix*)A->spptr; 212*3bf14a46SMatthew Knepley PetscScalar *array; 213*3bf14a46SMatthew Knepley Vec x_seq; 214*3bf14a46SMatthew Knepley IS is_iden,is_petsc; 215*3bf14a46SMatthew Knepley PetscErrorCode ierr; 216*3bf14a46SMatthew Knepley PetscInt i,j; 217*3bf14a46SMatthew Knepley 218*3bf14a46SMatthew Knepley ierr = PetscPrintf(lu->pastix_comm,"MatSolve_PaStiX\n");CHKERRQ(ierr); 219*3bf14a46SMatthew Knepley PetscFunctionBegin; 220*3bf14a46SMatthew Knepley lu->rhsnbr = 1; 221*3bf14a46SMatthew Knepley x_seq = lu->b_seq; 222*3bf14a46SMatthew Knepley if (lu->commSize > 1){ 223*3bf14a46SMatthew Knepley /* PaStiX only supports centralized rhs. Scatter b into a seqential rhs vector */ 224*3bf14a46SMatthew Knepley ierr = VecScatterBegin(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 225*3bf14a46SMatthew Knepley ierr = VecScatterEnd(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 226*3bf14a46SMatthew Knepley ierr = VecGetArray(x_seq,&array); 227*3bf14a46SMatthew Knepley CHKERRQ(ierr); 228*3bf14a46SMatthew Knepley } 229*3bf14a46SMatthew Knepley else { /* size == 1 */ 230*3bf14a46SMatthew Knepley ierr = VecCopy(b,x);CHKERRQ(ierr); 231*3bf14a46SMatthew Knepley ierr = VecGetArray(x,&array);CHKERRQ(ierr); 232*3bf14a46SMatthew Knepley } 233*3bf14a46SMatthew Knepley lu->rhs = array; 234*3bf14a46SMatthew Knepley if (lu->commSize == 1){ 235*3bf14a46SMatthew Knepley ierr = VecRestoreArray(x,&array);CHKERRQ(ierr); 236*3bf14a46SMatthew Knepley } else { 237*3bf14a46SMatthew Knepley ierr = VecRestoreArray(x_seq,&array);CHKERRQ(ierr); 238*3bf14a46SMatthew Knepley } 239*3bf14a46SMatthew Knepley 240*3bf14a46SMatthew Knepley /* solve phase */ 241*3bf14a46SMatthew Knepley /*-------------*/ 242*3bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK] = API_TASK_SOLVE; 243*3bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK] = API_TASK_REFINE; 244*3bf14a46SMatthew Knepley fprintf(stdout, "lu->pastix_data before solve %x\n", lu->pastix_data); 245*3bf14a46SMatthew Knepley 246*3bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 247*3bf14a46SMatthew Knepley (MPI_Comm) lu->pastix_comm, 248*3bf14a46SMatthew Knepley (pastix_int_t) lu->n, 249*3bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 250*3bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 251*3bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 252*3bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 253*3bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 254*3bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 255*3bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 256*3bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 257*3bf14a46SMatthew Knepley (double*) lu->dparm); 258*3bf14a46SMatthew Knepley 259*3bf14a46SMatthew Knepley if (lu->iparm[IPARM_ERROR_NUMBER] < 0) { 260*3bf14a46SMatthew Knepley SETERRQ1(PETSC_ERR_LIB,"Error reported by PaStiX in solve phase: lu->iparm[IPARM_ERROR_NUMBER] = %d\n", 261*3bf14a46SMatthew Knepley lu->iparm[IPARM_ERROR_NUMBER] ); 262*3bf14a46SMatthew Knepley } 263*3bf14a46SMatthew Knepley 264*3bf14a46SMatthew Knepley if (lu->commSize == 1){ 265*3bf14a46SMatthew Knepley ierr = VecRestoreArray(x,&(lu->rhs));CHKERRQ(ierr); 266*3bf14a46SMatthew Knepley } else { 267*3bf14a46SMatthew Knepley ierr = VecRestoreArray(x_seq,&(lu->rhs));CHKERRQ(ierr); 268*3bf14a46SMatthew Knepley } 269*3bf14a46SMatthew Knepley 270*3bf14a46SMatthew Knepley if (lu->commSize > 1) { /* convert PaStiX centralized solution to petsc mpi x */ 271*3bf14a46SMatthew Knepley ierr = VecScatterBegin(lu->scat_sol,x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 272*3bf14a46SMatthew Knepley ierr = VecScatterEnd(lu->scat_sol,x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 273*3bf14a46SMatthew Knepley } 274*3bf14a46SMatthew Knepley lu->nSolve++; 275*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 276*3bf14a46SMatthew Knepley } 277*3bf14a46SMatthew Knepley 278*3bf14a46SMatthew Knepley #if !defined(PETSC_USE_COMPLEX) 279*3bf14a46SMatthew Knepley /* 280*3bf14a46SMatthew Knepley TODO: Fill this function 281*3bf14a46SMatthew Knepley I didn't fill this function 282*3bf14a46SMatthew Knepley because I didn't understood its goal. 283*3bf14a46SMatthew Knepley */ 284*3bf14a46SMatthew Knepley 285*3bf14a46SMatthew Knepley /* 286*3bf14a46SMatthew Knepley input: 287*3bf14a46SMatthew Knepley F: numeric factor 288*3bf14a46SMatthew Knepley output: 289*3bf14a46SMatthew Knepley nneg: total number of pivots 290*3bf14a46SMatthew Knepley nzero: 0 291*3bf14a46SMatthew Knepley npos: (global dimension of F) - nneg 292*3bf14a46SMatthew Knepley */ 293*3bf14a46SMatthew Knepley 294*3bf14a46SMatthew Knepley #undef __FUNCT__ 295*3bf14a46SMatthew Knepley #define __FUNCT__ "MatGetInertia_SBAIJPASTIX" 296*3bf14a46SMatthew Knepley PetscErrorCode MatGetInertia_SBAIJPASTIX(Mat F,int *nneg,int *nzero,int *npos) 297*3bf14a46SMatthew Knepley { 298*3bf14a46SMatthew Knepley Mat_Pastix *lu =(Mat_Pastix*)F->spptr; 299*3bf14a46SMatthew Knepley PetscErrorCode ierr; 300*3bf14a46SMatthew Knepley PetscMPIInt size; 301*3bf14a46SMatthew Knepley 302*3bf14a46SMatthew Knepley ierr = PetscPrintf(lu->pastix_comm,"MatGetInertia_SBAIJPASTIX\n");CHKERRQ(ierr); 303*3bf14a46SMatthew Knepley PetscFunctionBegin; 304*3bf14a46SMatthew Knepley /* ierr = MPI_Comm_size(((PetscObject)F)->comm,&size);CHKERRQ(ierr); */ 305*3bf14a46SMatthew Knepley /* /\* PASTIX 4.3.1 calls ScaLAPACK when ICNTL(13)=0 (default), which does not offer the possibility to compute the inertia of a dense matrix. Set ICNTL(13)=1 to skip ScaLAPACK *\/ */ 306*3bf14a46SMatthew Knepley /* if (size > 1 && lu->id.ICNTL(13) != 1){ */ 307*3bf14a46SMatthew Knepley /* SETERRQ1(PETSC_ERR_ARG_WRONG,"ICNTL(13)=%d. -mat_pastix_icntl_13 must be set as 1 for correct global matrix inertia\n",lu->id.INFOG(13)); */ 308*3bf14a46SMatthew Knepley /* } */ 309*3bf14a46SMatthew Knepley /* if (nneg){ */ 310*3bf14a46SMatthew Knepley /* if (!lu->commSize){ */ 311*3bf14a46SMatthew Knepley /* *nneg = lu->id.INFOG(12); */ 312*3bf14a46SMatthew Knepley /* } */ 313*3bf14a46SMatthew Knepley /* ierr = MPI_Bcast(nneg,1,MPI_INT,0,lu->comm_pastix);CHKERRQ(ierr); */ 314*3bf14a46SMatthew Knepley /* } */ 315*3bf14a46SMatthew Knepley /* if (nzero) *nzero = lu->iparm[IPARM_NNZEROS]; */ 316*3bf14a46SMatthew Knepley /* if (npos) *npos = F->rmap->N - (*nneg); */ 317*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 318*3bf14a46SMatthew Knepley } 319*3bf14a46SMatthew Knepley #endif /* !defined(PETSC_USE_COMPLEX) */ 320*3bf14a46SMatthew Knepley 321*3bf14a46SMatthew Knepley /* 322*3bf14a46SMatthew Knepley Numeric factorisation using PaStiX solver. 323*3bf14a46SMatthew Knepley 324*3bf14a46SMatthew Knepley */ 325*3bf14a46SMatthew Knepley #undef __FUNCT__ 326*3bf14a46SMatthew Knepley #define __FUNCT__ "MatFactorNumeric_PASTIX" 327*3bf14a46SMatthew Knepley PetscErrorCode MatFactorNumeric_PaStiX(Mat F,Mat A,const MatFactorInfo *info) 328*3bf14a46SMatthew Knepley { 329*3bf14a46SMatthew Knepley Mat_Pastix *lu =(Mat_Pastix*)(F)->spptr; 330*3bf14a46SMatthew Knepley Mat *tseq,A_seq = PETSC_NULL; 331*3bf14a46SMatthew Knepley PetscErrorCode ierr = 0; 332*3bf14a46SMatthew Knepley PetscInt rnz,nnz,nz=0,i,*ai,*aj,icntl; 333*3bf14a46SMatthew Knepley PetscInt M=A->rmap->N,N=A->cmap->N; 334*3bf14a46SMatthew Knepley PetscTruth valOnly,flg, isSym; 335*3bf14a46SMatthew Knepley Mat F_diag; 336*3bf14a46SMatthew Knepley IS is_iden; 337*3bf14a46SMatthew Knepley Vec b; 338*3bf14a46SMatthew Knepley IS isrow; 339*3bf14a46SMatthew Knepley PetscTruth isSeqAIJ,isSeqSBAIJ; 340*3bf14a46SMatthew Knepley Mat_SeqAIJ *aa,*bb; 341*3bf14a46SMatthew Knepley 342*3bf14a46SMatthew Knepley ierr = PetscPrintf(((PetscObject)A)->comm,"MatFactorNumeric_PaStiX\n");CHKERRQ(ierr); 343*3bf14a46SMatthew Knepley PetscFunctionBegin; 344*3bf14a46SMatthew Knepley ierr = PetscTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr); 345*3bf14a46SMatthew Knepley ierr = PetscTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ);CHKERRQ(ierr); 346*3bf14a46SMatthew Knepley if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){ 347*3bf14a46SMatthew Knepley (F)->ops->solve = MatSolve_PaStiX; 348*3bf14a46SMatthew Knepley 349*3bf14a46SMatthew Knepley /* Initialize a PASTIX instance */ 350*3bf14a46SMatthew Knepley ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->pastix_comm));CHKERRQ(ierr); 351*3bf14a46SMatthew Knepley ierr = MPI_Comm_rank(lu->pastix_comm, &lu->commRank); CHKERRQ(ierr); 352*3bf14a46SMatthew Knepley ierr = MPI_Comm_size(lu->pastix_comm, &lu->commSize); CHKERRQ(ierr); 353*3bf14a46SMatthew Knepley 354*3bf14a46SMatthew Knepley /* Set pastix options */ 355*3bf14a46SMatthew Knepley lu->iparm[IPARM_MODIFY_PARAMETER] = API_NO; 356*3bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK] = API_TASK_INIT; 357*3bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK] = API_TASK_INIT; 358*3bf14a46SMatthew Knepley lu->rhsnbr = 1; 359*3bf14a46SMatthew Knepley 360*3bf14a46SMatthew Knepley /* Call to set default pastix options */ 361*3bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 362*3bf14a46SMatthew Knepley (MPI_Comm) lu->pastix_comm, 363*3bf14a46SMatthew Knepley (pastix_int_t) lu->n, 364*3bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 365*3bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 366*3bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 367*3bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 368*3bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 369*3bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 370*3bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 371*3bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 372*3bf14a46SMatthew Knepley (double*) lu->dparm); 373*3bf14a46SMatthew Knepley 374*3bf14a46SMatthew Knepley ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"PaStiX Options","Mat");CHKERRQ(ierr); 375*3bf14a46SMatthew Knepley 376*3bf14a46SMatthew Knepley icntl=-1; 377*3bf14a46SMatthew Knepley lu->iparm[IPARM_VERBOSE] = API_VERBOSE_NO; 378*3bf14a46SMatthew Knepley ierr = PetscOptionsInt("-mat_pastix_verbose","iparm[IPARM_VERBOSE] : level of printing (0 to 2)","None", 379*3bf14a46SMatthew Knepley lu->iparm[IPARM_VERBOSE],&icntl,&flg);CHKERRQ(ierr); 380*3bf14a46SMatthew Knepley if ((flg && icntl > 0) || PetscLogPrintInfo) { 381*3bf14a46SMatthew Knepley lu->iparm[IPARM_VERBOSE] = icntl; 382*3bf14a46SMatthew Knepley } 383*3bf14a46SMatthew Knepley icntl=-1; 384*3bf14a46SMatthew Knepley ierr = PetscOptionsInt("-mat_pastix_threadnbr","iparm[IPARM_THREAD_NBR] : Number of thread by MPI node", 385*3bf14a46SMatthew Knepley "None",lu->iparm[IPARM_THREAD_NBR],&icntl,PETSC_NULL);CHKERRQ(ierr); 386*3bf14a46SMatthew Knepley if ((flg && icntl > 0)) { 387*3bf14a46SMatthew Knepley lu->iparm[IPARM_THREAD_NBR] = icntl; 388*3bf14a46SMatthew Knepley } 389*3bf14a46SMatthew Knepley PetscOptionsEnd(); 390*3bf14a46SMatthew Knepley valOnly = PETSC_FALSE; 391*3bf14a46SMatthew Knepley } 392*3bf14a46SMatthew Knepley else { 393*3bf14a46SMatthew Knepley valOnly = PETSC_TRUE; 394*3bf14a46SMatthew Knepley } 395*3bf14a46SMatthew Knepley 396*3bf14a46SMatthew Knepley lu->iparm[IPARM_MATRIX_VERIFICATION] = API_YES; 397*3bf14a46SMatthew Knepley 398*3bf14a46SMatthew Knepley /* convert mpi A to seq mat A */ 399*3bf14a46SMatthew Knepley ierr = ISCreateStride(PETSC_COMM_SELF,M,0,1,&isrow);CHKERRQ(ierr); 400*3bf14a46SMatthew Knepley ierr = MatGetSubMatrices(A,1,&isrow,&isrow,MAT_INITIAL_MATRIX,&tseq);CHKERRQ(ierr); 401*3bf14a46SMatthew Knepley ierr = ISDestroy(isrow);CHKERRQ(ierr); 402*3bf14a46SMatthew Knepley A_seq = *tseq; 403*3bf14a46SMatthew Knepley ierr = PetscFree(tseq);CHKERRQ(ierr); 404*3bf14a46SMatthew Knepley 405*3bf14a46SMatthew Knepley ierr = MatConvertToCSC(A_seq,valOnly, &lu->n, &lu->colptr, &lu->row, &lu->val); CHKERRQ(ierr); 406*3bf14a46SMatthew Knepley ierr = PetscMalloc((lu->n)*sizeof(PetscInt) ,&(lu->perm));CHKERRQ(ierr); 407*3bf14a46SMatthew Knepley ierr = PetscMalloc((lu->n)*sizeof(PetscInt) ,&(lu->invp));CHKERRQ(ierr); 408*3bf14a46SMatthew Knepley 409*3bf14a46SMatthew Knepley { 410*3bf14a46SMatthew Knepley int rank; 411*3bf14a46SMatthew Knepley MPI_Comm_rank(MPI_COMM_WORLD,&rank); 412*3bf14a46SMatthew Knepley char toto[30]; 413*3bf14a46SMatthew Knepley FILE * plop; 414*3bf14a46SMatthew Knepley PetscInt i,j; 415*3bf14a46SMatthew Knepley sprintf(toto, "csc_ijv_%d_%d",rank, iter_print); 416*3bf14a46SMatthew Knepley plop = fopen(toto,"w"); 417*3bf14a46SMatthew Knepley for (i = 0; i <lu->n ; i++) 418*3bf14a46SMatthew Knepley for (j = lu->colptr[i]-1; j < lu->colptr[i+1]-1; j++) 419*3bf14a46SMatthew Knepley fprintf(plop,"%ld\t%ld\t%lg\n", lu->row[j], i+1, lu->val[j]); 420*3bf14a46SMatthew Knepley fclose(plop); 421*3bf14a46SMatthew Knepley iter_print++; 422*3bf14a46SMatthew Knepley } 423*3bf14a46SMatthew Knepley 424*3bf14a46SMatthew Knepley MatIsSymmetric_SeqAIJ(A_seq,0.0,&isSym); 425*3bf14a46SMatthew Knepley 426*3bf14a46SMatthew Knepley if (isSym) { 427*3bf14a46SMatthew Knepley lu->iparm[IPARM_SYM] = API_SYM_YES; 428*3bf14a46SMatthew Knepley lu->iparm[IPARM_FACTORIZATION] = API_FACT_LLT; 429*3bf14a46SMatthew Knepley } 430*3bf14a46SMatthew Knepley else { 431*3bf14a46SMatthew Knepley lu->iparm[IPARM_SYM] = API_SYM_NO; 432*3bf14a46SMatthew Knepley lu->iparm[IPARM_FACTORIZATION] = API_FACT_LU; 433*3bf14a46SMatthew Knepley } 434*3bf14a46SMatthew Knepley 435*3bf14a46SMatthew Knepley /*----------------*/ 436*3bf14a46SMatthew Knepley if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){ 437*3bf14a46SMatthew Knepley if (!(isSeqAIJ || isSeqSBAIJ)) { 438*3bf14a46SMatthew Knepley /* PaStiX only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */ 439*3bf14a46SMatthew Knepley ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&lu->b_seq);CHKERRQ(ierr); 440*3bf14a46SMatthew Knepley ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr); 441*3bf14a46SMatthew Knepley ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr); 442*3bf14a46SMatthew Knepley ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr); 443*3bf14a46SMatthew Knepley ierr = VecSetFromOptions(b);CHKERRQ(ierr); 444*3bf14a46SMatthew Knepley 445*3bf14a46SMatthew Knepley ierr = VecScatterCreate(b,is_iden,lu->b_seq,is_iden,&lu->scat_rhs);CHKERRQ(ierr); 446*3bf14a46SMatthew Knepley ierr = VecScatterCreate(lu->b_seq,is_iden,b,is_iden,&lu->scat_sol);CHKERRQ(ierr); 447*3bf14a46SMatthew Knepley ierr = ISDestroy(is_iden);CHKERRQ(ierr); 448*3bf14a46SMatthew Knepley ierr = VecDestroy(b);CHKERRQ(ierr); 449*3bf14a46SMatthew Knepley } 450*3bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK] = API_TASK_ORDERING; 451*3bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK] = API_TASK_NUMFACT; 452*3bf14a46SMatthew Knepley 453*3bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 454*3bf14a46SMatthew Knepley (MPI_Comm) lu->pastix_comm, 455*3bf14a46SMatthew Knepley (pastix_int_t) lu->n, 456*3bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 457*3bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 458*3bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 459*3bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 460*3bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 461*3bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 462*3bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 463*3bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 464*3bf14a46SMatthew Knepley (double*) lu->dparm); 465*3bf14a46SMatthew Knepley fprintf(stdout, "lu->pastix_data after factorising %x\n", lu->pastix_data); 466*3bf14a46SMatthew Knepley if (lu->iparm[IPARM_ERROR_NUMBER] < 0) { 467*3bf14a46SMatthew Knepley SETERRQ1(PETSC_ERR_LIB,"Error reported by PaStiX in analysis phase: ipparm(IPARM_ERROR_NUMBER)=%d\n", 468*3bf14a46SMatthew Knepley lu->iparm[IPARM_ERROR_NUMBER]); 469*3bf14a46SMatthew Knepley } 470*3bf14a46SMatthew Knepley } 471*3bf14a46SMatthew Knepley else { 472*3bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK] = API_TASK_NUMFACT; 473*3bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK] = API_TASK_NUMFACT; 474*3bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 475*3bf14a46SMatthew Knepley (MPI_Comm) lu->pastix_comm, 476*3bf14a46SMatthew Knepley (pastix_int_t) lu->n, 477*3bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 478*3bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 479*3bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 480*3bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 481*3bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 482*3bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 483*3bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 484*3bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 485*3bf14a46SMatthew Knepley (double*) lu->dparm); 486*3bf14a46SMatthew Knepley 487*3bf14a46SMatthew Knepley if (lu->iparm[IPARM_ERROR_NUMBER] < 0) { 488*3bf14a46SMatthew Knepley SETERRQ1(PETSC_ERR_LIB,"Error reported by PaStiX in analysis phase: ipparm(IPARM_ERROR_NUMBER)=%d\n", 489*3bf14a46SMatthew Knepley lu->iparm[IPARM_ERROR_NUMBER]); 490*3bf14a46SMatthew Knepley } 491*3bf14a46SMatthew Knepley } 492*3bf14a46SMatthew Knepley 493*3bf14a46SMatthew Knepley if (lu->commSize > 1){ 494*3bf14a46SMatthew Knepley if ((F)->factor == MAT_FACTOR_LU){ 495*3bf14a46SMatthew Knepley F_diag = ((Mat_MPIAIJ *)(F)->data)->A; 496*3bf14a46SMatthew Knepley } else { 497*3bf14a46SMatthew Knepley F_diag = ((Mat_MPISBAIJ *)(F)->data)->A; 498*3bf14a46SMatthew Knepley } 499*3bf14a46SMatthew Knepley F_diag->assembled = PETSC_TRUE; 500*3bf14a46SMatthew Knepley if (lu->nSolve){ 501*3bf14a46SMatthew Knepley ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr); 502*3bf14a46SMatthew Knepley ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr); 503*3bf14a46SMatthew Knepley } 504*3bf14a46SMatthew Knepley } 505*3bf14a46SMatthew Knepley (F)->assembled = PETSC_TRUE; 506*3bf14a46SMatthew Knepley lu->matstruc = SAME_NONZERO_PATTERN; 507*3bf14a46SMatthew Knepley lu->CleanUpPastix = PETSC_TRUE; 508*3bf14a46SMatthew Knepley lu->nSolve = 0; 509*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 510*3bf14a46SMatthew Knepley } 511*3bf14a46SMatthew Knepley 512*3bf14a46SMatthew Knepley 513*3bf14a46SMatthew Knepley /* Note the Petsc r and c permutations are ignored */ 514*3bf14a46SMatthew Knepley #undef __FUNCT__ 515*3bf14a46SMatthew Knepley #define __FUNCT__ "MatLUFactorSymbolic_AIJPASTIX" 516*3bf14a46SMatthew Knepley PetscErrorCode MatLUFactorSymbolic_AIJPASTIX(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 517*3bf14a46SMatthew Knepley { 518*3bf14a46SMatthew Knepley Mat_Pastix *lu = (Mat_Pastix*)F->spptr; 519*3bf14a46SMatthew Knepley PetscErrorCode ierr = 0; 520*3bf14a46SMatthew Knepley 521*3bf14a46SMatthew Knepley ierr = PetscPrintf(lu->pastix_comm,"MatLUFactorSymbolic_AIJPASTIX\n");CHKERRQ(ierr); 522*3bf14a46SMatthew Knepley PetscFunctionBegin; 523*3bf14a46SMatthew Knepley lu->iparm[IPARM_FACTORIZATION] = API_FACT_LU; 524*3bf14a46SMatthew Knepley lu->iparm[IPARM_SYM] = API_SYM_YES; 525*3bf14a46SMatthew Knepley lu->matstruc = DIFFERENT_NONZERO_PATTERN; 526*3bf14a46SMatthew Knepley F->ops->lufactornumeric = MatFactorNumeric_PaStiX; 527*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 528*3bf14a46SMatthew Knepley } 529*3bf14a46SMatthew Knepley 530*3bf14a46SMatthew Knepley 531*3bf14a46SMatthew Knepley /* Note the Petsc r permutation is ignored */ 532*3bf14a46SMatthew Knepley #undef __FUNCT__ 533*3bf14a46SMatthew Knepley #define __FUNCT__ "MatCholeskyFactorSymbolic_SBAIJPASTIX" 534*3bf14a46SMatthew Knepley PetscErrorCode MatCholeskyFactorSymbolic_SBAIJPASTIX(Mat F,Mat A,IS r,const MatFactorInfo *info) 535*3bf14a46SMatthew Knepley { 536*3bf14a46SMatthew Knepley Mat_Pastix *lu = (Mat_Pastix*)(F)->spptr; 537*3bf14a46SMatthew Knepley PetscErrorCode ierr = 0; 538*3bf14a46SMatthew Knepley 539*3bf14a46SMatthew Knepley ierr = PetscPrintf(lu->pastix_comm,"MatCholeskyFactorSymbolic_SBAIJPASTIX\n");CHKERRQ(ierr); 540*3bf14a46SMatthew Knepley PetscFunctionBegin; 541*3bf14a46SMatthew Knepley lu->iparm[IPARM_FACTORIZATION] = API_FACT_LLT; 542*3bf14a46SMatthew Knepley lu->iparm[IPARM_SYM] = API_SYM_NO; 543*3bf14a46SMatthew Knepley lu->matstruc = DIFFERENT_NONZERO_PATTERN; 544*3bf14a46SMatthew Knepley (F)->ops->choleskyfactornumeric = MatFactorNumeric_PaStiX; 545*3bf14a46SMatthew Knepley #if !defined(PETSC_USE_COMPLEX) 546*3bf14a46SMatthew Knepley (F)->ops->getinertia = MatGetInertia_SBAIJPASTIX; 547*3bf14a46SMatthew Knepley #endif 548*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 549*3bf14a46SMatthew Knepley } 550*3bf14a46SMatthew Knepley 551*3bf14a46SMatthew Knepley #undef __FUNCT__ 552*3bf14a46SMatthew Knepley #define __FUNCT__ "MatFactorInfo_PaStiX" 553*3bf14a46SMatthew Knepley PetscErrorCode MatFactorInfo_PaStiX(Mat A,PetscViewer viewer) { 554*3bf14a46SMatthew Knepley Mat_Pastix *lu=(Mat_Pastix*)A->spptr; 555*3bf14a46SMatthew Knepley PetscErrorCode ierr; 556*3bf14a46SMatthew Knepley 557*3bf14a46SMatthew Knepley ierr = PetscPrintf(lu->pastix_comm,"MatFactorInfo_PaStiX\n");CHKERRQ(ierr); 558*3bf14a46SMatthew Knepley PetscFunctionBegin; 559*3bf14a46SMatthew Knepley /* check if matrix is pastix type */ 560*3bf14a46SMatthew Knepley if (A->ops->solve != MatSolve_PaStiX) PetscFunctionReturn(0); 561*3bf14a46SMatthew Knepley 562*3bf14a46SMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"PaStiX run parameters:\n");CHKERRQ(ierr); 563*3bf14a46SMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer," Matrix type : %s \n", 564*3bf14a46SMatthew Knepley ((lu->iparm[IPARM_SYM] == API_SYM_YES)?"Symetric":"Non symetric"));CHKERRQ(ierr); 565*3bf14a46SMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer," Level of printing (0,1,2): %d \n", 566*3bf14a46SMatthew Knepley lu->iparm[IPARM_VERBOSE]);CHKERRQ(ierr); 567*3bf14a46SMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer," Number of refinements iterations : %d \n", 568*3bf14a46SMatthew Knepley lu->iparm[IPARM_NBITER]);CHKERRQ(ierr); 569*3bf14a46SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF," Error : %g \n", 570*3bf14a46SMatthew Knepley lu->dparm[DPARM_RELATIVE_ERROR]);CHKERRQ(ierr); 571*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 572*3bf14a46SMatthew Knepley } 573*3bf14a46SMatthew Knepley 574*3bf14a46SMatthew Knepley #undef __FUNCT__ 575*3bf14a46SMatthew Knepley #define __FUNCT__ "MatView_PaStiX" 576*3bf14a46SMatthew Knepley PetscErrorCode MatView_PaStiX(Mat A,PetscViewer viewer) 577*3bf14a46SMatthew Knepley { 578*3bf14a46SMatthew Knepley PetscErrorCode ierr; 579*3bf14a46SMatthew Knepley PetscTruth iascii; 580*3bf14a46SMatthew Knepley PetscViewerFormat format; 581*3bf14a46SMatthew Knepley 582*3bf14a46SMatthew Knepley ierr = PetscPrintf(((PetscObject)A)->comm,"MatView_PaStiX\n");CHKERRQ(ierr); 583*3bf14a46SMatthew Knepley PetscFunctionBegin; 584*3bf14a46SMatthew Knepley ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 585*3bf14a46SMatthew Knepley if (iascii) { 586*3bf14a46SMatthew Knepley ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 587*3bf14a46SMatthew Knepley if (format == PETSC_VIEWER_ASCII_INFO){ 588*3bf14a46SMatthew Knepley ierr = MatFactorInfo_PaStiX(A,viewer);CHKERRQ(ierr); 589*3bf14a46SMatthew Knepley } 590*3bf14a46SMatthew Knepley } 591*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 592*3bf14a46SMatthew Knepley } 593*3bf14a46SMatthew Knepley 594*3bf14a46SMatthew Knepley 595*3bf14a46SMatthew Knepley /*MC 596*3bf14a46SMatthew Knepley MATAIJPASTIX - MATAIJPASTIX = "aijpastix" - A matrix type providing direct solvers (LU) for distributed 597*3bf14a46SMatthew Knepley and sequential matrices via the external package PaStiX. 598*3bf14a46SMatthew Knepley 599*3bf14a46SMatthew Knepley If PaStiX is installed (see the manual for instructions 600*3bf14a46SMatthew Knepley on how to declare the existence of external packages), 601*3bf14a46SMatthew Knepley a matrix type can be constructed which invokes PaStiX solvers. 602*3bf14a46SMatthew Knepley After calling MatCreate(...,A), simply call MatSetType(A,MATAIJPASTIX), then 603*3bf14a46SMatthew Knepley optionally call MatSeqAIJSetPreallocation() or MatMPIAIJSetPreallocation() etc DO NOT 604*3bf14a46SMatthew Knepley call MatCreateSeqAIJ/MPIAIJ() directly or the preallocation information will be LOST! 605*3bf14a46SMatthew Knepley 606*3bf14a46SMatthew Knepley If created with a single process communicator, this matrix type inherits from MATSEQAIJ. 607*3bf14a46SMatthew Knepley Otherwise, this matrix type inherits from MATMPIAIJ. Hence for single process communicators, 608*3bf14a46SMatthew Knepley MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 609*3bf14a46SMatthew Knepley for communicators controlling multiple processes. It is recommended that you call both of 610*3bf14a46SMatthew Knepley the above preallocation routines for simplicity. One can also call MatConvert() for an inplace 611*3bf14a46SMatthew Knepley conversion to or from the MATSEQAIJ or MATMPIAIJ type (depending on the communicator size) 612*3bf14a46SMatthew Knepley without data copy AFTER the matrix values are set. 613*3bf14a46SMatthew Knepley 614*3bf14a46SMatthew Knepley Options Database Keys: 615*3bf14a46SMatthew Knepley + -mat_type sbaijpastix - sets the matrix type to "sbaijpastix" during a call to MatSetFromOptions() 616*3bf14a46SMatthew Knepley . -mat_pastix_sym <0,1> - 0 the matrix is symmetric, 1 unsymmetric 617*3bf14a46SMatthew Knepley . -mat_pastix_verbose <0,1,2> - print level 618*3bf14a46SMatthew Knepley . -mat_pastix_threadnbr <integer> - Set the thread number by MPI task. 619*3bf14a46SMatthew Knepley 620*3bf14a46SMatthew Knepley Level: beginner 621*3bf14a46SMatthew Knepley 622*3bf14a46SMatthew Knepley .seealso: MATSBAIJPASTIX 623*3bf14a46SMatthew Knepley M*/ 624*3bf14a46SMatthew Knepley 625*3bf14a46SMatthew Knepley 626*3bf14a46SMatthew Knepley #undef __FUNCT__ 627*3bf14a46SMatthew Knepley #define __FUNCT__ "MatGetInfo_PaStiX" 628*3bf14a46SMatthew Knepley PetscErrorCode MatGetInfo_PaStiX(Mat A,MatInfoType flag,MatInfo *info) 629*3bf14a46SMatthew Knepley { 630*3bf14a46SMatthew Knepley Mat_Pastix *lu =(Mat_Pastix*)A->spptr; 631*3bf14a46SMatthew Knepley PetscErrorCode ierr; 632*3bf14a46SMatthew Knepley 633*3bf14a46SMatthew Knepley ierr = PetscPrintf(lu->pastix_comm,"MatGetInfo_PaStiX\n");CHKERRQ(ierr); 634*3bf14a46SMatthew Knepley PetscFunctionBegin; 635*3bf14a46SMatthew Knepley info->block_size = 1.0; 636*3bf14a46SMatthew Knepley info->nz_allocated = lu->iparm[IPARM_NNZEROS]; 637*3bf14a46SMatthew Knepley info->nz_used = lu->iparm[IPARM_NNZEROS]; 638*3bf14a46SMatthew Knepley info->nz_unneeded = 0.0; 639*3bf14a46SMatthew Knepley info->assemblies = 0.0; 640*3bf14a46SMatthew Knepley info->mallocs = 0.0; 641*3bf14a46SMatthew Knepley info->memory = 0.0; 642*3bf14a46SMatthew Knepley info->fill_ratio_given = 0; 643*3bf14a46SMatthew Knepley info->fill_ratio_needed = 0; 644*3bf14a46SMatthew Knepley info->factor_mallocs = 0; 645*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 646*3bf14a46SMatthew Knepley } 647*3bf14a46SMatthew Knepley 648*3bf14a46SMatthew Knepley /*MC 649*3bf14a46SMatthew Knepley MATSBAIJPASTIX - MATSBAIJPASTIX = "sbaijpastix" - A symmetric matrix type providing direct solvers (Cholesky) for 650*3bf14a46SMatthew Knepley distributed and sequential matrices via the external package PaStiX. 651*3bf14a46SMatthew Knepley 652*3bf14a46SMatthew Knepley If PaStiX is installed (see the manual for instructions 653*3bf14a46SMatthew Knepley on how to declare the existence of external packages), 654*3bf14a46SMatthew Knepley a matrix type can be constructed which invokes PaStiX solvers. 655*3bf14a46SMatthew Knepley After calling MatCreate(...,A), simply call MatSetType(A,MATSBAIJPASTIX), then 656*3bf14a46SMatthew Knepley optionally call MatSeqSBAIJSetPreallocation() or MatMPISBAIJSetPreallocation() DO NOT 657*3bf14a46SMatthew Knepley call MatCreateSeqSBAIJ/MPISBAIJ() directly or the preallocation information will be LOST! 658*3bf14a46SMatthew Knepley 659*3bf14a46SMatthew Knepley If created with a single process communicator, this matrix type inherits from MATSEQSBAIJ. 660*3bf14a46SMatthew Knepley Otherwise, this matrix type inherits from MATMPISBAIJ. Hence for single process communicators, 661*3bf14a46SMatthew Knepley MatSeqSBAIJSetPreallocation() is supported, and similarly MatMPISBAIJSetPreallocation() is supported 662*3bf14a46SMatthew Knepley for communicators controlling multiple processes. It is recommended that you call both of 663*3bf14a46SMatthew Knepley the above preallocation routines for simplicity. One can also call MatConvert() for an inplace 664*3bf14a46SMatthew Knepley conversion to or from the MATSEQSBAIJ or MATMPISBAIJ type (depending on the communicator size) 665*3bf14a46SMatthew Knepley without data copy AFTER the matrix values have been set. 666*3bf14a46SMatthew Knepley 667*3bf14a46SMatthew Knepley Options Database Keys: 668*3bf14a46SMatthew Knepley + -mat_type aijpastix - sets the matrix type to "aijpastix" during a call to MatSetFromOptions() 669*3bf14a46SMatthew Knepley . -mat_pastix_sym <0,1> - 0 the matrix is symmetric, 1 unsymmetric 670*3bf14a46SMatthew Knepley . -mat_pastix_verbose <0,1,2> - print level 671*3bf14a46SMatthew Knepley . -mat_pastix_threadnbr <integer> - Set the thread number by MPI task. 672*3bf14a46SMatthew Knepley Level: beginner 673*3bf14a46SMatthew Knepley 674*3bf14a46SMatthew Knepley .seealso: MATAIJPASTIX 675*3bf14a46SMatthew Knepley M*/ 676*3bf14a46SMatthew Knepley 677*3bf14a46SMatthew Knepley EXTERN_C_BEGIN 678*3bf14a46SMatthew Knepley #undef __FUNCT__ 679*3bf14a46SMatthew Knepley #define __FUNCT__ "MatFactorGetSolverPackage_pastix" 680*3bf14a46SMatthew Knepley PetscErrorCode MatFactorGetSolverPackage_pastix(Mat A,const MatSolverPackage *type) 681*3bf14a46SMatthew Knepley { 682*3bf14a46SMatthew Knepley PetscErrorCode ierr = 0; 683*3bf14a46SMatthew Knepley 684*3bf14a46SMatthew Knepley ierr = PetscPrintf(((PetscObject)A)->comm,"MatFactorGetSolverPackage_pastix\n");CHKERRQ(ierr); 685*3bf14a46SMatthew Knepley PetscFunctionBegin; 686*3bf14a46SMatthew Knepley *type = MAT_SOLVER_PASTIX; 687*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 688*3bf14a46SMatthew Knepley } 689*3bf14a46SMatthew Knepley EXTERN_C_END 690*3bf14a46SMatthew Knepley 691*3bf14a46SMatthew Knepley EXTERN_C_BEGIN 692*3bf14a46SMatthew Knepley /* 693*3bf14a46SMatthew Knepley The seq and mpi versions of this function are the same 694*3bf14a46SMatthew Knepley */ 695*3bf14a46SMatthew Knepley #undef __FUNCT__ 696*3bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_seqaij_pastix" 697*3bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_seqaij_pastix(Mat A,MatFactorType ftype,Mat *F) 698*3bf14a46SMatthew Knepley { 699*3bf14a46SMatthew Knepley Mat B; 700*3bf14a46SMatthew Knepley PetscErrorCode ierr; 701*3bf14a46SMatthew Knepley Mat_Pastix *pastix; 702*3bf14a46SMatthew Knepley 703*3bf14a46SMatthew Knepley ierr = PetscPrintf(((PetscObject)A)->comm,"MatGetFactor_seqaij_pastix\n");CHKERRQ(ierr); 704*3bf14a46SMatthew Knepley PetscFunctionBegin; 705*3bf14a46SMatthew Knepley if (ftype != MAT_FACTOR_LU) { 706*3bf14a46SMatthew Knepley SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc AIJ matrices with PaStiX Cholesky, use SBAIJ matrix"); 707*3bf14a46SMatthew Knepley } 708*3bf14a46SMatthew Knepley /* Create the factorization matrix */ 709*3bf14a46SMatthew Knepley ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 710*3bf14a46SMatthew Knepley ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 711*3bf14a46SMatthew Knepley ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 712*3bf14a46SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 713*3bf14a46SMatthew Knepley 714*3bf14a46SMatthew Knepley B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJPASTIX; 715*3bf14a46SMatthew Knepley B->ops->view = MatView_PaStiX; 716*3bf14a46SMatthew Knepley B->ops->getinfo = MatGetInfo_PaStiX; 717*3bf14a46SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C", 718*3bf14a46SMatthew Knepley "MatFactorGetSolverPackage_pastix", 719*3bf14a46SMatthew Knepley MatFactorGetSolverPackage_pastix);CHKERRQ(ierr); 720*3bf14a46SMatthew Knepley B->factor = MAT_FACTOR_LU; 721*3bf14a46SMatthew Knepley 722*3bf14a46SMatthew Knepley ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr); 723*3bf14a46SMatthew Knepley pastix->CleanUpPastix = PETSC_FALSE; 724*3bf14a46SMatthew Knepley pastix->isAIJ = PETSC_TRUE; 725*3bf14a46SMatthew Knepley pastix->scat_rhs = PETSC_NULL; 726*3bf14a46SMatthew Knepley pastix->scat_sol = PETSC_NULL; 727*3bf14a46SMatthew Knepley pastix->nSolve = 0; 728*3bf14a46SMatthew Knepley pastix->MatDestroy = B->ops->destroy; 729*3bf14a46SMatthew Knepley B->ops->destroy = MatDestroy_Pastix; 730*3bf14a46SMatthew Knepley B->spptr = (void*)pastix; 731*3bf14a46SMatthew Knepley 732*3bf14a46SMatthew Knepley *F = B; 733*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 734*3bf14a46SMatthew Knepley } 735*3bf14a46SMatthew Knepley EXTERN_C_END 736*3bf14a46SMatthew Knepley 737*3bf14a46SMatthew Knepley EXTERN_C_BEGIN 738*3bf14a46SMatthew Knepley #undef __FUNCT__ 739*3bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_mpiaij_pastix" 740*3bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_mpiaij_pastix(Mat A,MatFactorType ftype,Mat *F) 741*3bf14a46SMatthew Knepley { 742*3bf14a46SMatthew Knepley Mat B; 743*3bf14a46SMatthew Knepley PetscErrorCode ierr; 744*3bf14a46SMatthew Knepley Mat_Pastix *pastix; 745*3bf14a46SMatthew Knepley 746*3bf14a46SMatthew Knepley ierr = PetscPrintf(((PetscObject)A)->comm,"MatGetFactor_mpiaij_pastix\n");CHKERRQ(ierr); 747*3bf14a46SMatthew Knepley PetscFunctionBegin; 748*3bf14a46SMatthew Knepley if (ftype != MAT_FACTOR_LU) { 749*3bf14a46SMatthew Knepley SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc AIJ matrices with PaStiX Cholesky, use SBAIJ matrix"); 750*3bf14a46SMatthew Knepley } 751*3bf14a46SMatthew Knepley /* Create the factorization matrix */ 752*3bf14a46SMatthew Knepley ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 753*3bf14a46SMatthew Knepley ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 754*3bf14a46SMatthew Knepley ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 755*3bf14a46SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 756*3bf14a46SMatthew Knepley ierr = MatMPIAIJSetPreallocation(B,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 757*3bf14a46SMatthew Knepley 758*3bf14a46SMatthew Knepley B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJPASTIX; 759*3bf14a46SMatthew Knepley B->ops->view = MatView_PaStiX; 760*3bf14a46SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B, 761*3bf14a46SMatthew Knepley "MatFactorGetSolverPackage_C", 762*3bf14a46SMatthew Knepley "MatFactorGetSolverPackage_pastix", 763*3bf14a46SMatthew Knepley MatFactorGetSolverPackage_pastix);CHKERRQ(ierr); 764*3bf14a46SMatthew Knepley B->factor = MAT_FACTOR_LU; 765*3bf14a46SMatthew Knepley 766*3bf14a46SMatthew Knepley ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr); 767*3bf14a46SMatthew Knepley pastix->CleanUpPastix = PETSC_FALSE; 768*3bf14a46SMatthew Knepley pastix->isAIJ = PETSC_TRUE; 769*3bf14a46SMatthew Knepley pastix->scat_rhs = PETSC_NULL; 770*3bf14a46SMatthew Knepley pastix->scat_sol = PETSC_NULL; 771*3bf14a46SMatthew Knepley pastix->nSolve = 0; 772*3bf14a46SMatthew Knepley pastix->MatDestroy = B->ops->destroy; 773*3bf14a46SMatthew Knepley B->ops->destroy = MatDestroy_Pastix; 774*3bf14a46SMatthew Knepley B->spptr = (void*)pastix; 775*3bf14a46SMatthew Knepley 776*3bf14a46SMatthew Knepley *F = B; 777*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 778*3bf14a46SMatthew Knepley } 779*3bf14a46SMatthew Knepley EXTERN_C_END 780*3bf14a46SMatthew Knepley 781*3bf14a46SMatthew Knepley EXTERN_C_BEGIN 782*3bf14a46SMatthew Knepley #undef __FUNCT__ 783*3bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_seqsbaij_pastix" 784*3bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_seqsbaij_pastix(Mat A,MatFactorType ftype,Mat *F) 785*3bf14a46SMatthew Knepley { 786*3bf14a46SMatthew Knepley Mat B; 787*3bf14a46SMatthew Knepley PetscErrorCode ierr; 788*3bf14a46SMatthew Knepley Mat_Pastix *pastix; 789*3bf14a46SMatthew Knepley 790*3bf14a46SMatthew Knepley ierr = PetscPrintf(((PetscObject)A)->comm,"MatGetFactor_seqsbaij_pastix\n");CHKERRQ(ierr); 791*3bf14a46SMatthew Knepley PetscFunctionBegin; 792*3bf14a46SMatthew Knepley if (ftype != MAT_FACTOR_CHOLESKY) { 793*3bf14a46SMatthew Knepley SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with PaStiX LU, use AIJ matrix"); 794*3bf14a46SMatthew Knepley } 795*3bf14a46SMatthew Knepley /* Create the factorization matrix */ 796*3bf14a46SMatthew Knepley ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 797*3bf14a46SMatthew Knepley ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 798*3bf14a46SMatthew Knepley ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 799*3bf14a46SMatthew Knepley ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr); 800*3bf14a46SMatthew Knepley ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 801*3bf14a46SMatthew Knepley 802*3bf14a46SMatthew Knepley B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJPASTIX; 803*3bf14a46SMatthew Knepley B->ops->view = MatView_PaStiX; 804*3bf14a46SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B, 805*3bf14a46SMatthew Knepley "MatFactorGetSolverPackage_C", 806*3bf14a46SMatthew Knepley "MatFactorGetSolverPackage_pastix", 807*3bf14a46SMatthew Knepley MatFactorGetSolverPackage_pastix);CHKERRQ(ierr); 808*3bf14a46SMatthew Knepley 809*3bf14a46SMatthew Knepley B->factor = MAT_FACTOR_CHOLESKY; 810*3bf14a46SMatthew Knepley 811*3bf14a46SMatthew Knepley ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr); 812*3bf14a46SMatthew Knepley pastix->CleanUpPastix = PETSC_FALSE; 813*3bf14a46SMatthew Knepley pastix->isAIJ = PETSC_TRUE; 814*3bf14a46SMatthew Knepley pastix->scat_rhs = PETSC_NULL; 815*3bf14a46SMatthew Knepley pastix->scat_sol = PETSC_NULL; 816*3bf14a46SMatthew Knepley pastix->nSolve = 0; 817*3bf14a46SMatthew Knepley pastix->MatDestroy = B->ops->destroy; 818*3bf14a46SMatthew Knepley B->ops->destroy = MatDestroy_Pastix; 819*3bf14a46SMatthew Knepley B->spptr = (void*)pastix; 820*3bf14a46SMatthew Knepley 821*3bf14a46SMatthew Knepley *F = B; 822*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 823*3bf14a46SMatthew Knepley } 824*3bf14a46SMatthew Knepley EXTERN_C_END 825*3bf14a46SMatthew Knepley 826*3bf14a46SMatthew Knepley EXTERN_C_BEGIN 827*3bf14a46SMatthew Knepley #undef __FUNCT__ 828*3bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_mpisbaij_pastix" 829*3bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_mpisbaij_pastix(Mat A,MatFactorType ftype,Mat *F) 830*3bf14a46SMatthew Knepley { 831*3bf14a46SMatthew Knepley Mat B; 832*3bf14a46SMatthew Knepley PetscErrorCode ierr; 833*3bf14a46SMatthew Knepley Mat_Pastix *pastix; 834*3bf14a46SMatthew Knepley 835*3bf14a46SMatthew Knepley ierr = PetscPrintf(((PetscObject)A)->comm,"MatGetFactor_mpisbaij_pastix\n");CHKERRQ(ierr); 836*3bf14a46SMatthew Knepley PetscFunctionBegin; 837*3bf14a46SMatthew Knepley if (ftype != MAT_FACTOR_CHOLESKY) { 838*3bf14a46SMatthew Knepley SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with PaStiX LU, use AIJ matrix"); 839*3bf14a46SMatthew Knepley } 840*3bf14a46SMatthew Knepley /* Create the factorization matrix */ 841*3bf14a46SMatthew Knepley ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 842*3bf14a46SMatthew Knepley ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 843*3bf14a46SMatthew Knepley ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 844*3bf14a46SMatthew Knepley ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr); 845*3bf14a46SMatthew Knepley ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 846*3bf14a46SMatthew Knepley 847*3bf14a46SMatthew Knepley B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJPASTIX; 848*3bf14a46SMatthew Knepley B->ops->view = MatView_PaStiX; 849*3bf14a46SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B, 850*3bf14a46SMatthew Knepley "MatFactorGetSolverPackage_C", 851*3bf14a46SMatthew Knepley "MatFactorGetSolverPackage_pastix", 852*3bf14a46SMatthew Knepley MatFactorGetSolverPackage_pastix);CHKERRQ(ierr); 853*3bf14a46SMatthew Knepley B->factor = MAT_FACTOR_CHOLESKY; 854*3bf14a46SMatthew Knepley 855*3bf14a46SMatthew Knepley ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr); 856*3bf14a46SMatthew Knepley pastix->CleanUpPastix = PETSC_FALSE; 857*3bf14a46SMatthew Knepley pastix->isAIJ = PETSC_TRUE; 858*3bf14a46SMatthew Knepley pastix->scat_rhs = PETSC_NULL; 859*3bf14a46SMatthew Knepley pastix->scat_sol = PETSC_NULL; 860*3bf14a46SMatthew Knepley pastix->nSolve = 0; 861*3bf14a46SMatthew Knepley pastix->MatDestroy = B->ops->destroy; 862*3bf14a46SMatthew Knepley B->ops->destroy = MatDestroy_Pastix; 863*3bf14a46SMatthew Knepley B->spptr = (void*)pastix; 864*3bf14a46SMatthew Knepley 865*3bf14a46SMatthew Knepley *F = B; 866*3bf14a46SMatthew Knepley PetscFunctionReturn(0); 867*3bf14a46SMatthew Knepley } 868*3bf14a46SMatthew Knepley EXTERN_C_END 869