Actual source code: matimpl.h
5: #include petscmat.h
7: /*
8: This file defines the parts of the matrix data structure that are
9: shared by all matrix types.
10: */
12: /*
13: If you add entries here also add them to the MATOP enum
14: in include/petscmat.h and include/finclude/petscmat.h
15: */
16: typedef struct _MatOps *MatOps;
17: struct _MatOps {
18: /* 0*/
19: PetscErrorCode (*setvalues)(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const MatScalar[],InsertMode);
20: PetscErrorCode (*getrow)(Mat,PetscInt,PetscInt *,PetscInt*[],PetscScalar*[]);
21: PetscErrorCode (*restorerow)(Mat,PetscInt,PetscInt *,PetscInt *[],PetscScalar *[]);
22: PetscErrorCode (*mult)(Mat,Vec,Vec);
23: PetscErrorCode (*multadd)(Mat,Vec,Vec,Vec);
24: /* 5*/
25: PetscErrorCode (*multtranspose)(Mat,Vec,Vec);
26: PetscErrorCode (*multtransposeadd)(Mat,Vec,Vec,Vec);
27: PetscErrorCode (*solve)(Mat,Vec,Vec);
28: PetscErrorCode (*solveadd)(Mat,Vec,Vec,Vec);
29: PetscErrorCode (*solvetranspose)(Mat,Vec,Vec);
30: /*10*/
31: PetscErrorCode (*solvetransposeadd)(Mat,Vec,Vec,Vec);
32: PetscErrorCode (*lufactor)(Mat,IS,IS,MatFactorInfo*);
33: PetscErrorCode (*choleskyfactor)(Mat,IS,MatFactorInfo*);
34: PetscErrorCode (*relax)(Mat,Vec,PetscReal,MatSORType,PetscReal,PetscInt,PetscInt,Vec);
35: PetscErrorCode (*transpose)(Mat,Mat *);
36: /*15*/
37: PetscErrorCode (*getinfo)(Mat,MatInfoType,MatInfo*);
38: PetscErrorCode (*equal)(Mat,Mat,PetscTruth *);
39: PetscErrorCode (*getdiagonal)(Mat,Vec);
40: PetscErrorCode (*diagonalscale)(Mat,Vec,Vec);
41: PetscErrorCode (*norm)(Mat,NormType,PetscReal*);
42: /*20*/
43: PetscErrorCode (*assemblybegin)(Mat,MatAssemblyType);
44: PetscErrorCode (*assemblyend)(Mat,MatAssemblyType);
45: PetscErrorCode (*compress)(Mat);
46: PetscErrorCode (*setoption)(Mat,MatOption);
47: PetscErrorCode (*zeroentries)(Mat);
48: /*25*/
49: PetscErrorCode (*zerorows)(Mat,PetscInt,const PetscInt[],PetscScalar);
50: PetscErrorCode (*lufactorsymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
51: PetscErrorCode (*lufactornumeric)(Mat,MatFactorInfo*,Mat*);
52: PetscErrorCode (*choleskyfactorsymbolic)(Mat,IS,MatFactorInfo*,Mat*);
53: PetscErrorCode (*choleskyfactornumeric)(Mat,MatFactorInfo*,Mat*);
54: /*30*/
55: PetscErrorCode (*setuppreallocation)(Mat);
56: PetscErrorCode (*ilufactorsymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
57: PetscErrorCode (*iccfactorsymbolic)(Mat,IS,MatFactorInfo*,Mat*);
58: PetscErrorCode (*getarray)(Mat,PetscScalar**);
59: PetscErrorCode (*restorearray)(Mat,PetscScalar**);
60: /*35*/
61: PetscErrorCode (*duplicate)(Mat,MatDuplicateOption,Mat*);
62: PetscErrorCode (*forwardsolve)(Mat,Vec,Vec);
63: PetscErrorCode (*backwardsolve)(Mat,Vec,Vec);
64: PetscErrorCode (*ilufactor)(Mat,IS,IS,MatFactorInfo*);
65: PetscErrorCode (*iccfactor)(Mat,IS,MatFactorInfo*);
66: /*40*/
67: PetscErrorCode (*axpy)(Mat,PetscScalar,Mat,MatStructure);
68: PetscErrorCode (*getsubmatrices)(Mat,PetscInt,const IS[],const IS[],MatReuse,Mat *[]);
69: PetscErrorCode (*increaseoverlap)(Mat,PetscInt,IS[],PetscInt);
70: PetscErrorCode (*getvalues)(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],PetscScalar []);
71: PetscErrorCode (*copy)(Mat,Mat,MatStructure);
72: /*45*/
73: PetscErrorCode (*printhelp)(Mat);
74: PetscErrorCode (*scale)(Mat,PetscScalar);
75: PetscErrorCode (*shift)(Mat,PetscScalar);
76: PetscErrorCode (*diagonalset)(Mat,Vec,InsertMode);
77: PetscErrorCode (*iludtfactor)(Mat,IS,IS,MatFactorInfo*,Mat *);
78: /*50*/
79: PetscErrorCode (*setblocksize)(Mat,PetscInt);
80: PetscErrorCode (*getrowij)(Mat,PetscInt,PetscTruth,PetscInt*,PetscInt *[],PetscInt *[],PetscTruth *);
81: PetscErrorCode (*restorerowij)(Mat,PetscInt,PetscTruth,PetscInt *,PetscInt *[],PetscInt *[],PetscTruth *);
82: PetscErrorCode (*getcolumnij)(Mat,PetscInt,PetscTruth,PetscInt*,PetscInt *[],PetscInt *[],PetscTruth *);
83: PetscErrorCode (*restorecolumnij)(Mat,PetscInt,PetscTruth,PetscInt*,PetscInt *[],PetscInt *[],PetscTruth *);
84: /*55*/
85: PetscErrorCode (*fdcoloringcreate)(Mat,ISColoring,MatFDColoring);
86: PetscErrorCode (*coloringpatch)(Mat,PetscInt,PetscInt,ISColoringValue[],ISColoring*);
87: PetscErrorCode (*setunfactored)(Mat);
88: PetscErrorCode (*permute)(Mat,IS,IS,Mat*);
89: PetscErrorCode (*setvaluesblocked)(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],InsertMode);
90: /*60*/
91: PetscErrorCode (*getsubmatrix)(Mat,IS,IS,PetscInt,MatReuse,Mat*);
92: PetscErrorCode (*destroy)(Mat);
93: PetscErrorCode (*view)(Mat,PetscViewer);
94: PetscErrorCode (*getmaps)(Mat,PetscMap*,PetscMap*);
95: PetscErrorCode (*usescaledform)(Mat,PetscTruth);
96: /*65*/
97: PetscErrorCode (*scalesystem)(Mat,Vec,Vec);
98: PetscErrorCode (*unscalesystem)(Mat,Vec,Vec);
99: PetscErrorCode (*setlocaltoglobalmapping)(Mat,ISLocalToGlobalMapping);
100: PetscErrorCode (*setvalueslocal)(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],InsertMode);
101: PetscErrorCode (*zerorowslocal)(Mat,PetscInt,const PetscInt[],PetscScalar);
102: /*70*/
103: PetscErrorCode (*getrowmax)(Mat,Vec);
104: PetscErrorCode (*convert)(Mat, MatType,MatReuse,Mat*);
105: PetscErrorCode (*setcoloring)(Mat,ISColoring);
106: PetscErrorCode (*setvaluesadic)(Mat,void*);
107: PetscErrorCode (*setvaluesadifor)(Mat,PetscInt,void*);
108: /*75*/
109: PetscErrorCode (*fdcoloringapply)(Mat,MatFDColoring,Vec,MatStructure*,void*);
110: PetscErrorCode (*setfromoptions)(Mat);
111: PetscErrorCode (*multconstrained)(Mat,Vec,Vec);
112: PetscErrorCode (*multtransposeconstrained)(Mat,Vec,Vec);
113: PetscErrorCode (*ilufactorsymbolicconstrained)(Mat,IS,IS,double,PetscInt,PetscInt,Mat *);
114: /*80*/
115: PetscErrorCode (*permutesparsify)(Mat, PetscInt, double, double, IS, IS, Mat *);
116: PetscErrorCode (*mults)(Mat, Vecs, Vecs);
117: PetscErrorCode (*solves)(Mat, Vecs, Vecs);
118: PetscErrorCode (*getinertia)(Mat,PetscInt*,PetscInt*,PetscInt*);
119: PetscErrorCode (*load)(PetscViewer, MatType,Mat*);
120: /*85*/
121: PetscErrorCode (*issymmetric)(Mat,PetscReal,PetscTruth*);
122: PetscErrorCode (*ishermitian)(Mat,PetscTruth*);
123: PetscErrorCode (*isstructurallysymmetric)(Mat,PetscTruth*);
124: PetscErrorCode (*pbrelax)(Mat,Vec,PetscReal,MatSORType,PetscReal,PetscInt,PetscInt,Vec);
125: PetscErrorCode (*getvecs)(Mat,Vec*,Vec*);
126: /*90*/
127: PetscErrorCode (*matmult)(Mat,Mat,MatReuse,PetscReal,Mat*);
128: PetscErrorCode (*matmultsymbolic)(Mat,Mat,PetscReal,Mat*);
129: PetscErrorCode (*matmultnumeric)(Mat,Mat,Mat);
130: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*);
131: PetscErrorCode (*ptapsymbolic)(Mat,Mat,PetscReal,Mat*); /* double dispatch wrapper routine */
132: /*95*/
133: PetscErrorCode (*ptapnumeric)(Mat,Mat,Mat); /* double dispatch wrapper routine */
134: PetscErrorCode (*matmulttranspose)(Mat,Mat,MatReuse,PetscReal,Mat*);
135: PetscErrorCode (*matmulttransposesymbolic)(Mat,Mat,PetscReal,Mat*);
136: PetscErrorCode (*matmulttransposenumeric)(Mat,Mat,Mat);
137: PetscErrorCode (*ptapsymbolic_seqaij)(Mat,Mat,PetscReal,Mat*); /* actual implememtation, A=seqaij */
138: /*100*/
139: PetscErrorCode (*ptapnumeric_seqaij)(Mat,Mat,Mat); /* actual implememtation, A=seqaij */
140: PetscErrorCode (*ptapsymbolic_mpiaij)(Mat,Mat,PetscReal,Mat*); /* actual implememtation, A=mpiaij */
141: PetscErrorCode (*ptapnumeric_mpiaij)(Mat,Mat,Mat); /* actual implememtation, A=mpiaij */
142: PetscErrorCode (*conjugate)(Mat); /* complex conjugate */
143: };
144: /*
145: If you add MatOps entries above also add them to the MATOP enum
146: in include/petscmat.h and include/finclude/petscmat.h
147: */
149: /*
150: Utility private matrix routines
151: */
152: EXTERN PetscErrorCode MatConvert_Basic(Mat, MatType,MatReuse,Mat*);
153: EXTERN PetscErrorCode MatCopy_Basic(Mat,Mat,MatStructure);
154: EXTERN PetscErrorCode MatView_Private(Mat);
155: EXTERN PetscErrorCode MatGetPetscMaps_Petsc(Mat,PetscMap *,PetscMap *);
156: EXTERN PetscErrorCode MatHeaderCopy(Mat,Mat);
157: EXTERN PetscErrorCode MatHeaderReplace(Mat,Mat);
158: EXTERN PetscErrorCode MatAXPYGetxtoy_Private(PetscInt,PetscInt*,PetscInt*,PetscInt*, PetscInt*,PetscInt*,PetscInt*, PetscInt**);
159: EXTERN PetscErrorCode MatPtAP_Basic(Mat,Mat,MatReuse,PetscReal,Mat*);
161: /*
162: The stash is used to temporarily store inserted matrix values that
163: belong to another processor. During the assembly phase the stashed
164: values are moved to the correct processor and
165: */
167: typedef struct {
168: PetscInt nmax; /* maximum stash size */
169: PetscInt umax; /* user specified max-size */
170: PetscInt oldnmax; /* the nmax value used previously */
171: PetscInt n; /* stash size */
172: PetscInt bs; /* block size of the stash */
173: PetscInt reallocs; /* preserve the no of mallocs invoked */
174: PetscInt *idx; /* global row numbers in stash */
175: PetscInt *idy; /* global column numbers in stash */
176: MatScalar *array; /* array to hold stashed values */
177: /* The following variables are used for communication */
178: MPI_Comm comm;
179: PetscMPIInt size,rank;
180: PetscMPIInt tag1,tag2;
181: MPI_Request *send_waits; /* array of send requests */
182: MPI_Request *recv_waits; /* array of receive requests */
183: MPI_Status *send_status; /* array of send status */
184: PetscInt nsends,nrecvs; /* numbers of sends and receives */
185: MatScalar *svalues; /* sending data */
186: MatScalar **rvalues; /* receiving data (values) */
187: PetscInt **rindices; /* receiving data (indices) */
188: PetscMPIInt *nprocs; /* tmp data used both during scatterbegin and end */
189: PetscInt nprocessed; /* number of messages already processed */
190: } MatStash;
192: EXTERN PetscErrorCode MatStashCreate_Private(MPI_Comm,PetscInt,MatStash*);
193: EXTERN PetscErrorCode MatStashDestroy_Private(MatStash*);
194: EXTERN PetscErrorCode MatStashScatterEnd_Private(MatStash*);
195: EXTERN PetscErrorCode MatStashSetInitialSize_Private(MatStash*,PetscInt);
196: EXTERN PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
197: EXTERN PetscErrorCode MatStashValuesRow_Private(MatStash*,PetscInt,PetscInt,const PetscInt[],const MatScalar[]);
198: EXTERN PetscErrorCode MatStashValuesCol_Private(MatStash*,PetscInt,PetscInt,const PetscInt[],const MatScalar[],PetscInt);
199: EXTERN PetscErrorCode MatStashValuesRowBlocked_Private(MatStash*,PetscInt,PetscInt,const PetscInt[],const MatScalar[],PetscInt,PetscInt,PetscInt);
200: EXTERN PetscErrorCode MatStashValuesColBlocked_Private(MatStash*,PetscInt,PetscInt,const PetscInt[],const MatScalar[],PetscInt,PetscInt,PetscInt);
201: EXTERN PetscErrorCode MatStashScatterBegin_Private(MatStash*,PetscInt*);
202: EXTERN PetscErrorCode MatStashScatterGetMesg_Private(MatStash*,PetscMPIInt*,PetscInt**,PetscInt**,MatScalar**,PetscInt*);
204: #define FACTOR_LU 1
205: #define FACTOR_CHOLESKY 2
207: typedef struct {
208: PetscInt dim;
209: PetscInt dims[4];
210: PetscInt starts[4];
211: PetscTruth noc; /* this is a single component problem, hence user will not set MatStencil.c */
212: } MatStencilInfo;
214: /* Info about using compressed row format */
215: typedef struct {
216: PetscTruth use;
217: PetscInt nrows; /* number of non-zero rows */
218: PetscInt *i; /* compressed row pointer */
219: PetscInt *rindex; /* compressed row index */
220: PetscTruth checked; /* if compressed row format have been checked for */
221: } Mat_CompressedRow;
222: EXTERN PetscErrorCode Mat_CheckCompressedRow(Mat,Mat_CompressedRow*,PetscInt*,PetscInt,PetscReal);
224: struct _p_Mat {
225: PETSCHEADER(struct _MatOps);
226: PetscMap rmap,cmap;
227: void *data; /* implementation-specific data */
228: PetscInt factor; /* 0, FACTOR_LU, or FACTOR_CHOLESKY */
229: PetscTruth assembled; /* is the matrix assembled? */
230: PetscTruth was_assembled; /* new values inserted into assembled mat */
231: PetscInt num_ass; /* number of times matrix has been assembled */
232: PetscTruth same_nonzero; /* matrix has same nonzero pattern as previous */
233: PetscInt M,N; /* global numbers of rows, columns */
234: PetscInt m,n; /* local numbers of rows, columns */
235: MatInfo info; /* matrix information */
236: ISLocalToGlobalMapping mapping; /* mapping used in MatSetValuesLocal() */
237: ISLocalToGlobalMapping bmapping; /* mapping used in MatSetValuesBlockedLocal() */
238: InsertMode insertmode; /* have values been inserted in matrix or added? */
239: MatStash stash,bstash; /* used for assembling off-proc mat emements */
240: MatNullSpace nullsp;
241: PetscTruth preallocated;
242: MatStencilInfo stencil; /* information for structured grid */
243: PetscTruth symmetric,hermitian,structurally_symmetric;
244: PetscTruth symmetric_set,hermitian_set,structurally_symmetric_set; /* if true, then corresponding flag is correct*/
245: PetscTruth symmetric_eternal;
246: PetscInt bs;
247: void *spptr; /* pointer for special library like SuperLU */
248: };
250: #define MatPreallocated(A) ((!(A)->preallocated) ? MatSetUpPreallocation(A) : 0)
252: /*
253: Frees the a, i, and j arrays from the XAIJ (AIJ, BAIJ, and SBAIJ) matrix types
254: */
257: PETSC_STATIC_INLINE PetscErrorCode MatSeqXAIJFreeAIJ(PetscTruth singlemalloc,PetscScalar **a,PetscInt **j,PetscInt **i) {
259: if (singlemalloc) {
260: PetscFree3(*a,*j,*i);
261: } else {
262: if (*a) {PetscFree(*a);}
263: if (*j) {PetscFree(*j);}
264: if (*i) {PetscFree(*i);}
265: }
266: *a = 0; *j = 0; *i = 0;
267: return 0;
268: }
270: /*
271: Allocates larger a, i, and j arrays for the XAIJ (AIJ, BAIJ, and SBAIJ) matrix types
272: */
273: #define MatSeqXAIJReallocateAIJ(A,BS2,NROW,ROW,COL,RMAX,AA,AI,AJ,AM,RP,AP,AIMAX,NONEW) \
274: if (NROW >= RMAX) { \
275: /* there is no extra room in row, therefore enlarge */ \
276: PetscInt new_nz = AI[AM] + CHUNKSIZE,len,*new_i,*new_j; \
277: PetscScalar *new_a; \
278: \
279: if (NONEW == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"New nonzero at (%D,%D) caused a malloc",ROW,COL); \
280: /* malloc new storage space */ \
281: PetscMalloc3(BS2*new_nz,PetscScalar,&new_a,new_nz,PetscInt,&new_j,AM+1,PetscInt,&new_i);\
282: \
283: /* copy over old data into new slots */ \
284: for (ii=0; ii<ROW+1; ii++) {new_i[ii] = AI[ii];} \
285: for (ii=ROW+1; ii<AM+1; ii++) {new_i[ii] = AI[ii]+CHUNKSIZE;} \
286: PetscMemcpy(new_j,AJ,(AI[ROW]+NROW)*sizeof(PetscInt)); \
287: len = (new_nz - CHUNKSIZE - AI[ROW] - NROW); \
288: PetscMemcpy(new_j+AI[ROW]+NROW+CHUNKSIZE,AJ+AI[ROW]+NROW,len*sizeof(PetscInt)); \
289: PetscMemcpy(new_a,AA,BS2*(AI[ROW]+NROW)*sizeof(PetscScalar)); \
290: PetscMemzero(new_a+BS2*(AI[ROW]+NROW),BS2*CHUNKSIZE*sizeof(MatScalar));\
291: PetscMemcpy(new_a+BS2*(AI[ROW]+NROW+CHUNKSIZE),AA+BS2*(AI[ROW]+NROW),BS2*len*sizeof(PetscScalar)); \
292: /* free up old matrix storage */ \
293: MatSeqXAIJFreeAIJ(A->singlemalloc,&A->a,&A->j,&A->i);\
294: AA = A->a = new_a; AI = A->i = new_i; AJ = A->j = new_j; \
295: A->singlemalloc = PETSC_TRUE; \
296: \
297: RP = AJ + AI[ROW]; AP = AA + BS2*AI[ROW]; \
298: RMAX = AIMAX[ROW] = AIMAX[ROW] + CHUNKSIZE; \
299: A->maxnz += CHUNKSIZE; \
300: A->reallocs++; \
301: } \
303: /*
304: Object for partitioning graphs
305: */
307: typedef struct _MatPartitioningOps *MatPartitioningOps;
308: struct _MatPartitioningOps {
309: PetscErrorCode (*apply)(MatPartitioning,IS*);
310: PetscErrorCode (*setfromoptions)(MatPartitioning);
311: PetscErrorCode (*destroy)(MatPartitioning);
312: PetscErrorCode (*view)(MatPartitioning,PetscViewer);
313: };
315: struct _p_MatPartitioning {
316: PETSCHEADER(struct _MatPartitioningOps);
317: Mat adj;
318: PetscInt *vertex_weights;
319: PetscReal *part_weights;
320: PetscInt n; /* number of partitions */
321: void *data;
322: PetscInt setupcalled;
323: };
325: /*
326: MatFDColoring is used to compute Jacobian matrices efficiently
327: via coloring. The data structure is explained below in an example.
329: Color = 0 1 0 2 | 2 3 0
330: ---------------------------------------------------
331: 00 01 | 05
332: 10 11 | 14 15 Processor 0
333: 22 23 | 25
334: 32 33 |
335: ===================================================
336: | 44 45 46
337: 50 | 55 Processor 1
338: | 64 66
339: ---------------------------------------------------
341: ncolors = 4;
343: ncolumns = {2,1,1,0}
344: columns = {{0,2},{1},{3},{}}
345: nrows = {4,2,3,3}
346: rows = {{0,1,2,3},{0,1},{1,2,3},{0,1,2}}
347: columnsforrow = {{0,0,2,2},{1,1},{4,3,3},{5,5,5}}
348: vscaleforrow = {{,,,},{,},{,,},{,,}}
349: vwscale = {dx(0),dx(1),dx(2),dx(3)} MPI Vec
350: vscale = {dx(0),dx(1),dx(2),dx(3),dx(4),dx(5)} Seq Vec
352: ncolumns = {1,0,1,1}
353: columns = {{6},{},{4},{5}}
354: nrows = {3,0,2,2}
355: rows = {{0,1,2},{},{1,2},{1,2}}
356: columnsforrow = {{6,0,6},{},{4,4},{5,5}}
357: vscaleforrow = {{,,},{},{,},{,}}
358: vwscale = {dx(4),dx(5),dx(6)} MPI Vec
359: vscale = {dx(0),dx(4),dx(5),dx(6)} Seq Vec
361: See the routine MatFDColoringApply() for how this data is used
362: to compute the Jacobian.
364: */
366: struct _p_MatFDColoring{
367: PETSCHEADER(int);
368: PetscInt M,N,m; /* total rows, columns; local rows */
369: PetscInt rstart; /* first row owned by local processor */
370: PetscInt ncolors; /* number of colors */
371: PetscInt *ncolumns; /* number of local columns for a color */
372: PetscInt **columns; /* lists the local columns of each color (using global column numbering) */
373: PetscInt *nrows; /* number of local rows for each color */
374: PetscInt **rows; /* lists the local rows for each color (using the local row numbering) */
375: PetscInt **columnsforrow; /* lists the corresponding columns for those rows (using the global column) */
376: PetscReal error_rel; /* square root of relative error in computing function */
377: PetscReal umin; /* minimum allowable u'dx value */
378: PetscInt freq; /* frequency at which new Jacobian is computed */
379: Vec w1,w2,w3; /* work vectors used in computing Jacobian */
380: PetscErrorCode (*f)(void); /* function that defines Jacobian */
381: void *fctx; /* optional user-defined context for use by the function f */
382: PetscInt **vscaleforrow; /* location in vscale for each columnsforrow[] entry */
383: Vec vscale; /* holds FD scaling, i.e. 1/dx for each perturbed column */
384: PetscTruth usersetsrecompute;/* user determines when Jacobian is recomputed, via MatFDColoringSetRecompute() */
385: PetscTruth recompute; /* used with usersetrecompute to determine if Jacobian should be recomputed */
386: Vec F; /* current value of user provided function; can set with MatFDColoringSetF() */
387: PetscInt currentcolor; /* color for which function evaluation is being done now */
388: };
390: /*
391: Null space context for preconditioner/operators
392: */
393: struct _p_MatNullSpace {
394: PETSCHEADER(int);
395: PetscTruth has_cnst;
396: PetscInt n;
397: Vec* vecs;
398: Vec vec; /* for out of place removals */
399: };
401: /*
402: Checking zero pivot for LU, ILU preconditioners.
403: */
404: typedef struct {
405: PetscInt nshift,nshift_max;
406: PetscReal shift_amount,shift_lo,shift_hi,shift_top;
407: PetscTruth lushift;
408: PetscReal rs; /* active row sum of abs(offdiagonals) */
409: PetscScalar pv; /* pivot of the active row */
410: } LUShift_Ctx;
414: /*@C
415: MatLUCheckShift_inline - shift the diagonals when zero pivot is detected on LU factor
417: Collective on Mat
419: Input Parameters:
420: + info - information about the matrix factorization
421: . sctx - pointer to the struct LUShift_Ctx
422: - newshift - 0: shift is unchanged; 1: shft is updated; -1: zeropivot
424: Level: developer
425: @*/
426: #define MatLUCheckShift_inline(info,sctx,newshift) 0;\
427: {\
428: PetscInt _newshift;\
429: PetscReal _zero = info->zeropivot*rs;\
430: if (info->shiftnz && PetscAbsScalar(sctx.pv) <= _zero){\
431: /* force |diag| > zeropivot*rs */\
432: if (!sctx.nshift){\
433: sctx.shift_amount = info->shiftnz;\
434: } else {\
435: sctx.shift_amount *= 2.0;\
436: }\
437: sctx.lushift = PETSC_TRUE;\
438: (sctx.nshift)++;\
439: _newshift = 1;\
440: } else if (info->shiftpd && PetscRealPart(sctx.pv) <= _zero){\
441: /* force matfactor to be diagonally dominant */\
442: if (sctx.nshift > sctx.nshift_max) {\
443: SETERRQ(PETSC_ERR_CONV_FAILED,"Unable to determine shift to enforce positive definite preconditioner");\
444: } else if (sctx.nshift == sctx.nshift_max) {\
445: info->shift_fraction = sctx.shift_hi;\
446: sctx.lushift = PETSC_TRUE;\
447: } else {\
448: sctx.shift_lo = info->shift_fraction;\
449: info->shift_fraction = (sctx.shift_hi+sctx.shift_lo)/2.;\
450: sctx.lushift = PETSC_TRUE;\
451: }\
452: sctx.shift_amount = info->shift_fraction * sctx.shift_top;\
453: sctx.nshift++;\
454: _newshift = 1;\
455: } else if (PetscAbsScalar(sctx.pv) <= _zero){\
456: _newshift = -1;\
457: } else {\
458: _newshift = 0;\
459: }\
460: newshift = _newshift;\
461: }
463: /*
464: Checking zero pivot for Cholesky, ICC preconditioners.
465: */
466: typedef struct {
467: PetscInt nshift;
468: PetscReal shift_amount;
469: PetscTruth chshift;
470: PetscReal rs; /* active row sum of abs(offdiagonals) */
471: PetscScalar pv; /* pivot of the active row */
472: } ChShift_Ctx;
476: /*@C
477: MatCholeskyCheckShift_inline - shift the diagonals when zero pivot is detected on Cholesky factor
479: Collective on Mat
481: Input Parameters:
482: + info - information about the matrix factorization
483: . sctx - pointer to the struct CholeskyShift_Ctx
484: - newshift - 0: shift is unchanged; 1: shft is updated; -1: zeropivot
486: Level: developer
487: Note: Unlike in the ILU case there is no exit condition on nshift:
488: we increase the shift until it converges. There is no guarantee that
489: this algorithm converges faster or slower, or is better or worse
490: than the ILU algorithm.
491: @*/
492: #define MatCholeskyCheckShift_inline(info,sctx,newshift) 0;\
493: {\
494: PetscInt _newshift;\
495: PetscReal _zero = info->zeropivot*rs;\
496: if (info->shiftnz && PetscAbsScalar(sctx.pv) <= _zero){\
497: /* force |diag| > zeropivot*sctx.rs */\
498: if (!sctx.nshift){\
499: sctx.shift_amount = info->shiftnz;\
500: } else {\
501: sctx.shift_amount *= 2.0;\
502: }\
503: sctx.chshift = PETSC_TRUE;\
504: sctx.nshift++;\
505: _newshift = 1;\
506: } else if (info->shiftpd && PetscRealPart(sctx.pv) <= _zero){\
507: /* calculate a shift that would make this row diagonally dominant */\
508: sctx.shift_amount = PetscMax(sctx.rs+PetscAbs(PetscRealPart(sctx.pv)),1.1*sctx.shift_amount);\
509: sctx.chshift = PETSC_TRUE;\
510: sctx.nshift++;\
511: _newshift = 1;\
512: } else if (PetscAbsScalar(sctx.pv) <= _zero){\
513: _newshift = -1;\
514: } else {\
515: _newshift = 0; \
516: }\
517: newshift = _newshift;\
518: }
520: #endif