Actual source code: umfpack.c

  1: /*$Id: umfpack.c,v 1.10 2001/08/15 15:56:50 bsmith Exp $*/

  3: /* 
  4:         Provides an interface to the UMFPACK sparse solver
  5: */

 7:  #include src/mat/impls/aij/seq/aij.h

  9: #if defined(PETSC_HAVE_UMFPACK) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
 10: EXTERN_C_BEGIN
 11: #include "umfpack.h"
 12: EXTERN_C_END

 14: typedef struct {
 15:   void         *Symbolic, *Numeric;
 16:   double       Info[UMFPACK_INFO], Control[UMFPACK_CONTROL],*W;
 17:   int          *Wi,*ai,*aj,*perm_c;
 18:   PetscScalar  *av;
 19:   MatStructure flg;
 20:   PetscTruth   PetscMatOdering;
 21: } Mat_SeqAIJ_UMFPACK;


 24: extern int MatDestroy_SeqAIJ(Mat);

 26: #undef __FUNCT__  
 28: int MatDestroy_SeqAIJ_UMFPACK(Mat A)
 29: {
 30:   Mat_SeqAIJ_UMFPACK *lu = (Mat_SeqAIJ_UMFPACK*)A->spptr;
 31:   int                ierr;

 34:   umfpack_di_free_symbolic(&lu->Symbolic) ;
 35:   umfpack_di_free_numeric(&lu->Numeric) ;
 36:   PetscFree(lu->Wi);
 37:   PetscFree(lu->W);

 39:   if (lu->PetscMatOdering) {
 40:     PetscFree(lu->perm_c);
 41:   }
 42:   PetscFree(lu);
 43:   MatDestroy_SeqAIJ(A);
 44:   return(0);
 45: }

 47: #undef __FUNCT__  
 49: int MatSolve_SeqAIJ_UMFPACK(Mat A,Vec b,Vec x)
 50: {
 51:   Mat_SeqAIJ_UMFPACK *lu = (Mat_SeqAIJ_UMFPACK*)A->spptr;
 52:   PetscScalar        *av=lu->av,*ba,*xa;
 53:   int                ierr,*ai=lu->ai,*aj=lu->aj,status;
 54: 
 56:   /* solve Ax = b by umfpack_di_wsolve */
 57:   /* ----------------------------------*/
 58:   VecGetArray(b,&ba);
 59:   VecGetArray(x,&xa);

 61:   status = umfpack_di_wsolve(UMFPACK_At,ai,aj,av,xa,ba,lu->Numeric,lu->Control,lu->Info,lu->Wi,lu->W);
 62:   umfpack_di_report_info(lu->Control, lu->Info);
 63:   if (status < 0){
 64:     umfpack_di_report_status(lu->Control, status) ;
 65:     SETERRQ(1,"umfpack_di_wsolve failed") ;
 66:   }
 67: 
 68:   VecRestoreArray(b,&ba);
 69:   VecRestoreArray(x,&xa);
 70:   return(0);
 71: }

 73: #undef __FUNCT__  
 75: int MatLUFactorNumeric_SeqAIJ_UMFPACK(Mat A,Mat *F)
 76: {
 77:   Mat_SeqAIJ_UMFPACK *lu = (Mat_SeqAIJ_UMFPACK*)(*F)->spptr;
 78:   int                *ai=lu->ai,*aj=lu->aj,m=A->m,status,ierr;
 79:   PetscScalar        *av=lu->av;

 82:   /* numeric factorization of A' */
 83:   /* ----------------------------*/
 84:   status = umfpack_di_numeric (ai,aj,av,lu->Symbolic,&lu->Numeric,lu->Control,lu->Info) ;
 85:   if (status < 0) SETERRQ(1,"umfpack_di_numeric failed");
 86:   /* report numeric factorization of A' when Control[PRL] > 3 */
 87:   (void) umfpack_di_report_numeric (lu->Numeric, lu->Control) ;

 89:   if (lu->flg == DIFFERENT_NONZERO_PATTERN){  /* first numeric factorization */
 90:     /* allocate working space to be used by Solve */
 91:     PetscMalloc(m * sizeof(int), &lu->Wi);
 92:     PetscMalloc(5*m * sizeof(double), &lu->W);

 94:     lu->flg = SAME_NONZERO_PATTERN;
 95:   }

 97:   return(0);
 98: }

