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