xref: /petsc/src/mat/impls/aij/mpi/pastix/pastix.c (revision 745c78f7e0f2290eec82a5e78331729191e43cff)
13bf14a46SMatthew Knepley #define PETSCMAT_DLL
23bf14a46SMatthew Knepley 
33bf14a46SMatthew Knepley /*
43bf14a46SMatthew Knepley     Provides an interface to the PaStiX sparse solver
53bf14a46SMatthew Knepley */
63bf14a46SMatthew Knepley #include "../src/mat/impls/aij/seq/aij.h"
73bf14a46SMatthew Knepley #include "../src/mat/impls/aij/mpi/mpiaij.h"
83bf14a46SMatthew Knepley #include "../src/mat/impls/sbaij/seq/sbaij.h"
93bf14a46SMatthew Knepley #include "../src/mat/impls/sbaij/mpi/mpisbaij.h"
10*745c78f7SBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat,PetscReal,PetscTruth*);
113bf14a46SMatthew Knepley 
123bf14a46SMatthew Knepley EXTERN_C_BEGIN
133bf14a46SMatthew Knepley #include "mpi.h"
143bf14a46SMatthew Knepley #include "pastix.h"
153bf14a46SMatthew Knepley static int iter_print = 0;
163bf14a46SMatthew Knepley static int csr_iter_print = 0;
173bf14a46SMatthew Knepley EXTERN_C_END
183bf14a46SMatthew Knepley 
193bf14a46SMatthew Knepley typedef struct Mat_Pastix_ {
203bf14a46SMatthew Knepley   pastix_data_t *pastix_data;              /* Pastix data storage structure                        */
213bf14a46SMatthew Knepley   MatStructure   matstruc;
223bf14a46SMatthew Knepley   PetscInt       n;                        /* Number of columns in the matrix                      */
233bf14a46SMatthew Knepley   PetscInt       *colptr;                  /* Index of first element of each column in row and val */
243bf14a46SMatthew Knepley   PetscInt       *row;                     /* Row of each element of the matrix                    */
253bf14a46SMatthew Knepley   PetscScalar    *val;                     /* Value of each element of the matrix                  */
263bf14a46SMatthew Knepley   PetscInt       *perm;                    /* Permutation tabular                                  */
273bf14a46SMatthew Knepley   PetscInt       *invp;                    /* Reverse permutation tabular                          */
283bf14a46SMatthew Knepley   PetscScalar    *rhs;                     /* Rhight-hand-side member                              */
293bf14a46SMatthew Knepley   PetscInt       rhsnbr;                   /* Rhight-hand-side number (must be 1)                  */
303bf14a46SMatthew Knepley   PetscInt       iparm[64];                /* Integer parameters                                   */
313bf14a46SMatthew Knepley   double         dparm[64];                /* Floating point parameters                            */
323bf14a46SMatthew Knepley   MPI_Comm       pastix_comm;              /* PaStiX MPI communicator                              */
333bf14a46SMatthew Knepley   PetscMPIInt    commRank;                 /* MPI rank                                             */
343bf14a46SMatthew Knepley   PetscMPIInt    commSize;                 /* MPI communicator size                                */
353bf14a46SMatthew Knepley   PetscTruth     CleanUpPastix;            /* Boolean indicating if we call PaStiX clean step      */
363bf14a46SMatthew Knepley   VecScatter     scat_rhs;
373bf14a46SMatthew Knepley   VecScatter     scat_sol;
383bf14a46SMatthew Knepley   Vec            b_seq,x_seq;
393bf14a46SMatthew Knepley   PetscTruth     isAIJ;
403bf14a46SMatthew Knepley   PetscInt       nSolve;                   /* Number of consecutive solve                          */
413bf14a46SMatthew Knepley   PetscErrorCode (*MatDestroy)(Mat);
423bf14a46SMatthew Knepley } Mat_Pastix;
433bf14a46SMatthew Knepley 
443bf14a46SMatthew Knepley EXTERN PetscErrorCode MatDuplicate_Pastix(Mat,MatDuplicateOption,Mat*);
453bf14a46SMatthew Knepley 
463bf14a46SMatthew Knepley /*
473bf14a46SMatthew Knepley    convert Petsc seqaij matrix to CSC: colptr[n], row[nz], val[nz]
483bf14a46SMatthew Knepley 
493bf14a46SMatthew Knepley   input:
503bf14a46SMatthew Knepley     A       - matrix in seqaij or mpisbaij (bs=1) format
513bf14a46SMatthew Knepley     valOnly - FALSE: spaces are allocated and values are set for the CSC
523bf14a46SMatthew Knepley               TRUE:  Only fill values
533bf14a46SMatthew Knepley   output:
543bf14a46SMatthew Knepley     n       - Size of the matrix
553bf14a46SMatthew Knepley     colptr  - Index of first element of each column in row and val
563bf14a46SMatthew Knepley     row     - Row of each element of the matrix
573bf14a46SMatthew Knepley     values  - Value of each element of the matrix
583bf14a46SMatthew Knepley  */
593bf14a46SMatthew Knepley PetscErrorCode MatConvertToCSC(Mat           A,
603bf14a46SMatthew Knepley 			       PetscTruth    valOnly,
613bf14a46SMatthew Knepley 			       PetscInt     *n,
623bf14a46SMatthew Knepley 			       PetscInt    **colptr,
633bf14a46SMatthew Knepley 			       PetscInt    **row,
643bf14a46SMatthew Knepley 			       PetscScalar **values) {
653bf14a46SMatthew Knepley   Mat_SeqAIJ     *aa      = (Mat_SeqAIJ*)A->data;
663bf14a46SMatthew Knepley   PetscInt       *rowptr  = aa->i;
673bf14a46SMatthew Knepley   PetscInt       *col     = aa->j;
683bf14a46SMatthew Knepley   PetscScalar    *rvalues = aa->a;
693bf14a46SMatthew Knepley   PetscInt        m       = A->rmap->N;
70*745c78f7SBarry Smith   PetscInt        nnz;
713bf14a46SMatthew Knepley   PetscInt        i,j, k;
723bf14a46SMatthew Knepley   PetscInt        base = 1;
733bf14a46SMatthew Knepley   PetscInt        idx;
743bf14a46SMatthew Knepley   PetscErrorCode  ierr;
753bf14a46SMatthew Knepley   PetscInt        colidx;
763bf14a46SMatthew Knepley   PetscInt       *colcount;
77*745c78f7SBarry Smith   PetscTruth      isSym;
783bf14a46SMatthew Knepley 
793bf14a46SMatthew Knepley 
803bf14a46SMatthew Knepley   PetscFunctionBegin;
813bf14a46SMatthew Knepley   /* Allocate the CSC */
823bf14a46SMatthew Knepley 
833bf14a46SMatthew Knepley 
84*745c78f7SBarry Smith   MatIsSymmetric_SeqAIJ(A,0.0,&isSym);
85*745c78f7SBarry Smith   *n = A->cmap->N;
86*745c78f7SBarry Smith 
87*745c78f7SBarry Smith   /* PaStiX only needs triangular matrix if matrix is symmetric
88*745c78f7SBarry Smith    */
89*745c78f7SBarry Smith   if (isSym)
90*745c78f7SBarry Smith     {
91*745c78f7SBarry Smith       nnz = (aa->nz - *n)/2 + *n;
92*745c78f7SBarry Smith     }
93*745c78f7SBarry Smith   else
94*745c78f7SBarry Smith     {
95*745c78f7SBarry Smith       nnz     = aa->nz;
963bf14a46SMatthew Knepley     }
973bf14a46SMatthew Knepley 
983bf14a46SMatthew Knepley   ierr = PetscMalloc((*n)*sizeof(PetscInt)   ,&colcount);CHKERRQ(ierr);
993bf14a46SMatthew Knepley   if (!valOnly){
1003bf14a46SMatthew Knepley     ierr = PetscMalloc(((*n)+1) *sizeof(PetscInt)   ,colptr );CHKERRQ(ierr);
1013bf14a46SMatthew Knepley     ierr = PetscMalloc( nnz     *sizeof(PetscInt)   ,row);CHKERRQ(ierr);
1023bf14a46SMatthew Knepley     ierr = PetscMalloc( nnz     *sizeof(PetscScalar),values);CHKERRQ(ierr);
1033bf14a46SMatthew Knepley 
1043bf14a46SMatthew Knepley     for (i = 0; i < m; i++)
1053bf14a46SMatthew Knepley       colcount[i] = 0;
1063bf14a46SMatthew Knepley     /* Fill-in colptr */
1073bf14a46SMatthew Knepley     for (i = 0; i < m; i++)
1083bf14a46SMatthew Knepley       for (j = rowptr[i]; j < rowptr[i+1]; j++)
109*745c78f7SBarry Smith 	if (!isSym || col[j] <= i)
1103bf14a46SMatthew Knepley 	  colcount[col[j]]++;
111*745c78f7SBarry Smith 
1123bf14a46SMatthew Knepley     (*colptr)[0] = base;
1133bf14a46SMatthew Knepley     for (j = 0; j < *n; j++) {
1143bf14a46SMatthew Knepley       (*colptr)[j+1] = (*colptr)[j] + colcount[j];
115*745c78f7SBarry Smith       /* in next loop we fill starting from (*colptr)[colidx] - base */
1163bf14a46SMatthew Knepley       colcount[j] = -base;
1173bf14a46SMatthew Knepley     }
1183bf14a46SMatthew Knepley 
1193bf14a46SMatthew Knepley     /* Fill-in rows and values */
1203bf14a46SMatthew Knepley     for (i = 0; i < m; i++) {
1213bf14a46SMatthew Knepley       for (j = rowptr[i]; j < rowptr[i+1]; j++) {
122*745c78f7SBarry Smith 	if (!isSym || col[j] <= i)
123*745c78f7SBarry Smith 	  {
1243bf14a46SMatthew Knepley 	    colidx = col[j];
1253bf14a46SMatthew Knepley 	    idx    = (*colptr)[colidx] + colcount[colidx];
1263bf14a46SMatthew Knepley 	    (*row)[idx]    = i + base;
1273bf14a46SMatthew Knepley 	    (*values)[idx] = rvalues[j];
1283bf14a46SMatthew Knepley 	    colcount[colidx]++;
1293bf14a46SMatthew Knepley 	  }
1303bf14a46SMatthew Knepley       }
1313bf14a46SMatthew Knepley     }
132*745c78f7SBarry Smith   }
1333bf14a46SMatthew Knepley   else {
134*745c78f7SBarry Smith     /* Fill-in only values */
1353bf14a46SMatthew Knepley     for (i = 0; i < m; i++) {
1363bf14a46SMatthew Knepley       for (j = rowptr[i]; j < rowptr[i+1]; j++) {
1373bf14a46SMatthew Knepley 	colidx = col[j];
138*745c78f7SBarry Smith 	if (!isSym || col[j] <= i)
139*745c78f7SBarry Smith 	  {
140*745c78f7SBarry Smith 	    /* look for the value to fill */
141*745c78f7SBarry Smith 	    for (k = (*colptr)[colidx] - base;
142*745c78f7SBarry Smith 		 k < (*colptr)[colidx + 1] - base;
143*745c78f7SBarry Smith 		 k++) {
1443bf14a46SMatthew Knepley 	      if ((*row)[k] == i) {
1453bf14a46SMatthew Knepley 		(*values)[k] = rvalues[j];
1463bf14a46SMatthew Knepley 		break;
1473bf14a46SMatthew Knepley 	      }
1483bf14a46SMatthew Knepley 	    }
149*745c78f7SBarry Smith 	    /* shouldn't happen, overflow */
1503bf14a46SMatthew Knepley 	    if (k == (*colptr)[colidx + 1] - base)
1513bf14a46SMatthew Knepley 	      PetscFunctionReturn(1);
1523bf14a46SMatthew Knepley 	  }
1533bf14a46SMatthew Knepley       }
1543bf14a46SMatthew Knepley     }
155*745c78f7SBarry Smith   }
1563bf14a46SMatthew Knepley   ierr = PetscFree(colcount);CHKERRQ(ierr);
1573bf14a46SMatthew Knepley 
1583bf14a46SMatthew Knepley   PetscFunctionReturn(0);
1593bf14a46SMatthew Knepley }
1603bf14a46SMatthew Knepley 
1613bf14a46SMatthew Knepley 
1623bf14a46SMatthew Knepley 
1633bf14a46SMatthew Knepley #undef __FUNCT__
1643bf14a46SMatthew Knepley #define __FUNCT__ "MatDestroy_Pastix"
1653bf14a46SMatthew Knepley /*
1663bf14a46SMatthew Knepley   Call clean step of PaStiX if lu->CleanUpPastix == true.
1673bf14a46SMatthew Knepley   Free the CSC matrix.
1683bf14a46SMatthew Knepley  */
1693bf14a46SMatthew Knepley PetscErrorCode MatDestroy_Pastix(Mat A)
1703bf14a46SMatthew Knepley {
1713bf14a46SMatthew Knepley   Mat_Pastix      *lu=(Mat_Pastix*)A->spptr;
1723bf14a46SMatthew Knepley   PetscErrorCode   ierr;
1733bf14a46SMatthew Knepley   PetscMPIInt      size=lu->commSize;
174*745c78f7SBarry Smith 
1753bf14a46SMatthew Knepley   PetscFunctionBegin;
1763bf14a46SMatthew Knepley   if (lu->CleanUpPastix) {
1773bf14a46SMatthew Knepley     /* Terminate instance, deallocate memories */
1783bf14a46SMatthew Knepley     if (size > 1){
1793bf14a46SMatthew Knepley       ierr = VecScatterDestroy(lu->scat_rhs);CHKERRQ(ierr);
1803bf14a46SMatthew Knepley       ierr = VecDestroy(lu->b_seq);CHKERRQ(ierr);
1813bf14a46SMatthew Knepley       if (lu->nSolve && lu->scat_sol){ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr);}
1823bf14a46SMatthew Knepley       if (lu->nSolve && lu->x_seq){ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr);}
1833bf14a46SMatthew Knepley     }
1843bf14a46SMatthew Knepley 
1853bf14a46SMatthew Knepley     lu->iparm[IPARM_START_TASK]=API_TASK_CLEAN;
1863bf14a46SMatthew Knepley     lu->iparm[IPARM_END_TASK]=API_TASK_CLEAN;
1873bf14a46SMatthew Knepley 
1883bf14a46SMatthew Knepley     pastix((pastix_data_t **)&(lu->pastix_data),
1893bf14a46SMatthew Knepley 	                      lu->pastix_comm,
1903bf14a46SMatthew Knepley 	   (pastix_int_t)     lu->n,
1913bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->colptr,
1923bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->row,
1933bf14a46SMatthew Knepley 	   (pastix_float_t*)  lu->val,
1943bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->perm,
1953bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->invp,
1963bf14a46SMatthew Knepley 	   (pastix_float_t*)  lu->rhs,
1973bf14a46SMatthew Knepley 	   (pastix_int_t)     lu->rhsnbr,
1983bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->iparm,
1993bf14a46SMatthew Knepley 	                      lu->dparm);
2003bf14a46SMatthew Knepley 
2013bf14a46SMatthew Knepley     ierr = PetscFree(lu->colptr);CHKERRQ(ierr);
2023bf14a46SMatthew Knepley     ierr = PetscFree(lu->row);   CHKERRQ(ierr);
2033bf14a46SMatthew Knepley     ierr = PetscFree(lu->val);   CHKERRQ(ierr);
2043bf14a46SMatthew Knepley     ierr = PetscFree(lu->perm);  CHKERRQ(ierr);
2053bf14a46SMatthew Knepley     ierr = PetscFree(lu->invp);  CHKERRQ(ierr);
2063bf14a46SMatthew Knepley /*     ierr = PetscFree(lu->rhs);   CHKERRQ(ierr); */
2073bf14a46SMatthew Knepley     ierr = MPI_Comm_free(&(lu->pastix_comm));CHKERRQ(ierr);
2083bf14a46SMatthew Knepley 
2093bf14a46SMatthew Knepley   }
2103bf14a46SMatthew Knepley   ierr = (lu->MatDestroy)(A);CHKERRQ(ierr);
2113bf14a46SMatthew Knepley   PetscFunctionReturn(0);
2123bf14a46SMatthew Knepley }
2133bf14a46SMatthew Knepley 
2143bf14a46SMatthew Knepley #undef __FUNCT__
2153bf14a46SMatthew Knepley #define __FUNCT__ "MatSolve_PaStiX"
2163bf14a46SMatthew Knepley /*
2173bf14a46SMatthew Knepley   Gather right-hand-side.
2183bf14a46SMatthew Knepley   Call for Solve step.
2193bf14a46SMatthew Knepley   Scatter solution.
2203bf14a46SMatthew Knepley  */
2213bf14a46SMatthew Knepley PetscErrorCode MatSolve_PaStiX(Mat A,Vec b,Vec x)
2223bf14a46SMatthew Knepley {
2233bf14a46SMatthew Knepley   Mat_Pastix     *lu=(Mat_Pastix*)A->spptr;
2243bf14a46SMatthew Knepley   PetscScalar    *array;
2253bf14a46SMatthew Knepley   Vec             x_seq;
2263bf14a46SMatthew Knepley   IS              is_iden,is_petsc;
2273bf14a46SMatthew Knepley   PetscErrorCode  ierr;
2283bf14a46SMatthew Knepley   PetscInt        i,j;
2293bf14a46SMatthew Knepley 
2303bf14a46SMatthew Knepley   PetscFunctionBegin;
2313bf14a46SMatthew Knepley   lu->rhsnbr = 1;
2323bf14a46SMatthew Knepley   x_seq = lu->b_seq;
2333bf14a46SMatthew Knepley   if (lu->commSize > 1){
2343bf14a46SMatthew Knepley     /* PaStiX only supports centralized rhs. Scatter b into a seqential rhs vector */
2353bf14a46SMatthew Knepley     ierr = VecScatterBegin(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2363bf14a46SMatthew Knepley     ierr = VecScatterEnd(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2373bf14a46SMatthew Knepley     ierr = VecGetArray(x_seq,&array);
2383bf14a46SMatthew Knepley     CHKERRQ(ierr);
2393bf14a46SMatthew Knepley   }
2403bf14a46SMatthew Knepley   else {  /* size == 1 */
2413bf14a46SMatthew Knepley     ierr = VecCopy(b,x);CHKERRQ(ierr);
2423bf14a46SMatthew Knepley     ierr = VecGetArray(x,&array);CHKERRQ(ierr);
2433bf14a46SMatthew Knepley   }
2443bf14a46SMatthew Knepley   lu->rhs = array;
2453bf14a46SMatthew Knepley   if (lu->commSize == 1){
2463bf14a46SMatthew Knepley     ierr = VecRestoreArray(x,&array);CHKERRQ(ierr);
2473bf14a46SMatthew Knepley   } else {
2483bf14a46SMatthew Knepley     ierr = VecRestoreArray(x_seq,&array);CHKERRQ(ierr);
2493bf14a46SMatthew Knepley   }
2503bf14a46SMatthew Knepley 
2513bf14a46SMatthew Knepley   /* solve phase */
2523bf14a46SMatthew Knepley   /*-------------*/
2533bf14a46SMatthew Knepley   lu->iparm[IPARM_START_TASK] = API_TASK_SOLVE;
2543bf14a46SMatthew Knepley   lu->iparm[IPARM_END_TASK]   = API_TASK_REFINE;
255*745c78f7SBarry Smith   lu->iparm[IPARM_RHS_MAKING] = API_RHS_B;
2563bf14a46SMatthew Knepley 
2573bf14a46SMatthew Knepley   pastix((pastix_data_t **)&(lu->pastix_data),
2583bf14a46SMatthew Knepley 	 (MPI_Comm)         lu->pastix_comm,
2593bf14a46SMatthew Knepley 	 (pastix_int_t)     lu->n,
2603bf14a46SMatthew Knepley 	 (pastix_int_t*)    lu->colptr,
2613bf14a46SMatthew Knepley 	 (pastix_int_t*)    lu->row,
2623bf14a46SMatthew Knepley 	 (pastix_float_t*)  lu->val,
2633bf14a46SMatthew Knepley 	 (pastix_int_t*)    lu->perm,
2643bf14a46SMatthew Knepley 	 (pastix_int_t*)    lu->invp,
2653bf14a46SMatthew Knepley 	 (pastix_float_t*)  lu->rhs,
2663bf14a46SMatthew Knepley 	 (pastix_int_t)     lu->rhsnbr,
2673bf14a46SMatthew Knepley 	 (pastix_int_t*)    lu->iparm,
2683bf14a46SMatthew Knepley 	 (double*)          lu->dparm);
2693bf14a46SMatthew Knepley 
2703bf14a46SMatthew Knepley   if (lu->iparm[IPARM_ERROR_NUMBER] < 0) {
2713bf14a46SMatthew Knepley     SETERRQ1(PETSC_ERR_LIB,"Error reported by PaStiX in solve phase: lu->iparm[IPARM_ERROR_NUMBER] = %d\n",
2723bf14a46SMatthew Knepley 	     lu->iparm[IPARM_ERROR_NUMBER] );
2733bf14a46SMatthew Knepley   }
2743bf14a46SMatthew Knepley 
2753bf14a46SMatthew Knepley   if (lu->commSize == 1){
2763bf14a46SMatthew Knepley     ierr = VecRestoreArray(x,&(lu->rhs));CHKERRQ(ierr);
2773bf14a46SMatthew Knepley   } else {
2783bf14a46SMatthew Knepley     ierr = VecRestoreArray(x_seq,&(lu->rhs));CHKERRQ(ierr);
2793bf14a46SMatthew Knepley   }
2803bf14a46SMatthew Knepley 
2813bf14a46SMatthew Knepley   if (lu->commSize > 1) { /* convert PaStiX centralized solution to petsc mpi x */
2823bf14a46SMatthew Knepley     ierr = VecScatterBegin(lu->scat_sol,x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2833bf14a46SMatthew Knepley     ierr = VecScatterEnd(lu->scat_sol,x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2843bf14a46SMatthew Knepley   }
2853bf14a46SMatthew Knepley   lu->nSolve++;
2863bf14a46SMatthew Knepley   PetscFunctionReturn(0);
2873bf14a46SMatthew Knepley }
2883bf14a46SMatthew Knepley 
2893bf14a46SMatthew Knepley #if !defined(PETSC_USE_COMPLEX)
2903bf14a46SMatthew Knepley   /*
2913bf14a46SMatthew Knepley      TODO: Fill this function
2923bf14a46SMatthew Knepley      I didn't fill this function
2933bf14a46SMatthew Knepley      because I didn't understood its goal.
2943bf14a46SMatthew Knepley   */
2953bf14a46SMatthew Knepley 
2963bf14a46SMatthew Knepley /*
2973bf14a46SMatthew Knepley   input:
2983bf14a46SMatthew Knepley    F:        numeric factor
2993bf14a46SMatthew Knepley   output:
3003bf14a46SMatthew Knepley    nneg:     total number of pivots
3013bf14a46SMatthew Knepley    nzero:    0
3023bf14a46SMatthew Knepley    npos:     (global dimension of F) - nneg
3033bf14a46SMatthew Knepley */
3043bf14a46SMatthew Knepley 
3053bf14a46SMatthew Knepley #undef __FUNCT__
3063bf14a46SMatthew Knepley #define __FUNCT__ "MatGetInertia_SBAIJPASTIX"
3073bf14a46SMatthew Knepley PetscErrorCode MatGetInertia_SBAIJPASTIX(Mat F,int *nneg,int *nzero,int *npos)
3083bf14a46SMatthew Knepley {
3093bf14a46SMatthew Knepley   Mat_Pastix    *lu =(Mat_Pastix*)F->spptr;
3103bf14a46SMatthew Knepley   PetscErrorCode ierr;
3113bf14a46SMatthew Knepley   PetscMPIInt    size;
3123bf14a46SMatthew Knepley 
3133bf14a46SMatthew Knepley   PetscFunctionBegin;
3143bf14a46SMatthew Knepley /*   ierr = MPI_Comm_size(((PetscObject)F)->comm,&size);CHKERRQ(ierr); */
3153bf14a46SMatthew 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 *\/ */
3163bf14a46SMatthew Knepley /*   if (size > 1 && lu->id.ICNTL(13) != 1){ */
3173bf14a46SMatthew 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)); */
3183bf14a46SMatthew Knepley /*   } */
3193bf14a46SMatthew Knepley /*   if (nneg){ */
3203bf14a46SMatthew Knepley /*     if (!lu->commSize){ */
3213bf14a46SMatthew Knepley /*       *nneg = lu->id.INFOG(12); */
3223bf14a46SMatthew Knepley /*     } */
3233bf14a46SMatthew Knepley /*     ierr = MPI_Bcast(nneg,1,MPI_INT,0,lu->comm_pastix);CHKERRQ(ierr); */
3243bf14a46SMatthew Knepley /*   } */
3253bf14a46SMatthew Knepley /*   if (nzero) *nzero = lu->iparm[IPARM_NNZEROS]; */
3263bf14a46SMatthew Knepley /*   if (npos)  *npos  = F->rmap->N - (*nneg); */
3273bf14a46SMatthew Knepley   PetscFunctionReturn(0);
3283bf14a46SMatthew Knepley }
3293bf14a46SMatthew Knepley #endif /* !defined(PETSC_USE_COMPLEX) */
3303bf14a46SMatthew Knepley 
3313bf14a46SMatthew Knepley /*
3323bf14a46SMatthew Knepley   Numeric factorisation using PaStiX solver.
3333bf14a46SMatthew Knepley 
3343bf14a46SMatthew Knepley  */
3353bf14a46SMatthew Knepley #undef __FUNCT__
3363bf14a46SMatthew Knepley #define __FUNCT__ "MatFactorNumeric_PASTIX"
3373bf14a46SMatthew Knepley PetscErrorCode MatFactorNumeric_PaStiX(Mat F,Mat A,const MatFactorInfo *info)
3383bf14a46SMatthew Knepley {
3393bf14a46SMatthew Knepley   Mat_Pastix    *lu =(Mat_Pastix*)(F)->spptr;
3403bf14a46SMatthew Knepley   Mat           *tseq,A_seq = PETSC_NULL;
3413bf14a46SMatthew Knepley   PetscErrorCode ierr = 0;
3423bf14a46SMatthew Knepley   PetscInt       rnz,nnz,nz=0,i,*ai,*aj,icntl;
3433bf14a46SMatthew Knepley   PetscInt       M=A->rmap->N,N=A->cmap->N;
3443bf14a46SMatthew Knepley   PetscTruth     valOnly,flg, isSym;
3453bf14a46SMatthew Knepley   Mat            F_diag;
3463bf14a46SMatthew Knepley   IS             is_iden;
3473bf14a46SMatthew Knepley   Vec            b;
3483bf14a46SMatthew Knepley   IS               isrow;
3493bf14a46SMatthew Knepley   PetscTruth     isSeqAIJ,isSeqSBAIJ;
3503bf14a46SMatthew Knepley   Mat_SeqAIJ     *aa,*bb;
3513bf14a46SMatthew Knepley 
3523bf14a46SMatthew Knepley   PetscFunctionBegin;
3533bf14a46SMatthew Knepley   ierr = PetscTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr);
3543bf14a46SMatthew Knepley   ierr = PetscTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ);CHKERRQ(ierr);
3553bf14a46SMatthew Knepley   if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){
3563bf14a46SMatthew Knepley     (F)->ops->solve   = MatSolve_PaStiX;
3573bf14a46SMatthew Knepley 
3583bf14a46SMatthew Knepley     /* Initialize a PASTIX instance */
3593bf14a46SMatthew Knepley     ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->pastix_comm));CHKERRQ(ierr);
3603bf14a46SMatthew Knepley     ierr = MPI_Comm_rank(lu->pastix_comm, &lu->commRank);          CHKERRQ(ierr);
3613bf14a46SMatthew Knepley     ierr = MPI_Comm_size(lu->pastix_comm, &lu->commSize);          CHKERRQ(ierr);
3623bf14a46SMatthew Knepley 
3633bf14a46SMatthew Knepley     /* Set pastix options */
3643bf14a46SMatthew Knepley     lu->iparm[IPARM_MODIFY_PARAMETER] = API_NO;
3653bf14a46SMatthew Knepley     lu->iparm[IPARM_START_TASK]       = API_TASK_INIT;
3663bf14a46SMatthew Knepley     lu->iparm[IPARM_END_TASK]         = API_TASK_INIT;
3673bf14a46SMatthew Knepley     lu->rhsnbr = 1;
3683bf14a46SMatthew Knepley 
3693bf14a46SMatthew Knepley     /* Call to set default pastix options */
3703bf14a46SMatthew Knepley     pastix((pastix_data_t **)&(lu->pastix_data),
3713bf14a46SMatthew Knepley 	   (MPI_Comm)         lu->pastix_comm,
3723bf14a46SMatthew Knepley 	   (pastix_int_t)     lu->n,
3733bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->colptr,
3743bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->row,
3753bf14a46SMatthew Knepley 	   (pastix_float_t*)  lu->val,
3763bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->perm,
3773bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->invp,
3783bf14a46SMatthew Knepley 	   (pastix_float_t*)  lu->rhs,
3793bf14a46SMatthew Knepley 	   (pastix_int_t)     lu->rhsnbr,
3803bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->iparm,
3813bf14a46SMatthew Knepley 	   (double*)          lu->dparm);
3823bf14a46SMatthew Knepley 
3833bf14a46SMatthew Knepley     ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"PaStiX Options","Mat");CHKERRQ(ierr);
3843bf14a46SMatthew Knepley 
3853bf14a46SMatthew Knepley     icntl=-1;
3863bf14a46SMatthew Knepley     lu->iparm[IPARM_VERBOSE] = API_VERBOSE_NO;
3873bf14a46SMatthew Knepley     ierr = PetscOptionsInt("-mat_pastix_verbose","iparm[IPARM_VERBOSE] : level of printing (0 to 2)","None",
3883bf14a46SMatthew Knepley 			   lu->iparm[IPARM_VERBOSE],&icntl,&flg);CHKERRQ(ierr);
3893bf14a46SMatthew Knepley     if ((flg && icntl > 0) || PetscLogPrintInfo) {
3903bf14a46SMatthew Knepley       lu->iparm[IPARM_VERBOSE] =  icntl;
3913bf14a46SMatthew Knepley     }
3923bf14a46SMatthew Knepley     icntl=-1;
3933bf14a46SMatthew Knepley     ierr = PetscOptionsInt("-mat_pastix_threadnbr","iparm[IPARM_THREAD_NBR] : Number of thread by MPI node",
3943bf14a46SMatthew Knepley 			   "None",lu->iparm[IPARM_THREAD_NBR],&icntl,PETSC_NULL);CHKERRQ(ierr);
3953bf14a46SMatthew Knepley     if ((flg && icntl > 0)) {
3963bf14a46SMatthew Knepley       lu->iparm[IPARM_THREAD_NBR] = icntl;
3973bf14a46SMatthew Knepley     }
3983bf14a46SMatthew Knepley     PetscOptionsEnd();
3993bf14a46SMatthew Knepley     valOnly = PETSC_FALSE;
4003bf14a46SMatthew Knepley   }
4013bf14a46SMatthew Knepley   else {
4023bf14a46SMatthew Knepley     valOnly = PETSC_TRUE;
4033bf14a46SMatthew Knepley   }
4043bf14a46SMatthew Knepley 
4053bf14a46SMatthew Knepley   lu->iparm[IPARM_MATRIX_VERIFICATION] = API_YES;
4063bf14a46SMatthew Knepley 
4073bf14a46SMatthew Knepley   /* convert mpi A to seq mat A */
4083bf14a46SMatthew Knepley   ierr = ISCreateStride(PETSC_COMM_SELF,M,0,1,&isrow);CHKERRQ(ierr);
4093bf14a46SMatthew Knepley   ierr = MatGetSubMatrices(A,1,&isrow,&isrow,MAT_INITIAL_MATRIX,&tseq);CHKERRQ(ierr);
4103bf14a46SMatthew Knepley   ierr = ISDestroy(isrow);CHKERRQ(ierr);
4113bf14a46SMatthew Knepley   A_seq = *tseq;
4123bf14a46SMatthew Knepley   ierr = PetscFree(tseq);CHKERRQ(ierr);
4133bf14a46SMatthew Knepley 
4143bf14a46SMatthew Knepley   ierr = MatConvertToCSC(A_seq,valOnly, &lu->n, &lu->colptr, &lu->row, &lu->val); CHKERRQ(ierr);
4153bf14a46SMatthew Knepley   ierr = PetscMalloc((lu->n)*sizeof(PetscInt)   ,&(lu->perm));CHKERRQ(ierr);
4163bf14a46SMatthew Knepley   ierr = PetscMalloc((lu->n)*sizeof(PetscInt)   ,&(lu->invp));CHKERRQ(ierr);
4173bf14a46SMatthew Knepley 
4183bf14a46SMatthew Knepley   MatIsSymmetric_SeqAIJ(A_seq,0.0,&isSym);
4193bf14a46SMatthew Knepley 
4203bf14a46SMatthew Knepley   if (isSym) {
421*745c78f7SBarry Smith     /* On symmetric matrix, LLT */
4223bf14a46SMatthew Knepley     lu->iparm[IPARM_SYM] = API_SYM_YES;
4233bf14a46SMatthew Knepley     lu->iparm[IPARM_FACTORIZATION] = API_FACT_LLT;
4243bf14a46SMatthew Knepley   }
4253bf14a46SMatthew Knepley   else {
426*745c78f7SBarry Smith     /* On unsymmetric matrix, LU */
4273bf14a46SMatthew Knepley     lu->iparm[IPARM_SYM] = API_SYM_NO;
4283bf14a46SMatthew Knepley     lu->iparm[IPARM_FACTORIZATION] = API_FACT_LU;
4293bf14a46SMatthew Knepley   }
4303bf14a46SMatthew Knepley 
4313bf14a46SMatthew Knepley   /*----------------*/
4323bf14a46SMatthew Knepley   if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){
4333bf14a46SMatthew Knepley     if (!(isSeqAIJ || isSeqSBAIJ)) {
4343bf14a46SMatthew Knepley       /* PaStiX only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
4353bf14a46SMatthew Knepley 	ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&lu->b_seq);CHKERRQ(ierr);
4363bf14a46SMatthew Knepley 	ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
4373bf14a46SMatthew Knepley 	ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr);
4383bf14a46SMatthew Knepley 	ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr);
4393bf14a46SMatthew Knepley 	ierr = VecSetFromOptions(b);CHKERRQ(ierr);
4403bf14a46SMatthew Knepley 
4413bf14a46SMatthew Knepley 	ierr = VecScatterCreate(b,is_iden,lu->b_seq,is_iden,&lu->scat_rhs);CHKERRQ(ierr);
4423bf14a46SMatthew Knepley 	ierr = VecScatterCreate(lu->b_seq,is_iden,b,is_iden,&lu->scat_sol);CHKERRQ(ierr);
4433bf14a46SMatthew Knepley 	ierr = ISDestroy(is_iden);CHKERRQ(ierr);
4443bf14a46SMatthew Knepley 	ierr = VecDestroy(b);CHKERRQ(ierr);
4453bf14a46SMatthew Knepley     }
4463bf14a46SMatthew Knepley     lu->iparm[IPARM_START_TASK] = API_TASK_ORDERING;
4473bf14a46SMatthew Knepley     lu->iparm[IPARM_END_TASK]   = API_TASK_NUMFACT;
4483bf14a46SMatthew Knepley 
4493bf14a46SMatthew Knepley     pastix((pastix_data_t **)&(lu->pastix_data),
4503bf14a46SMatthew Knepley 	   (MPI_Comm)         lu->pastix_comm,
4513bf14a46SMatthew Knepley 	   (pastix_int_t)     lu->n,
4523bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->colptr,
4533bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->row,
4543bf14a46SMatthew Knepley 	   (pastix_float_t*)  lu->val,
4553bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->perm,
4563bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->invp,
4573bf14a46SMatthew Knepley 	   (pastix_float_t*)  lu->rhs,
4583bf14a46SMatthew Knepley 	   (pastix_int_t)     lu->rhsnbr,
4593bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->iparm,
4603bf14a46SMatthew Knepley 	   (double*)          lu->dparm);
4613bf14a46SMatthew Knepley     if (lu->iparm[IPARM_ERROR_NUMBER] < 0) {
4623bf14a46SMatthew Knepley       SETERRQ1(PETSC_ERR_LIB,"Error reported by PaStiX in analysis phase: ipparm(IPARM_ERROR_NUMBER)=%d\n",
4633bf14a46SMatthew Knepley 	       lu->iparm[IPARM_ERROR_NUMBER]);
4643bf14a46SMatthew Knepley     }
4653bf14a46SMatthew Knepley   }
4663bf14a46SMatthew Knepley   else {
4673bf14a46SMatthew Knepley     lu->iparm[IPARM_START_TASK] = API_TASK_NUMFACT;
4683bf14a46SMatthew Knepley     lu->iparm[IPARM_END_TASK]   = API_TASK_NUMFACT;
4693bf14a46SMatthew Knepley     pastix((pastix_data_t **)&(lu->pastix_data),
4703bf14a46SMatthew Knepley 	   (MPI_Comm)         lu->pastix_comm,
4713bf14a46SMatthew Knepley 	   (pastix_int_t)     lu->n,
4723bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->colptr,
4733bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->row,
4743bf14a46SMatthew Knepley 	   (pastix_float_t*)  lu->val,
4753bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->perm,
4763bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->invp,
4773bf14a46SMatthew Knepley 	   (pastix_float_t*)  lu->rhs,
4783bf14a46SMatthew Knepley 	   (pastix_int_t)     lu->rhsnbr,
4793bf14a46SMatthew Knepley 	   (pastix_int_t*)    lu->iparm,
4803bf14a46SMatthew Knepley 	   (double*)          lu->dparm);
4813bf14a46SMatthew Knepley 
4823bf14a46SMatthew Knepley     if (lu->iparm[IPARM_ERROR_NUMBER] < 0) {
4833bf14a46SMatthew Knepley       SETERRQ1(PETSC_ERR_LIB,"Error reported by PaStiX in analysis phase: ipparm(IPARM_ERROR_NUMBER)=%d\n",
4843bf14a46SMatthew Knepley 	       lu->iparm[IPARM_ERROR_NUMBER]);
4853bf14a46SMatthew Knepley     }
4863bf14a46SMatthew Knepley   }
4873bf14a46SMatthew Knepley 
4883bf14a46SMatthew Knepley   if (lu->commSize > 1){
4893bf14a46SMatthew Knepley     if ((F)->factor == MAT_FACTOR_LU){
4903bf14a46SMatthew Knepley       F_diag = ((Mat_MPIAIJ *)(F)->data)->A;
4913bf14a46SMatthew Knepley     } else {
4923bf14a46SMatthew Knepley       F_diag = ((Mat_MPISBAIJ *)(F)->data)->A;
4933bf14a46SMatthew Knepley     }
4943bf14a46SMatthew Knepley     F_diag->assembled = PETSC_TRUE;
4953bf14a46SMatthew Knepley     if (lu->nSolve){
4963bf14a46SMatthew Knepley       ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr);
4973bf14a46SMatthew Knepley       ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr);
4983bf14a46SMatthew Knepley     }
4993bf14a46SMatthew Knepley   }
5003bf14a46SMatthew Knepley   (F)->assembled     = PETSC_TRUE;
5013bf14a46SMatthew Knepley   lu->matstruc       = SAME_NONZERO_PATTERN;
5023bf14a46SMatthew Knepley   lu->CleanUpPastix  = PETSC_TRUE;
5033bf14a46SMatthew Knepley   lu->nSolve         = 0;
5043bf14a46SMatthew Knepley   PetscFunctionReturn(0);
5053bf14a46SMatthew Knepley }
5063bf14a46SMatthew Knepley 
5073bf14a46SMatthew Knepley 
5083bf14a46SMatthew Knepley /* Note the Petsc r and c permutations are ignored */
5093bf14a46SMatthew Knepley #undef __FUNCT__
5103bf14a46SMatthew Knepley #define __FUNCT__ "MatLUFactorSymbolic_AIJPASTIX"
5113bf14a46SMatthew Knepley PetscErrorCode MatLUFactorSymbolic_AIJPASTIX(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
5123bf14a46SMatthew Knepley {
5133bf14a46SMatthew Knepley   Mat_Pastix      *lu = (Mat_Pastix*)F->spptr;
5143bf14a46SMatthew Knepley   PetscErrorCode ierr = 0;
5153bf14a46SMatthew Knepley 
5163bf14a46SMatthew Knepley   PetscFunctionBegin;
5173bf14a46SMatthew Knepley   lu->iparm[IPARM_FACTORIZATION] = API_FACT_LU;
5183bf14a46SMatthew Knepley   lu->iparm[IPARM_SYM]           = API_SYM_YES;
5193bf14a46SMatthew Knepley   lu->matstruc                   = DIFFERENT_NONZERO_PATTERN;
5203bf14a46SMatthew Knepley   F->ops->lufactornumeric        = MatFactorNumeric_PaStiX;
5213bf14a46SMatthew Knepley   PetscFunctionReturn(0);
5223bf14a46SMatthew Knepley }
5233bf14a46SMatthew Knepley 
5243bf14a46SMatthew Knepley 
5253bf14a46SMatthew Knepley /* Note the Petsc r permutation is ignored */
5263bf14a46SMatthew Knepley #undef __FUNCT__
5273bf14a46SMatthew Knepley #define __FUNCT__ "MatCholeskyFactorSymbolic_SBAIJPASTIX"
5283bf14a46SMatthew Knepley PetscErrorCode MatCholeskyFactorSymbolic_SBAIJPASTIX(Mat F,Mat A,IS r,const MatFactorInfo *info)
5293bf14a46SMatthew Knepley {
5303bf14a46SMatthew Knepley   Mat_Pastix      *lu = (Mat_Pastix*)(F)->spptr;
5313bf14a46SMatthew Knepley   PetscErrorCode ierr = 0;
5323bf14a46SMatthew Knepley 
5333bf14a46SMatthew Knepley   PetscFunctionBegin;
5343bf14a46SMatthew Knepley   lu->iparm[IPARM_FACTORIZATION]  = API_FACT_LLT;
5353bf14a46SMatthew Knepley   lu->iparm[IPARM_SYM]            = API_SYM_NO;
5363bf14a46SMatthew Knepley   lu->matstruc                    = DIFFERENT_NONZERO_PATTERN;
5373bf14a46SMatthew Knepley   (F)->ops->choleskyfactornumeric = MatFactorNumeric_PaStiX;
5383bf14a46SMatthew Knepley #if !defined(PETSC_USE_COMPLEX)
5393bf14a46SMatthew Knepley   (F)->ops->getinertia            = MatGetInertia_SBAIJPASTIX;
5403bf14a46SMatthew Knepley #endif
5413bf14a46SMatthew Knepley   PetscFunctionReturn(0);
5423bf14a46SMatthew Knepley }
5433bf14a46SMatthew Knepley 
5443bf14a46SMatthew Knepley #undef __FUNCT__
5453bf14a46SMatthew Knepley #define __FUNCT__ "MatFactorInfo_PaStiX"
5463bf14a46SMatthew Knepley PetscErrorCode MatFactorInfo_PaStiX(Mat A,PetscViewer viewer) {
5473bf14a46SMatthew Knepley   Mat_Pastix      *lu=(Mat_Pastix*)A->spptr;
5483bf14a46SMatthew Knepley   PetscErrorCode ierr;
5493bf14a46SMatthew Knepley 
5503bf14a46SMatthew Knepley   PetscFunctionBegin;
5513bf14a46SMatthew Knepley   /* check if matrix is pastix type */
5523bf14a46SMatthew Knepley   if (A->ops->solve != MatSolve_PaStiX) PetscFunctionReturn(0);
5533bf14a46SMatthew Knepley 
5543bf14a46SMatthew Knepley   ierr = PetscViewerASCIIPrintf(viewer,"PaStiX run parameters:\n");CHKERRQ(ierr);
5553bf14a46SMatthew Knepley   ierr = PetscViewerASCIIPrintf(viewer,"  Matrix type :                      %s \n",
556*745c78f7SBarry Smith 				((lu->iparm[IPARM_SYM] == API_SYM_YES)?"Symmetric":"Unsymmetric"));CHKERRQ(ierr);
5573bf14a46SMatthew Knepley   ierr = PetscViewerASCIIPrintf(viewer,"  Level of printing (0,1,2):         %d \n",
5583bf14a46SMatthew Knepley 				lu->iparm[IPARM_VERBOSE]);CHKERRQ(ierr);
5593bf14a46SMatthew Knepley   ierr = PetscViewerASCIIPrintf(viewer,"  Number of refinements iterations : %d \n",
5603bf14a46SMatthew Knepley 				lu->iparm[IPARM_NBITER]);CHKERRQ(ierr);
5613bf14a46SMatthew Knepley   ierr = PetscPrintf(PETSC_COMM_SELF,"  Error :                        %g \n",
5623bf14a46SMatthew Knepley 		     lu->dparm[DPARM_RELATIVE_ERROR]);CHKERRQ(ierr);
5633bf14a46SMatthew Knepley   PetscFunctionReturn(0);
5643bf14a46SMatthew Knepley }
5653bf14a46SMatthew Knepley 
5663bf14a46SMatthew Knepley #undef __FUNCT__
5673bf14a46SMatthew Knepley #define __FUNCT__ "MatView_PaStiX"
5683bf14a46SMatthew Knepley PetscErrorCode MatView_PaStiX(Mat A,PetscViewer viewer)
5693bf14a46SMatthew Knepley {
5703bf14a46SMatthew Knepley   PetscErrorCode    ierr;
5713bf14a46SMatthew Knepley   PetscTruth        iascii;
5723bf14a46SMatthew Knepley   PetscViewerFormat format;
5733bf14a46SMatthew Knepley 
5743bf14a46SMatthew Knepley   PetscFunctionBegin;
5753bf14a46SMatthew Knepley     ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
5763bf14a46SMatthew Knepley   if (iascii) {
5773bf14a46SMatthew Knepley     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
5783bf14a46SMatthew Knepley     if (format == PETSC_VIEWER_ASCII_INFO){
5793bf14a46SMatthew Knepley       ierr = MatFactorInfo_PaStiX(A,viewer);CHKERRQ(ierr);
5803bf14a46SMatthew Knepley     }
5813bf14a46SMatthew Knepley   }
5823bf14a46SMatthew Knepley   PetscFunctionReturn(0);
5833bf14a46SMatthew Knepley }
5843bf14a46SMatthew Knepley 
5853bf14a46SMatthew Knepley 
5863bf14a46SMatthew Knepley /*MC
5873bf14a46SMatthew Knepley   MATAIJPASTIX - MATAIJPASTIX = "aijpastix" - A matrix type providing direct solvers (LU) for distributed
5883bf14a46SMatthew Knepley   and sequential matrices via the external package PaStiX.
5893bf14a46SMatthew Knepley 
5903bf14a46SMatthew Knepley   If PaStiX is installed (see the manual for instructions
5913bf14a46SMatthew Knepley   on how to declare the existence of external packages),
5923bf14a46SMatthew Knepley   a matrix type can be constructed which invokes PaStiX solvers.
5933bf14a46SMatthew Knepley   After calling MatCreate(...,A), simply call MatSetType(A,MATAIJPASTIX), then
5943bf14a46SMatthew Knepley   optionally call MatSeqAIJSetPreallocation() or MatMPIAIJSetPreallocation() etc DO NOT
5953bf14a46SMatthew Knepley   call MatCreateSeqAIJ/MPIAIJ() directly or the preallocation information will be LOST!
5963bf14a46SMatthew Knepley 
5973bf14a46SMatthew Knepley   If created with a single process communicator, this matrix type inherits from MATSEQAIJ.
5983bf14a46SMatthew Knepley   Otherwise, this matrix type inherits from MATMPIAIJ.  Hence for single process communicators,
5993bf14a46SMatthew Knepley   MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
6003bf14a46SMatthew Knepley   for communicators controlling multiple processes.  It is recommended that you call both of
6013bf14a46SMatthew Knepley   the above preallocation routines for simplicity.  One can also call MatConvert() for an inplace
6023bf14a46SMatthew Knepley   conversion to or from the MATSEQAIJ or MATMPIAIJ type (depending on the communicator size)
6033bf14a46SMatthew Knepley   without data copy AFTER the matrix values are set.
6043bf14a46SMatthew Knepley 
6053bf14a46SMatthew Knepley   Options Database Keys:
6063bf14a46SMatthew Knepley + -mat_type sbaijpastix           - sets the matrix type to "sbaijpastix" during a call to MatSetFromOptions()
6073bf14a46SMatthew Knepley . -mat_pastix_sym       <0,1>     - 0 the matrix is symmetric, 1 unsymmetric
6083bf14a46SMatthew Knepley . -mat_pastix_verbose   <0,1,2>   - print level
6093bf14a46SMatthew Knepley . -mat_pastix_threadnbr <integer> - Set the thread number by MPI task.
6103bf14a46SMatthew Knepley 
6113bf14a46SMatthew Knepley   Level: beginner
6123bf14a46SMatthew Knepley 
6133bf14a46SMatthew Knepley .seealso: MATSBAIJPASTIX
6143bf14a46SMatthew Knepley M*/
6153bf14a46SMatthew Knepley 
6163bf14a46SMatthew Knepley 
6173bf14a46SMatthew Knepley #undef __FUNCT__
6183bf14a46SMatthew Knepley #define __FUNCT__ "MatGetInfo_PaStiX"
6193bf14a46SMatthew Knepley PetscErrorCode MatGetInfo_PaStiX(Mat A,MatInfoType flag,MatInfo *info)
6203bf14a46SMatthew Knepley {
6213bf14a46SMatthew Knepley     Mat_Pastix  *lu =(Mat_Pastix*)A->spptr;
6223bf14a46SMatthew Knepley     PetscErrorCode ierr;
6233bf14a46SMatthew Knepley 
6243bf14a46SMatthew Knepley     PetscFunctionBegin;
6253bf14a46SMatthew Knepley     info->block_size        = 1.0;
6263bf14a46SMatthew Knepley     info->nz_allocated      = lu->iparm[IPARM_NNZEROS];
6273bf14a46SMatthew Knepley     info->nz_used           = lu->iparm[IPARM_NNZEROS];
6283bf14a46SMatthew Knepley     info->nz_unneeded       = 0.0;
6293bf14a46SMatthew Knepley     info->assemblies        = 0.0;
6303bf14a46SMatthew Knepley     info->mallocs           = 0.0;
6313bf14a46SMatthew Knepley     info->memory            = 0.0;
6323bf14a46SMatthew Knepley     info->fill_ratio_given  = 0;
6333bf14a46SMatthew Knepley     info->fill_ratio_needed = 0;
6343bf14a46SMatthew Knepley     info->factor_mallocs    = 0;
6353bf14a46SMatthew Knepley     PetscFunctionReturn(0);
6363bf14a46SMatthew Knepley }
6373bf14a46SMatthew Knepley 
6383bf14a46SMatthew Knepley /*MC
6393bf14a46SMatthew Knepley   MATSBAIJPASTIX - MATSBAIJPASTIX = "sbaijpastix" - A symmetric matrix type providing direct solvers (Cholesky) for
6403bf14a46SMatthew Knepley   distributed and sequential matrices via the external package PaStiX.
6413bf14a46SMatthew Knepley 
6423bf14a46SMatthew Knepley   If PaStiX is installed (see the manual for instructions
6433bf14a46SMatthew Knepley   on how to declare the existence of external packages),
6443bf14a46SMatthew Knepley   a matrix type can be constructed which invokes PaStiX solvers.
6453bf14a46SMatthew Knepley   After calling MatCreate(...,A), simply call MatSetType(A,MATSBAIJPASTIX), then
6463bf14a46SMatthew Knepley   optionally call MatSeqSBAIJSetPreallocation() or MatMPISBAIJSetPreallocation() DO NOT
6473bf14a46SMatthew Knepley   call MatCreateSeqSBAIJ/MPISBAIJ() directly or the preallocation information will be LOST!
6483bf14a46SMatthew Knepley 
6493bf14a46SMatthew Knepley   If created with a single process communicator, this matrix type inherits from MATSEQSBAIJ.
6503bf14a46SMatthew Knepley   Otherwise, this matrix type inherits from MATMPISBAIJ.  Hence for single process communicators,
6513bf14a46SMatthew Knepley   MatSeqSBAIJSetPreallocation() is supported, and similarly MatMPISBAIJSetPreallocation() is supported
6523bf14a46SMatthew Knepley   for communicators controlling multiple processes.  It is recommended that you call both of
6533bf14a46SMatthew Knepley   the above preallocation routines for simplicity.  One can also call MatConvert() for an inplace
6543bf14a46SMatthew Knepley   conversion to or from the MATSEQSBAIJ or MATMPISBAIJ type (depending on the communicator size)
6553bf14a46SMatthew Knepley   without data copy AFTER the matrix values have been set.
6563bf14a46SMatthew Knepley 
6573bf14a46SMatthew Knepley   Options Database Keys:
6583bf14a46SMatthew Knepley + -mat_type aijpastix             - sets the matrix type to "aijpastix" during a call to MatSetFromOptions()
6593bf14a46SMatthew Knepley . -mat_pastix_sym       <0,1>     - 0 the matrix is symmetric, 1 unsymmetric
6603bf14a46SMatthew Knepley . -mat_pastix_verbose   <0,1,2>   - print level
6613bf14a46SMatthew Knepley . -mat_pastix_threadnbr <integer> - Set the thread number by MPI task.
6623bf14a46SMatthew Knepley   Level: beginner
6633bf14a46SMatthew Knepley 
6643bf14a46SMatthew Knepley .seealso: MATAIJPASTIX
6653bf14a46SMatthew Knepley M*/
6663bf14a46SMatthew Knepley 
6673bf14a46SMatthew Knepley EXTERN_C_BEGIN
6683bf14a46SMatthew Knepley #undef __FUNCT__
6693bf14a46SMatthew Knepley #define __FUNCT__ "MatFactorGetSolverPackage_pastix"
6703bf14a46SMatthew Knepley PetscErrorCode MatFactorGetSolverPackage_pastix(Mat A,const MatSolverPackage *type)
6713bf14a46SMatthew Knepley {
6723bf14a46SMatthew Knepley   PetscErrorCode ierr = 0;
6733bf14a46SMatthew Knepley 
6743bf14a46SMatthew Knepley   PetscFunctionBegin;
6753bf14a46SMatthew Knepley   *type = MAT_SOLVER_PASTIX;
6763bf14a46SMatthew Knepley   PetscFunctionReturn(0);
6773bf14a46SMatthew Knepley }
6783bf14a46SMatthew Knepley EXTERN_C_END
6793bf14a46SMatthew Knepley 
6803bf14a46SMatthew Knepley EXTERN_C_BEGIN
6813bf14a46SMatthew Knepley /*
6823bf14a46SMatthew Knepley     The seq and mpi versions of this function are the same
6833bf14a46SMatthew Knepley */
6843bf14a46SMatthew Knepley #undef __FUNCT__
6853bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_seqaij_pastix"
6863bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_seqaij_pastix(Mat A,MatFactorType ftype,Mat *F)
6873bf14a46SMatthew Knepley {
6883bf14a46SMatthew Knepley   Mat            B;
6893bf14a46SMatthew Knepley   PetscErrorCode ierr;
6903bf14a46SMatthew Knepley   Mat_Pastix    *pastix;
6913bf14a46SMatthew Knepley 
6923bf14a46SMatthew Knepley   PetscFunctionBegin;
6933bf14a46SMatthew Knepley   if (ftype != MAT_FACTOR_LU) {
6943bf14a46SMatthew Knepley     SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc AIJ matrices with PaStiX Cholesky, use SBAIJ matrix");
6953bf14a46SMatthew Knepley   }
6963bf14a46SMatthew Knepley   /* Create the factorization matrix */
6973bf14a46SMatthew Knepley   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
6983bf14a46SMatthew Knepley   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
6993bf14a46SMatthew Knepley   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
7003bf14a46SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
7013bf14a46SMatthew Knepley 
7023bf14a46SMatthew Knepley   B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJPASTIX;
7033bf14a46SMatthew Knepley   B->ops->view             = MatView_PaStiX;
7043bf14a46SMatthew Knepley   B->ops->getinfo          = MatGetInfo_PaStiX;
7053bf14a46SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C",
7063bf14a46SMatthew Knepley 					   "MatFactorGetSolverPackage_pastix",
7073bf14a46SMatthew Knepley 					   MatFactorGetSolverPackage_pastix);CHKERRQ(ierr);
7083bf14a46SMatthew Knepley   B->factor                = MAT_FACTOR_LU;
7093bf14a46SMatthew Knepley 
7103bf14a46SMatthew Knepley   ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr);
7113bf14a46SMatthew Knepley   pastix->CleanUpPastix             = PETSC_FALSE;
7123bf14a46SMatthew Knepley   pastix->isAIJ                     = PETSC_TRUE;
7133bf14a46SMatthew Knepley   pastix->scat_rhs                  = PETSC_NULL;
7143bf14a46SMatthew Knepley   pastix->scat_sol                  = PETSC_NULL;
7153bf14a46SMatthew Knepley   pastix->nSolve                    = 0;
7163bf14a46SMatthew Knepley   pastix->MatDestroy                = B->ops->destroy;
7173bf14a46SMatthew Knepley   B->ops->destroy                   = MatDestroy_Pastix;
7183bf14a46SMatthew Knepley   B->spptr                          = (void*)pastix;
7193bf14a46SMatthew Knepley 
7203bf14a46SMatthew Knepley   *F = B;
7213bf14a46SMatthew Knepley   PetscFunctionReturn(0);
7223bf14a46SMatthew Knepley }
7233bf14a46SMatthew Knepley EXTERN_C_END
7243bf14a46SMatthew Knepley 
7253bf14a46SMatthew Knepley EXTERN_C_BEGIN
7263bf14a46SMatthew Knepley #undef __FUNCT__
7273bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_mpiaij_pastix"
7283bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_mpiaij_pastix(Mat A,MatFactorType ftype,Mat *F)
7293bf14a46SMatthew Knepley {
7303bf14a46SMatthew Knepley   Mat            B;
7313bf14a46SMatthew Knepley   PetscErrorCode ierr;
7323bf14a46SMatthew Knepley   Mat_Pastix    *pastix;
7333bf14a46SMatthew Knepley 
7343bf14a46SMatthew Knepley   PetscFunctionBegin;
7353bf14a46SMatthew Knepley   if (ftype != MAT_FACTOR_LU) {
7363bf14a46SMatthew Knepley     SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc AIJ matrices with PaStiX Cholesky, use SBAIJ matrix");
7373bf14a46SMatthew Knepley   }
7383bf14a46SMatthew Knepley   /* Create the factorization matrix */
7393bf14a46SMatthew Knepley   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
7403bf14a46SMatthew Knepley   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
7413bf14a46SMatthew Knepley   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
7423bf14a46SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
7433bf14a46SMatthew Knepley   ierr = MatMPIAIJSetPreallocation(B,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
7443bf14a46SMatthew Knepley 
7453bf14a46SMatthew Knepley   B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJPASTIX;
7463bf14a46SMatthew Knepley   B->ops->view             = MatView_PaStiX;
7473bf14a46SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,
7483bf14a46SMatthew Knepley 					   "MatFactorGetSolverPackage_C",
7493bf14a46SMatthew Knepley 					   "MatFactorGetSolverPackage_pastix",
7503bf14a46SMatthew Knepley 					   MatFactorGetSolverPackage_pastix);CHKERRQ(ierr);
7513bf14a46SMatthew Knepley   B->factor                = MAT_FACTOR_LU;
7523bf14a46SMatthew Knepley 
7533bf14a46SMatthew Knepley   ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr);
7543bf14a46SMatthew Knepley   pastix->CleanUpPastix             = PETSC_FALSE;
7553bf14a46SMatthew Knepley   pastix->isAIJ                     = PETSC_TRUE;
7563bf14a46SMatthew Knepley   pastix->scat_rhs                  = PETSC_NULL;
7573bf14a46SMatthew Knepley   pastix->scat_sol                  = PETSC_NULL;
7583bf14a46SMatthew Knepley   pastix->nSolve                    = 0;
7593bf14a46SMatthew Knepley   pastix->MatDestroy                = B->ops->destroy;
7603bf14a46SMatthew Knepley   B->ops->destroy                  = MatDestroy_Pastix;
7613bf14a46SMatthew Knepley   B->spptr                         = (void*)pastix;
7623bf14a46SMatthew Knepley 
7633bf14a46SMatthew Knepley   *F = B;
7643bf14a46SMatthew Knepley   PetscFunctionReturn(0);
7653bf14a46SMatthew Knepley }
7663bf14a46SMatthew Knepley EXTERN_C_END
7673bf14a46SMatthew Knepley 
7683bf14a46SMatthew Knepley EXTERN_C_BEGIN
7693bf14a46SMatthew Knepley #undef __FUNCT__
7703bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_seqsbaij_pastix"
7713bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_seqsbaij_pastix(Mat A,MatFactorType ftype,Mat *F)
7723bf14a46SMatthew Knepley {
7733bf14a46SMatthew Knepley   Mat            B;
7743bf14a46SMatthew Knepley   PetscErrorCode ierr;
7753bf14a46SMatthew Knepley   Mat_Pastix    *pastix;
7763bf14a46SMatthew Knepley 
7773bf14a46SMatthew Knepley   PetscFunctionBegin;
7783bf14a46SMatthew Knepley   if (ftype != MAT_FACTOR_CHOLESKY) {
7793bf14a46SMatthew Knepley     SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with PaStiX LU, use AIJ matrix");
7803bf14a46SMatthew Knepley   }
7813bf14a46SMatthew Knepley   /* Create the factorization matrix */
7823bf14a46SMatthew Knepley   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
7833bf14a46SMatthew Knepley   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
7843bf14a46SMatthew Knepley   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
7853bf14a46SMatthew Knepley   ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr);
7863bf14a46SMatthew Knepley   ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
7873bf14a46SMatthew Knepley 
7883bf14a46SMatthew Knepley   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJPASTIX;
7893bf14a46SMatthew Knepley   B->ops->view                   = MatView_PaStiX;
7903bf14a46SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,
7913bf14a46SMatthew Knepley 					   "MatFactorGetSolverPackage_C",
7923bf14a46SMatthew Knepley 					   "MatFactorGetSolverPackage_pastix",
7933bf14a46SMatthew Knepley 					   MatFactorGetSolverPackage_pastix);CHKERRQ(ierr);
7943bf14a46SMatthew Knepley 
7953bf14a46SMatthew Knepley   B->factor                      = MAT_FACTOR_CHOLESKY;
7963bf14a46SMatthew Knepley 
7973bf14a46SMatthew Knepley   ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr);
7983bf14a46SMatthew Knepley   pastix->CleanUpPastix             = PETSC_FALSE;
7993bf14a46SMatthew Knepley   pastix->isAIJ                     = PETSC_TRUE;
8003bf14a46SMatthew Knepley   pastix->scat_rhs                  = PETSC_NULL;
8013bf14a46SMatthew Knepley   pastix->scat_sol                  = PETSC_NULL;
8023bf14a46SMatthew Knepley   pastix->nSolve                    = 0;
8033bf14a46SMatthew Knepley   pastix->MatDestroy                = B->ops->destroy;
8043bf14a46SMatthew Knepley   B->ops->destroy                  = MatDestroy_Pastix;
8053bf14a46SMatthew Knepley   B->spptr                         = (void*)pastix;
8063bf14a46SMatthew Knepley 
8073bf14a46SMatthew Knepley   *F = B;
8083bf14a46SMatthew Knepley   PetscFunctionReturn(0);
8093bf14a46SMatthew Knepley }
8103bf14a46SMatthew Knepley EXTERN_C_END
8113bf14a46SMatthew Knepley 
8123bf14a46SMatthew Knepley EXTERN_C_BEGIN
8133bf14a46SMatthew Knepley #undef __FUNCT__
8143bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_mpisbaij_pastix"
8153bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_mpisbaij_pastix(Mat A,MatFactorType ftype,Mat *F)
8163bf14a46SMatthew Knepley {
8173bf14a46SMatthew Knepley   Mat            B;
8183bf14a46SMatthew Knepley   PetscErrorCode ierr;
8193bf14a46SMatthew Knepley   Mat_Pastix    *pastix;
8203bf14a46SMatthew Knepley 
8213bf14a46SMatthew Knepley   PetscFunctionBegin;
8223bf14a46SMatthew Knepley   if (ftype != MAT_FACTOR_CHOLESKY) {
8233bf14a46SMatthew Knepley     SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with PaStiX LU, use AIJ matrix");
8243bf14a46SMatthew Knepley   }
8253bf14a46SMatthew Knepley   /* Create the factorization matrix */
8263bf14a46SMatthew Knepley   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
8273bf14a46SMatthew Knepley   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
8283bf14a46SMatthew Knepley   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
8293bf14a46SMatthew Knepley   ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr);
8303bf14a46SMatthew Knepley   ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
8313bf14a46SMatthew Knepley 
8323bf14a46SMatthew Knepley   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJPASTIX;
8333bf14a46SMatthew Knepley   B->ops->view                   = MatView_PaStiX;
8343bf14a46SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,
8353bf14a46SMatthew Knepley 					   "MatFactorGetSolverPackage_C",
8363bf14a46SMatthew Knepley 					   "MatFactorGetSolverPackage_pastix",
8373bf14a46SMatthew Knepley 					   MatFactorGetSolverPackage_pastix);CHKERRQ(ierr);
8383bf14a46SMatthew Knepley   B->factor                      = MAT_FACTOR_CHOLESKY;
8393bf14a46SMatthew Knepley 
8403bf14a46SMatthew Knepley   ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr);
8413bf14a46SMatthew Knepley   pastix->CleanUpPastix             = PETSC_FALSE;
8423bf14a46SMatthew Knepley   pastix->isAIJ                     = PETSC_TRUE;
8433bf14a46SMatthew Knepley   pastix->scat_rhs                  = PETSC_NULL;
8443bf14a46SMatthew Knepley   pastix->scat_sol                  = PETSC_NULL;
8453bf14a46SMatthew Knepley   pastix->nSolve                    = 0;
8463bf14a46SMatthew Knepley   pastix->MatDestroy                = B->ops->destroy;
8473bf14a46SMatthew Knepley   B->ops->destroy                   = MatDestroy_Pastix;
8483bf14a46SMatthew Knepley   B->spptr                          = (void*)pastix;
8493bf14a46SMatthew Knepley 
8503bf14a46SMatthew Knepley   *F = B;
8513bf14a46SMatthew Knepley   PetscFunctionReturn(0);
8523bf14a46SMatthew Knepley }
8533bf14a46SMatthew Knepley EXTERN_C_END
854