100: /*
101:    Note the r permutation is ignored
102: */
103: #undef __FUNCT__  
105: int MatLUFactorSymbolic_SeqAIJ_UMFPACK(Mat A,IS r,IS c,MatLUInfo *info,Mat *F)
106: {
107:   Mat_SeqAIJ          *mat=(Mat_SeqAIJ*)A->data;
108:   Mat_SeqAIJ_UMFPACK  *lu;
109:   int                 ierr,m=A->m,n=A->n,*ai=mat->i,*aj=mat->j,status,*ca;
110:   PetscScalar         *av=mat->a;
111: 
113:   /* Create the factorization matrix F */
114:   MatCreateSeqAIJ(A->comm,m,n,PETSC_NULL,PETSC_NULL,F);
115: 
116:   (*F)->ops->lufactornumeric = MatLUFactorNumeric_SeqAIJ_UMFPACK;
117:   (*F)->ops->solve           = MatSolve_SeqAIJ_UMFPACK;
118:   (*F)->ops->destroy         = MatDestroy_SeqAIJ_UMFPACK;
119:   (*F)->factor               = FACTOR_LU;
120:   (*F)->assembled            = PETSC_TRUE;  /* required by -sles_view */

122:   ierr        = PetscNew(Mat_SeqAIJ_UMFPACK,&lu);
123:   (*F)->spptr = (void*)lu;
124: 
125:   /* initializations */
126:   /* ------------------------------------------------*/
127:   /* get the default control parameters */
128:   umfpack_di_defaults (lu->Control) ;
129:   lu->perm_c = PETSC_NULL;  /* use defaul UMFPACK col permutation */

131:   PetscOptionsBegin(A->comm,A->prefix,"UMFPACK Options","Mat");
132:   /* Control parameters used by reporting routiones */
133:   PetscOptionsReal("-mat_umfpack_prl","Control[UMFPACK_PRL]","None",lu->Control[UMFPACK_PRL],&lu->Control[UMFPACK_PRL],PETSC_NULL);

135:   /* Control parameters for symbolic factorization */
136:   PetscOptionsReal("-mat_umfpack_dense_col","Control[UMFPACK_DENSE_COL]","None",lu->Control[UMFPACK_DENSE_COL],&lu->Control[UMFPACK_DENSE_COL],PETSC_NULL);
137:   PetscOptionsReal("-mat_umfpack_dense_row","Control[UMFPACK_DENSE_ROW]","None",lu->Control[UMFPACK_DENSE_ROW],&lu->Control[UMFPACK_DENSE_ROW],PETSC_NULL);
138:   PetscOptionsReal("-mat_umfpack_block_size","Control[UMFPACK_BLOCK_SIZE]","None",lu->Control[UMFPACK_BLOCK_SIZE],&lu->Control[UMFPACK_BLOCK_SIZE],PETSC_NULL);

140:   /* Control parameters used by numeric factorization */
141:   PetscOptionsReal("-mat_umfpack_pivot_tolerance","Control[UMFPACK_PIVOT_TOLERANCE]","None",lu->Control[UMFPACK_PIVOT_TOLERANCE],&lu->Control[UMFPACK_PIVOT_TOLERANCE],PETSC_NULL);
142:   PetscOptionsReal("-mat_umfpack_relaxed_amalgamation","Control[UMFPACK_RELAXED_AMALGAMATION]","None",lu->Control[UMFPACK_RELAXED_AMALGAMATION],&lu->Control[UMFPACK_RELAXED_AMALGAMATION],PETSC_NULL);
143:   PetscOptionsReal("-mat_umfpack_relaxed2_amalgamation","Control[UMFPACK_RELAXED2_AMALGAMATION]","None",lu->Control[UMFPACK_RELAXED2_AMALGAMATION],&lu->Control[UMFPACK_RELAXED2_AMALGAMATION],PETSC_NULL);
144:   PetscOptionsReal("-mat_umfpack_relaxed3_amalgamation","Control[UMFPACK_RELAXED3_AMALGAMATION]","None",lu->Control[UMFPACK_RELAXED3_AMALGAMATION],&lu->Control[UMFPACK_RELAXED3_AMALGAMATION],PETSC_NULL);
145:   PetscOptionsReal("-mat_umfpack_alloc_init","Control[UMFPACK_ALLOC_INIT]","None",lu->Control[UMFPACK_ALLOC_INIT],&lu->Control[UMFPACK_ALLOC_INIT],PETSC_NULL);

147:   /* Control parameters used by solve */
148:   PetscOptionsReal("-mat_umfpack_irstep","Control[UMFPACK_IRSTEP]","None",lu->Control[UMFPACK_IRSTEP],&lu->Control[UMFPACK_IRSTEP],PETSC_NULL);
149: 
150:   /* use Petsc mat ordering (notice size is for the transpose) */
151:   PetscOptionsHasName(PETSC_NULL,"-pc_lu_mat_ordering_type",&lu->PetscMatOdering);
152:   if (lu->PetscMatOdering) {
153:     ISGetIndices(c,&ca);
154:     PetscMalloc(A->m*sizeof(int),&lu->perm_c);
155:     PetscMemcpy(lu->perm_c,ca,A->m*sizeof(int));
156:     ISRestoreIndices(c,&ca);
157:   }
158:   PetscOptionsEnd();

160:   /* print the control parameters */
161:   if( lu->Control[UMFPACK_PRL] > 1 ) umfpack_di_report_control (lu->Control);

163:   /* symbolic factorization of A' */
164:   /* ---------------------------------------------------------------------- */
165:   status = umfpack_di_qsymbolic(n,m,ai,aj,lu->perm_c,&lu->Symbolic,lu->Control,lu->Info) ;
166:   if (status < 0){
167:     umfpack_di_report_info(lu->Control, lu->Info) ;
168:     umfpack_di_report_status(lu->Control, status) ;
169:     SETERRQ(1,"umfpack_di_symbolic failed");
170:   }
171:   /* report sumbolic factorization of A' when Control[PRL] > 3 */
172:   (void) umfpack_di_report_symbolic(lu->Symbolic, lu->Control) ;

174:   lu->flg = DIFFERENT_NONZERO_PATTERN;
175:   lu->ai  = ai;
176:   lu->aj  = aj;
177:   lu->av  = av;
178:   return(0);
179: }

