xref: /petsc/src/mat/impls/aij/mpi/pastix/pastix.c (revision 3bf14a46ed47d428346a6714cb3295913ad8ded2)
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