xref: /petsc/src/mat/interface/matrix.c (revision ebe3b25b9af58f1e4889057721e8e5fb9fab5adc)
1 /*$Id: matrix.c,v 1.414 2001/09/28 18:57:28 balay Exp $*/
2 
3 /*
4    This is where the abstract matrix operations are defined
5 */
6 
7 #include "src/mat/matimpl.h"        /*I "petscmat.h" I*/
8 #include "src/vec/vecimpl.h"
9 
10 /* Logging support */
11 int MAT_COOKIE = 0;
12 int MATSNESMFCTX_COOKIE = 0;
13 int MAT_Mult = 0, MAT_MultMatrixFree = 0, MAT_Mults = 0, MAT_MultConstrained = 0, MAT_MultAdd = 0, MAT_MultTranspose = 0;
14 int MAT_MultTransposeConstrained = 0, MAT_MultTransposeAdd = 0, MAT_Solve = 0, MAT_Solves = 0, MAT_SolveAdd = 0, MAT_SolveTranspose = 0;
15 int MAT_SolveTransposeAdd = 0, MAT_Relax = 0, MAT_ForwardSolve = 0, MAT_BackwardSolve = 0, MAT_LUFactor = 0, MAT_LUFactorSymbolic = 0;
16 int MAT_LUFactorNumeric = 0, MAT_CholeskyFactor = 0, MAT_CholeskyFactorSymbolic = 0, MAT_CholeskyFactorNumeric = 0, MAT_ILUFactor = 0;
17 int MAT_ILUFactorSymbolic = 0, MAT_ICCFactorSymbolic = 0, MAT_Copy = 0, MAT_Convert = 0, MAT_Scale = 0, MAT_AssemblyBegin = 0;
18 int MAT_AssemblyEnd = 0, MAT_SetValues = 0, MAT_GetValues = 0, MAT_GetRow = 0, MAT_GetSubMatrices = 0, MAT_GetColoring = 0, MAT_GetOrdering = 0;
19 int MAT_IncreaseOverlap = 0, MAT_Partitioning = 0, MAT_ZeroEntries = 0, MAT_Load = 0, MAT_View = 0, MAT_AXPY = 0, MAT_FDColoringCreate = 0;
20 int MAT_FDColoringApply = 0,MAT_Transpose = 0,MAT_FDColoringFunction = 0;
21 
22 #undef __FUNCT__
23 #define __FUNCT__ "MatGetRow"
24 /*@C
25    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
26    for each row that you get to ensure that your application does
27    not bleed memory.
28 
29    Not Collective
30 
31    Input Parameters:
32 +  mat - the matrix
33 -  row - the row to get
34 
35    Output Parameters:
36 +  ncols -  if not NULL, the number of nonzeros in the row
37 .  cols - if not NULL, the column numbers
38 -  vals - if not NULL, the values
39 
40    Notes:
41    This routine is provided for people who need to have direct access
42    to the structure of a matrix.  We hope that we provide enough
43    high-level matrix routines that few users will need it.
44 
45    MatGetRow() always returns 0-based column indices, regardless of
46    whether the internal representation is 0-based (default) or 1-based.
47 
48    For better efficiency, set cols and/or vals to PETSC_NULL if you do
49    not wish to extract these quantities.
50 
51    The user can only examine the values extracted with MatGetRow();
52    the values cannot be altered.  To change the matrix entries, one
53    must use MatSetValues().
54 
55    You can only have one call to MatGetRow() outstanding for a particular
56    matrix at a time, per processor. MatGetRow() can only obtained rows
57    associated with the given processor, it cannot get rows from the
58    other processors; for that we suggest using MatGetSubMatrices(), then
59    MatGetRow() on the submatrix. The row indix passed to MatGetRows()
60    is in the global number of rows.
61 
62    Fortran Notes:
63    The calling sequence from Fortran is
64 .vb
65    MatGetRow(matrix,row,ncols,cols,values,ierr)
66          Mat     matrix (input)
67          integer row    (input)
68          integer ncols  (output)
69          integer cols(maxcols) (output)
70          double precision (or double complex) values(maxcols) output
71 .ve
72    where maxcols >= maximum nonzeros in any row of the matrix.
73 
74    Caution:
75    Do not try to change the contents of the output arrays (cols and vals).
76    In some cases, this may corrupt the matrix.
77 
78    Level: advanced
79 
80    Concepts: matrices^row access
81 
82 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubmatrices(), MatGetDiagonal()
83 @*/
84 int MatGetRow(Mat mat,int row,int *ncols,int *cols[],PetscScalar *vals[])
85 {
86   int   incols,ierr;
87 
88   PetscFunctionBegin;
89   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
90   PetscValidType(mat,1);
91   MatPreallocated(mat);
92   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
93   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
94   if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
95   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
96   ierr = (*mat->ops->getrow)(mat,row,&incols,cols,vals);CHKERRQ(ierr);
97   if (ncols) *ncols = incols;
98   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
99   PetscFunctionReturn(0);
100 }
101 
102 #undef __FUNCT__
103 #define __FUNCT__ "MatRestoreRow"
104 /*@C
105    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
106 
107    Not Collective
108 
109    Input Parameters:
110 +  mat - the matrix
111 .  row - the row to get
112 .  ncols, cols - the number of nonzeros and their columns
113 -  vals - if nonzero the column values
114 
115    Notes:
116    This routine should be called after you have finished examining the entries.
117 
118    Fortran Notes:
119    The calling sequence from Fortran is
120 .vb
121    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
122       Mat     matrix (input)
123       integer row    (input)
124       integer ncols  (output)
125       integer cols(maxcols) (output)
126       double precision (or double complex) values(maxcols) output
127 .ve
128    Where maxcols >= maximum nonzeros in any row of the matrix.
129 
130    In Fortran MatRestoreRow() MUST be called after MatGetRow()
131    before another call to MatGetRow() can be made.
132 
133    Level: advanced
134 
135 .seealso:  MatGetRow()
136 @*/
137 int MatRestoreRow(Mat mat,int row,int *ncols,int *cols[],PetscScalar *vals[])
138 {
139   int ierr;
140 
141   PetscFunctionBegin;
142   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
143   PetscValidIntPointer(ncols,3);
144   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
145   if (!mat->ops->restorerow) PetscFunctionReturn(0);
146   ierr = (*mat->ops->restorerow)(mat,row,ncols,cols,vals);CHKERRQ(ierr);
147   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
148   PetscFunctionReturn(0);
149 }
150 
151 #undef __FUNCT__
152 #define __FUNCT__ "MatView"
153 /*@C
154    MatView - Visualizes a matrix object.
155 
156    Collective on Mat
157 
158    Input Parameters:
159 +  mat - the matrix
160 -  viewer - visualization context
161 
162   Notes:
163   The available visualization contexts include
164 +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
165 .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
166         output where only the first processor opens
167         the file.  All other processors send their
168         data to the first processor to print.
169 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
170 
171    The user can open alternative visualization contexts with
172 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
173 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
174          specified file; corresponding input uses MatLoad()
175 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
176          an X window display
177 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
178          Currently only the sequential dense and AIJ
179          matrix types support the Socket viewer.
180 
181    The user can call PetscViewerSetFormat() to specify the output
182    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
183    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
184 +    PETSC_VIEWER_ASCII_DEFAULT - default, prints matrix contents
185 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
186 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
187 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
188          format common among all matrix types
189 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
190          format (which is in many cases the same as the default)
191 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
192          size and structure (not the matrix entries)
193 .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
194          the matrix structure
195 
196    Options Database Keys:
197 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
198 .  -mat_view_info_detailed - Prints more detailed info
199 .  -mat_view - Prints matrix in ASCII format
200 .  -mat_view_matlab - Prints matrix in Matlab format
201 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
202 .  -display <name> - Sets display name (default is host)
203 .  -draw_pause <sec> - Sets number of seconds to pause after display
204 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
205 .  -viewer_socket_machine <machine>
206 .  -viewer_socket_port <port>
207 .  -mat_view_binary - save matrix to file in binary format
208 -  -viewer_binary_filename <name>
209    Level: beginner
210 
211    Concepts: matrices^viewing
212    Concepts: matrices^plotting
213    Concepts: matrices^printing
214 
215 .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
216           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
217 @*/
218 int MatView(Mat mat,PetscViewer viewer)
219 {
220   int               ierr,rows,cols;
221   PetscTruth        isascii;
222   char              *cstr;
223   PetscViewerFormat format;
224 
225   PetscFunctionBegin;
226   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
227   PetscValidType(mat,1);
228   MatPreallocated(mat);
229   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mat->comm);
230   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2);
231   PetscCheckSameComm(mat,1,viewer,2);
232   if (!mat->assembled) SETERRQ(1,"Must call MatAssemblyBegin/End() before viewing matrix");
233 
234   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
235   if (isascii) {
236     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
237     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
238       if (mat->prefix) {
239         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",mat->prefix);CHKERRQ(ierr);
240       } else {
241         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");CHKERRQ(ierr);
242       }
243       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
244       ierr = MatGetType(mat,&cstr);CHKERRQ(ierr);
245       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
246       ierr = PetscViewerASCIIPrintf(viewer,"type=%s, rows=%d, cols=%d\n",cstr,rows,cols);CHKERRQ(ierr);
247       if (mat->ops->getinfo) {
248         MatInfo info;
249         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
250         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%d, allocated nonzeros=%d\n",
251                           (int)info.nz_used,(int)info.nz_allocated);CHKERRQ(ierr);
252       }
253     }
254   }
255   if (mat->ops->view) {
256     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
257     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
258     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
259   } else if (!isascii) {
260     SETERRQ1(1,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
261   }
262   if (isascii) {
263     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
264     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
265       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
266     }
267   }
268   PetscFunctionReturn(0);
269 }
270 
271 #undef __FUNCT__
272 #define __FUNCT__ "MatScaleSystem"
273 /*@C
274    MatScaleSystem - Scale a vector solution and right hand side to
275    match the scaling of a scaled matrix.
276 
277    Collective on Mat
278 
279    Input Parameter:
280 +  mat - the matrix
281 .  x - solution vector (or PETSC_NULL)
282 -  b - right hand side vector (or PETSC_NULL)
283 
284 
285    Notes:
286    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not
287    internally scaled, so this does nothing. For MPIROWBS it
288    permutes and diagonally scales.
289 
290    The KSP methods automatically call this routine when required
291    (via PCPreSolve()) so it is rarely used directly.
292 
293    Level: Developer
294 
295    Concepts: matrices^scaling
296 
297 .seealso: MatUseScaledForm(), MatUnScaleSystem()
298 @*/
299 int MatScaleSystem(Mat mat,Vec x,Vec b)
300 {
301   int ierr;
302 
303   PetscFunctionBegin;
304   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
305   PetscValidType(mat,1);
306   MatPreallocated(mat);
307   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,2);PetscCheckSameComm(mat,1,x,2);}
308   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,3);PetscCheckSameComm(mat,1,b,3);}
309 
310   if (mat->ops->scalesystem) {
311     ierr = (*mat->ops->scalesystem)(mat,x,b);CHKERRQ(ierr);
312   }
313   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
314   PetscFunctionReturn(0);
315 }
316 
317 #undef __FUNCT__
318 #define __FUNCT__ "MatUnScaleSystem"
319 /*@C
320    MatUnScaleSystem - Unscales a vector solution and right hand side to
321    match the original scaling of a scaled matrix.
322 
323    Collective on Mat
324 
325    Input Parameter:
326 +  mat - the matrix
327 .  x - solution vector (or PETSC_NULL)
328 -  b - right hand side vector (or PETSC_NULL)
329 
330 
331    Notes:
332    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not
333    internally scaled, so this does nothing. For MPIROWBS it
334    permutes and diagonally scales.
335 
336    The KSP methods automatically call this routine when required
337    (via PCPreSolve()) so it is rarely used directly.
338 
339    Level: Developer
340 
341 .seealso: MatUseScaledForm(), MatScaleSystem()
342 @*/
343 int MatUnScaleSystem(Mat mat,Vec x,Vec b)
344 {
345   int ierr;
346 
347   PetscFunctionBegin;
348   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
349   PetscValidType(mat,1);
350   MatPreallocated(mat);
351   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,2);PetscCheckSameComm(mat,1,x,2);}
352   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,3);PetscCheckSameComm(mat,1,b,3);}
353   if (mat->ops->unscalesystem) {
354     ierr = (*mat->ops->unscalesystem)(mat,x,b);CHKERRQ(ierr);
355   }
356   PetscFunctionReturn(0);
357 }
358 
359 #undef __FUNCT__
360 #define __FUNCT__ "MatUseScaledForm"
361 /*@C
362    MatUseScaledForm - For matrix storage formats that scale the
363    matrix (for example MPIRowBS matrices are diagonally scaled on
364    assembly) indicates matrix operations (MatMult() etc) are
365    applied using the scaled matrix.
366 
367    Collective on Mat
368 
369    Input Parameter:
370 +  mat - the matrix
371 -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
372             applying the original matrix
373 
374    Notes:
375    For scaled matrix formats, applying the original, unscaled matrix
376    will be slightly more expensive
377 
378    Level: Developer
379 
380 .seealso: MatScaleSystem(), MatUnScaleSystem()
381 @*/
382 int MatUseScaledForm(Mat mat,PetscTruth scaled)
383 {
384   int ierr;
385 
386   PetscFunctionBegin;
387   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
388   PetscValidType(mat,1);
389   MatPreallocated(mat);
390   if (mat->ops->usescaledform) {
391     ierr = (*mat->ops->usescaledform)(mat,scaled);CHKERRQ(ierr);
392   }
393   PetscFunctionReturn(0);
394 }
395 
396 #undef __FUNCT__
397 #define __FUNCT__ "MatDestroy"
398 /*@C
399    MatDestroy - Frees space taken by a matrix.
400 
401    Collective on Mat
402 
403    Input Parameter:
404 .  A - the matrix
405 
406    Level: beginner
407 
408 @*/
409 int MatDestroy(Mat A)
410 {
411   int ierr;
412 
413   PetscFunctionBegin;
414   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
415   PetscValidType(A,1);
416   MatPreallocated(A);
417   if (--A->refct > 0) PetscFunctionReturn(0);
418 
419   /* if memory was published with AMS then destroy it */
420   ierr = PetscObjectDepublish(A);CHKERRQ(ierr);
421   if (A->mapping) {
422     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
423   }
424   if (A->bmapping) {
425     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
426   }
427   if (A->rmap) {
428     ierr = PetscMapDestroy(A->rmap);CHKERRQ(ierr);
429   }
430   if (A->cmap) {
431     ierr = PetscMapDestroy(A->cmap);CHKERRQ(ierr);
432   }
433 
434   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
435   PetscLogObjectDestroy(A);
436   PetscHeaderDestroy(A);
437   PetscFunctionReturn(0);
438 }
439 
440 #undef __FUNCT__
441 #define __FUNCT__ "MatValid"
442 /*@
443    MatValid - Checks whether a matrix object is valid.
444 
445    Collective on Mat
446 
447    Input Parameter:
448 .  m - the matrix to check
449 
450    Output Parameter:
451    flg - flag indicating matrix status, either
452    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
453 
454    Level: developer
455 
456    Concepts: matrices^validity
457 @*/
458 int MatValid(Mat m,PetscTruth *flg)
459 {
460   PetscFunctionBegin;
461   PetscValidIntPointer(flg,1);
462   if (!m)                           *flg = PETSC_FALSE;
463   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
464   else                              *flg = PETSC_TRUE;
465   PetscFunctionReturn(0);
466 }
467 
468 #undef __FUNCT__
469 #define __FUNCT__ "MatSetValues"
470 /*@
471    MatSetValues - Inserts or adds a block of values into a matrix.
472    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
473    MUST be called after all calls to MatSetValues() have been completed.
474 
475    Not Collective
476 
477    Input Parameters:
478 +  mat - the matrix
479 .  v - a logically two-dimensional array of values
480 .  m, idxm - the number of rows and their global indices
481 .  n, idxn - the number of columns and their global indices
482 -  addv - either ADD_VALUES or INSERT_VALUES, where
483    ADD_VALUES adds values to any existing entries, and
484    INSERT_VALUES replaces existing entries with new values
485 
486    Notes:
487    By default the values, v, are row-oriented and unsorted.
488    See MatSetOption() for other options.
489 
490    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
491    options cannot be mixed without intervening calls to the assembly
492    routines.
493 
494    MatSetValues() uses 0-based row and column numbers in Fortran
495    as well as in C.
496 
497    Negative indices may be passed in idxm and idxn, these rows and columns are
498    simply ignored. This allows easily inserting element stiffness matrices
499    with homogeneous Dirchlet boundary conditions that you don't want represented
500    in the matrix.
501 
502    Efficiency Alert:
503    The routine MatSetValuesBlocked() may offer much better efficiency
504    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
505 
506    Level: beginner
507 
508    Concepts: matrices^putting entries in
509 
510 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
511 @*/
512 int MatSetValues(Mat mat,int m,const int idxm[],int n,const int idxn[],const PetscScalar v[],InsertMode addv)
513 {
514   int ierr;
515 
516   PetscFunctionBegin;
517   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
518   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
519   PetscValidType(mat,1);
520   MatPreallocated(mat);
521   PetscValidIntPointer(idxm,3);
522   PetscValidIntPointer(idxn,5);
523   PetscValidScalarPointer(v,6);
524   if (mat->insertmode == NOT_SET_VALUES) {
525     mat->insertmode = addv;
526   }
527 #if defined(PETSC_USE_BOPT_g)
528   else if (mat->insertmode != addv) {
529     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
530   }
531   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
532 #endif
533 
534   if (mat->assembled) {
535     mat->was_assembled = PETSC_TRUE;
536     mat->assembled     = PETSC_FALSE;
537   }
538   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
539   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
540   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
541   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
542   PetscFunctionReturn(0);
543 }
544 
545 #undef __FUNCT__
546 #define __FUNCT__ "MatSetValuesStencil"
547 /*@C
548    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
549      Using structured grid indexing
550 
551    Not Collective
552 
553    Input Parameters:
554 +  mat - the matrix
555 .  v - a logically two-dimensional array of values
556 .  m - number of rows being entered
557 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
558 .  n - number of columns being entered
559 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
560 -  addv - either ADD_VALUES or INSERT_VALUES, where
561    ADD_VALUES adds values to any existing entries, and
562    INSERT_VALUES replaces existing entries with new values
563 
564    Notes:
565    By default the values, v, are row-oriented and unsorted.
566    See MatSetOption() for other options.
567 
568    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
569    options cannot be mixed without intervening calls to the assembly
570    routines.
571 
572    The grid coordinates are across the entire grid, not just the local portion
573 
574    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
575    as well as in C.
576 
577    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
578 
579    In order to use this routine you must either obtain the matrix with DAGetMatrix()
580    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
581 
582    The columns and rows in the stencil passed in MUST be contained within the
583    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
584    if you create a DA with an overlap of one grid level and on a particular process its first
585    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
586    first i index you can use in your column and row indices in MatSetStencil() is 5.
587 
588    In Fortran idxm and idxn should be declared as
589 $     MatStencil idxm(4,m),idxn(4,n)
590    and the values inserted using
591 $    idxm(MatStencil_i,1) = i
592 $    idxm(MatStencil_j,1) = j
593 $    idxm(MatStencil_k,1) = k
594 $    idxm(MatStencil_c,1) = c
595    etc
596 
597    Negative indices may be passed in idxm and idxn, these rows and columns are
598    simply ignored. This allows easily inserting element stiffness matrices
599    with homogeneous Dirchlet boundary conditions that you don't want represented
600    in the matrix.
601 
602    Inspired by the structured grid interface to the HYPRE package
603    (http://www.llnl.gov/CASC/hypre)
604 
605    Efficiency Alert:
606    The routine MatSetValuesBlockedStencil() may offer much better efficiency
607    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
608 
609    Level: beginner
610 
611    Concepts: matrices^putting entries in
612 
613 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
614           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
615 @*/
616 int MatSetValuesStencil(Mat mat,int m,const MatStencil idxm[],int n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
617 {
618   int j,i,ierr,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
619   int *starts = mat->stencil.starts,*dxm = (int*)idxm,*dxn = (int*)idxn,sdim = dim - (1 - (int)mat->stencil.noc);
620 
621   PetscFunctionBegin;
622   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
623   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
624   PetscValidType(mat,1);
625   PetscValidIntPointer(idxm,3);
626   PetscValidIntPointer(idxn,5);
627   PetscValidScalarPointer(v,6);
628 
629   if (m > 128) SETERRQ1(1,"Can only set 128 rows at a time; trying to set %d",m);
630   if (n > 128) SETERRQ1(1,"Can only set 256 columns at a time; trying to set %d",n);
631 
632   for (i=0; i<m; i++) {
633     for (j=0; j<3-sdim; j++) dxm++;
634     tmp = *dxm++ - starts[0];
635     for (j=0; j<dim-1; j++) {
636       tmp = tmp*dims[j] + *dxm++ - starts[j+1];
637     }
638     if (mat->stencil.noc) dxm++;
639     jdxm[i] = tmp;
640   }
641   for (i=0; i<n; i++) {
642     for (j=0; j<3-sdim; j++) dxn++;
643     tmp = *dxn++ - starts[0];
644     for (j=0; j<dim-1; j++) {
645       tmp = tmp*dims[j] + *dxn++ - starts[j+1];
646     }
647     if (mat->stencil.noc) dxn++;
648     jdxn[i] = tmp;
649   }
650   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
651   PetscFunctionReturn(0);
652 }
653 
654 #undef __FUNCT__
655 #define __FUNCT__ "MatSetValuesBlockedStencil"
656 /*@C
657    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
658      Using structured grid indexing
659 
660    Not Collective
661 
662    Input Parameters:
663 +  mat - the matrix
664 .  v - a logically two-dimensional array of values
665 .  m - number of rows being entered
666 .  idxm - grid coordinates for matrix rows being entered
667 .  n - number of columns being entered
668 .  idxn - grid coordinates for matrix columns being entered
669 -  addv - either ADD_VALUES or INSERT_VALUES, where
670    ADD_VALUES adds values to any existing entries, and
671    INSERT_VALUES replaces existing entries with new values
672 
673    Notes:
674    By default the values, v, are row-oriented and unsorted.
675    See MatSetOption() for other options.
676 
677    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
678    options cannot be mixed without intervening calls to the assembly
679    routines.
680 
681    The grid coordinates are across the entire grid, not just the local portion
682 
683    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
684    as well as in C.
685 
686    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
687 
688    In order to use this routine you must either obtain the matrix with DAGetMatrix()
689    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
690 
691    The columns and rows in the stencil passed in MUST be contained within the
692    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
693    if you create a DA with an overlap of one grid level and on a particular process its first
694    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
695    first i index you can use in your column and row indices in MatSetStencil() is 5.
696 
697    In Fortran idxm and idxn should be declared as
698 $     MatStencil idxm(4,m),idxn(4,n)
699    and the values inserted using
700 $    idxm(MatStencil_i,1) = i
701 $    idxm(MatStencil_j,1) = j
702 $    idxm(MatStencil_k,1) = k
703    etc
704 
705    Negative indices may be passed in idxm and idxn, these rows and columns are
706    simply ignored. This allows easily inserting element stiffness matrices
707    with homogeneous Dirchlet boundary conditions that you don't want represented
708    in the matrix.
709 
710    Inspired by the structured grid interface to the HYPRE package
711    (http://www.llnl.gov/CASC/hypre)
712 
713    Level: beginner
714 
715    Concepts: matrices^putting entries in
716 
717 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
718           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
719 @*/
720 int MatSetValuesBlockedStencil(Mat mat,int m,const MatStencil idxm[],int n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
721 {
722   int j,i,ierr,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
723   int *starts = mat->stencil.starts,*dxm = (int*)idxm,*dxn = (int*)idxn,sdim = dim - (1 - (int)mat->stencil.noc);
724 
725   PetscFunctionBegin;
726   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
727   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
728   PetscValidType(mat,1);
729   PetscValidIntPointer(idxm,3);
730   PetscValidIntPointer(idxn,5);
731   PetscValidScalarPointer(v,6);
732 
733   if (m > 128) SETERRQ1(1,"Can only set 128 rows at a time; trying to set %d",m);
734   if (n > 128) SETERRQ1(1,"Can only set 256 columns at a time; trying to set %d",n);
735 
736   for (i=0; i<m; i++) {
737     for (j=0; j<3-sdim; j++) dxm++;
738     tmp = *dxm++ - starts[0];
739     for (j=0; j<sdim-1; j++) {
740       tmp = tmp*dims[j] + *dxm++ - starts[j+1];
741     }
742     dxm++;
743     jdxm[i] = tmp;
744   }
745   for (i=0; i<n; i++) {
746     for (j=0; j<3-sdim; j++) dxn++;
747     tmp = *dxn++ - starts[0];
748     for (j=0; j<sdim-1; j++) {
749       tmp = tmp*dims[j] + *dxn++ - starts[j+1];
750     }
751     dxn++;
752     jdxn[i] = tmp;
753   }
754   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
755   PetscFunctionReturn(0);
756 }
757 
758 #undef __FUNCT__
759 #define __FUNCT__ "MatSetStencil"
760 /*@
761    MatSetStencil - Sets the grid information for setting values into a matrix via
762         MatSetValuesStencil()
763 
764    Not Collective
765 
766    Input Parameters:
767 +  mat - the matrix
768 .  dim - dimension of the grid 1, 2, or 3
769 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
770 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
771 -  dof - number of degrees of freedom per node
772 
773 
774    Inspired by the structured grid interface to the HYPRE package
775    (www.llnl.gov/CASC/hyper)
776 
777    For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
778    user.
779 
780    Level: beginner
781 
782    Concepts: matrices^putting entries in
783 
784 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
785           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
786 @*/
787 int MatSetStencil(Mat mat,int dim,const int dims[],const int starts[],int dof)
788 {
789   int i;
790 
791   PetscFunctionBegin;
792   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
793   PetscValidIntPointer(dims,3);
794   PetscValidIntPointer(starts,4);
795 
796   mat->stencil.dim = dim + (dof > 1);
797   for (i=0; i<dim; i++) {
798     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
799     mat->stencil.starts[i] = starts[dim-i-1];
800   }
801   mat->stencil.dims[dim]   = dof;
802   mat->stencil.starts[dim] = 0;
803   mat->stencil.noc         = (PetscTruth)(dof == 1);
804   PetscFunctionReturn(0);
805 }
806 
807 #undef __FUNCT__
808 #define __FUNCT__ "MatSetValuesBlocked"
809 /*@
810    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
811 
812    Not Collective
813 
814    Input Parameters:
815 +  mat - the matrix
816 .  v - a logically two-dimensional array of values
817 .  m, idxm - the number of block rows and their global block indices
818 .  n, idxn - the number of block columns and their global block indices
819 -  addv - either ADD_VALUES or INSERT_VALUES, where
820    ADD_VALUES adds values to any existing entries, and
821    INSERT_VALUES replaces existing entries with new values
822 
823    Notes:
824    By default the values, v, are row-oriented and unsorted. So the layout of
825    v is the same as for MatSetValues(). See MatSetOption() for other options.
826 
827    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
828    options cannot be mixed without intervening calls to the assembly
829    routines.
830 
831    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
832    as well as in C.
833 
834    Negative indices may be passed in idxm and idxn, these rows and columns are
835    simply ignored. This allows easily inserting element stiffness matrices
836    with homogeneous Dirchlet boundary conditions that you don't want represented
837    in the matrix.
838 
839    Each time an entry is set within a sparse matrix via MatSetValues(),
840    internal searching must be done to determine where to place the the
841    data in the matrix storage space.  By instead inserting blocks of
842    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
843    reduced.
844 
845    Restrictions:
846    MatSetValuesBlocked() is currently supported only for the BAIJ and SBAIJ formats
847 
848    Level: intermediate
849 
850    Concepts: matrices^putting entries in blocked
851 
852 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
853 @*/
854 int MatSetValuesBlocked(Mat mat,int m,const int idxm[],int n,const int idxn[],const PetscScalar v[],InsertMode addv)
855 {
856   int ierr;
857 
858   PetscFunctionBegin;
859   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
860   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
861   PetscValidType(mat,1);
862   MatPreallocated(mat);
863   PetscValidIntPointer(idxm,3);
864   PetscValidIntPointer(idxn,5);
865   PetscValidScalarPointer(v,6);
866   if (mat->insertmode == NOT_SET_VALUES) {
867     mat->insertmode = addv;
868   }
869 #if defined(PETSC_USE_BOPT_g)
870   else if (mat->insertmode != addv) {
871     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
872   }
873   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
874 #endif
875 
876   if (mat->assembled) {
877     mat->was_assembled = PETSC_TRUE;
878     mat->assembled     = PETSC_FALSE;
879   }
880   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
881   if (!mat->ops->setvaluesblocked) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
882   ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
883   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
884   PetscFunctionReturn(0);
885 }
886 
887 #undef __FUNCT__
888 #define __FUNCT__ "MatGetValues"
889 /*@
890    MatGetValues - Gets a block of values from a matrix.
891 
892    Not Collective; currently only returns a local block
893 
894    Input Parameters:
895 +  mat - the matrix
896 .  v - a logically two-dimensional array for storing the values
897 .  m, idxm - the number of rows and their global indices
898 -  n, idxn - the number of columns and their global indices
899 
900    Notes:
901    The user must allocate space (m*n PetscScalars) for the values, v.
902    The values, v, are then returned in a row-oriented format,
903    analogous to that used by default in MatSetValues().
904 
905    MatGetValues() uses 0-based row and column numbers in
906    Fortran as well as in C.
907 
908    MatGetValues() requires that the matrix has been assembled
909    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
910    MatSetValues() and MatGetValues() CANNOT be made in succession
911    without intermediate matrix assembly.
912 
913    Level: advanced
914 
915    Concepts: matrices^accessing values
916 
917 .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues()
918 @*/
919 int MatGetValues(Mat mat,int m,const int idxm[],int n,const int idxn[],PetscScalar v[])
920 {
921   int ierr;
922 
923   PetscFunctionBegin;
924   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
925   PetscValidType(mat,1);
926   MatPreallocated(mat);
927   PetscValidIntPointer(idxm,3);
928   PetscValidIntPointer(idxn,5);
929   PetscValidScalarPointer(v,6);
930   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
931   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
932   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
933 
934   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
935   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
936   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
937   PetscFunctionReturn(0);
938 }
939 
940 #undef __FUNCT__
941 #define __FUNCT__ "MatSetLocalToGlobalMapping"
942 /*@
943    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
944    the routine MatSetValuesLocal() to allow users to insert matrix entries
945    using a local (per-processor) numbering.
946 
947    Not Collective
948 
949    Input Parameters:
950 +  x - the matrix
951 -  mapping - mapping created with ISLocalToGlobalMappingCreate()
952              or ISLocalToGlobalMappingCreateIS()
953 
954    Level: intermediate
955 
956    Concepts: matrices^local to global mapping
957    Concepts: local to global mapping^for matrices
958 
959 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
960 @*/
961 int MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
962 {
963   int ierr;
964   PetscFunctionBegin;
965   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
966   PetscValidType(x,1);
967   MatPreallocated(x);
968   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
969   if (x->mapping) {
970     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
971   }
972 
973   if (x->ops->setlocaltoglobalmapping) {
974     ierr = (*x->ops->setlocaltoglobalmapping)(x,mapping);CHKERRQ(ierr);
975   } else {
976     x->mapping = mapping;
977     ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
978   }
979   PetscFunctionReturn(0);
980 }
981 
982 #undef __FUNCT__
983 #define __FUNCT__ "MatSetLocalToGlobalMappingBlock"
984 /*@
985    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
986    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
987    entries using a local (per-processor) numbering.
988 
989    Not Collective
990 
991    Input Parameters:
992 +  x - the matrix
993 -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
994              ISLocalToGlobalMappingCreateIS()
995 
996    Level: intermediate
997 
998    Concepts: matrices^local to global mapping blocked
999    Concepts: local to global mapping^for matrices, blocked
1000 
1001 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1002            MatSetValuesBlocked(), MatSetValuesLocal()
1003 @*/
1004 int MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1005 {
1006   int ierr;
1007   PetscFunctionBegin;
1008   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
1009   PetscValidType(x,1);
1010   MatPreallocated(x);
1011   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
1012   if (x->bmapping) {
1013     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1014   }
1015 
1016   x->bmapping = mapping;
1017   ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1018   PetscFunctionReturn(0);
1019 }
1020 
1021 #undef __FUNCT__
1022 #define __FUNCT__ "MatSetValuesLocal"
1023 /*@
1024    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1025    using a local ordering of the nodes.
1026 
1027    Not Collective
1028 
1029    Input Parameters:
1030 +  x - the matrix
1031 .  nrow, irow - number of rows and their local indices
1032 .  ncol, icol - number of columns and their local indices
1033 .  y -  a logically two-dimensional array of values
1034 -  addv - either INSERT_VALUES or ADD_VALUES, where
1035    ADD_VALUES adds values to any existing entries, and
1036    INSERT_VALUES replaces existing entries with new values
1037 
1038    Notes:
1039    Before calling MatSetValuesLocal(), the user must first set the
1040    local-to-global mapping by calling MatSetLocalToGlobalMapping().
1041 
1042    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1043    options cannot be mixed without intervening calls to the assembly
1044    routines.
1045 
1046    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1047    MUST be called after all calls to MatSetValuesLocal() have been completed.
1048 
1049    Level: intermediate
1050 
1051    Concepts: matrices^putting entries in with local numbering
1052 
1053 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1054            MatSetValueLocal()
1055 @*/
1056 int MatSetValuesLocal(Mat mat,int nrow,const int irow[],int ncol,const int icol[],const PetscScalar y[],InsertMode addv)
1057 {
1058   int ierr,irowm[2048],icolm[2048];
1059 
1060   PetscFunctionBegin;
1061   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1062   PetscValidType(mat,1);
1063   MatPreallocated(mat);
1064   PetscValidIntPointer(irow,3);
1065   PetscValidIntPointer(icol,5);
1066   PetscValidScalarPointer(y,6);
1067 
1068   if (mat->insertmode == NOT_SET_VALUES) {
1069     mat->insertmode = addv;
1070   }
1071 #if defined(PETSC_USE_BOPT_g)
1072   else if (mat->insertmode != addv) {
1073     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1074   }
1075   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1076     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
1077   }
1078   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1079 #endif
1080 
1081   if (mat->assembled) {
1082     mat->was_assembled = PETSC_TRUE;
1083     mat->assembled     = PETSC_FALSE;
1084   }
1085   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1086   if (!mat->ops->setvalueslocal) {
1087     ierr = ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);CHKERRQ(ierr);
1088     ierr = ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);CHKERRQ(ierr);
1089     ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1090   } else {
1091     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
1092   }
1093   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1094   PetscFunctionReturn(0);
1095 }
1096 
1097 #undef __FUNCT__
1098 #define __FUNCT__ "MatSetValuesBlockedLocal"
1099 /*@
1100    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1101    using a local ordering of the nodes a block at a time.
1102 
1103    Not Collective
1104 
1105    Input Parameters:
1106 +  x - the matrix
1107 .  nrow, irow - number of rows and their local indices
1108 .  ncol, icol - number of columns and their local indices
1109 .  y -  a logically two-dimensional array of values
1110 -  addv - either INSERT_VALUES or ADD_VALUES, where
1111    ADD_VALUES adds values to any existing entries, and
1112    INSERT_VALUES replaces existing entries with new values
1113 
1114    Notes:
1115    Before calling MatSetValuesBlockedLocal(), the user must first set the
1116    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1117    where the mapping MUST be set for matrix blocks, not for matrix elements.
1118 
1119    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1120    options cannot be mixed without intervening calls to the assembly
1121    routines.
1122 
1123    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1124    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1125 
1126    Level: intermediate
1127 
1128    Concepts: matrices^putting blocked values in with local numbering
1129 
1130 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1131 @*/
1132 int MatSetValuesBlockedLocal(Mat mat,int nrow,const int irow[],int ncol,const int icol[],const PetscScalar y[],InsertMode addv)
1133 {
1134   int ierr,irowm[2048],icolm[2048];
1135 
1136   PetscFunctionBegin;
1137   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1138   PetscValidType(mat,1);
1139   MatPreallocated(mat);
1140   PetscValidIntPointer(irow,3);
1141   PetscValidIntPointer(icol,5);
1142   PetscValidScalarPointer(y,6);
1143   if (mat->insertmode == NOT_SET_VALUES) {
1144     mat->insertmode = addv;
1145   }
1146 #if defined(PETSC_USE_BOPT_g)
1147   else if (mat->insertmode != addv) {
1148     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1149   }
1150   if (!mat->bmapping) {
1151     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1152   }
1153   if (nrow > 2048 || ncol > 2048) {
1154     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
1155   }
1156   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1157 #endif
1158 
1159   if (mat->assembled) {
1160     mat->was_assembled = PETSC_TRUE;
1161     mat->assembled     = PETSC_FALSE;
1162   }
1163   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1164   ierr = ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);CHKERRQ(ierr);
1165   ierr = ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);CHKERRQ(ierr);
1166   ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1167   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1168   PetscFunctionReturn(0);
1169 }
1170 
1171 /* --------------------------------------------------------*/
1172 #undef __FUNCT__
1173 #define __FUNCT__ "MatMult"
1174 /*@
1175    MatMult - Computes the matrix-vector product, y = Ax.
1176 
1177    Collective on Mat and Vec
1178 
1179    Input Parameters:
1180 +  mat - the matrix
1181 -  x   - the vector to be multiplied
1182 
1183    Output Parameters:
1184 .  y - the result
1185 
1186    Notes:
1187    The vectors x and y cannot be the same.  I.e., one cannot
1188    call MatMult(A,y,y).
1189 
1190    Level: beginner
1191 
1192    Concepts: matrix-vector product
1193 
1194 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1195 @*/
1196 int MatMult(Mat mat,Vec x,Vec y)
1197 {
1198   int ierr;
1199 
1200   PetscFunctionBegin;
1201   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1202   PetscValidType(mat,1);
1203   MatPreallocated(mat);
1204   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1205   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1206 
1207   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1208   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1209   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1210 #ifndef PETSC_HAVE_CONSTRAINTS
1211   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1212   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1213   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1214 #endif
1215 
1216   if (mat->nullsp) {
1217     ierr = MatNullSpaceRemove(mat->nullsp,x,&x);CHKERRQ(ierr);
1218   }
1219 
1220   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1221   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
1222   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1223 
1224   if (mat->nullsp) {
1225     ierr = MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);CHKERRQ(ierr);
1226   }
1227   ierr = PetscObjectIncreaseState((PetscObject)y); CHKERRQ(ierr);
1228   PetscFunctionReturn(0);
1229 }
1230 
1231 #undef __FUNCT__
1232 #define __FUNCT__ "MatMultTranspose"
1233 /*@
1234    MatMultTranspose - Computes matrix transpose times a vector.
1235 
1236    Collective on Mat and Vec
1237 
1238    Input Parameters:
1239 +  mat - the matrix
1240 -  x   - the vector to be multilplied
1241 
1242    Output Parameters:
1243 .  y - the result
1244 
1245    Notes:
1246    The vectors x and y cannot be the same.  I.e., one cannot
1247    call MatMultTranspose(A,y,y).
1248 
1249    Level: beginner
1250 
1251    Concepts: matrix vector product^transpose
1252 
1253 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1254 @*/
1255 int MatMultTranspose(Mat mat,Vec x,Vec y)
1256 {
1257   int ierr;
1258   PetscTruth flg1, flg2;
1259 
1260   PetscFunctionBegin;
1261   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1262   PetscValidType(mat,1);
1263   MatPreallocated(mat);
1264   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1265   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1266 
1267   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1268   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1269   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1270 #ifndef PETSC_HAVE_CONSTRAINTS
1271   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
1272   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
1273 #endif
1274 
1275   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP, "Operation not supported");
1276   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1277   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1278 
1279   ierr = PetscTypeCompare((PetscObject)mat,MATSEQSBAIJ,&flg1);
1280   ierr = PetscTypeCompare((PetscObject)mat,MATMPISBAIJ,&flg2);
1281   if (flg1 || flg2) { /* mat is in sbaij format */
1282     ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
1283   } else {
1284     ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
1285   }
1286   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1287   ierr = PetscObjectIncreaseState((PetscObject)y); CHKERRQ(ierr);
1288   PetscFunctionReturn(0);
1289 }
1290 
1291 #undef __FUNCT__
1292 #define __FUNCT__ "MatMultAdd"
1293 /*@
1294     MatMultAdd -  Computes v3 = v2 + A * v1.
1295 
1296     Collective on Mat and Vec
1297 
1298     Input Parameters:
1299 +   mat - the matrix
1300 -   v1, v2 - the vectors
1301 
1302     Output Parameters:
1303 .   v3 - the result
1304 
1305     Notes:
1306     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1307     call MatMultAdd(A,v1,v2,v1).
1308 
1309     Level: beginner
1310 
1311     Concepts: matrix vector product^addition
1312 
1313 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1314 @*/
1315 int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1316 {
1317   int ierr;
1318 
1319   PetscFunctionBegin;
1320   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1321   PetscValidType(mat,1);
1322   MatPreallocated(mat);
1323   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1324   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1325   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1326 
1327   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1328   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1329   if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->N,v1->N);
1330   if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->M,v2->N);
1331   if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->M,v3->N);
1332   if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %d %d",mat->m,v3->n);
1333   if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %d %d",mat->m,v2->n);
1334   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1335 
1336   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1337   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1338   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1339   ierr = PetscObjectIncreaseState((PetscObject)v3); CHKERRQ(ierr);
1340   PetscFunctionReturn(0);
1341 }
1342 
1343 #undef __FUNCT__
1344 #define __FUNCT__ "MatMultTransposeAdd"
1345 /*@
1346    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1347 
1348    Collective on Mat and Vec
1349 
1350    Input Parameters:
1351 +  mat - the matrix
1352 -  v1, v2 - the vectors
1353 
1354    Output Parameters:
1355 .  v3 - the result
1356 
1357    Notes:
1358    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1359    call MatMultTransposeAdd(A,v1,v2,v1).
1360 
1361    Level: beginner
1362 
1363    Concepts: matrix vector product^transpose and addition
1364 
1365 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1366 @*/
1367 int MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1368 {
1369   int ierr;
1370 
1371   PetscFunctionBegin;
1372   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1373   PetscValidType(mat,1);
1374   MatPreallocated(mat);
1375   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1376   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1377   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1378 
1379   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1380   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1381   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1382   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1383   if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->M,v1->N);
1384   if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->N,v2->N);
1385   if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->N,v3->N);
1386 
1387   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1388   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1389   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1390   ierr = PetscObjectIncreaseState((PetscObject)v3); CHKERRQ(ierr);
1391   PetscFunctionReturn(0);
1392 }
1393 
1394 #undef __FUNCT__
1395 #define __FUNCT__ "MatMultConstrained"
1396 /*@
1397    MatMultConstrained - The inner multiplication routine for a
1398    constrained matrix P^T A P.
1399 
1400    Collective on Mat and Vec
1401 
1402    Input Parameters:
1403 +  mat - the matrix
1404 -  x   - the vector to be multilplied
1405 
1406    Output Parameters:
1407 .  y - the result
1408 
1409    Notes:
1410    The vectors x and y cannot be the same.  I.e., one cannot
1411    call MatMult(A,y,y).
1412 
1413    Level: beginner
1414 
1415 .keywords: matrix, multiply, matrix-vector product, constraint
1416 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1417 @*/
1418 int MatMultConstrained(Mat mat,Vec x,Vec y)
1419 {
1420   int ierr;
1421 
1422   PetscFunctionBegin;
1423   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1424   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1425   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1426   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1427   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1428   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1429   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1430   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1431   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1432 
1433   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1434   ierr = (*mat->ops->multconstrained)(mat,x,y); CHKERRQ(ierr);
1435   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1436   ierr = PetscObjectIncreaseState((PetscObject)y); CHKERRQ(ierr);
1437 
1438   PetscFunctionReturn(0);
1439 }
1440 
1441 #undef __FUNCT__
1442 #define __FUNCT__ "MatMultTransposeConstrained"
1443 /*@
1444    MatMultTransposeConstrained - The inner multiplication routine for a
1445    constrained matrix P^T A^T P.
1446 
1447    Collective on Mat and Vec
1448 
1449    Input Parameters:
1450 +  mat - the matrix
1451 -  x   - the vector to be multilplied
1452 
1453    Output Parameters:
1454 .  y - the result
1455 
1456    Notes:
1457    The vectors x and y cannot be the same.  I.e., one cannot
1458    call MatMult(A,y,y).
1459 
1460    Level: beginner
1461 
1462 .keywords: matrix, multiply, matrix-vector product, constraint
1463 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1464 @*/
1465 int MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1466 {
1467   int ierr;
1468 
1469   PetscFunctionBegin;
1470   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1471   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1472   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1473   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1474   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1475   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1476   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1477   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1478 
1479   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1480   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
1481   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1482   ierr = PetscObjectIncreaseState((PetscObject)y); CHKERRQ(ierr);
1483 
1484   PetscFunctionReturn(0);
1485 }
1486 /* ------------------------------------------------------------*/
1487 #undef __FUNCT__
1488 #define __FUNCT__ "MatGetInfo"
1489 /*@C
1490    MatGetInfo - Returns information about matrix storage (number of
1491    nonzeros, memory, etc.).
1492 
1493    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1494    as the flag
1495 
1496    Input Parameters:
1497 .  mat - the matrix
1498 
1499    Output Parameters:
1500 +  flag - flag indicating the type of parameters to be returned
1501    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1502    MAT_GLOBAL_SUM - sum over all processors)
1503 -  info - matrix information context
1504 
1505    Notes:
1506    The MatInfo context contains a variety of matrix data, including
1507    number of nonzeros allocated and used, number of mallocs during
1508    matrix assembly, etc.  Additional information for factored matrices
1509    is provided (such as the fill ratio, number of mallocs during
1510    factorization, etc.).  Much of this info is printed to STDOUT
1511    when using the runtime options
1512 $       -log_info -mat_view_info
1513 
1514    Example for C/C++ Users:
1515    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1516    data within the MatInfo context.  For example,
1517 .vb
1518       MatInfo info;
1519       Mat     A;
1520       double  mal, nz_a, nz_u;
1521 
1522       MatGetInfo(A,MAT_LOCAL,&info);
1523       mal  = info.mallocs;
1524       nz_a = info.nz_allocated;
1525 .ve
1526 
1527    Example for Fortran Users:
1528    Fortran users should declare info as a double precision
1529    array of dimension MAT_INFO_SIZE, and then extract the parameters
1530    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
1531    a complete list of parameter names.
1532 .vb
1533       double  precision info(MAT_INFO_SIZE)
1534       double  precision mal, nz_a
1535       Mat     A
1536       integer ierr
1537 
1538       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1539       mal = info(MAT_INFO_MALLOCS)
1540       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1541 .ve
1542 
1543     Level: intermediate
1544 
1545     Concepts: matrices^getting information on
1546 
1547 @*/
1548 int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1549 {
1550   int ierr;
1551 
1552   PetscFunctionBegin;
1553   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1554   PetscValidType(mat,1);
1555   MatPreallocated(mat);
1556   PetscValidPointer(info,3);
1557   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1558   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
1559   PetscFunctionReturn(0);
1560 }
1561 
1562 /* ----------------------------------------------------------*/
1563 #undef __FUNCT__
1564 #define __FUNCT__ "MatILUDTFactor"
1565 /*@C
1566    MatILUDTFactor - Performs a drop tolerance ILU factorization.
1567 
1568    Collective on Mat
1569 
1570    Input Parameters:
1571 +  mat - the matrix
1572 .  info - information about the factorization to be done
1573 .  row - row permutation
1574 -  col - column permutation
1575 
1576    Output Parameters:
1577 .  fact - the factored matrix
1578 
1579    Level: developer
1580 
1581    Notes:
1582    Most users should employ the simplified KSP interface for linear solvers
1583    instead of working directly with matrix algebra routines such as this.
1584    See, e.g., KSPCreate().
1585 
1586    This is currently only supported for the SeqAIJ matrix format using code
1587    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
1588    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
1589    and thus can be distributed with PETSc.
1590 
1591     Concepts: matrices^ILUDT factorization
1592 
1593 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1594 @*/
1595 int MatILUDTFactor(Mat mat,MatFactorInfo *info,IS row,IS col,Mat *fact)
1596 {
1597   int ierr;
1598 
1599   PetscFunctionBegin;
1600   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1601   PetscValidType(mat,1);
1602   MatPreallocated(mat);
1603   PetscValidPointer(info,2);
1604   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,3);
1605   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,4);
1606   PetscValidPointer(fact,5);
1607   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1608   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1609   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1610 
1611   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1612   ierr = (*mat->ops->iludtfactor)(mat,info,row,col,fact);CHKERRQ(ierr);
1613   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1614   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1615 
1616   PetscFunctionReturn(0);
1617 }
1618 
1619 #undef __FUNCT__
1620 #define __FUNCT__ "MatLUFactor"
1621 /*@
1622    MatLUFactor - Performs in-place LU factorization of matrix.
1623 
1624    Collective on Mat
1625 
1626    Input Parameters:
1627 +  mat - the matrix
1628 .  row - row permutation
1629 .  col - column permutation
1630 -  info - options for factorization, includes
1631 $          fill - expected fill as ratio of original fill.
1632 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1633 $                   Run with the option -log_info to determine an optimal value to use
1634 
1635    Notes:
1636    Most users should employ the simplified KSP interface for linear solvers
1637    instead of working directly with matrix algebra routines such as this.
1638    See, e.g., KSPCreate().
1639 
1640    This changes the state of the matrix to a factored matrix; it cannot be used
1641    for example with MatSetValues() unless one first calls MatSetUnfactored().
1642 
1643    Level: developer
1644 
1645    Concepts: matrices^LU factorization
1646 
1647 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
1648           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
1649 
1650 @*/
1651 int MatLUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1652 {
1653   int ierr;
1654 
1655   PetscFunctionBegin;
1656   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1657   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
1658   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
1659   PetscValidPointer(info,4);
1660   PetscValidType(mat,1);
1661   MatPreallocated(mat);
1662   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1663   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1664   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1665 
1666   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1667   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
1668   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1669   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
1670   PetscFunctionReturn(0);
1671 }
1672 
1673 #undef __FUNCT__
1674 #define __FUNCT__ "MatILUFactor"
1675 /*@
1676    MatILUFactor - Performs in-place ILU factorization of matrix.
1677 
1678    Collective on Mat
1679 
1680    Input Parameters:
1681 +  mat - the matrix
1682 .  row - row permutation
1683 .  col - column permutation
1684 -  info - structure containing
1685 $      levels - number of levels of fill.
1686 $      expected fill - as ratio of original fill.
1687 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1688                 missing diagonal entries)
1689 
1690    Notes:
1691    Probably really in-place only when level of fill is zero, otherwise allocates
1692    new space to store factored matrix and deletes previous memory.
1693 
1694    Most users should employ the simplified KSP interface for linear solvers
1695    instead of working directly with matrix algebra routines such as this.
1696    See, e.g., KSPCreate().
1697 
1698    Level: developer
1699 
1700    Concepts: matrices^ILU factorization
1701 
1702 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1703 @*/
1704 int MatILUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1705 {
1706   int ierr;
1707 
1708   PetscFunctionBegin;
1709   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1710   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
1711   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
1712   PetscValidPointer(info,4);
1713   PetscValidType(mat,1);
1714   MatPreallocated(mat);
1715   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
1716   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1717   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1718   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1719 
1720   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1721   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
1722   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1723   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
1724   PetscFunctionReturn(0);
1725 }
1726 
1727 #undef __FUNCT__
1728 #define __FUNCT__ "MatLUFactorSymbolic"
1729 /*@
1730    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1731    Call this routine before calling MatLUFactorNumeric().
1732 
1733    Collective on Mat
1734 
1735    Input Parameters:
1736 +  mat - the matrix
1737 .  row, col - row and column permutations
1738 -  info - options for factorization, includes
1739 $          fill - expected fill as ratio of original fill.
1740 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1741 $                   Run with the option -log_info to determine an optimal value to use
1742 
1743    Output Parameter:
1744 .  fact - new matrix that has been symbolically factored
1745 
1746    Notes:
1747    See the users manual for additional information about
1748    choosing the fill factor for better efficiency.
1749 
1750    Most users should employ the simplified KSP interface for linear solvers
1751    instead of working directly with matrix algebra routines such as this.
1752    See, e.g., KSPCreate().
1753 
1754    Level: developer
1755 
1756    Concepts: matrices^LU symbolic factorization
1757 
1758 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1759 @*/
1760 int MatLUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
1761 {
1762   int ierr;
1763 
1764   PetscFunctionBegin;
1765   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1766   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
1767   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
1768   PetscValidPointer(info,4);
1769   PetscValidType(mat,1);
1770   MatPreallocated(mat);
1771   PetscValidPointer(fact,5);
1772   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1773   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1774   if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",mat->type_name);
1775 
1776   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1777   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
1778   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1779   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1780   PetscFunctionReturn(0);
1781 }
1782 
1783 #undef __FUNCT__
1784 #define __FUNCT__ "MatLUFactorNumeric"
1785 /*@
1786    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1787    Call this routine after first calling MatLUFactorSymbolic().
1788 
1789    Collective on Mat
1790 
1791    Input Parameters:
1792 +  mat - the matrix
1793 -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()
1794 
1795    Notes:
1796    See MatLUFactor() for in-place factorization.  See
1797    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
1798 
1799    Most users should employ the simplified KSP interface for linear solvers
1800    instead of working directly with matrix algebra routines such as this.
1801    See, e.g., KSPCreate().
1802 
1803    Level: developer
1804 
1805    Concepts: matrices^LU numeric factorization
1806 
1807 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1808 @*/
1809 int MatLUFactorNumeric(Mat mat,Mat *fact)
1810 {
1811   int        ierr;
1812 
1813   PetscFunctionBegin;
1814   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1815   PetscValidType(mat,1);
1816   MatPreallocated(mat);
1817   PetscValidPointer(fact,2);
1818   PetscValidHeaderSpecific(*fact,MAT_COOKIE,2);
1819   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1820   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1821     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d",
1822             mat->M,(*fact)->M,mat->N,(*fact)->N);
1823   }
1824   if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1825 
1826   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1827   ierr = (*(*fact)->ops->lufactornumeric)(mat,fact);CHKERRQ(ierr);
1828   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1829 
1830   ierr = MatView_Private(*fact);CHKERRQ(ierr);
1831   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1832   PetscFunctionReturn(0);
1833 }
1834 
1835 #undef __FUNCT__
1836 #define __FUNCT__ "MatCholeskyFactor"
1837 /*@
1838    MatCholeskyFactor - Performs in-place Cholesky factorization of a
1839    symmetric matrix.
1840 
1841    Collective on Mat
1842 
1843    Input Parameters:
1844 +  mat - the matrix
1845 .  perm - row and column permutations
1846 -  f - expected fill as ratio of original fill
1847 
1848    Notes:
1849    See MatLUFactor() for the nonsymmetric case.  See also
1850    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
1851 
1852    Most users should employ the simplified KSP interface for linear solvers
1853    instead of working directly with matrix algebra routines such as this.
1854    See, e.g., KSPCreate().
1855 
1856    Level: developer
1857 
1858    Concepts: matrices^Cholesky factorization
1859 
1860 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
1861           MatGetOrdering()
1862 
1863 @*/
1864 int MatCholeskyFactor(Mat mat,IS perm,MatFactorInfo *info)
1865 {
1866   int ierr;
1867 
1868   PetscFunctionBegin;
1869   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1870   PetscValidType(mat,1);
1871   MatPreallocated(mat);
1872   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
1873   PetscValidPointer(info,3);
1874   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1875   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1876   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1877   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1878 
1879   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1880   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
1881   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1882   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
1883   PetscFunctionReturn(0);
1884 }
1885 
1886 #undef __FUNCT__
1887 #define __FUNCT__ "MatCholeskyFactorSymbolic"
1888 /*@
1889    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
1890    of a symmetric matrix.
1891 
1892    Collective on Mat
1893 
1894    Input Parameters:
1895 +  mat - the matrix
1896 .  perm - row and column permutations
1897 -  info - options for factorization, includes
1898 $          fill - expected fill as ratio of original fill.
1899 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1900 $                   Run with the option -log_info to determine an optimal value to use
1901 
1902    Output Parameter:
1903 .  fact - the factored matrix
1904 
1905    Notes:
1906    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
1907    MatCholeskyFactor() and MatCholeskyFactorNumeric().
1908 
1909    Most users should employ the simplified KSP interface for linear solvers
1910    instead of working directly with matrix algebra routines such as this.
1911    See, e.g., KSPCreate().
1912 
1913    Level: developer
1914 
1915    Concepts: matrices^Cholesky symbolic factorization
1916 
1917 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
1918           MatGetOrdering()
1919 
1920 @*/
1921 int MatCholeskyFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
1922 {
1923   int ierr;
1924 
1925   PetscFunctionBegin;
1926   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1927   PetscValidType(mat,1);
1928   MatPreallocated(mat);
1929   if (perm) PetscValidHeaderSpecific(perm,IS_COOKIE,2);
1930   PetscValidPointer(info,3);
1931   PetscValidPointer(fact,4);
1932   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1933   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1934   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1935   if (!mat->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1936 
1937   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1938   ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
1939   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1940   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1941   PetscFunctionReturn(0);
1942 }
1943 
1944 #undef __FUNCT__
1945 #define __FUNCT__ "MatCholeskyFactorNumeric"
1946 /*@
1947    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
1948    of a symmetric matrix. Call this routine after first calling
1949    MatCholeskyFactorSymbolic().
1950 
1951    Collective on Mat
1952 
1953    Input Parameter:
1954 .  mat - the initial matrix
1955 
1956    Output Parameter:
1957 .  fact - the factored matrix
1958 
1959    Notes:
1960    Most users should employ the simplified KSP interface for linear solvers
1961    instead of working directly with matrix algebra routines such as this.
1962    See, e.g., KSPCreate().
1963 
1964    Level: developer
1965 
1966    Concepts: matrices^Cholesky numeric factorization
1967 
1968 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
1969 @*/
1970 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
1971 {
1972   int ierr;
1973 
1974   PetscFunctionBegin;
1975   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1976   PetscValidType(mat,1);
1977   MatPreallocated(mat);
1978   PetscValidPointer(fact,2);
1979   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1980   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1981   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1982     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d",
1983             mat->M,(*fact)->M,mat->N,(*fact)->N);
1984   }
1985 
1986   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1987   ierr = (*(*fact)->ops->choleskyfactornumeric)(mat,fact);CHKERRQ(ierr);
1988   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1989   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1990   PetscFunctionReturn(0);
1991 }
1992 
1993 /* ----------------------------------------------------------------*/
1994 #undef __FUNCT__
1995 #define __FUNCT__ "MatSolve"
1996 /*@
1997    MatSolve - Solves A x = b, given a factored matrix.
1998 
1999    Collective on Mat and Vec
2000 
2001    Input Parameters:
2002 +  mat - the factored matrix
2003 -  b - the right-hand-side vector
2004 
2005    Output Parameter:
2006 .  x - the result vector
2007 
2008    Notes:
2009    The vectors b and x cannot be the same.  I.e., one cannot
2010    call MatSolve(A,x,x).
2011 
2012    Notes:
2013    Most users should employ the simplified KSP interface for linear solvers
2014    instead of working directly with matrix algebra routines such as this.
2015    See, e.g., KSPCreate().
2016 
2017    Level: developer
2018 
2019    Concepts: matrices^triangular solves
2020 
2021 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2022 @*/
2023 int MatSolve(Mat mat,Vec b,Vec x)
2024 {
2025   int ierr;
2026 
2027   PetscFunctionBegin;
2028   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2029   PetscValidType(mat,1);
2030   MatPreallocated(mat);
2031   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2032   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2033   PetscCheckSameComm(mat,1,b,2);
2034   PetscCheckSameComm(mat,1,x,3);
2035   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2036   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2037   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2038   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2039   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2040   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
2041 
2042   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2043   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2044   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
2045   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2046   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2047   PetscFunctionReturn(0);
2048 }
2049 
2050 #undef __FUNCT__
2051 #define __FUNCT__ "MatForwardSolve"
2052 /* @
2053    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
2054 
2055    Collective on Mat and Vec
2056 
2057    Input Parameters:
2058 +  mat - the factored matrix
2059 -  b - the right-hand-side vector
2060 
2061    Output Parameter:
2062 .  x - the result vector
2063 
2064    Notes:
2065    MatSolve() should be used for most applications, as it performs
2066    a forward solve followed by a backward solve.
2067 
2068    The vectors b and x cannot be the same.  I.e., one cannot
2069    call MatForwardSolve(A,x,x).
2070 
2071    Most users should employ the simplified KSP interface for linear solvers
2072    instead of working directly with matrix algebra routines such as this.
2073    See, e.g., KSPCreate().
2074 
2075    Level: developer
2076 
2077    Concepts: matrices^forward solves
2078 
2079 .seealso: MatSolve(), MatBackwardSolve()
2080 @ */
2081 int MatForwardSolve(Mat mat,Vec b,Vec x)
2082 {
2083   int ierr;
2084 
2085   PetscFunctionBegin;
2086   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2087   PetscValidType(mat,1);
2088   MatPreallocated(mat);
2089   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2090   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2091   PetscCheckSameComm(mat,1,b,2);
2092   PetscCheckSameComm(mat,1,x,3);
2093   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2094   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2095   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2096   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2097   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2098   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2099 
2100   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2101   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
2102   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2103   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2104   PetscFunctionReturn(0);
2105 }
2106 
2107 #undef __FUNCT__
2108 #define __FUNCT__ "MatBackwardSolve"
2109 /* @
2110    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2111 
2112    Collective on Mat and Vec
2113 
2114    Input Parameters:
2115 +  mat - the factored matrix
2116 -  b - the right-hand-side vector
2117 
2118    Output Parameter:
2119 .  x - the result vector
2120 
2121    Notes:
2122    MatSolve() should be used for most applications, as it performs
2123    a forward solve followed by a backward solve.
2124 
2125    The vectors b and x cannot be the same.  I.e., one cannot
2126    call MatBackwardSolve(A,x,x).
2127 
2128    Most users should employ the simplified KSP interface for linear solvers
2129    instead of working directly with matrix algebra routines such as this.
2130    See, e.g., KSPCreate().
2131 
2132    Level: developer
2133 
2134    Concepts: matrices^backward solves
2135 
2136 .seealso: MatSolve(), MatForwardSolve()
2137 @ */
2138 int MatBackwardSolve(Mat mat,Vec b,Vec x)
2139 {
2140   int ierr;
2141 
2142   PetscFunctionBegin;
2143   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2144   PetscValidType(mat,1);
2145   MatPreallocated(mat);
2146   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2147   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2148   PetscCheckSameComm(mat,1,b,2);
2149   PetscCheckSameComm(mat,1,x,3);
2150   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2151   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2152   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2153   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2154   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2155   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2156 
2157   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2158   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
2159   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2160   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2161   PetscFunctionReturn(0);
2162 }
2163 
2164 #undef __FUNCT__
2165 #define __FUNCT__ "MatSolveAdd"
2166 /*@
2167    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2168 
2169    Collective on Mat and Vec
2170 
2171    Input Parameters:
2172 +  mat - the factored matrix
2173 .  b - the right-hand-side vector
2174 -  y - the vector to be added to
2175 
2176    Output Parameter:
2177 .  x - the result vector
2178 
2179    Notes:
2180    The vectors b and x cannot be the same.  I.e., one cannot
2181    call MatSolveAdd(A,x,y,x).
2182 
2183    Most users should employ the simplified KSP interface for linear solvers
2184    instead of working directly with matrix algebra routines such as this.
2185    See, e.g., KSPCreate().
2186 
2187    Level: developer
2188 
2189    Concepts: matrices^triangular solves
2190 
2191 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2192 @*/
2193 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2194 {
2195   PetscScalar one = 1.0;
2196   Vec    tmp;
2197   int    ierr;
2198 
2199   PetscFunctionBegin;
2200   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2201   PetscValidType(mat,1);
2202   MatPreallocated(mat);
2203   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2204   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2205   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2206   PetscCheckSameComm(mat,1,b,2);
2207   PetscCheckSameComm(mat,1,y,2);
2208   PetscCheckSameComm(mat,1,x,3);
2209   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2210   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2211   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2212   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2213   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
2214   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2215   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2216 
2217   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2218   if (mat->ops->solveadd)  {
2219     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2220   } else {
2221     /* do the solve then the add manually */
2222     if (x != y) {
2223       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2224       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2225     } else {
2226       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2227       PetscLogObjectParent(mat,tmp);
2228       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2229       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2230       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2231       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2232     }
2233   }
2234   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2235   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2236   PetscFunctionReturn(0);
2237 }
2238 
2239 #undef __FUNCT__
2240 #define __FUNCT__ "MatSolveTranspose"
2241 /*@
2242    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2243 
2244    Collective on Mat and Vec
2245 
2246    Input Parameters:
2247 +  mat - the factored matrix
2248 -  b - the right-hand-side vector
2249 
2250    Output Parameter:
2251 .  x - the result vector
2252 
2253    Notes:
2254    The vectors b and x cannot be the same.  I.e., one cannot
2255    call MatSolveTranspose(A,x,x).
2256 
2257    Most users should employ the simplified KSP interface for linear solvers
2258    instead of working directly with matrix algebra routines such as this.
2259    See, e.g., KSPCreate().
2260 
2261    Level: developer
2262 
2263    Concepts: matrices^triangular solves
2264 
2265 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2266 @*/
2267 int MatSolveTranspose(Mat mat,Vec b,Vec x)
2268 {
2269   int ierr;
2270 
2271   PetscFunctionBegin;
2272   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2273   PetscValidType(mat,1);
2274   MatPreallocated(mat);
2275   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2276   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2277   PetscCheckSameComm(mat,1,b,2);
2278   PetscCheckSameComm(mat,1,x,3);
2279   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2280   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2281   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name);
2282   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2283   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2284 
2285   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2286   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2287   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2288   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2289   PetscFunctionReturn(0);
2290 }
2291 
2292 #undef __FUNCT__
2293 #define __FUNCT__ "MatSolveTransposeAdd"
2294 /*@
2295    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2296                       factored matrix.
2297 
2298    Collective on Mat and Vec
2299 
2300    Input Parameters:
2301 +  mat - the factored matrix
2302 .  b - the right-hand-side vector
2303 -  y - the vector to be added to
2304 
2305    Output Parameter:
2306 .  x - the result vector
2307 
2308    Notes:
2309    The vectors b and x cannot be the same.  I.e., one cannot
2310    call MatSolveTransposeAdd(A,x,y,x).
2311 
2312    Most users should employ the simplified KSP interface for linear solvers
2313    instead of working directly with matrix algebra routines such as this.
2314    See, e.g., KSPCreate().
2315 
2316    Level: developer
2317 
2318    Concepts: matrices^triangular solves
2319 
2320 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2321 @*/
2322 int MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2323 {
2324   PetscScalar one = 1.0;
2325   int         ierr;
2326   Vec         tmp;
2327 
2328   PetscFunctionBegin;
2329   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2330   PetscValidType(mat,1);
2331   MatPreallocated(mat);
2332   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2333   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2334   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2335   PetscCheckSameComm(mat,1,b,2);
2336   PetscCheckSameComm(mat,1,y,3);
2337   PetscCheckSameComm(mat,1,x,4);
2338   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2339   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2340   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2341   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2342   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
2343   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2344 
2345   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2346   if (mat->ops->solvetransposeadd) {
2347     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
2348   } else {
2349     /* do the solve then the add manually */
2350     if (x != y) {
2351       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2352       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2353     } else {
2354       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2355       PetscLogObjectParent(mat,tmp);
2356       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2357       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2358       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2359       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2360     }
2361   }
2362   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2363   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2364   PetscFunctionReturn(0);
2365 }
2366 /* ----------------------------------------------------------------*/
2367 
2368 #undef __FUNCT__
2369 #define __FUNCT__ "MatRelax"
2370 /*@
2371    MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2372 
2373    Collective on Mat and Vec
2374 
2375    Input Parameters:
2376 +  mat - the matrix
2377 .  b - the right hand side
2378 .  omega - the relaxation factor
2379 .  flag - flag indicating the type of SOR (see below)
2380 .  shift -  diagonal shift
2381 -  its - the number of iterations
2382 -  lits - the number of local iterations
2383 
2384    Output Parameters:
2385 .  x - the solution (can contain an initial guess)
2386 
2387    SOR Flags:
2388 .     SOR_FORWARD_SWEEP - forward SOR
2389 .     SOR_BACKWARD_SWEEP - backward SOR
2390 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2391 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
2392 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
2393 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2394 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
2395          upper/lower triangular part of matrix to
2396          vector (with omega)
2397 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
2398 
2399    Notes:
2400    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2401    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
2402    on each processor.
2403 
2404    Application programmers will not generally use MatRelax() directly,
2405    but instead will employ the KSP/PC interface.
2406 
2407    Notes for Advanced Users:
2408    The flags are implemented as bitwise inclusive or operations.
2409    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2410    to specify a zero initial guess for SSOR.
2411 
2412    Most users should employ the simplified KSP interface for linear solvers
2413    instead of working directly with matrix algebra routines such as this.
2414    See, e.g., KSPCreate().
2415 
2416    See also, MatPBRelax(). This routine will automatically call the point block
2417    version if the point version is not available.
2418 
2419    Level: developer
2420 
2421    Concepts: matrices^relaxation
2422    Concepts: matrices^SOR
2423    Concepts: matrices^Gauss-Seidel
2424 
2425 @*/
2426 int MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x)
2427 {
2428   int ierr;
2429 
2430   PetscFunctionBegin;
2431   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2432   PetscValidType(mat,1);
2433   MatPreallocated(mat);
2434   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2435   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
2436   PetscCheckSameComm(mat,1,b,2);
2437   PetscCheckSameComm(mat,1,x,8);
2438   if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2439   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2440   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2441   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2442   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2443   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2444 
2445   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2446   if (mat->ops->relax) {
2447     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2448   } else {
2449     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2450   }
2451   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2452   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2453   PetscFunctionReturn(0);
2454 }
2455 
2456 #undef __FUNCT__
2457 #define __FUNCT__ "MatPBRelax"
2458 /*@
2459    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2460 
2461    Collective on Mat and Vec
2462 
2463    See MatRelax() for usage
2464 
2465    For multi-component PDEs where the Jacobian is stored in a point block format
2466    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
2467    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
2468    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
2469 
2470    Level: developer
2471 
2472 @*/
2473 int MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x)
2474 {
2475   int ierr;
2476 
2477   PetscFunctionBegin;
2478   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2479   PetscValidType(mat,1);
2480   MatPreallocated(mat);
2481   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2482   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
2483   PetscCheckSameComm(mat,1,b,2);
2484   PetscCheckSameComm(mat,1,x,8);
2485   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2486   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2487   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2488   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2489   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2490   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2491 
2492   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2493   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2494   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2495   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2496   PetscFunctionReturn(0);
2497 }
2498 
2499 #undef __FUNCT__
2500 #define __FUNCT__ "MatCopy_Basic"
2501 /*
2502       Default matrix copy routine.
2503 */
2504 int MatCopy_Basic(Mat A,Mat B,MatStructure str)
2505 {
2506   int         ierr,i,rstart,rend,nz,*cwork;
2507   PetscScalar *vwork;
2508 
2509   PetscFunctionBegin;
2510   ierr = MatZeroEntries(B);CHKERRQ(ierr);
2511   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
2512   for (i=rstart; i<rend; i++) {
2513     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2514     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
2515     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2516   }
2517   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2518   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2519   ierr = PetscObjectIncreaseState((PetscObject)B); CHKERRQ(ierr);
2520   PetscFunctionReturn(0);
2521 }
2522 
2523 #undef __FUNCT__
2524 #define __FUNCT__ "MatCopy"
2525 /*@C
2526    MatCopy - Copys a matrix to another matrix.
2527 
2528    Collective on Mat
2529 
2530    Input Parameters:
2531 +  A - the matrix
2532 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
2533 
2534    Output Parameter:
2535 .  B - where the copy is put
2536 
2537    Notes:
2538    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
2539    same nonzero pattern or the routine will crash.
2540 
2541    MatCopy() copies the matrix entries of a matrix to another existing
2542    matrix (after first zeroing the second matrix).  A related routine is
2543    MatConvert(), which first creates a new matrix and then copies the data.
2544 
2545    Level: intermediate
2546 
2547    Concepts: matrices^copying
2548 
2549 .seealso: MatConvert(), MatDuplicate()
2550 
2551 @*/
2552 int MatCopy(Mat A,Mat B,MatStructure str)
2553 {
2554   int ierr;
2555 
2556   PetscFunctionBegin;
2557   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
2558   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
2559   PetscValidType(A,1);
2560   MatPreallocated(A);
2561   PetscValidType(B,2);
2562   MatPreallocated(B);
2563   PetscCheckSameComm(A,1,B,2);
2564   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2565   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2566   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%d,%d) (%d,%d)",A->M,B->M,
2567                                              A->N,B->N);
2568 
2569   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2570   if (A->ops->copy) {
2571     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
2572   } else { /* generic conversion */
2573     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2574   }
2575   if (A->mapping) {
2576     if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);B->mapping = 0;}
2577     ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr);
2578   }
2579   if (A->bmapping) {
2580     if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);B->bmapping = 0;}
2581     ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr);
2582   }
2583   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2584   ierr = PetscObjectIncreaseState((PetscObject)B); CHKERRQ(ierr);
2585   PetscFunctionReturn(0);
2586 }
2587 
2588 #include "petscsys.h"
2589 PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
2590 PetscFList MatConvertList              = 0;
2591 
2592 #undef __FUNCT__
2593 #define __FUNCT__ "MatConvertRegister"
2594 /*@C
2595     MatConvertRegister - Allows one to register a routine that converts a sparse matrix
2596         from one format to another.
2597 
2598   Not Collective
2599 
2600   Input Parameters:
2601 +   type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ.
2602 -   Converter - the function that reads the matrix from the binary file.
2603 
2604   Level: developer
2605 
2606 .seealso: MatConvertRegisterAll(), MatConvert()
2607 
2608 @*/
2609 int MatConvertRegister(const char sname[],const char path[],const char name[],int (*function)(Mat,MatType,Mat*))
2610 {
2611   int  ierr;
2612   char fullname[PETSC_MAX_PATH_LEN];
2613 
2614   PetscFunctionBegin;
2615   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
2616   ierr = PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
2617   PetscFunctionReturn(0);
2618 }
2619 
2620 #undef __FUNCT__
2621 #define __FUNCT__ "MatConvert"
2622 /*@C
2623    MatConvert - Converts a matrix to another matrix, either of the same
2624    or different type.
2625 
2626    Collective on Mat
2627 
2628    Input Parameters:
2629 +  mat - the matrix
2630 -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
2631    same type as the original matrix.
2632 
2633    Output Parameter:
2634 .  M - pointer to place new matrix
2635 
2636    Notes:
2637    MatConvert() first creates a new matrix and then copies the data from
2638    the first matrix.  A related routine is MatCopy(), which copies the matrix
2639    entries of one matrix to another already existing matrix context.
2640 
2641    Level: intermediate
2642 
2643    Concepts: matrices^converting between storage formats
2644 
2645 .seealso: MatCopy(), MatDuplicate()
2646 @*/
2647 int MatConvert(Mat mat,const MatType newtype,Mat *M)
2648 {
2649   int        ierr;
2650   PetscTruth sametype,issame,flg;
2651   char       convname[256],mtype[256];
2652 
2653   PetscFunctionBegin;
2654   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2655   PetscValidType(mat,1);
2656   MatPreallocated(mat);
2657   PetscValidPointer(M,3);
2658   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2659   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2660 
2661   ierr = PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
2662   if (flg) {
2663     newtype = mtype;
2664   }
2665   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2666 
2667   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
2668   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
2669   if ((sametype || issame) && mat->ops->duplicate) {
2670     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
2671   } else {
2672     int (*conv)(Mat,const MatType,Mat*)=PETSC_NULL;
2673     /*
2674        Order of precedence:
2675        1) See if a specialized converter is known to the current matrix.
2676        2) See if a specialized converter is known to the desired matrix class.
2677        3) See if a good general converter is registered for the desired class
2678           (as of 6/27/03 only MATMPIADJ falls into this category).
2679        4) See if a good general converter is known for the current matrix.
2680        5) Use a really basic converter.
2681     */
2682     ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
2683     ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
2684     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
2685     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
2686     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
2687     ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
2688     if (!conv) {
2689       Mat B;
2690       ierr = MatCreate(mat->comm,0,0,0,0,&B);CHKERRQ(ierr);
2691       ierr = MatSetType(B,newtype);CHKERRQ(ierr);
2692       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
2693       ierr = MatDestroy(B);CHKERRQ(ierr);
2694       if (!conv) {
2695         if (!MatConvertRegisterAllCalled) {
2696           ierr = MatConvertRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2697         }
2698         ierr = PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);CHKERRQ(ierr);
2699         if (!conv) {
2700           if (mat->ops->convert) {
2701             conv = mat->ops->convert;
2702           } else {
2703             conv = MatConvert_Basic;
2704           }
2705         }
2706       }
2707     }
2708     ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr);
2709   }
2710   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2711   ierr = PetscObjectIncreaseState((PetscObject)*M); CHKERRQ(ierr);
2712   PetscFunctionReturn(0);
2713 }
2714 
2715 
2716 #undef __FUNCT__
2717 #define __FUNCT__ "MatDuplicate"
2718 /*@C
2719    MatDuplicate - Duplicates a matrix including the non-zero structure.
2720 
2721    Collective on Mat
2722 
2723    Input Parameters:
2724 +  mat - the matrix
2725 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
2726         values as well or not
2727 
2728    Output Parameter:
2729 .  M - pointer to place new matrix
2730 
2731    Level: intermediate
2732 
2733    Concepts: matrices^duplicating
2734 
2735 .seealso: MatCopy(), MatConvert()
2736 @*/
2737 int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
2738 {
2739   int ierr;
2740 
2741   PetscFunctionBegin;
2742   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2743   PetscValidType(mat,1);
2744   MatPreallocated(mat);
2745   PetscValidPointer(M,3);
2746   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2747   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2748 
2749   *M  = 0;
2750   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2751   if (!mat->ops->duplicate) {
2752     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
2753   }
2754   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
2755   if (mat->mapping) {
2756     ierr = MatSetLocalToGlobalMapping(*M,mat->mapping);CHKERRQ(ierr);
2757   }
2758   if (mat->bmapping) {
2759     ierr = MatSetLocalToGlobalMappingBlock(*M,mat->mapping);CHKERRQ(ierr);
2760   }
2761   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2762   ierr = PetscObjectIncreaseState((PetscObject)*M); CHKERRQ(ierr);
2763   PetscFunctionReturn(0);
2764 }
2765 
2766 #undef __FUNCT__
2767 #define __FUNCT__ "MatGetDiagonal"
2768 /*@
2769    MatGetDiagonal - Gets the diagonal of a matrix.
2770 
2771    Collective on Mat and Vec
2772 
2773    Input Parameters:
2774 +  mat - the matrix
2775 -  v - the vector for storing the diagonal
2776 
2777    Output Parameter:
2778 .  v - the diagonal of the matrix
2779 
2780    Notes:
2781    For the SeqAIJ matrix format, this routine may also be called
2782    on a LU factored matrix; in that case it routines the reciprocal of
2783    the diagonal entries in U. It returns the entries permuted by the
2784    row and column permutation used during the symbolic factorization.
2785 
2786    Level: intermediate
2787 
2788    Concepts: matrices^accessing diagonals
2789 
2790 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
2791 @*/
2792 int MatGetDiagonal(Mat mat,Vec v)
2793 {
2794   int ierr;
2795 
2796   PetscFunctionBegin;
2797   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2798   PetscValidType(mat,1);
2799   MatPreallocated(mat);
2800   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
2801   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2802   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2803 
2804   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
2805   ierr = PetscObjectIncreaseState((PetscObject)v); CHKERRQ(ierr);
2806   PetscFunctionReturn(0);
2807 }
2808 
2809 #undef __FUNCT__
2810 #define __FUNCT__ "MatGetRowMax"
2811 /*@
2812    MatGetRowMax - Gets the maximum value (in absolute value) of each
2813         row of the matrix
2814 
2815    Collective on Mat and Vec
2816 
2817    Input Parameters:
2818 .  mat - the matrix
2819 
2820    Output Parameter:
2821 .  v - the vector for storing the maximums
2822 
2823    Level: intermediate
2824 
2825    Concepts: matrices^getting row maximums
2826 
2827 .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
2828 @*/
2829 int MatGetRowMax(Mat mat,Vec v)
2830 {
2831   int ierr;
2832 
2833   PetscFunctionBegin;
2834   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2835   PetscValidType(mat,1);
2836   MatPreallocated(mat);
2837   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
2838   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2839   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2840 
2841   ierr = (*mat->ops->getrowmax)(mat,v);CHKERRQ(ierr);
2842   ierr = PetscObjectIncreaseState((PetscObject)v); CHKERRQ(ierr);
2843   PetscFunctionReturn(0);
2844 }
2845 
2846 #undef __FUNCT__
2847 #define __FUNCT__ "MatTranspose"
2848 /*@C
2849    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
2850 
2851    Collective on Mat
2852 
2853    Input Parameter:
2854 .  mat - the matrix to transpose
2855 
2856    Output Parameters:
2857 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
2858 
2859    Level: intermediate
2860 
2861    Concepts: matrices^transposing
2862 
2863 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
2864 @*/
2865 int MatTranspose(Mat mat,Mat *B)
2866 {
2867   int ierr;
2868 
2869   PetscFunctionBegin;
2870   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2871   PetscValidType(mat,1);
2872   MatPreallocated(mat);
2873   PetscValidPointer(B,2);
2874   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2875   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2876   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2877 
2878   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
2879   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
2880   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
2881   if (B) {ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);}
2882   PetscFunctionReturn(0);
2883 }
2884 
2885 #undef __FUNCT__
2886 #define __FUNCT__ "MatIsTranspose"
2887 /*@C
2888    MatIsTranspose - Test whether a matrix is another one's transpose,
2889         or its own, in which case it tests symmetry.
2890 
2891    Collective on Mat
2892 
2893    Input Parameter:
2894 +  A - the matrix to test
2895 -  B - the matrix to test against, this can equal the first parameter
2896 
2897    Output Parameters:
2898 .  flg - the result
2899 
2900    Notes:
2901    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
2902    has a running time of the order of the number of nonzeros; the parallel
2903    test involves parallel copies of the block-offdiagonal parts of the matrix.
2904 
2905    Level: intermediate
2906 
2907    Concepts: matrices^transposing, matrix^symmetry
2908 
2909 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
2910 @*/
2911 int MatIsTranspose(Mat A,Mat B,PetscTruth *flg)
2912 {
2913   int ierr,(*f)(Mat,Mat,PetscTruth*),(*g)(Mat,Mat,PetscTruth*);
2914 
2915   PetscFunctionBegin;
2916   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
2917   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
2918   PetscValidPointer(flg,3);
2919   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
2920   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
2921   if (f && g) {
2922     if (f==g) {
2923       ierr = (*f)(A,B,flg);CHKERRQ(ierr);
2924     } else {
2925       SETERRQ(1,"Matrices do not have the same comparator for symmetry test");
2926     }
2927   }
2928   PetscFunctionReturn(0);
2929 }
2930 
2931 #undef __FUNCT__
2932 #define __FUNCT__ "MatPermute"
2933 /*@C
2934    MatPermute - Creates a new matrix with rows and columns permuted from the
2935    original.
2936 
2937    Collective on Mat
2938 
2939    Input Parameters:
2940 +  mat - the matrix to permute
2941 .  row - row permutation, each processor supplies only the permutation for its rows
2942 -  col - column permutation, each processor needs the entire column permutation, that is
2943          this is the same size as the total number of columns in the matrix
2944 
2945    Output Parameters:
2946 .  B - the permuted matrix
2947 
2948    Level: advanced
2949 
2950    Concepts: matrices^permuting
2951 
2952 .seealso: MatGetOrdering()
2953 @*/
2954 int MatPermute(Mat mat,IS row,IS col,Mat *B)
2955 {
2956   int ierr;
2957 
2958   PetscFunctionBegin;
2959   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2960   PetscValidType(mat,1);
2961   MatPreallocated(mat);
2962   PetscValidHeaderSpecific(row,IS_COOKIE,2);
2963   PetscValidHeaderSpecific(col,IS_COOKIE,3);
2964   PetscValidPointer(B,4);
2965   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2966   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2967   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2968   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
2969   ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);
2970   PetscFunctionReturn(0);
2971 }
2972 
2973 #undef __FUNCT__
2974 #define __FUNCT__ "MatPermuteSparsify"
2975 /*@C
2976   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
2977   original and sparsified to the prescribed tolerance.
2978 
2979   Collective on Mat
2980 
2981   Input Parameters:
2982 + A    - The matrix to permute
2983 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
2984 . frac - The half-bandwidth as a fraction of the total size, or 0.0
2985 . tol  - The drop tolerance
2986 . rowp - The row permutation
2987 - colp - The column permutation
2988 
2989   Output Parameter:
2990 . B    - The permuted, sparsified matrix
2991 
2992   Level: advanced
2993 
2994   Note:
2995   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
2996   restrict the half-bandwidth of the resulting matrix to 5% of the
2997   total matrix size.
2998 
2999 .keywords: matrix, permute, sparsify
3000 
3001 .seealso: MatGetOrdering(), MatPermute()
3002 @*/
3003 int MatPermuteSparsify(Mat A, int band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
3004 {
3005   IS           irowp, icolp;
3006   int         *rows, *cols;
3007   int          M, N, locRowStart, locRowEnd;
3008   int          nz, newNz;
3009   int         *cwork, *cnew;
3010   PetscScalar *vwork, *vnew;
3011   int          bw, size;
3012   int          row, locRow, newRow, col, newCol;
3013   int          ierr;
3014 
3015   PetscFunctionBegin;
3016   PetscValidHeaderSpecific(A,    MAT_COOKIE,1);
3017   PetscValidHeaderSpecific(rowp, IS_COOKIE,5);
3018   PetscValidHeaderSpecific(colp, IS_COOKIE,6);
3019   PetscValidPointer(B,7);
3020   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
3021   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
3022   if (!A->ops->permutesparsify) {
3023     ierr = MatGetSize(A, &M, &N);                                                                         CHKERRQ(ierr);
3024     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);                                             CHKERRQ(ierr);
3025     ierr = ISGetSize(rowp, &size);                                                                        CHKERRQ(ierr);
3026     if (size != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for row permutation, should be %d", size, M);
3027     ierr = ISGetSize(colp, &size);                                                                        CHKERRQ(ierr);
3028     if (size != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for column permutation, should be %d", size, N);
3029     ierr = ISInvertPermutation(rowp, 0, &irowp);                                                          CHKERRQ(ierr);
3030     ierr = ISGetIndices(irowp, &rows);                                                                    CHKERRQ(ierr);
3031     ierr = ISInvertPermutation(colp, 0, &icolp);                                                          CHKERRQ(ierr);
3032     ierr = ISGetIndices(icolp, &cols);                                                                    CHKERRQ(ierr);
3033     ierr = PetscMalloc(N * sizeof(int),         &cnew);                                                   CHKERRQ(ierr);
3034     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);                                                   CHKERRQ(ierr);
3035 
3036     /* Setup bandwidth to include */
3037     if (band == PETSC_DECIDE) {
3038       if (frac <= 0.0)
3039         bw = (int) (M * 0.05);
3040       else
3041         bw = (int) (M * frac);
3042     } else {
3043       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
3044       bw = band;
3045     }
3046 
3047     /* Put values into new matrix */
3048     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);                                                    CHKERRQ(ierr);
3049     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
3050       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);                                                      CHKERRQ(ierr);
3051       newRow   = rows[locRow]+locRowStart;
3052       for(col = 0, newNz = 0; col < nz; col++) {
3053         newCol = cols[cwork[col]];
3054         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
3055           cnew[newNz] = newCol;
3056           vnew[newNz] = vwork[col];
3057           newNz++;
3058         }
3059       }
3060       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);                              CHKERRQ(ierr);
3061       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);                                                  CHKERRQ(ierr);
3062     }
3063     ierr = PetscFree(cnew);                                                                               CHKERRQ(ierr);
3064     ierr = PetscFree(vnew);                                                                               CHKERRQ(ierr);
3065     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);                                                      CHKERRQ(ierr);
3066     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);                                                        CHKERRQ(ierr);
3067     ierr = ISRestoreIndices(irowp, &rows);                                                                CHKERRQ(ierr);
3068     ierr = ISRestoreIndices(icolp, &cols);                                                                CHKERRQ(ierr);
3069     ierr = ISDestroy(irowp);                                                                              CHKERRQ(ierr);
3070     ierr = ISDestroy(icolp);                                                                              CHKERRQ(ierr);
3071   } else {
3072     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);                                 CHKERRQ(ierr);
3073   }
3074   ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);
3075   PetscFunctionReturn(0);
3076 }
3077 
3078 #undef __FUNCT__
3079 #define __FUNCT__ "MatEqual"
3080 /*@
3081    MatEqual - Compares two matrices.
3082 
3083    Collective on Mat
3084 
3085    Input Parameters:
3086 +  A - the first matrix
3087 -  B - the second matrix
3088 
3089    Output Parameter:
3090 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
3091 
3092    Level: intermediate
3093 
3094    Concepts: matrices^equality between
3095 @*/
3096 int MatEqual(Mat A,Mat B,PetscTruth *flg)
3097 {
3098   int ierr;
3099 
3100   PetscFunctionBegin;
3101   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3102   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3103   PetscValidType(A,1);
3104   MatPreallocated(A);
3105   PetscValidType(B,2);
3106   MatPreallocated(B);
3107   PetscValidIntPointer(flg,3);
3108   PetscCheckSameComm(A,1,B,2);
3109   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3110   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3111   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %d %d %d %d",A->M,B->M,A->N,B->N);
3112   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
3113   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",B->type_name);
3114   if (A->ops->equal != B->ops->equal) SETERRQ2(PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",A->type_name,B->type_name);
3115   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
3116   PetscFunctionReturn(0);
3117 }
3118 
3119 #undef __FUNCT__
3120 #define __FUNCT__ "MatDiagonalScale"
3121 /*@
3122    MatDiagonalScale - Scales a matrix on the left and right by diagonal
3123    matrices that are stored as vectors.  Either of the two scaling
3124    matrices can be PETSC_NULL.
3125 
3126    Collective on Mat
3127 
3128    Input Parameters:
3129 +  mat - the matrix to be scaled
3130 .  l - the left scaling vector (or PETSC_NULL)
3131 -  r - the right scaling vector (or PETSC_NULL)
3132 
3133    Notes:
3134    MatDiagonalScale() computes A = LAR, where
3135    L = a diagonal matrix, R = a diagonal matrix
3136 
3137    Level: intermediate
3138 
3139    Concepts: matrices^diagonal scaling
3140    Concepts: diagonal scaling of matrices
3141 
3142 .seealso: MatScale()
3143 @*/
3144 int MatDiagonalScale(Mat mat,Vec l,Vec r)
3145 {
3146   int ierr;
3147 
3148   PetscFunctionBegin;
3149   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3150   PetscValidType(mat,1);
3151   MatPreallocated(mat);
3152   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3153   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE,2);PetscCheckSameComm(mat,1,l,2);}
3154   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE,3);PetscCheckSameComm(mat,1,r,3);}
3155   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3156   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3157 
3158   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3159   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
3160   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3161   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3162   PetscFunctionReturn(0);
3163 }
3164 
3165 #undef __FUNCT__
3166 #define __FUNCT__ "MatScale"
3167 /*@
3168     MatScale - Scales all elements of a matrix by a given number.
3169 
3170     Collective on Mat
3171 
3172     Input Parameters:
3173 +   mat - the matrix to be scaled
3174 -   a  - the scaling value
3175 
3176     Output Parameter:
3177 .   mat - the scaled matrix
3178 
3179     Level: intermediate
3180 
3181     Concepts: matrices^scaling all entries
3182 
3183 .seealso: MatDiagonalScale()
3184 @*/
3185 int MatScale(const PetscScalar *a,Mat mat)
3186 {
3187   int ierr;
3188 
3189   PetscFunctionBegin;
3190   PetscValidScalarPointer(a,1);
3191   PetscValidHeaderSpecific(mat,MAT_COOKIE,2);
3192   PetscValidType(mat,2);
3193   MatPreallocated(mat);
3194   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3195   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3196   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3197 
3198   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3199   ierr = (*mat->ops->scale)(a,mat);CHKERRQ(ierr);
3200   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3201   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3202   PetscFunctionReturn(0);
3203 }
3204 
3205 #undef __FUNCT__
3206 #define __FUNCT__ "MatNorm"
3207 /*@
3208    MatNorm - Calculates various norms of a matrix.
3209 
3210    Collective on Mat
3211 
3212    Input Parameters:
3213 +  mat - the matrix
3214 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
3215 
3216    Output Parameters:
3217 .  nrm - the resulting norm
3218 
3219    Level: intermediate
3220 
3221    Concepts: matrices^norm
3222    Concepts: norm^of matrix
3223 @*/
3224 int MatNorm(Mat mat,NormType type,PetscReal *nrm)
3225 {
3226   int ierr;
3227 
3228   PetscFunctionBegin;
3229   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3230   PetscValidType(mat,1);
3231   MatPreallocated(mat);
3232   PetscValidScalarPointer(nrm,3);
3233 
3234   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3235   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3236   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3237   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
3238   PetscFunctionReturn(0);
3239 }
3240 
3241 /*
3242      This variable is used to prevent counting of MatAssemblyBegin() that
3243    are called from within a MatAssemblyEnd().
3244 */
3245 static int MatAssemblyEnd_InUse = 0;
3246 #undef __FUNCT__
3247 #define __FUNCT__ "MatAssemblyBegin"
3248 /*@
3249    MatAssemblyBegin - Begins assembling the matrix.  This routine should
3250    be called after completing all calls to MatSetValues().
3251 
3252    Collective on Mat
3253 
3254    Input Parameters:
3255 +  mat - the matrix
3256 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3257 
3258    Notes:
3259    MatSetValues() generally caches the values.  The matrix is ready to
3260    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3261    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3262    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3263    using the matrix.
3264 
3265    Level: beginner
3266 
3267    Concepts: matrices^assembling
3268 
3269 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
3270 @*/
3271 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
3272 {
3273   int ierr;
3274 
3275   PetscFunctionBegin;
3276   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3277   PetscValidType(mat,1);
3278   MatPreallocated(mat);
3279   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
3280   if (mat->assembled) {
3281     mat->was_assembled = PETSC_TRUE;
3282     mat->assembled     = PETSC_FALSE;
3283   }
3284   if (!MatAssemblyEnd_InUse) {
3285     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3286     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3287     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3288   } else {
3289     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3290   }
3291   PetscFunctionReturn(0);
3292 }
3293 
3294 #undef __FUNCT__
3295 #define __FUNCT__ "MatAssembed"
3296 /*@
3297    MatAssembled - Indicates if a matrix has been assembled and is ready for
3298      use; for example, in matrix-vector product.
3299 
3300    Collective on Mat
3301 
3302    Input Parameter:
3303 .  mat - the matrix
3304 
3305    Output Parameter:
3306 .  assembled - PETSC_TRUE or PETSC_FALSE
3307 
3308    Level: advanced
3309 
3310    Concepts: matrices^assembled?
3311 
3312 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
3313 @*/
3314 int MatAssembled(Mat mat,PetscTruth *assembled)
3315 {
3316   PetscFunctionBegin;
3317   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3318   PetscValidType(mat,1);
3319   MatPreallocated(mat);
3320   PetscValidPointer(assembled,2);
3321   *assembled = mat->assembled;
3322   PetscFunctionReturn(0);
3323 }
3324 
3325 #undef __FUNCT__
3326 #define __FUNCT__ "MatView_Private"
3327 /*
3328     Processes command line options to determine if/how a matrix
3329   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
3330 */
3331 int MatView_Private(Mat mat)
3332 {
3333   int               ierr;
3334   PetscTruth        flg;
3335   static PetscTruth incall = PETSC_FALSE;
3336 
3337   PetscFunctionBegin;
3338   if (incall) PetscFunctionReturn(0);
3339   incall = PETSC_TRUE;
3340   ierr = PetscOptionsBegin(mat->comm,mat->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
3341     ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg);CHKERRQ(ierr);
3342     if (flg) {
3343       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
3344       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3345       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3346     }
3347     ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg);CHKERRQ(ierr);
3348     if (flg) {
3349       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
3350       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3351       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3352     }
3353     ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg);CHKERRQ(ierr);
3354     if (flg) {
3355       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3356     }
3357     ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg);CHKERRQ(ierr);
3358     if (flg) {
3359       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
3360       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3361       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3362     }
3363     ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg);CHKERRQ(ierr);
3364     if (flg) {
3365       ierr = MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3366       ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3367     }
3368     ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg);CHKERRQ(ierr);
3369     if (flg) {
3370       ierr = MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3371       ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3372     }
3373   ierr = PetscOptionsEnd();CHKERRQ(ierr);
3374   /* cannot have inside PetscOptionsBegin() because uses PetscOptionsBegin() */
3375   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);CHKERRQ(ierr);
3376   if (flg) {
3377     ierr = PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);CHKERRQ(ierr);
3378     if (flg) {
3379       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
3380     }
3381     ierr = MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3382     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3383     if (flg) {
3384       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3385     }
3386   }
3387   incall = PETSC_FALSE;
3388   PetscFunctionReturn(0);
3389 }
3390 
3391 #undef __FUNCT__
3392 #define __FUNCT__ "MatAssemblyEnd"
3393 /*@
3394    MatAssemblyEnd - Completes assembling the matrix.  This routine should
3395    be called after MatAssemblyBegin().
3396 
3397    Collective on Mat
3398 
3399    Input Parameters:
3400 +  mat - the matrix
3401 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3402 
3403    Options Database Keys:
3404 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3405 .  -mat_view_info_detailed - Prints more detailed info
3406 .  -mat_view - Prints matrix in ASCII format
3407 .  -mat_view_matlab - Prints matrix in Matlab format
3408 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3409 .  -display <name> - Sets display name (default is host)
3410 .  -draw_pause <sec> - Sets number of seconds to pause after display
3411 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
3412 .  -viewer_socket_machine <machine>
3413 .  -viewer_socket_port <port>
3414 .  -mat_view_binary - save matrix to file in binary format
3415 -  -viewer_binary_filename <name>
3416 
3417    Notes:
3418    MatSetValues() generally caches the values.  The matrix is ready to
3419    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3420    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3421    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3422    using the matrix.
3423 
3424    Level: beginner
3425 
3426 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
3427 @*/
3428 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
3429 {
3430   int        ierr;
3431   static int inassm = 0;
3432   PetscTruth flg;
3433 
3434   PetscFunctionBegin;
3435   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3436   PetscValidType(mat,1);
3437   MatPreallocated(mat);
3438 
3439   inassm++;
3440   MatAssemblyEnd_InUse++;
3441   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3442     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3443     if (mat->ops->assemblyend) {
3444       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3445     }
3446     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3447   } else {
3448     if (mat->ops->assemblyend) {
3449       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3450     }
3451   }
3452 
3453   /* Flush assembly is not a true assembly */
3454   if (type != MAT_FLUSH_ASSEMBLY) {
3455     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3456   }
3457   mat->insertmode = NOT_SET_VALUES;
3458   MatAssemblyEnd_InUse--;
3459   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3460   if (!mat->symmetric_eternal) {
3461     mat->symmetric_set              = PETSC_FALSE;
3462     mat->hermitian_set              = PETSC_FALSE;
3463     mat->structurally_symmetric_set = PETSC_FALSE;
3464   }
3465   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3466     ierr = MatView_Private(mat);CHKERRQ(ierr);
3467   }
3468   inassm--;
3469   ierr = PetscOptionsHasName(mat->prefix,"-help",&flg);CHKERRQ(ierr);
3470   if (flg) {
3471     ierr = MatPrintHelp(mat);CHKERRQ(ierr);
3472   }
3473   PetscFunctionReturn(0);
3474 }
3475 
3476 
3477 #undef __FUNCT__
3478 #define __FUNCT__ "MatCompress"
3479 /*@
3480    MatCompress - Tries to store the matrix in as little space as
3481    possible.  May fail if memory is already fully used, since it
3482    tries to allocate new space.
3483 
3484    Collective on Mat
3485 
3486    Input Parameters:
3487 .  mat - the matrix
3488 
3489    Level: advanced
3490 
3491 @*/
3492 int MatCompress(Mat mat)
3493 {
3494   int ierr;
3495 
3496   PetscFunctionBegin;
3497   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3498   PetscValidType(mat,1);
3499   MatPreallocated(mat);
3500   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
3501   PetscFunctionReturn(0);
3502 }
3503 
3504 #undef __FUNCT__
3505 #define __FUNCT__ "MatSetOption"
3506 /*@
3507    MatSetOption - Sets a parameter option for a matrix. Some options
3508    may be specific to certain storage formats.  Some options
3509    determine how values will be inserted (or added). Sorted,
3510    row-oriented input will generally assemble the fastest. The default
3511    is row-oriented, nonsorted input.
3512 
3513    Collective on Mat
3514 
3515    Input Parameters:
3516 +  mat - the matrix
3517 -  option - the option, one of those listed below (and possibly others),
3518              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
3519 
3520    Options Describing Matrix Structure:
3521 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3522 .    MAT_HERMITIAN - transpose is the complex conjugation
3523 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
3524 .    MAT_NOT_SYMMETRIC - not symmetric in value
3525 .    MAT_NOT_HERMITIAN - transpose is not the complex conjugation
3526 .    MAT_NOT_STRUCTURALLY_SYMMETRIC - not symmetric nonzero structure
3527 .    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
3528                             you set to be kept with all future use of the matrix
3529                             including after MatAssemblyBegin/End() which could
3530                             potentially change the symmetry structure, i.e. you
3531                             KNOW the matrix will ALWAYS have the property you set.
3532 -    MAT_NOT_SYMMETRY_ETERNAL - if MatAssemblyBegin/End() is called then the
3533                                 flags you set will be dropped (in case potentially
3534                                 the symmetry etc was lost).
3535 
3536    Options For Use with MatSetValues():
3537    Insert a logically dense subblock, which can be
3538 +    MAT_ROW_ORIENTED - row-oriented (default)
3539 .    MAT_COLUMN_ORIENTED - column-oriented
3540 .    MAT_ROWS_SORTED - sorted by row
3541 .    MAT_ROWS_UNSORTED - not sorted by row (default)
3542 .    MAT_COLUMNS_SORTED - sorted by column
3543 -    MAT_COLUMNS_UNSORTED - not sorted by column (default)
3544 
3545    Not these options reflect the data you pass in with MatSetValues(); it has
3546    nothing to do with how the data is stored internally in the matrix
3547    data structure.
3548 
3549    When (re)assembling a matrix, we can restrict the input for
3550    efficiency/debugging purposes.  These options include
3551 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
3552         allowed if they generate a new nonzero
3553 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
3554 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
3555          they generate a nonzero in a new diagonal (for block diagonal format only)
3556 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
3557 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
3558 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
3559 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
3560 
3561    Notes:
3562    Some options are relevant only for particular matrix types and
3563    are thus ignored by others.  Other options are not supported by
3564    certain matrix types and will generate an error message if set.
3565 
3566    If using a Fortran 77 module to compute a matrix, one may need to
3567    use the column-oriented option (or convert to the row-oriented
3568    format).
3569 
3570    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
3571    that would generate a new entry in the nonzero structure is instead
3572    ignored.  Thus, if memory has not alredy been allocated for this particular
3573    data, then the insertion is ignored. For dense matrices, in which
3574    the entire array is allocated, no entries are ever ignored.
3575    Set after the first MatAssemblyEnd()
3576 
3577    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
3578    that would generate a new entry in the nonzero structure instead produces
3579    an error. (Currently supported for AIJ and BAIJ formats only.)
3580    This is a useful flag when using SAME_NONZERO_PATTERN in calling
3581    KSPSetOperators() to ensure that the nonzero pattern truely does
3582    remain unchanged. Set after the first MatAssemblyEnd()
3583 
3584    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
3585    that would generate a new entry that has not been preallocated will
3586    instead produce an error. (Currently supported for AIJ and BAIJ formats
3587    only.) This is a useful flag when debugging matrix memory preallocation.
3588 
3589    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
3590    other processors should be dropped, rather than stashed.
3591    This is useful if you know that the "owning" processor is also
3592    always generating the correct matrix entries, so that PETSc need
3593    not transfer duplicate entries generated on another processor.
3594 
3595    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
3596    searches during matrix assembly. When this flag is set, the hash table
3597    is created during the first Matrix Assembly. This hash table is
3598    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
3599    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
3600    should be used with MAT_USE_HASH_TABLE flag. This option is currently
3601    supported by MATMPIBAIJ format only.
3602 
3603    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
3604    are kept in the nonzero structure
3605 
3606    MAT_IGNORE_ZERO_ENTRIES - for AIJ matrices this will stop zero values from creating
3607    a zero location in the matrix
3608 
3609    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
3610    ROWBS matrix types
3611 
3612    MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works
3613    with AIJ and ROWBS matrix types
3614 
3615    Level: intermediate
3616 
3617    Concepts: matrices^setting options
3618 
3619 @*/
3620 int MatSetOption(Mat mat,MatOption op)
3621 {
3622   int ierr;
3623 
3624   PetscFunctionBegin;
3625   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3626   PetscValidType(mat,1);
3627   MatPreallocated(mat);
3628   switch (op) {
3629   case MAT_SYMMETRIC:
3630     mat->symmetric                  = PETSC_TRUE;
3631     mat->structurally_symmetric     = PETSC_TRUE;
3632     mat->symmetric_set              = PETSC_TRUE;
3633     mat->structurally_symmetric_set = PETSC_TRUE;
3634     break;
3635   case MAT_HERMITIAN:
3636     mat->hermitian                  = PETSC_TRUE;
3637     mat->structurally_symmetric     = PETSC_TRUE;
3638     mat->hermitian_set              = PETSC_TRUE;
3639     mat->structurally_symmetric_set = PETSC_TRUE;
3640     break;
3641   case MAT_STRUCTURALLY_SYMMETRIC:
3642     mat->structurally_symmetric     = PETSC_TRUE;
3643     mat->structurally_symmetric_set = PETSC_TRUE;
3644     break;
3645   case MAT_NOT_SYMMETRIC:
3646     mat->symmetric                  = PETSC_FALSE;
3647     mat->symmetric_set              = PETSC_TRUE;
3648     break;
3649   case MAT_NOT_HERMITIAN:
3650     mat->hermitian                  = PETSC_FALSE;
3651     mat->hermitian_set              = PETSC_TRUE;
3652     break;
3653   case MAT_NOT_STRUCTURALLY_SYMMETRIC:
3654     mat->structurally_symmetric     = PETSC_FALSE;
3655     mat->structurally_symmetric_set = PETSC_TRUE;
3656     break;
3657   case MAT_SYMMETRY_ETERNAL:
3658     mat->symmetric_eternal          = PETSC_TRUE;
3659   case MAT_NOT_SYMMETRY_ETERNAL:
3660     mat->symmetric_eternal          = PETSC_FALSE;
3661   default:
3662     break;
3663   }
3664   if (mat->ops->setoption) {
3665     ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);
3666   }
3667   PetscFunctionReturn(0);
3668 }
3669 
3670 #undef __FUNCT__
3671 #define __FUNCT__ "MatZeroEntries"
3672 /*@
3673    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
3674    this routine retains the old nonzero structure.
3675 
3676    Collective on Mat
3677 
3678    Input Parameters:
3679 .  mat - the matrix
3680 
3681    Level: intermediate
3682 
3683    Concepts: matrices^zeroing
3684 
3685 .seealso: MatZeroRows()
3686 @*/
3687 int MatZeroEntries(Mat mat)
3688 {
3689   int ierr;
3690 
3691   PetscFunctionBegin;
3692   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3693   PetscValidType(mat,1);
3694   MatPreallocated(mat);
3695   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3696   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3697 
3698   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3699   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
3700   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3701   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3702   PetscFunctionReturn(0);
3703 }
3704 
3705 #undef __FUNCT__
3706 #define __FUNCT__ "MatZeroRows"
3707 /*@C
3708    MatZeroRows - Zeros all entries (except possibly the main diagonal)
3709    of a set of rows of a matrix.
3710 
3711    Collective on Mat
3712 
3713    Input Parameters:
3714 +  mat - the matrix
3715 .  is - index set of rows to remove
3716 -  diag - pointer to value put in all diagonals of eliminated rows.
3717           Note that diag is not a pointer to an array, but merely a
3718           pointer to a single value.
3719 
3720    Notes:
3721    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
3722    but does not release memory.  For the dense and block diagonal
3723    formats this does not alter the nonzero structure.
3724 
3725    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3726    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3727    merely zeroed.
3728 
3729    The user can set a value in the diagonal entry (or for the AIJ and
3730    row formats can optionally remove the main diagonal entry from the
3731    nonzero structure as well, by passing a null pointer (PETSC_NULL
3732    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3733 
3734    For the parallel case, all processes that share the matrix (i.e.,
3735    those in the communicator used for matrix creation) MUST call this
3736    routine, regardless of whether any rows being zeroed are owned by
3737    them.
3738 
3739    Level: intermediate
3740 
3741    Concepts: matrices^zeroing rows
3742 
3743 .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
3744 @*/
3745 int MatZeroRows(Mat mat,IS is,const PetscScalar *diag)
3746 {
3747   int ierr;
3748 
3749   PetscFunctionBegin;
3750   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3751   PetscValidType(mat,1);
3752   MatPreallocated(mat);
3753   PetscValidHeaderSpecific(is,IS_COOKIE,2);
3754   if (diag) PetscValidScalarPointer(diag,3);
3755   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3756   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3757   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3758 
3759   ierr = (*mat->ops->zerorows)(mat,is,diag);CHKERRQ(ierr);
3760   ierr = MatView_Private(mat);CHKERRQ(ierr);
3761   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3762   PetscFunctionReturn(0);
3763 }
3764 
3765 #undef __FUNCT__
3766 #define __FUNCT__ "MatZeroRowsLocal"
3767 /*@C
3768    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
3769    of a set of rows of a matrix; using local numbering of rows.
3770 
3771    Collective on Mat
3772 
3773    Input Parameters:
3774 +  mat - the matrix
3775 .  is - index set of rows to remove
3776 -  diag - pointer to value put in all diagonals of eliminated rows.
3777           Note that diag is not a pointer to an array, but merely a
3778           pointer to a single value.
3779 
3780    Notes:
3781    Before calling MatZeroRowsLocal(), the user must first set the
3782    local-to-global mapping by calling MatSetLocalToGlobalMapping().
3783 
3784    For the AIJ matrix formats this removes the old nonzero structure,
3785    but does not release memory.  For the dense and block diagonal
3786    formats this does not alter the nonzero structure.
3787 
3788    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3789    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3790    merely zeroed.
3791 
3792    The user can set a value in the diagonal entry (or for the AIJ and
3793    row formats can optionally remove the main diagonal entry from the
3794    nonzero structure as well, by passing a null pointer (PETSC_NULL
3795    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3796 
3797    Level: intermediate
3798 
3799    Concepts: matrices^zeroing
3800 
3801 .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3802 @*/
3803 int MatZeroRowsLocal(Mat mat,IS is,const PetscScalar *diag)
3804 {
3805   int ierr;
3806   IS  newis;
3807 
3808   PetscFunctionBegin;
3809   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3810   PetscValidType(mat,1);
3811   MatPreallocated(mat);
3812   PetscValidHeaderSpecific(is,IS_COOKIE,2);
3813   if (diag) PetscValidScalarPointer(diag,3);
3814   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3815   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3816 
3817   if (mat->ops->zerorowslocal) {
3818     ierr = (*mat->ops->zerorowslocal)(mat,is,diag);CHKERRQ(ierr);
3819   } else {
3820     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3821     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
3822     ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr);
3823     ierr = ISDestroy(newis);CHKERRQ(ierr);
3824   }
3825   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3826   PetscFunctionReturn(0);
3827 }
3828 
3829 #undef __FUNCT__
3830 #define __FUNCT__ "MatGetSize"
3831 /*@
3832    MatGetSize - Returns the numbers of rows and columns in a matrix.
3833 
3834    Not Collective
3835 
3836    Input Parameter:
3837 .  mat - the matrix
3838 
3839    Output Parameters:
3840 +  m - the number of global rows
3841 -  n - the number of global columns
3842 
3843    Level: beginner
3844 
3845    Concepts: matrices^size
3846 
3847 .seealso: MatGetLocalSize()
3848 @*/
3849 int MatGetSize(Mat mat,int *m,int* n)
3850 {
3851   PetscFunctionBegin;
3852   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3853   if (m) *m = mat->M;
3854   if (n) *n = mat->N;
3855   PetscFunctionReturn(0);
3856 }
3857 
3858 #undef __FUNCT__
3859 #define __FUNCT__ "MatGetLocalSize"
3860 /*@
3861    MatGetLocalSize - Returns the number of rows and columns in a matrix
3862    stored locally.  This information may be implementation dependent, so
3863    use with care.
3864 
3865    Not Collective
3866 
3867    Input Parameters:
3868 .  mat - the matrix
3869 
3870    Output Parameters:
3871 +  m - the number of local rows
3872 -  n - the number of local columns
3873 
3874    Level: beginner
3875 
3876    Concepts: matrices^local size
3877 
3878 .seealso: MatGetSize()
3879 @*/
3880 int MatGetLocalSize(Mat mat,int *m,int* n)
3881 {
3882   PetscFunctionBegin;
3883   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3884   if (m) PetscValidIntPointer(m,2);
3885   if (n) PetscValidIntPointer(n,3);
3886   if (m) *m = mat->m;
3887   if (n) *n = mat->n;
3888   PetscFunctionReturn(0);
3889 }
3890 
3891 #undef __FUNCT__
3892 #define __FUNCT__ "MatGetOwnershipRange"
3893 /*@
3894    MatGetOwnershipRange - Returns the range of matrix rows owned by
3895    this processor, assuming that the matrix is laid out with the first
3896    n1 rows on the first processor, the next n2 rows on the second, etc.
3897    For certain parallel layouts this range may not be well defined.
3898 
3899    Not Collective
3900 
3901    Input Parameters:
3902 .  mat - the matrix
3903 
3904    Output Parameters:
3905 +  m - the global index of the first local row
3906 -  n - one more than the global index of the last local row
3907 
3908    Level: beginner
3909 
3910    Concepts: matrices^row ownership
3911 @*/
3912 int MatGetOwnershipRange(Mat mat,int *m,int* n)
3913 {
3914   int ierr;
3915 
3916   PetscFunctionBegin;
3917   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3918   PetscValidType(mat,1);
3919   MatPreallocated(mat);
3920   if (m) PetscValidIntPointer(m,2);
3921   if (n) PetscValidIntPointer(n,3);
3922   ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr);
3923   PetscFunctionReturn(0);
3924 }
3925 
3926 #undef __FUNCT__
3927 #define __FUNCT__ "MatILUFactorSymbolic"
3928 /*@
3929    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3930    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
3931    to complete the factorization.
3932 
3933    Collective on Mat
3934 
3935    Input Parameters:
3936 +  mat - the matrix
3937 .  row - row permutation
3938 .  column - column permutation
3939 -  info - structure containing
3940 $      levels - number of levels of fill.
3941 $      expected fill - as ratio of original fill.
3942 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3943                 missing diagonal entries)
3944 
3945    Output Parameters:
3946 .  fact - new matrix that has been symbolically factored
3947 
3948    Notes:
3949    See the users manual for additional information about
3950    choosing the fill factor for better efficiency.
3951 
3952    Most users should employ the simplified KSP interface for linear solvers
3953    instead of working directly with matrix algebra routines such as this.
3954    See, e.g., KSPCreate().
3955 
3956    Level: developer
3957 
3958   Concepts: matrices^symbolic LU factorization
3959   Concepts: matrices^factorization
3960   Concepts: LU^symbolic factorization
3961 
3962 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3963           MatGetOrdering(), MatFactorInfo
3964 
3965 @*/
3966 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
3967 {
3968   int ierr;
3969 
3970   PetscFunctionBegin;
3971   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3972   PetscValidType(mat,1);
3973   MatPreallocated(mat);
3974   PetscValidHeaderSpecific(row,IS_COOKIE,2);
3975   PetscValidHeaderSpecific(col,IS_COOKIE,3);
3976   PetscValidPointer(info,4);
3977   PetscValidPointer(fact,5);
3978   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",(int)info->levels);
3979   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3980   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3981   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3982   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3983 
3984   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3985   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
3986   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3987   PetscFunctionReturn(0);
3988 }
3989 
3990 #undef __FUNCT__
3991 #define __FUNCT__ "MatICCFactorSymbolic"
3992 /*@
3993    MatICCFactorSymbolic - Performs symbolic incomplete
3994    Cholesky factorization for a symmetric matrix.  Use
3995    MatCholeskyFactorNumeric() to complete the factorization.
3996 
3997    Collective on Mat
3998 
3999    Input Parameters:
4000 +  mat - the matrix
4001 .  perm - row and column permutation
4002 -  info - structure containing
4003 $      levels - number of levels of fill.
4004 $      expected fill - as ratio of original fill.
4005 
4006    Output Parameter:
4007 .  fact - the factored matrix
4008 
4009    Notes:
4010    Currently only no-fill factorization is supported.
4011 
4012    Most users should employ the simplified KSP interface for linear solvers
4013    instead of working directly with matrix algebra routines such as this.
4014    See, e.g., KSPCreate().
4015 
4016    Level: developer
4017 
4018   Concepts: matrices^symbolic incomplete Cholesky factorization
4019   Concepts: matrices^factorization
4020   Concepts: Cholsky^symbolic factorization
4021 
4022 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
4023 @*/
4024 int MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
4025 {
4026   int ierr;
4027 
4028   PetscFunctionBegin;
4029   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4030   PetscValidType(mat,1);
4031   MatPreallocated(mat);
4032   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
4033   PetscValidPointer(info,3);
4034   PetscValidPointer(fact,4);
4035   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4036   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %d",(int) info->levels);
4037   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
4038   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
4039   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4040 
4041   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4042   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
4043   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4044   PetscFunctionReturn(0);
4045 }
4046 
4047 #undef __FUNCT__
4048 #define __FUNCT__ "MatGetArray"
4049 /*@C
4050    MatGetArray - Returns a pointer to the element values in the matrix.
4051    The result of this routine is dependent on the underlying matrix data
4052    structure, and may not even work for certain matrix types.  You MUST
4053    call MatRestoreArray() when you no longer need to access the array.
4054 
4055    Not Collective
4056 
4057    Input Parameter:
4058 .  mat - the matrix
4059 
4060    Output Parameter:
4061 .  v - the location of the values
4062 
4063 
4064    Fortran Note:
4065    This routine is used differently from Fortran, e.g.,
4066 .vb
4067         Mat         mat
4068         PetscScalar mat_array(1)
4069         PetscOffset i_mat
4070         int         ierr
4071         call MatGetArray(mat,mat_array,i_mat,ierr)
4072 
4073   C  Access first local entry in matrix; note that array is
4074   C  treated as one dimensional
4075         value = mat_array(i_mat + 1)
4076 
4077         [... other code ...]
4078         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4079 .ve
4080 
4081    See the Fortran chapter of the users manual and
4082    petsc/src/mat/examples/tests for details.
4083 
4084    Level: advanced
4085 
4086    Concepts: matrices^access array
4087 
4088 .seealso: MatRestoreArray(), MatGetArrayF90()
4089 @*/
4090 int MatGetArray(Mat mat,PetscScalar *v[])
4091 {
4092   int ierr;
4093 
4094   PetscFunctionBegin;
4095   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4096   PetscValidType(mat,1);
4097   MatPreallocated(mat);
4098   PetscValidPointer(v,2);
4099   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4100   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
4101   PetscFunctionReturn(0);
4102 }
4103 
4104 #undef __FUNCT__
4105 #define __FUNCT__ "MatRestoreArray"
4106 /*@C
4107    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
4108 
4109    Not Collective
4110 
4111    Input Parameter:
4112 +  mat - the matrix
4113 -  v - the location of the values
4114 
4115    Fortran Note:
4116    This routine is used differently from Fortran, e.g.,
4117 .vb
4118         Mat         mat
4119         PetscScalar mat_array(1)
4120         PetscOffset i_mat
4121         int         ierr
4122         call MatGetArray(mat,mat_array,i_mat,ierr)
4123 
4124   C  Access first local entry in matrix; note that array is
4125   C  treated as one dimensional
4126         value = mat_array(i_mat + 1)
4127 
4128         [... other code ...]
4129         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4130 .ve
4131 
4132    See the Fortran chapter of the users manual and
4133    petsc/src/mat/examples/tests for details
4134 
4135    Level: advanced
4136 
4137 .seealso: MatGetArray(), MatRestoreArrayF90()
4138 @*/
4139 int MatRestoreArray(Mat mat,PetscScalar *v[])
4140 {
4141   int ierr;
4142 
4143   PetscFunctionBegin;
4144   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4145   PetscValidType(mat,1);
4146   MatPreallocated(mat);
4147   PetscValidPointer(v,2);
4148 #if defined(PETSC_USE_BOPT_g)
4149   CHKMEMQ;
4150 #endif
4151   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4152   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
4153   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
4154   PetscFunctionReturn(0);
4155 }
4156 
4157 #undef __FUNCT__
4158 #define __FUNCT__ "MatGetSubMatrices"
4159 /*@C
4160    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
4161    points to an array of valid matrices, they may be reused to store the new
4162    submatrices.
4163 
4164    Collective on Mat
4165 
4166    Input Parameters:
4167 +  mat - the matrix
4168 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
4169 .  irow, icol - index sets of rows and columns to extract
4170 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4171 
4172    Output Parameter:
4173 .  submat - the array of submatrices
4174 
4175    Notes:
4176    MatGetSubMatrices() can extract only sequential submatrices
4177    (from both sequential and parallel matrices). Use MatGetSubMatrix()
4178    to extract a parallel submatrix.
4179 
4180    When extracting submatrices from a parallel matrix, each processor can
4181    form a different submatrix by setting the rows and columns of its
4182    individual index sets according to the local submatrix desired.
4183 
4184    When finished using the submatrices, the user should destroy
4185    them with MatDestroyMatrices().
4186 
4187    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
4188    original matrix has not changed from that last call to MatGetSubMatrices().
4189 
4190    This routine creates the matrices in submat; you should NOT create them before
4191    calling it. It also allocates the array of matrix pointers submat.
4192 
4193    Fortran Note:
4194    The Fortran interface is slightly different from that given below; it
4195    requires one to pass in  as submat a Mat (integer) array of size at least m.
4196 
4197    Level: advanced
4198 
4199    Concepts: matrices^accessing submatrices
4200    Concepts: submatrices
4201 
4202 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
4203 @*/
4204 int MatGetSubMatrices(Mat mat,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
4205 {
4206   int        ierr;
4207 
4208   PetscFunctionBegin;
4209   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4210   PetscValidType(mat,1);
4211   MatPreallocated(mat);
4212   if (n) {
4213     PetscValidPointer(irow,3);
4214     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
4215     PetscValidPointer(icol,4);
4216     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
4217   }
4218   PetscValidPointer(submat,6);
4219   if (n && scall == MAT_REUSE_MATRIX) {
4220     PetscValidPointer(*submat,6);
4221     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
4222   }
4223   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4224   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4225   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4226 
4227   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4228   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
4229   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4230   PetscFunctionReturn(0);
4231 }
4232 
4233 #undef __FUNCT__
4234 #define __FUNCT__ "MatDestroyMatrices"
4235 /*@C
4236    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
4237 
4238    Collective on Mat
4239 
4240    Input Parameters:
4241 +  n - the number of local matrices
4242 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
4243                        sequence of MatGetSubMatrices())
4244 
4245    Level: advanced
4246 
4247     Notes: Frees not only the matrices, but also the array that contains the matrices
4248 
4249 .seealso: MatGetSubMatrices()
4250 @*/
4251 int MatDestroyMatrices(int n,Mat *mat[])
4252 {
4253   int ierr,i;
4254 
4255   PetscFunctionBegin;
4256   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
4257   PetscValidPointer(mat,2);
4258   for (i=0; i<n; i++) {
4259     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
4260   }
4261   /* memory is allocated even if n = 0 */
4262   ierr = PetscFree(*mat);CHKERRQ(ierr);
4263   PetscFunctionReturn(0);
4264 }
4265 
4266 #undef __FUNCT__
4267 #define __FUNCT__ "MatIncreaseOverlap"
4268 /*@
4269    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
4270    replaces the index sets by larger ones that represent submatrices with
4271    additional overlap.
4272 
4273    Collective on Mat
4274 
4275    Input Parameters:
4276 +  mat - the matrix
4277 .  n   - the number of index sets
4278 .  is  - the array of index sets (these index sets will changed during the call)
4279 -  ov  - the additional overlap requested
4280 
4281    Level: developer
4282 
4283    Concepts: overlap
4284    Concepts: ASM^computing overlap
4285 
4286 .seealso: MatGetSubMatrices()
4287 @*/
4288 int MatIncreaseOverlap(Mat mat,int n,IS is[],int ov)
4289 {
4290   int ierr;
4291 
4292   PetscFunctionBegin;
4293   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4294   PetscValidType(mat,1);
4295   MatPreallocated(mat);
4296   if (n < 0) SETERRQ1(1,"Must have one or more domains, you have %d",n);
4297   if (n) {
4298     PetscValidPointer(is,3);
4299     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
4300   }
4301   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4302   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4303 
4304   if (!ov) PetscFunctionReturn(0);
4305   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4306   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4307   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
4308   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4309   PetscFunctionReturn(0);
4310 }
4311 
4312 #undef __FUNCT__
4313 #define __FUNCT__ "MatPrintHelp"
4314 /*@
4315    MatPrintHelp - Prints all the options for the matrix.
4316 
4317    Collective on Mat
4318 
4319    Input Parameter:
4320 .  mat - the matrix
4321 
4322    Options Database Keys:
4323 +  -help - Prints matrix options
4324 -  -h - Prints matrix options
4325 
4326    Level: developer
4327 
4328 .seealso: MatCreate(), MatCreateXXX()
4329 @*/
4330 int MatPrintHelp(Mat mat)
4331 {
4332   static PetscTruth called = PETSC_FALSE;
4333   int               ierr;
4334 
4335   PetscFunctionBegin;
4336   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4337   PetscValidType(mat,1);
4338   MatPreallocated(mat);
4339 
4340   if (!called) {
4341     if (mat->ops->printhelp) {
4342       ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
4343     }
4344     called = PETSC_TRUE;
4345   }
4346   PetscFunctionReturn(0);
4347 }
4348 
4349 #undef __FUNCT__
4350 #define __FUNCT__ "MatGetBlockSize"
4351 /*@
4352    MatGetBlockSize - Returns the matrix block size; useful especially for the
4353    block row and block diagonal formats.
4354 
4355    Not Collective
4356 
4357    Input Parameter:
4358 .  mat - the matrix
4359 
4360    Output Parameter:
4361 .  bs - block size
4362 
4363    Notes:
4364    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
4365    Block row formats are MATSEQBAIJ, MATMPIBAIJ
4366 
4367    Level: intermediate
4368 
4369    Concepts: matrices^block size
4370 
4371 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
4372 @*/
4373 int MatGetBlockSize(Mat mat,int *bs)
4374 {
4375   int ierr;
4376 
4377   PetscFunctionBegin;
4378   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4379   PetscValidType(mat,1);
4380   MatPreallocated(mat);
4381   PetscValidIntPointer(bs,2);
4382   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4383   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
4384   PetscFunctionReturn(0);
4385 }
4386 
4387 #undef __FUNCT__
4388 #define __FUNCT__ "MatGetRowIJ"
4389 /*@C
4390     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
4391 
4392    Collective on Mat
4393 
4394     Input Parameters:
4395 +   mat - the matrix
4396 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
4397 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4398                 symmetrized
4399 
4400     Output Parameters:
4401 +   n - number of rows in the (possibly compressed) matrix
4402 .   ia - the row pointers
4403 .   ja - the column indices
4404 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4405 
4406     Level: developer
4407 
4408 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4409 @*/
4410 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4411 {
4412   int ierr;
4413 
4414   PetscFunctionBegin;
4415   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4416   PetscValidType(mat,1);
4417   MatPreallocated(mat);
4418   PetscValidIntPointer(n,4);
4419   if (ia) PetscValidIntPointer(ia,5);
4420   if (ja) PetscValidIntPointer(ja,6);
4421   PetscValidIntPointer(done,7);
4422   if (!mat->ops->getrowij) *done = PETSC_FALSE;
4423   else {
4424     *done = PETSC_TRUE;
4425     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4426   }
4427   PetscFunctionReturn(0);
4428 }
4429 
4430 #undef __FUNCT__
4431 #define __FUNCT__ "MatGetColumnIJ"
4432 /*@C
4433     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
4434 
4435     Collective on Mat
4436 
4437     Input Parameters:
4438 +   mat - the matrix
4439 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4440 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4441                 symmetrized
4442 
4443     Output Parameters:
4444 +   n - number of columns in the (possibly compressed) matrix
4445 .   ia - the column pointers
4446 .   ja - the row indices
4447 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4448 
4449     Level: developer
4450 
4451 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4452 @*/
4453 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4454 {
4455   int ierr;
4456 
4457   PetscFunctionBegin;
4458   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4459   PetscValidType(mat,1);
4460   MatPreallocated(mat);
4461   PetscValidIntPointer(n,4);
4462   if (ia) PetscValidIntPointer(ia,5);
4463   if (ja) PetscValidIntPointer(ja,6);
4464   PetscValidIntPointer(done,7);
4465 
4466   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
4467   else {
4468     *done = PETSC_TRUE;
4469     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4470   }
4471   PetscFunctionReturn(0);
4472 }
4473 
4474 #undef __FUNCT__
4475 #define __FUNCT__ "MatRestoreRowIJ"
4476 /*@C
4477     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
4478     MatGetRowIJ().
4479 
4480     Collective on Mat
4481 
4482     Input Parameters:
4483 +   mat - the matrix
4484 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4485 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4486                 symmetrized
4487 
4488     Output Parameters:
4489 +   n - size of (possibly compressed) matrix
4490 .   ia - the row pointers
4491 .   ja - the column indices
4492 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4493 
4494     Level: developer
4495 
4496 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4497 @*/
4498 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4499 {
4500   int ierr;
4501 
4502   PetscFunctionBegin;
4503   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4504   PetscValidType(mat,1);
4505   MatPreallocated(mat);
4506   if (ia) PetscValidIntPointer(ia,5);
4507   if (ja) PetscValidIntPointer(ja,6);
4508   PetscValidIntPointer(done,7);
4509 
4510   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
4511   else {
4512     *done = PETSC_TRUE;
4513     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4514   }
4515   PetscFunctionReturn(0);
4516 }
4517 
4518 #undef __FUNCT__
4519 #define __FUNCT__ "MatRestoreColumnIJ"
4520 /*@C
4521     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4522     MatGetColumnIJ().
4523 
4524     Collective on Mat
4525 
4526     Input Parameters:
4527 +   mat - the matrix
4528 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4529 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4530                 symmetrized
4531 
4532     Output Parameters:
4533 +   n - size of (possibly compressed) matrix
4534 .   ia - the column pointers
4535 .   ja - the row indices
4536 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4537 
4538     Level: developer
4539 
4540 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4541 @*/
4542 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4543 {
4544   int ierr;
4545 
4546   PetscFunctionBegin;
4547   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4548   PetscValidType(mat,1);
4549   MatPreallocated(mat);
4550   if (ia) PetscValidIntPointer(ia,5);
4551   if (ja) PetscValidIntPointer(ja,6);
4552   PetscValidIntPointer(done,7);
4553 
4554   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4555   else {
4556     *done = PETSC_TRUE;
4557     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4558   }
4559   PetscFunctionReturn(0);
4560 }
4561 
4562 #undef __FUNCT__
4563 #define __FUNCT__ "MatColoringPatch"
4564 /*@C
4565     MatColoringPatch -Used inside matrix coloring routines that
4566     use MatGetRowIJ() and/or MatGetColumnIJ().
4567 
4568     Collective on Mat
4569 
4570     Input Parameters:
4571 +   mat - the matrix
4572 .   n   - number of colors
4573 -   colorarray - array indicating color for each column
4574 
4575     Output Parameters:
4576 .   iscoloring - coloring generated using colorarray information
4577 
4578     Level: developer
4579 
4580 .seealso: MatGetRowIJ(), MatGetColumnIJ()
4581 
4582 @*/
4583 int MatColoringPatch(Mat mat,int n,int ncolors,const ISColoringValue colorarray[],ISColoring *iscoloring)
4584 {
4585   int ierr;
4586 
4587   PetscFunctionBegin;
4588   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4589   PetscValidType(mat,1);
4590   MatPreallocated(mat);
4591   PetscValidIntPointer(colorarray,4);
4592   PetscValidPointer(iscoloring,5);
4593 
4594   if (!mat->ops->coloringpatch){
4595     ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr);
4596   } else {
4597     ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr);
4598   }
4599   PetscFunctionReturn(0);
4600 }
4601 
4602 
4603 #undef __FUNCT__
4604 #define __FUNCT__ "MatSetUnfactored"
4605 /*@
4606    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
4607 
4608    Collective on Mat
4609 
4610    Input Parameter:
4611 .  mat - the factored matrix to be reset
4612 
4613    Notes:
4614    This routine should be used only with factored matrices formed by in-place
4615    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
4616    format).  This option can save memory, for example, when solving nonlinear
4617    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
4618    ILU(0) preconditioner.
4619 
4620    Note that one can specify in-place ILU(0) factorization by calling
4621 .vb
4622      PCType(pc,PCILU);
4623      PCILUSeUseInPlace(pc);
4624 .ve
4625    or by using the options -pc_type ilu -pc_ilu_in_place
4626 
4627    In-place factorization ILU(0) can also be used as a local
4628    solver for the blocks within the block Jacobi or additive Schwarz
4629    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
4630    of these preconditioners in the users manual for details on setting
4631    local solver options.
4632 
4633    Most users should employ the simplified KSP interface for linear solvers
4634    instead of working directly with matrix algebra routines such as this.
4635    See, e.g., KSPCreate().
4636 
4637    Level: developer
4638 
4639 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
4640 
4641    Concepts: matrices^unfactored
4642 
4643 @*/
4644 int MatSetUnfactored(Mat mat)
4645 {
4646   int ierr;
4647 
4648   PetscFunctionBegin;
4649   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4650   PetscValidType(mat,1);
4651   MatPreallocated(mat);
4652   mat->factor = 0;
4653   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
4654   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
4655   PetscFunctionReturn(0);
4656 }
4657 
4658 /*MC
4659     MatGetArrayF90 - Accesses a matrix array from Fortran90.
4660 
4661     Synopsis:
4662     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4663 
4664     Not collective
4665 
4666     Input Parameter:
4667 .   x - matrix
4668 
4669     Output Parameters:
4670 +   xx_v - the Fortran90 pointer to the array
4671 -   ierr - error code
4672 
4673     Example of Usage:
4674 .vb
4675       PetscScalar, pointer xx_v(:)
4676       ....
4677       call MatGetArrayF90(x,xx_v,ierr)
4678       a = xx_v(3)
4679       call MatRestoreArrayF90(x,xx_v,ierr)
4680 .ve
4681 
4682     Notes:
4683     Not yet supported for all F90 compilers
4684 
4685     Level: advanced
4686 
4687 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
4688 
4689     Concepts: matrices^accessing array
4690 
4691 M*/
4692 
4693 /*MC
4694     MatRestoreArrayF90 - Restores a matrix array that has been
4695     accessed with MatGetArrayF90().
4696 
4697     Synopsis:
4698     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4699 
4700     Not collective
4701 
4702     Input Parameters:
4703 +   x - matrix
4704 -   xx_v - the Fortran90 pointer to the array
4705 
4706     Output Parameter:
4707 .   ierr - error code
4708 
4709     Example of Usage:
4710 .vb
4711        PetscScalar, pointer xx_v(:)
4712        ....
4713        call MatGetArrayF90(x,xx_v,ierr)
4714        a = xx_v(3)
4715        call MatRestoreArrayF90(x,xx_v,ierr)
4716 .ve
4717 
4718     Notes:
4719     Not yet supported for all F90 compilers
4720 
4721     Level: advanced
4722 
4723 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
4724 
4725 M*/
4726 
4727 
4728 #undef __FUNCT__
4729 #define __FUNCT__ "MatGetSubMatrix"
4730 /*@
4731     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4732                       as the original matrix.
4733 
4734     Collective on Mat
4735 
4736     Input Parameters:
4737 +   mat - the original matrix
4738 .   isrow - rows this processor should obtain
4739 .   iscol - columns for all processors you wish to keep
4740 .   csize - number of columns "local" to this processor (does nothing for sequential
4741             matrices). This should match the result from VecGetLocalSize(x,...) if you
4742             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4743 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4744 
4745     Output Parameter:
4746 .   newmat - the new submatrix, of the same type as the old
4747 
4748     Level: advanced
4749 
4750     Notes: the iscol argument MUST be the same on each processor. You might be
4751     able to create the iscol argument with ISAllGather().
4752 
4753       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
4754    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
4755    to this routine with a mat of the same nonzero structure will reuse the matrix
4756    generated the first time.
4757 
4758     Concepts: matrices^submatrices
4759 
4760 .seealso: MatGetSubMatrices(), ISAllGather()
4761 @*/
4762 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4763 {
4764   int     ierr, size;
4765   Mat     *local;
4766 
4767   PetscFunctionBegin;
4768   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4769   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
4770   PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
4771   PetscValidPointer(newmat,6);
4772   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
4773   PetscValidType(mat,1);
4774   MatPreallocated(mat);
4775   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4776   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
4777 
4778   /* if original matrix is on just one processor then use submatrix generated */
4779   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4780     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
4781     PetscFunctionReturn(0);
4782   } else if (!mat->ops->getsubmatrix && size == 1) {
4783     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
4784     *newmat = *local;
4785     ierr    = PetscFree(local);CHKERRQ(ierr);
4786     PetscFunctionReturn(0);
4787   }
4788 
4789   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4790   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
4791   ierr = PetscObjectIncreaseState((PetscObject)*newmat); CHKERRQ(ierr);
4792   PetscFunctionReturn(0);
4793 }
4794 
4795 #undef __FUNCT__
4796 #define __FUNCT__ "MatGetPetscMaps"
4797 /*@C
4798    MatGetPetscMaps - Returns the maps associated with the matrix.
4799 
4800    Not Collective
4801 
4802    Input Parameter:
4803 .  mat - the matrix
4804 
4805    Output Parameters:
4806 +  rmap - the row (right) map
4807 -  cmap - the column (left) map
4808 
4809    Level: developer
4810 
4811    Concepts: maps^getting from matrix
4812 
4813 @*/
4814 int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4815 {
4816   int ierr;
4817 
4818   PetscFunctionBegin;
4819   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4820   PetscValidType(mat,1);
4821   MatPreallocated(mat);
4822   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
4823   PetscFunctionReturn(0);
4824 }
4825 
4826 /*
4827       Version that works for all PETSc matrices
4828 */
4829 #undef __FUNCT__
4830 #define __FUNCT__ "MatGetPetscMaps_Petsc"
4831 int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4832 {
4833   PetscFunctionBegin;
4834   if (rmap) *rmap = mat->rmap;
4835   if (cmap) *cmap = mat->cmap;
4836   PetscFunctionReturn(0);
4837 }
4838 
4839 #undef __FUNCT__
4840 #define __FUNCT__ "MatSetStashInitialSize"
4841 /*@
4842    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4843    used during the assembly process to store values that belong to
4844    other processors.
4845 
4846    Not Collective
4847 
4848    Input Parameters:
4849 +  mat   - the matrix
4850 .  size  - the initial size of the stash.
4851 -  bsize - the initial size of the block-stash(if used).
4852 
4853    Options Database Keys:
4854 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4855 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
4856 
4857    Level: intermediate
4858 
4859    Notes:
4860      The block-stash is used for values set with VecSetValuesBlocked() while
4861      the stash is used for values set with VecSetValues()
4862 
4863      Run with the option -log_info and look for output of the form
4864      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4865      to determine the appropriate value, MM, to use for size and
4866      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4867      to determine the value, BMM to use for bsize
4868 
4869    Concepts: stash^setting matrix size
4870    Concepts: matrices^stash
4871 
4872 @*/
4873 int MatSetStashInitialSize(Mat mat,int size, int bsize)
4874 {
4875   int ierr;
4876 
4877   PetscFunctionBegin;
4878   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4879   PetscValidType(mat,1);
4880   MatPreallocated(mat);
4881   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
4882   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
4883   PetscFunctionReturn(0);
4884 }
4885 
4886 #undef __FUNCT__
4887 #define __FUNCT__ "MatInterpolateAdd"
4888 /*@
4889    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
4890      the matrix
4891 
4892    Collective on Mat
4893 
4894    Input Parameters:
4895 +  mat   - the matrix
4896 .  x,y - the vectors
4897 -  w - where the result is stored
4898 
4899    Level: intermediate
4900 
4901    Notes:
4902     w may be the same vector as y.
4903 
4904     This allows one to use either the restriction or interpolation (its transpose)
4905     matrix to do the interpolation
4906 
4907     Concepts: interpolation
4908 
4909 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4910 
4911 @*/
4912 int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4913 {
4914   int M,N,ierr;
4915 
4916   PetscFunctionBegin;
4917   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
4918   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
4919   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
4920   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
4921   PetscValidType(A,1);
4922   MatPreallocated(A);
4923   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4924   if (N > M) {
4925     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
4926   } else {
4927     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
4928   }
4929   PetscFunctionReturn(0);
4930 }
4931 
4932 #undef __FUNCT__
4933 #define __FUNCT__ "MatInterpolate"
4934 /*@
4935    MatInterpolate - y = A*x or A'*x depending on the shape of
4936      the matrix
4937 
4938    Collective on Mat
4939 
4940    Input Parameters:
4941 +  mat   - the matrix
4942 -  x,y - the vectors
4943 
4944    Level: intermediate
4945 
4946    Notes:
4947     This allows one to use either the restriction or interpolation (its transpose)
4948     matrix to do the interpolation
4949 
4950    Concepts: matrices^interpolation
4951 
4952 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4953 
4954 @*/
4955 int MatInterpolate(Mat A,Vec x,Vec y)
4956 {
4957   int M,N,ierr;
4958 
4959   PetscFunctionBegin;
4960   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
4961   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
4962   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
4963   PetscValidType(A,1);
4964   MatPreallocated(A);
4965   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4966   if (N > M) {
4967     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4968   } else {
4969     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4970   }
4971   PetscFunctionReturn(0);
4972 }
4973 
4974 #undef __FUNCT__
4975 #define __FUNCT__ "MatRestrict"
4976 /*@
4977    MatRestrict - y = A*x or A'*x
4978 
4979    Collective on Mat
4980 
4981    Input Parameters:
4982 +  mat   - the matrix
4983 -  x,y - the vectors
4984 
4985    Level: intermediate
4986 
4987    Notes:
4988     This allows one to use either the restriction or interpolation (its transpose)
4989     matrix to do the restriction
4990 
4991    Concepts: matrices^restriction
4992 
4993 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
4994 
4995 @*/
4996 int MatRestrict(Mat A,Vec x,Vec y)
4997 {
4998   int M,N,ierr;
4999 
5000   PetscFunctionBegin;
5001   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5002   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5003   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5004   PetscValidType(A,1);
5005   MatPreallocated(A);
5006   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5007   if (N > M) {
5008     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5009   } else {
5010     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5011   }
5012   PetscFunctionReturn(0);
5013 }
5014 
5015 #undef __FUNCT__
5016 #define __FUNCT__ "MatNullSpaceAttach"
5017 /*@C
5018    MatNullSpaceAttach - attaches a null space to a matrix.
5019         This null space will be removed from the resulting vector whenever
5020         MatMult() is called
5021 
5022    Collective on Mat
5023 
5024    Input Parameters:
5025 +  mat - the matrix
5026 -  nullsp - the null space object
5027 
5028    Level: developer
5029 
5030    Notes:
5031       Overwrites any previous null space that may have been attached
5032 
5033    Concepts: null space^attaching to matrix
5034 
5035 .seealso: MatCreate(), MatNullSpaceCreate()
5036 @*/
5037 int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
5038 {
5039   int ierr;
5040 
5041   PetscFunctionBegin;
5042   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5043   PetscValidType(mat,1);
5044   MatPreallocated(mat);
5045   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
5046 
5047   if (mat->nullsp) {
5048     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
5049   }
5050   mat->nullsp = nullsp;
5051   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
5052   PetscFunctionReturn(0);
5053 }
5054 
5055 #undef __FUNCT__
5056 #define __FUNCT__ "MatICCFactor"
5057 /*@
5058    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
5059 
5060    Collective on Mat
5061 
5062    Input Parameters:
5063 +  mat - the matrix
5064 .  row - row/column permutation
5065 .  fill - expected fill factor >= 1.0
5066 -  level - level of fill, for ICC(k)
5067 
5068    Notes:
5069    Probably really in-place only when level of fill is zero, otherwise allocates
5070    new space to store factored matrix and deletes previous memory.
5071 
5072    Most users should employ the simplified KSP interface for linear solvers
5073    instead of working directly with matrix algebra routines such as this.
5074    See, e.g., KSPCreate().
5075 
5076    Level: developer
5077 
5078    Concepts: matrices^incomplete Cholesky factorization
5079    Concepts: Cholesky factorization
5080 
5081 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5082 @*/
5083 int MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
5084 {
5085   int ierr;
5086 
5087   PetscFunctionBegin;
5088   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5089   PetscValidType(mat,1);
5090   MatPreallocated(mat);
5091   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
5092   PetscValidPointer(info,3);
5093   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
5094   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5095   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5096   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5097   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
5098   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5099   PetscFunctionReturn(0);
5100 }
5101 
5102 #undef __FUNCT__
5103 #define __FUNCT__ "MatSetValuesAdic"
5104 /*@
5105    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
5106 
5107    Not Collective
5108 
5109    Input Parameters:
5110 +  mat - the matrix
5111 -  v - the values compute with ADIC
5112 
5113    Level: developer
5114 
5115    Notes:
5116      Must call MatSetColoring() before using this routine. Also this matrix must already
5117      have its nonzero pattern determined.
5118 
5119 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5120           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5121 @*/
5122 int MatSetValuesAdic(Mat mat,void *v)
5123 {
5124   int ierr;
5125 
5126   PetscFunctionBegin;
5127   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5128   PetscValidType(mat,1);
5129   PetscValidPointer(mat,2);
5130 
5131   if (!mat->assembled) {
5132     SETERRQ(1,"Matrix must be already assembled");
5133   }
5134   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5135   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5136   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
5137   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5138   ierr = MatView_Private(mat);CHKERRQ(ierr);
5139   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5140   PetscFunctionReturn(0);
5141 }
5142 
5143 
5144 #undef __FUNCT__
5145 #define __FUNCT__ "MatSetColoring"
5146 /*@
5147    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
5148 
5149    Not Collective
5150 
5151    Input Parameters:
5152 +  mat - the matrix
5153 -  coloring - the coloring
5154 
5155    Level: developer
5156 
5157 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5158           MatSetValues(), MatSetValuesAdic()
5159 @*/
5160 int MatSetColoring(Mat mat,ISColoring coloring)
5161 {
5162   int ierr;
5163 
5164   PetscFunctionBegin;
5165   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5166   PetscValidType(mat,1);
5167   PetscValidPointer(coloring,2);
5168 
5169   if (!mat->assembled) {
5170     SETERRQ(1,"Matrix must be already assembled");
5171   }
5172   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5173   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
5174   PetscFunctionReturn(0);
5175 }
5176 
5177 #undef __FUNCT__
5178 #define __FUNCT__ "MatSetValuesAdifor"
5179 /*@
5180    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
5181 
5182    Not Collective
5183 
5184    Input Parameters:
5185 +  mat - the matrix
5186 .  nl - leading dimension of v
5187 -  v - the values compute with ADIFOR
5188 
5189    Level: developer
5190 
5191    Notes:
5192      Must call MatSetColoring() before using this routine. Also this matrix must already
5193      have its nonzero pattern determined.
5194 
5195 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5196           MatSetValues(), MatSetColoring()
5197 @*/
5198 int MatSetValuesAdifor(Mat mat,int nl,void *v)
5199 {
5200   int ierr;
5201 
5202   PetscFunctionBegin;
5203   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5204   PetscValidType(mat,1);
5205   PetscValidPointer(v,3);
5206 
5207   if (!mat->assembled) {
5208     SETERRQ(1,"Matrix must be already assembled");
5209   }
5210   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5211   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5212   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
5213   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5214   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5215   PetscFunctionReturn(0);
5216 }
5217 
5218 EXTERN int MatMPIAIJDiagonalScaleLocal(Mat,Vec);
5219 EXTERN int MatMPIBAIJDiagonalScaleLocal(Mat,Vec);
5220 
5221 #undef __FUNCT__
5222 #define __FUNCT__ "MatDiagonalScaleLocal"
5223 /*@
5224    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
5225          ghosted ones.
5226 
5227    Not Collective
5228 
5229    Input Parameters:
5230 +  mat - the matrix
5231 -  diag = the diagonal values, including ghost ones
5232 
5233    Level: developer
5234 
5235    Notes: Works only for MPIAIJ and MPIBAIJ matrices
5236 
5237 .seealso: MatDiagonalScale()
5238 @*/
5239 int MatDiagonalScaleLocal(Mat mat,Vec diag)
5240 {
5241   int        ierr,size;
5242 
5243   PetscFunctionBegin;
5244   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5245   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
5246   PetscValidType(mat,1);
5247 
5248   if (!mat->assembled) {
5249     SETERRQ(1,"Matrix must be already assembled");
5250   }
5251   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5252   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5253   if (size == 1) {
5254     int n,m;
5255     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
5256     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
5257     if (m == n) {
5258       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
5259     } else {
5260       SETERRQ(1,"Only supprted for sequential matrices when no ghost points/periodic conditions");
5261     }
5262   } else {
5263     int (*f)(Mat,Vec);
5264     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
5265     if (f) {
5266       ierr = (*f)(mat,diag);CHKERRQ(ierr);
5267     } else {
5268       SETERRQ(1,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
5269     }
5270   }
5271   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5272   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5273   PetscFunctionReturn(0);
5274 }
5275 
5276 #undef __FUNCT__
5277 #define __FUNCT__ "MatGetInertia"
5278 /*@
5279    MatGetInertia - Gets the inertia from a factored matrix
5280 
5281    Collective on Mat
5282 
5283    Input Parameter:
5284 .  mat - the matrix
5285 
5286    Output Parameters:
5287 +   nneg - number of negative eigenvalues
5288 .   nzero - number of zero eigenvalues
5289 -   npos - number of positive eigenvalues
5290 
5291    Level: advanced
5292 
5293    Notes: Matrix must have been factored by MatCholeskyFactor()
5294 
5295 
5296 @*/
5297 int MatGetInertia(Mat mat,int *nneg,int *nzero,int *npos)
5298 {
5299   int        ierr;
5300 
5301   PetscFunctionBegin;
5302   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5303   PetscValidType(mat,1);
5304   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5305   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
5306   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5307   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
5308   PetscFunctionReturn(0);
5309 }
5310 
5311 /* ----------------------------------------------------------------*/
5312 #undef __FUNCT__
5313 #define __FUNCT__ "MatSolves"
5314 /*@
5315    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
5316 
5317    Collective on Mat and Vecs
5318 
5319    Input Parameters:
5320 +  mat - the factored matrix
5321 -  b - the right-hand-side vectors
5322 
5323    Output Parameter:
5324 .  x - the result vectors
5325 
5326    Notes:
5327    The vectors b and x cannot be the same.  I.e., one cannot
5328    call MatSolves(A,x,x).
5329 
5330    Notes:
5331    Most users should employ the simplified KSP interface for linear solvers
5332    instead of working directly with matrix algebra routines such as this.
5333    See, e.g., KSPCreate().
5334 
5335    Level: developer
5336 
5337    Concepts: matrices^triangular solves
5338 
5339 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
5340 @*/
5341 int MatSolves(Mat mat,Vecs b,Vecs x)
5342 {
5343   int ierr;
5344 
5345   PetscFunctionBegin;
5346   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5347   PetscValidType(mat,1);
5348   MatPreallocated(mat);
5349   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
5350   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5351   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
5352 
5353   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5354   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5355   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
5356   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5357   PetscFunctionReturn(0);
5358 }
5359 
5360 #undef __FUNCT__
5361 #define __FUNCT__ "MatIsSymmetric"
5362 /*@C
5363    MatIsSymmetric - Test whether a matrix is symmetric
5364 
5365    Collective on Mat
5366 
5367    Input Parameter:
5368 .  A - the matrix to test
5369 
5370    Output Parameters:
5371 .  flg - the result
5372 
5373    Level: intermediate
5374 
5375    Concepts: matrix^symmetry
5376 
5377 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption()
5378 @*/
5379 int MatIsSymmetric(Mat A,PetscTruth *flg)
5380 {
5381   int ierr;
5382 
5383   PetscFunctionBegin;
5384   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5385   PetscValidPointer(flg,2);
5386   if (!A->symmetric_set) {
5387     if (!A->ops->issymmetric) {
5388       MatType mattype;
5389       ierr = MatGetType(A,&mattype); CHKERRQ(ierr);
5390       SETERRQ1(1,"Matrix of type <%s> does not support checking for symmetric",
5391 	       mattype);
5392     }
5393     ierr = (*A->ops->issymmetric)(A,&A->symmetric); CHKERRQ(ierr);
5394     A->symmetric_set = PETSC_TRUE;
5395     if (A->symmetric) {
5396       A->structurally_symmetric_set = PETSC_TRUE;
5397       A->structurally_symmetric     = PETSC_TRUE;
5398     }
5399   }
5400   *flg = A->symmetric;
5401   PetscFunctionReturn(0);
5402 }
5403 
5404 #undef __FUNCT__
5405 #define __FUNCT__ "MatIsStructurallySymmetric"
5406 /*@C
5407    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
5408 
5409    Collective on Mat
5410 
5411    Input Parameter:
5412 .  A - the matrix to test
5413 
5414    Output Parameters:
5415 .  flg - the result
5416 
5417    Level: intermediate
5418 
5419    Concepts: matrix^symmetry
5420 
5421 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
5422 @*/
5423 int MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
5424 {
5425   int ierr;
5426 
5427   PetscFunctionBegin;
5428   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5429   PetscValidPointer(flg,2);
5430   if (!A->structurally_symmetric_set) {
5431     if (!A->ops->isstructurallysymmetric) SETERRQ(1,"Matrix does not support checking for structural symmetric");
5432     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
5433     A->structurally_symmetric_set = PETSC_TRUE;
5434   }
5435   *flg = A->structurally_symmetric;
5436   PetscFunctionReturn(0);
5437 }
5438 
5439 #undef __FUNCT__
5440 #define __FUNCT__ "MatIsHermitian"
5441 /*@C
5442    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.
5443 
5444    Collective on Mat
5445 
5446    Input Parameter:
5447 .  A - the matrix to test
5448 
5449    Output Parameters:
5450 .  flg - the result
5451 
5452    Level: intermediate
5453 
5454    Concepts: matrix^symmetry
5455 
5456 .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
5457 @*/
5458 int MatIsHermitian(Mat A,PetscTruth *flg)
5459 {
5460   int ierr;
5461 
5462   PetscFunctionBegin;
5463   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5464   PetscValidPointer(flg,2);
5465   if (!A->hermitian_set) {
5466     if (!A->ops->ishermitian) SETERRQ(1,"Matrix does not support checking for being Hermitian");
5467     ierr = (*A->ops->ishermitian)(A,&A->hermitian);CHKERRQ(ierr);
5468     A->hermitian_set = PETSC_TRUE;
5469     if (A->hermitian) {
5470       A->structurally_symmetric_set = PETSC_TRUE;
5471       A->structurally_symmetric     = PETSC_TRUE;
5472     }
5473   }
5474   *flg = A->hermitian;
5475   PetscFunctionReturn(0);
5476 }
5477