181: #undef __FUNCT__  
183: int MatUseUMFPACK_SeqAIJ(Mat A)
184: {
186:   A->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqAIJ_UMFPACK;
187:   return(0);
188: }

190: /* used by -sles_view */
191: #undef __FUNCT__  
193: int MatSeqAIJFactorInfo_UMFPACK(Mat A,PetscViewer viewer)
194: {
195:   Mat_SeqAIJ_UMFPACK      *lu= (Mat_SeqAIJ_UMFPACK*)A->spptr;
196:   int                     ierr;
198:   /* check if matrix is UMFPACK type */
199:   if (A->ops->solve != MatSolve_SeqAIJ_UMFPACK) return(0);

201:   PetscViewerASCIIPrintf(viewer,"UMFPACK run parameters:n");
202:   /* Control parameters used by reporting routiones */
203:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_PRL]: %gn",lu->Control[UMFPACK_PRL]);

205:   /* Control parameters used by symbolic factorization */
206:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_DENSE_COL]: %gn",lu->Control[UMFPACK_DENSE_COL]);
207:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_DENSE_ROW]: %gn",lu->Control[UMFPACK_DENSE_ROW]);
208:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_BLOCK_SIZE]: %gn",lu->Control[UMFPACK_BLOCK_SIZE]);

210:   /* Control parameters used by numeric factorization */
211:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_PIVOT_TOLERANCE]: %gn",lu->Control[UMFPACK_PIVOT_TOLERANCE]);
212:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_RELAXED_AMALGAMATION]: %gn",lu->Control[UMFPACK_RELAXED_AMALGAMATION]);
213:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_RELAXED2_AMALGAMATION]: %gn",lu->Control[UMFPACK_RELAXED2_AMALGAMATION]);
214:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_RELAXED3_AMALGAMATION]: %gn",lu->Control[UMFPACK_RELAXED3_AMALGAMATION]);
215:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_ALLOC_INIT]: %gn",lu->Control[UMFPACK_ALLOC_INIT]);

217:   /* Control parameters used by solve */
218:   PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_IRSTEP]: %gn",lu->Control[UMFPACK_IRSTEP]);

220:   /* mat ordering */
221:   if(!lu->PetscMatOdering) PetscViewerASCIIPrintf(viewer,"  UMFPACK default matrix ordering is used (not the PETSc matrix ordering) n");

223:   return(0);
224: }

226: #else

228: #undef __FUNCT__  
230: int MatUseUMFPACK_SeqAIJ(Mat A)
231: {
233:   return(0);
234: }

236: #endif