xref: /petsc/src/mat/interface/matrix.c (revision bf26f7e935f39f9c40e49c3c6aaf15d72c25d5bc)
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);
90   PetscValidType(mat);
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);
143   PetscValidIntPointer(ncols);
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);
227   PetscValidType(mat);
228   MatPreallocated(mat);
229   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mat->comm);
230   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE);
231   PetscCheckSameComm(mat,viewer);
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);
305   PetscValidType(mat);
306   MatPreallocated(mat);
307   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);}
308   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,b);}
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);
349   PetscValidType(mat);
350   MatPreallocated(mat);
351   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);}
352   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,b);}
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);
388   PetscValidType(mat);
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);
415   PetscValidType(A);
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);
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);
519   PetscValidType(mat);
520   MatPreallocated(mat);
521   PetscValidIntPointer(idxm);
522   PetscValidIntPointer(idxn);
523   PetscValidScalarPointer(v);
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);
624   PetscValidType(mat);
625   PetscValidIntPointer(idxm);
626   PetscValidIntPointer(idxn);
627   PetscValidScalarPointer(v);
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);
728   PetscValidType(mat);
729   PetscValidIntPointer(idxm);
730   PetscValidIntPointer(idxn);
731   PetscValidScalarPointer(v);
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);
793   PetscValidIntPointer(dims);
794   PetscValidIntPointer(starts);
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);
861   PetscValidType(mat);
862   MatPreallocated(mat);
863   PetscValidIntPointer(idxm);
864   PetscValidIntPointer(idxn);
865   PetscValidScalarPointer(v);
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);
925   PetscValidType(mat);
926   MatPreallocated(mat);
927   PetscValidIntPointer(idxm);
928   PetscValidIntPointer(idxn);
929   PetscValidScalarPointer(v);
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);
966   PetscValidType(x);
967   MatPreallocated(x);
968   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
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);
1009   PetscValidType(x);
1010   MatPreallocated(x);
1011   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
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);
1062   PetscValidType(mat);
1063   MatPreallocated(mat);
1064   PetscValidIntPointer(irow);
1065   PetscValidIntPointer(icol);
1066   PetscValidScalarPointer(y);
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);
1138   PetscValidType(mat);
1139   MatPreallocated(mat);
1140   PetscValidIntPointer(irow);
1141   PetscValidIntPointer(icol);
1142   PetscValidScalarPointer(y);
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);
1202   PetscValidType(mat);
1203   MatPreallocated(mat);
1204   PetscValidHeaderSpecific(x,VEC_COOKIE);
1205   PetscValidHeaderSpecific(y,VEC_COOKIE);
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);
1262   PetscValidType(mat);
1263   MatPreallocated(mat);
1264   PetscValidHeaderSpecific(x,VEC_COOKIE);
1265   PetscValidHeaderSpecific(y,VEC_COOKIE);
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);
1321   PetscValidType(mat);
1322   MatPreallocated(mat);
1323   PetscValidHeaderSpecific(v1,VEC_COOKIE);
1324   PetscValidHeaderSpecific(v2,VEC_COOKIE);
1325   PetscValidHeaderSpecific(v3,VEC_COOKIE);
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);
1373   PetscValidType(mat);
1374   MatPreallocated(mat);
1375   PetscValidHeaderSpecific(v1,VEC_COOKIE);
1376   PetscValidHeaderSpecific(v2,VEC_COOKIE);
1377   PetscValidHeaderSpecific(v3,VEC_COOKIE);
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);
1424   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1425   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1426   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1427   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1428   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1429   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1430   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1431 
1432   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1433   ierr = (*mat->ops->multconstrained)(mat,x,y); CHKERRQ(ierr);
1434   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1435   ierr = PetscObjectIncreaseState((PetscObject)y); CHKERRQ(ierr);
1436 
1437   PetscFunctionReturn(0);
1438 }
1439 
1440 #undef __FUNCT__
1441 #define __FUNCT__ "MatMultTransposeConstrained"
1442 /*@
1443    MatMultTransposeConstrained - The inner multiplication routine for a
1444    constrained matrix P^T A^T P.
1445 
1446    Collective on Mat and Vec
1447 
1448    Input Parameters:
1449 +  mat - the matrix
1450 -  x   - the vector to be multilplied
1451 
1452    Output Parameters:
1453 .  y - the result
1454 
1455    Notes:
1456    The vectors x and y cannot be the same.  I.e., one cannot
1457    call MatMult(A,y,y).
1458 
1459    Level: beginner
1460 
1461 .keywords: matrix, multiply, matrix-vector product, constraint
1462 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1463 @*/
1464 int MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1465 {
1466   int ierr;
1467 
1468   PetscFunctionBegin;
1469   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1470   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1471   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1472   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1473   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1474   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1475   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1476 
1477   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1478   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
1479   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1480   ierr = PetscObjectIncreaseState((PetscObject)y); CHKERRQ(ierr);
1481 
1482   PetscFunctionReturn(0);
1483 }
1484 /* ------------------------------------------------------------*/
1485 #undef __FUNCT__
1486 #define __FUNCT__ "MatGetInfo"
1487 /*@C
1488    MatGetInfo - Returns information about matrix storage (number of
1489    nonzeros, memory, etc.).
1490 
1491    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1492    as the flag
1493 
1494    Input Parameters:
1495 .  mat - the matrix
1496 
1497    Output Parameters:
1498 +  flag - flag indicating the type of parameters to be returned
1499    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1500    MAT_GLOBAL_SUM - sum over all processors)
1501 -  info - matrix information context
1502 
1503    Notes:
1504    The MatInfo context contains a variety of matrix data, including
1505    number of nonzeros allocated and used, number of mallocs during
1506    matrix assembly, etc.  Additional information for factored matrices
1507    is provided (such as the fill ratio, number of mallocs during
1508    factorization, etc.).  Much of this info is printed to STDOUT
1509    when using the runtime options
1510 $       -log_info -mat_view_info
1511 
1512    Example for C/C++ Users:
1513    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1514    data within the MatInfo context.  For example,
1515 .vb
1516       MatInfo info;
1517       Mat     A;
1518       double  mal, nz_a, nz_u;
1519 
1520       MatGetInfo(A,MAT_LOCAL,&info);
1521       mal  = info.mallocs;
1522       nz_a = info.nz_allocated;
1523 .ve
1524 
1525    Example for Fortran Users:
1526    Fortran users should declare info as a double precision
1527    array of dimension MAT_INFO_SIZE, and then extract the parameters
1528    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
1529    a complete list of parameter names.
1530 .vb
1531       double  precision info(MAT_INFO_SIZE)
1532       double  precision mal, nz_a
1533       Mat     A
1534       integer ierr
1535 
1536       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1537       mal = info(MAT_INFO_MALLOCS)
1538       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1539 .ve
1540 
1541     Level: intermediate
1542 
1543     Concepts: matrices^getting information on
1544 
1545 @*/
1546 int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1547 {
1548   int ierr;
1549 
1550   PetscFunctionBegin;
1551   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1552   PetscValidType(mat);
1553   MatPreallocated(mat);
1554   PetscValidPointer(info);
1555   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1556   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
1557   PetscFunctionReturn(0);
1558 }
1559 
1560 /* ----------------------------------------------------------*/
1561 #undef __FUNCT__
1562 #define __FUNCT__ "MatILUDTFactor"
1563 /*@C
1564    MatILUDTFactor - Performs a drop tolerance ILU factorization.
1565 
1566    Collective on Mat
1567 
1568    Input Parameters:
1569 +  mat - the matrix
1570 .  info - information about the factorization to be done
1571 .  row - row permutation
1572 -  col - column permutation
1573 
1574    Output Parameters:
1575 .  fact - the factored matrix
1576 
1577    Level: developer
1578 
1579    Notes:
1580    Most users should employ the simplified KSP interface for linear solvers
1581    instead of working directly with matrix algebra routines such as this.
1582    See, e.g., KSPCreate().
1583 
1584    This is currently only supported for the SeqAIJ matrix format using code
1585    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
1586    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
1587    and thus can be distributed with PETSc.
1588 
1589     Concepts: matrices^ILUDT factorization
1590 
1591 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1592 @*/
1593 int MatILUDTFactor(Mat mat,MatFactorInfo *info,IS row,IS col,Mat *fact)
1594 {
1595   int ierr;
1596 
1597   PetscFunctionBegin;
1598   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1599   PetscValidType(mat);
1600   MatPreallocated(mat);
1601   PetscValidPointer(fact);
1602   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1603   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1604   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1605 
1606   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1607   ierr = (*mat->ops->iludtfactor)(mat,info,row,col,fact);CHKERRQ(ierr);
1608   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1609   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1610 
1611   PetscFunctionReturn(0);
1612 }
1613 
1614 #undef __FUNCT__
1615 #define __FUNCT__ "MatLUFactor"
1616 /*@
1617    MatLUFactor - Performs in-place LU factorization of matrix.
1618 
1619    Collective on Mat
1620 
1621    Input Parameters:
1622 +  mat - the matrix
1623 .  row - row permutation
1624 .  col - column permutation
1625 -  info - options for factorization, includes
1626 $          fill - expected fill as ratio of original fill.
1627 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1628 $                   Run with the option -log_info to determine an optimal value to use
1629 
1630    Notes:
1631    Most users should employ the simplified KSP interface for linear solvers
1632    instead of working directly with matrix algebra routines such as this.
1633    See, e.g., KSPCreate().
1634 
1635    This changes the state of the matrix to a factored matrix; it cannot be used
1636    for example with MatSetValues() unless one first calls MatSetUnfactored().
1637 
1638    Level: developer
1639 
1640    Concepts: matrices^LU factorization
1641 
1642 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
1643           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
1644 
1645 @*/
1646 int MatLUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1647 {
1648   int ierr;
1649 
1650   PetscFunctionBegin;
1651   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1652   PetscValidType(mat);
1653   MatPreallocated(mat);
1654   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1655   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1656   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1657 
1658   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1659   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
1660   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1661   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
1662   PetscFunctionReturn(0);
1663 }
1664 
1665 #undef __FUNCT__
1666 #define __FUNCT__ "MatILUFactor"
1667 /*@
1668    MatILUFactor - Performs in-place ILU factorization of matrix.
1669 
1670    Collective on Mat
1671 
1672    Input Parameters:
1673 +  mat - the matrix
1674 .  row - row permutation
1675 .  col - column permutation
1676 -  info - structure containing
1677 $      levels - number of levels of fill.
1678 $      expected fill - as ratio of original fill.
1679 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1680                 missing diagonal entries)
1681 
1682    Notes:
1683    Probably really in-place only when level of fill is zero, otherwise allocates
1684    new space to store factored matrix and deletes previous memory.
1685 
1686    Most users should employ the simplified KSP interface for linear solvers
1687    instead of working directly with matrix algebra routines such as this.
1688    See, e.g., KSPCreate().
1689 
1690    Level: developer
1691 
1692    Concepts: matrices^ILU factorization
1693 
1694 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1695 @*/
1696 int MatILUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1697 {
1698   int ierr;
1699 
1700   PetscFunctionBegin;
1701   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1702   PetscValidType(mat);
1703   MatPreallocated(mat);
1704   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
1705   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1706   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1707   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1708 
1709   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1710   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
1711   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1712   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
1713   PetscFunctionReturn(0);
1714 }
1715 
1716 #undef __FUNCT__
1717 #define __FUNCT__ "MatLUFactorSymbolic"
1718 /*@
1719    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1720    Call this routine before calling MatLUFactorNumeric().
1721 
1722    Collective on Mat
1723 
1724    Input Parameters:
1725 +  mat - the matrix
1726 .  row, col - row and column permutations
1727 -  info - options for factorization, includes
1728 $          fill - expected fill as ratio of original fill.
1729 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1730 $                   Run with the option -log_info to determine an optimal value to use
1731 
1732    Output Parameter:
1733 .  fact - new matrix that has been symbolically factored
1734 
1735    Notes:
1736    See the users manual for additional information about
1737    choosing the fill factor for better efficiency.
1738 
1739    Most users should employ the simplified KSP interface for linear solvers
1740    instead of working directly with matrix algebra routines such as this.
1741    See, e.g., KSPCreate().
1742 
1743    Level: developer
1744 
1745    Concepts: matrices^LU symbolic factorization
1746 
1747 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1748 @*/
1749 int MatLUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
1750 {
1751   int ierr;
1752 
1753   PetscFunctionBegin;
1754   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1755   PetscValidType(mat);
1756   MatPreallocated(mat);
1757   PetscValidPointer(fact);
1758   PetscValidHeaderSpecific(row,IS_COOKIE);
1759   PetscValidHeaderSpecific(col,IS_COOKIE);
1760   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1761   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1762   if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",mat->type_name);
1763 
1764   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1765   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
1766   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1767   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1768   PetscFunctionReturn(0);
1769 }
1770 
1771 #undef __FUNCT__
1772 #define __FUNCT__ "MatLUFactorNumeric"
1773 /*@
1774    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1775    Call this routine after first calling MatLUFactorSymbolic().
1776 
1777    Collective on Mat
1778 
1779    Input Parameters:
1780 +  mat - the matrix
1781 -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()
1782 
1783    Notes:
1784    See MatLUFactor() for in-place factorization.  See
1785    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
1786 
1787    Most users should employ the simplified KSP interface for linear solvers
1788    instead of working directly with matrix algebra routines such as this.
1789    See, e.g., KSPCreate().
1790 
1791    Level: developer
1792 
1793    Concepts: matrices^LU numeric factorization
1794 
1795 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1796 @*/
1797 int MatLUFactorNumeric(Mat mat,Mat *fact)
1798 {
1799   int        ierr;
1800 
1801   PetscFunctionBegin;
1802   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1803   PetscValidType(mat);
1804   MatPreallocated(mat);
1805   PetscValidPointer(fact);
1806   PetscValidHeaderSpecific(*fact,MAT_COOKIE);
1807   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1808   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1809     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d",
1810             mat->M,(*fact)->M,mat->N,(*fact)->N);
1811   }
1812   if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1813 
1814   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1815   ierr = (*(*fact)->ops->lufactornumeric)(mat,fact);CHKERRQ(ierr);
1816   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1817 
1818   ierr = MatView_Private(*fact);CHKERRQ(ierr);
1819   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1820   PetscFunctionReturn(0);
1821 }
1822 
1823 #undef __FUNCT__
1824 #define __FUNCT__ "MatCholeskyFactor"
1825 /*@
1826    MatCholeskyFactor - Performs in-place Cholesky factorization of a
1827    symmetric matrix.
1828 
1829    Collective on Mat
1830 
1831    Input Parameters:
1832 +  mat - the matrix
1833 .  perm - row and column permutations
1834 -  f - expected fill as ratio of original fill
1835 
1836    Notes:
1837    See MatLUFactor() for the nonsymmetric case.  See also
1838    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
1839 
1840    Most users should employ the simplified KSP interface for linear solvers
1841    instead of working directly with matrix algebra routines such as this.
1842    See, e.g., KSPCreate().
1843 
1844    Level: developer
1845 
1846    Concepts: matrices^Cholesky factorization
1847 
1848 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
1849           MatGetOrdering()
1850 
1851 @*/
1852 int MatCholeskyFactor(Mat mat,IS perm,MatFactorInfo *info)
1853 {
1854   int ierr;
1855 
1856   PetscFunctionBegin;
1857   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1858   PetscValidType(mat);
1859   MatPreallocated(mat);
1860   PetscValidHeaderSpecific(perm,IS_COOKIE);
1861   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1862   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1863   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1864   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1865 
1866   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1867   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
1868   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1869   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
1870   PetscFunctionReturn(0);
1871 }
1872 
1873 #undef __FUNCT__
1874 #define __FUNCT__ "MatCholeskyFactorSymbolic"
1875 /*@
1876    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
1877    of a symmetric matrix.
1878 
1879    Collective on Mat
1880 
1881    Input Parameters:
1882 +  mat - the matrix
1883 .  perm - row and column permutations
1884 -  info - options for factorization, includes
1885 $          fill - expected fill as ratio of original fill.
1886 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1887 $                   Run with the option -log_info to determine an optimal value to use
1888 
1889    Output Parameter:
1890 .  fact - the factored matrix
1891 
1892    Notes:
1893    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
1894    MatCholeskyFactor() and MatCholeskyFactorNumeric().
1895 
1896    Most users should employ the simplified KSP interface for linear solvers
1897    instead of working directly with matrix algebra routines such as this.
1898    See, e.g., KSPCreate().
1899 
1900    Level: developer
1901 
1902    Concepts: matrices^Cholesky symbolic factorization
1903 
1904 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
1905           MatGetOrdering()
1906 
1907 @*/
1908 int MatCholeskyFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
1909 {
1910   int ierr;
1911 
1912   PetscFunctionBegin;
1913   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1914   PetscValidType(mat);
1915   MatPreallocated(mat);
1916   PetscValidPointer(fact);
1917   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1918   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1919   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1920   if (!mat->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1921 
1922   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1923   ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
1924   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1925   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1926   PetscFunctionReturn(0);
1927 }
1928 
1929 #undef __FUNCT__
1930 #define __FUNCT__ "MatCholeskyFactorNumeric"
1931 /*@
1932    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
1933    of a symmetric matrix. Call this routine after first calling
1934    MatCholeskyFactorSymbolic().
1935 
1936    Collective on Mat
1937 
1938    Input Parameter:
1939 .  mat - the initial matrix
1940 
1941    Output Parameter:
1942 .  fact - the factored matrix
1943 
1944    Notes:
1945    Most users should employ the simplified KSP interface for linear solvers
1946    instead of working directly with matrix algebra routines such as this.
1947    See, e.g., KSPCreate().
1948 
1949    Level: developer
1950 
1951    Concepts: matrices^Cholesky numeric factorization
1952 
1953 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
1954 @*/
1955 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
1956 {
1957   int ierr;
1958 
1959   PetscFunctionBegin;
1960   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1961   PetscValidType(mat);
1962   MatPreallocated(mat);
1963   PetscValidPointer(fact);
1964   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1965   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1966   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1967     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d",
1968             mat->M,(*fact)->M,mat->N,(*fact)->N);
1969   }
1970 
1971   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1972   ierr = (*(*fact)->ops->choleskyfactornumeric)(mat,fact);CHKERRQ(ierr);
1973   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1974   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1975   PetscFunctionReturn(0);
1976 }
1977 
1978 /* ----------------------------------------------------------------*/
1979 #undef __FUNCT__
1980 #define __FUNCT__ "MatSolve"
1981 /*@
1982    MatSolve - Solves A x = b, given a factored matrix.
1983 
1984    Collective on Mat and Vec
1985 
1986    Input Parameters:
1987 +  mat - the factored matrix
1988 -  b - the right-hand-side vector
1989 
1990    Output Parameter:
1991 .  x - the result vector
1992 
1993    Notes:
1994    The vectors b and x cannot be the same.  I.e., one cannot
1995    call MatSolve(A,x,x).
1996 
1997    Notes:
1998    Most users should employ the simplified KSP interface for linear solvers
1999    instead of working directly with matrix algebra routines such as this.
2000    See, e.g., KSPCreate().
2001 
2002    Level: developer
2003 
2004    Concepts: matrices^triangular solves
2005 
2006 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2007 @*/
2008 int MatSolve(Mat mat,Vec b,Vec x)
2009 {
2010   int ierr;
2011 
2012   PetscFunctionBegin;
2013   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2014   PetscValidType(mat);
2015   MatPreallocated(mat);
2016   PetscValidHeaderSpecific(b,VEC_COOKIE);
2017   PetscValidHeaderSpecific(x,VEC_COOKIE);
2018   PetscCheckSameComm(mat,b);
2019   PetscCheckSameComm(mat,x);
2020   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2021   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2022   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2023   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2024   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2025   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
2026 
2027   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2028   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2029   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
2030   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2031   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2032   PetscFunctionReturn(0);
2033 }
2034 
2035 #undef __FUNCT__
2036 #define __FUNCT__ "MatForwardSolve"
2037 /* @
2038    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
2039 
2040    Collective on Mat and Vec
2041 
2042    Input Parameters:
2043 +  mat - the factored matrix
2044 -  b - the right-hand-side vector
2045 
2046    Output Parameter:
2047 .  x - the result vector
2048 
2049    Notes:
2050    MatSolve() should be used for most applications, as it performs
2051    a forward solve followed by a backward solve.
2052 
2053    The vectors b and x cannot be the same.  I.e., one cannot
2054    call MatForwardSolve(A,x,x).
2055 
2056    Most users should employ the simplified KSP interface for linear solvers
2057    instead of working directly with matrix algebra routines such as this.
2058    See, e.g., KSPCreate().
2059 
2060    Level: developer
2061 
2062    Concepts: matrices^forward solves
2063 
2064 .seealso: MatSolve(), MatBackwardSolve()
2065 @ */
2066 int MatForwardSolve(Mat mat,Vec b,Vec x)
2067 {
2068   int ierr;
2069 
2070   PetscFunctionBegin;
2071   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2072   PetscValidType(mat);
2073   MatPreallocated(mat);
2074   PetscValidHeaderSpecific(b,VEC_COOKIE);
2075   PetscValidHeaderSpecific(x,VEC_COOKIE);
2076   PetscCheckSameComm(mat,b);
2077   PetscCheckSameComm(mat,x);
2078   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2079   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2080   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2081   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2082   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2083   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2084 
2085   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2086   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
2087   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2088   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2089   PetscFunctionReturn(0);
2090 }
2091 
2092 #undef __FUNCT__
2093 #define __FUNCT__ "MatBackwardSolve"
2094 /* @
2095    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2096 
2097    Collective on Mat and Vec
2098 
2099    Input Parameters:
2100 +  mat - the factored matrix
2101 -  b - the right-hand-side vector
2102 
2103    Output Parameter:
2104 .  x - the result vector
2105 
2106    Notes:
2107    MatSolve() should be used for most applications, as it performs
2108    a forward solve followed by a backward solve.
2109 
2110    The vectors b and x cannot be the same.  I.e., one cannot
2111    call MatBackwardSolve(A,x,x).
2112 
2113    Most users should employ the simplified KSP interface for linear solvers
2114    instead of working directly with matrix algebra routines such as this.
2115    See, e.g., KSPCreate().
2116 
2117    Level: developer
2118 
2119    Concepts: matrices^backward solves
2120 
2121 .seealso: MatSolve(), MatForwardSolve()
2122 @ */
2123 int MatBackwardSolve(Mat mat,Vec b,Vec x)
2124 {
2125   int ierr;
2126 
2127   PetscFunctionBegin;
2128   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2129   PetscValidType(mat);
2130   MatPreallocated(mat);
2131   PetscValidHeaderSpecific(b,VEC_COOKIE);
2132   PetscValidHeaderSpecific(x,VEC_COOKIE);
2133   PetscCheckSameComm(mat,b);
2134   PetscCheckSameComm(mat,x);
2135   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2136   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2137   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2138   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2139   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2140   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2141 
2142   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2143   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
2144   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2145   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2146   PetscFunctionReturn(0);
2147 }
2148 
2149 #undef __FUNCT__
2150 #define __FUNCT__ "MatSolveAdd"
2151 /*@
2152    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2153 
2154    Collective on Mat and Vec
2155 
2156    Input Parameters:
2157 +  mat - the factored matrix
2158 .  b - the right-hand-side vector
2159 -  y - the vector to be added to
2160 
2161    Output Parameter:
2162 .  x - the result vector
2163 
2164    Notes:
2165    The vectors b and x cannot be the same.  I.e., one cannot
2166    call MatSolveAdd(A,x,y,x).
2167 
2168    Most users should employ the simplified KSP interface for linear solvers
2169    instead of working directly with matrix algebra routines such as this.
2170    See, e.g., KSPCreate().
2171 
2172    Level: developer
2173 
2174    Concepts: matrices^triangular solves
2175 
2176 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2177 @*/
2178 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2179 {
2180   PetscScalar one = 1.0;
2181   Vec    tmp;
2182   int    ierr;
2183 
2184   PetscFunctionBegin;
2185   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2186   PetscValidType(mat);
2187   MatPreallocated(mat);
2188   PetscValidHeaderSpecific(y,VEC_COOKIE);
2189   PetscValidHeaderSpecific(b,VEC_COOKIE);
2190   PetscValidHeaderSpecific(x,VEC_COOKIE);
2191   PetscCheckSameComm(mat,b);
2192   PetscCheckSameComm(mat,y);
2193   PetscCheckSameComm(mat,x);
2194   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2195   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2196   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2197   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2198   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
2199   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2200   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2201 
2202   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2203   if (mat->ops->solveadd)  {
2204     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2205   } else {
2206     /* do the solve then the add manually */
2207     if (x != y) {
2208       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2209       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2210     } else {
2211       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2212       PetscLogObjectParent(mat,tmp);
2213       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2214       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2215       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2216       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2217     }
2218   }
2219   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2220   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2221   PetscFunctionReturn(0);
2222 }
2223 
2224 #undef __FUNCT__
2225 #define __FUNCT__ "MatSolveTranspose"
2226 /*@
2227    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2228 
2229    Collective on Mat and Vec
2230 
2231    Input Parameters:
2232 +  mat - the factored matrix
2233 -  b - the right-hand-side vector
2234 
2235    Output Parameter:
2236 .  x - the result vector
2237 
2238    Notes:
2239    The vectors b and x cannot be the same.  I.e., one cannot
2240    call MatSolveTranspose(A,x,x).
2241 
2242    Most users should employ the simplified KSP interface for linear solvers
2243    instead of working directly with matrix algebra routines such as this.
2244    See, e.g., KSPCreate().
2245 
2246    Level: developer
2247 
2248    Concepts: matrices^triangular solves
2249 
2250 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2251 @*/
2252 int MatSolveTranspose(Mat mat,Vec b,Vec x)
2253 {
2254   int ierr;
2255 
2256   PetscFunctionBegin;
2257   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2258   PetscValidType(mat);
2259   MatPreallocated(mat);
2260   PetscValidHeaderSpecific(b,VEC_COOKIE);
2261   PetscValidHeaderSpecific(x,VEC_COOKIE);
2262   PetscCheckSameComm(mat,b);
2263   PetscCheckSameComm(mat,x);
2264   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2265   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2266   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name);
2267   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2268   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2269 
2270   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2271   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2272   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2273   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2274   PetscFunctionReturn(0);
2275 }
2276 
2277 #undef __FUNCT__
2278 #define __FUNCT__ "MatSolveTransposeAdd"
2279 /*@
2280    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2281                       factored matrix.
2282 
2283    Collective on Mat and Vec
2284 
2285    Input Parameters:
2286 +  mat - the factored matrix
2287 .  b - the right-hand-side vector
2288 -  y - the vector to be added to
2289 
2290    Output Parameter:
2291 .  x - the result vector
2292 
2293    Notes:
2294    The vectors b and x cannot be the same.  I.e., one cannot
2295    call MatSolveTransposeAdd(A,x,y,x).
2296 
2297    Most users should employ the simplified KSP interface for linear solvers
2298    instead of working directly with matrix algebra routines such as this.
2299    See, e.g., KSPCreate().
2300 
2301    Level: developer
2302 
2303    Concepts: matrices^triangular solves
2304 
2305 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2306 @*/
2307 int MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2308 {
2309   PetscScalar one = 1.0;
2310   int         ierr;
2311   Vec         tmp;
2312 
2313   PetscFunctionBegin;
2314   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2315   PetscValidType(mat);
2316   MatPreallocated(mat);
2317   PetscValidHeaderSpecific(y,VEC_COOKIE);
2318   PetscValidHeaderSpecific(b,VEC_COOKIE);
2319   PetscValidHeaderSpecific(x,VEC_COOKIE);
2320   PetscCheckSameComm(mat,b);
2321   PetscCheckSameComm(mat,y);
2322   PetscCheckSameComm(mat,x);
2323   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2324   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2325   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2326   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2327   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
2328   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2329 
2330   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2331   if (mat->ops->solvetransposeadd) {
2332     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
2333   } else {
2334     /* do the solve then the add manually */
2335     if (x != y) {
2336       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2337       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2338     } else {
2339       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2340       PetscLogObjectParent(mat,tmp);
2341       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2342       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2343       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2344       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2345     }
2346   }
2347   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2348   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2349   PetscFunctionReturn(0);
2350 }
2351 /* ----------------------------------------------------------------*/
2352 
2353 #undef __FUNCT__
2354 #define __FUNCT__ "MatRelax"
2355 /*@
2356    MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2357 
2358    Collective on Mat and Vec
2359 
2360    Input Parameters:
2361 +  mat - the matrix
2362 .  b - the right hand side
2363 .  omega - the relaxation factor
2364 .  flag - flag indicating the type of SOR (see below)
2365 .  shift -  diagonal shift
2366 -  its - the number of iterations
2367 -  lits - the number of local iterations
2368 
2369    Output Parameters:
2370 .  x - the solution (can contain an initial guess)
2371 
2372    SOR Flags:
2373 .     SOR_FORWARD_SWEEP - forward SOR
2374 .     SOR_BACKWARD_SWEEP - backward SOR
2375 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2376 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
2377 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
2378 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2379 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
2380          upper/lower triangular part of matrix to
2381          vector (with omega)
2382 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
2383 
2384    Notes:
2385    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2386    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
2387    on each processor.
2388 
2389    Application programmers will not generally use MatRelax() directly,
2390    but instead will employ the KSP/PC interface.
2391 
2392    Notes for Advanced Users:
2393    The flags are implemented as bitwise inclusive or operations.
2394    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2395    to specify a zero initial guess for SSOR.
2396 
2397    Most users should employ the simplified KSP interface for linear solvers
2398    instead of working directly with matrix algebra routines such as this.
2399    See, e.g., KSPCreate().
2400 
2401    See also, MatPBRelax(). This routine will automatically call the point block
2402    version if the point version is not available.
2403 
2404    Level: developer
2405 
2406    Concepts: matrices^relaxation
2407    Concepts: matrices^SOR
2408    Concepts: matrices^Gauss-Seidel
2409 
2410 @*/
2411 int MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x)
2412 {
2413   int ierr;
2414 
2415   PetscFunctionBegin;
2416   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2417   PetscValidType(mat);
2418   MatPreallocated(mat);
2419   PetscValidHeaderSpecific(b,VEC_COOKIE);
2420   PetscValidHeaderSpecific(x,VEC_COOKIE);
2421   PetscCheckSameComm(mat,b);
2422   PetscCheckSameComm(mat,x);
2423   if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2424   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2425   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2426   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2427   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2428   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2429 
2430   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2431   if (mat->ops->relax) {
2432     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2433   } else {
2434     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2435   }
2436   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2437   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2438   PetscFunctionReturn(0);
2439 }
2440 
2441 #undef __FUNCT__
2442 #define __FUNCT__ "MatPBRelax"
2443 /*@
2444    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2445 
2446    Collective on Mat and Vec
2447 
2448    See MatRelax() for usage
2449 
2450    For multi-component PDEs where the Jacobian is stored in a point block format
2451    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
2452    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
2453    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
2454 
2455    Level: developer
2456 
2457 @*/
2458 int MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x)
2459 {
2460   int ierr;
2461 
2462   PetscFunctionBegin;
2463   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2464   PetscValidType(mat);
2465   MatPreallocated(mat);
2466   PetscValidHeaderSpecific(b,VEC_COOKIE);
2467   PetscValidHeaderSpecific(x,VEC_COOKIE);
2468   PetscCheckSameComm(mat,b);
2469   PetscCheckSameComm(mat,x);
2470   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2471   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2472   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2473   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2474   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2475   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2476 
2477   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2478   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2479   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2480   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2481   PetscFunctionReturn(0);
2482 }
2483 
2484 #undef __FUNCT__
2485 #define __FUNCT__ "MatCopy_Basic"
2486 /*
2487       Default matrix copy routine.
2488 */
2489 int MatCopy_Basic(Mat A,Mat B,MatStructure str)
2490 {
2491   int         ierr,i,rstart,rend,nz,*cwork;
2492   PetscScalar *vwork;
2493 
2494   PetscFunctionBegin;
2495   ierr = MatZeroEntries(B);CHKERRQ(ierr);
2496   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
2497   for (i=rstart; i<rend; i++) {
2498     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2499     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
2500     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2501   }
2502   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2503   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2504   ierr = PetscObjectIncreaseState((PetscObject)B); CHKERRQ(ierr);
2505   PetscFunctionReturn(0);
2506 }
2507 
2508 #undef __FUNCT__
2509 #define __FUNCT__ "MatCopy"
2510 /*@C
2511    MatCopy - Copys a matrix to another matrix.
2512 
2513    Collective on Mat
2514 
2515    Input Parameters:
2516 +  A - the matrix
2517 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
2518 
2519    Output Parameter:
2520 .  B - where the copy is put
2521 
2522    Notes:
2523    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
2524    same nonzero pattern or the routine will crash.
2525 
2526    MatCopy() copies the matrix entries of a matrix to another existing
2527    matrix (after first zeroing the second matrix).  A related routine is
2528    MatConvert(), which first creates a new matrix and then copies the data.
2529 
2530    Level: intermediate
2531 
2532    Concepts: matrices^copying
2533 
2534 .seealso: MatConvert(), MatDuplicate()
2535 
2536 @*/
2537 int MatCopy(Mat A,Mat B,MatStructure str)
2538 {
2539   int ierr;
2540 
2541   PetscFunctionBegin;
2542   PetscValidHeaderSpecific(A,MAT_COOKIE);
2543   PetscValidHeaderSpecific(B,MAT_COOKIE);
2544   PetscValidType(A);
2545   MatPreallocated(A);
2546   PetscValidType(B);
2547   MatPreallocated(B);
2548   PetscCheckSameComm(A,B);
2549   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2550   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2551   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,
2552                                              A->N,B->N);
2553 
2554   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2555   if (A->ops->copy) {
2556     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
2557   } else { /* generic conversion */
2558     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2559   }
2560   if (A->mapping) {
2561     if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);B->mapping = 0;}
2562     ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr);
2563   }
2564   if (A->bmapping) {
2565     if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);B->bmapping = 0;}
2566     ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr);
2567   }
2568   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2569   ierr = PetscObjectIncreaseState((PetscObject)B); CHKERRQ(ierr);
2570   PetscFunctionReturn(0);
2571 }
2572 
2573 #include "petscsys.h"
2574 PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
2575 PetscFList MatConvertList              = 0;
2576 
2577 #undef __FUNCT__
2578 #define __FUNCT__ "MatConvertRegister"
2579 /*@C
2580     MatConvertRegister - Allows one to register a routine that converts a sparse matrix
2581         from one format to another.
2582 
2583   Not Collective
2584 
2585   Input Parameters:
2586 +   type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ.
2587 -   Converter - the function that reads the matrix from the binary file.
2588 
2589   Level: developer
2590 
2591 .seealso: MatConvertRegisterAll(), MatConvert()
2592 
2593 @*/
2594 int MatConvertRegister(const char sname[],const char path[],const char name[],int (*function)(Mat,MatType,Mat*))
2595 {
2596   int  ierr;
2597   char fullname[PETSC_MAX_PATH_LEN];
2598 
2599   PetscFunctionBegin;
2600   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
2601   ierr = PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
2602   PetscFunctionReturn(0);
2603 }
2604 
2605 #undef __FUNCT__
2606 #define __FUNCT__ "MatConvert"
2607 /*@C
2608    MatConvert - Converts a matrix to another matrix, either of the same
2609    or different type.
2610 
2611    Collective on Mat
2612 
2613    Input Parameters:
2614 +  mat - the matrix
2615 -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
2616    same type as the original matrix.
2617 
2618    Output Parameter:
2619 .  M - pointer to place new matrix
2620 
2621    Notes:
2622    MatConvert() first creates a new matrix and then copies the data from
2623    the first matrix.  A related routine is MatCopy(), which copies the matrix
2624    entries of one matrix to another already existing matrix context.
2625 
2626    Level: intermediate
2627 
2628    Concepts: matrices^converting between storage formats
2629 
2630 .seealso: MatCopy(), MatDuplicate()
2631 @*/
2632 int MatConvert(Mat mat,const MatType newtype,Mat *M)
2633 {
2634   int        ierr;
2635   PetscTruth sametype,issame,flg;
2636   char       convname[256],mtype[256];
2637 
2638   PetscFunctionBegin;
2639   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2640   PetscValidType(mat);
2641   MatPreallocated(mat);
2642   PetscValidPointer(M);
2643   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2644   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2645 
2646   ierr = PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
2647   if (flg) {
2648     newtype = mtype;
2649   }
2650   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2651 
2652   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
2653   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
2654   if ((sametype || issame) && mat->ops->duplicate) {
2655     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
2656   } else {
2657     int (*conv)(Mat,const MatType,Mat*)=PETSC_NULL;
2658     /*
2659        Order of precedence:
2660        1) See if a specialized converter is known to the current matrix.
2661        2) See if a specialized converter is known to the desired matrix class.
2662        3) See if a good general converter is registered for the desired class
2663           (as of 6/27/03 only MATMPIADJ falls into this category).
2664        4) See if a good general converter is known for the current matrix.
2665        5) Use a really basic converter.
2666     */
2667     ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
2668     ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
2669     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
2670     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
2671     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
2672     ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
2673     if (!conv) {
2674       Mat B;
2675       ierr = MatCreate(mat->comm,0,0,0,0,&B);CHKERRQ(ierr);
2676       ierr = MatSetType(B,newtype);CHKERRQ(ierr);
2677       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
2678       ierr = MatDestroy(B);CHKERRQ(ierr);
2679       if (!conv) {
2680         if (!MatConvertRegisterAllCalled) {
2681           ierr = MatConvertRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2682         }
2683         ierr = PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);CHKERRQ(ierr);
2684         if (!conv) {
2685           if (mat->ops->convert) {
2686             conv = mat->ops->convert;
2687           } else {
2688             conv = MatConvert_Basic;
2689           }
2690         }
2691       }
2692     }
2693     ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr);
2694   }
2695   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2696   ierr = PetscObjectIncreaseState((PetscObject)*M); CHKERRQ(ierr);
2697   PetscFunctionReturn(0);
2698 }
2699 
2700 
2701 #undef __FUNCT__
2702 #define __FUNCT__ "MatDuplicate"
2703 /*@C
2704    MatDuplicate - Duplicates a matrix including the non-zero structure.
2705 
2706    Collective on Mat
2707 
2708    Input Parameters:
2709 +  mat - the matrix
2710 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
2711         values as well or not
2712 
2713    Output Parameter:
2714 .  M - pointer to place new matrix
2715 
2716    Level: intermediate
2717 
2718    Concepts: matrices^duplicating
2719 
2720 .seealso: MatCopy(), MatConvert()
2721 @*/
2722 int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
2723 {
2724   int ierr;
2725 
2726   PetscFunctionBegin;
2727   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2728   PetscValidType(mat);
2729   MatPreallocated(mat);
2730   PetscValidPointer(M);
2731   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2732   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2733 
2734   *M  = 0;
2735   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2736   if (!mat->ops->duplicate) {
2737     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
2738   }
2739   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
2740   if (mat->mapping) {
2741     ierr = MatSetLocalToGlobalMapping(*M,mat->mapping);CHKERRQ(ierr);
2742   }
2743   if (mat->bmapping) {
2744     ierr = MatSetLocalToGlobalMappingBlock(*M,mat->mapping);CHKERRQ(ierr);
2745   }
2746   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2747   ierr = PetscObjectIncreaseState((PetscObject)*M); CHKERRQ(ierr);
2748   PetscFunctionReturn(0);
2749 }
2750 
2751 #undef __FUNCT__
2752 #define __FUNCT__ "MatGetDiagonal"
2753 /*@
2754    MatGetDiagonal - Gets the diagonal of a matrix.
2755 
2756    Collective on Mat and Vec
2757 
2758    Input Parameters:
2759 +  mat - the matrix
2760 -  v - the vector for storing the diagonal
2761 
2762    Output Parameter:
2763 .  v - the diagonal of the matrix
2764 
2765    Notes:
2766    For the SeqAIJ matrix format, this routine may also be called
2767    on a LU factored matrix; in that case it routines the reciprocal of
2768    the diagonal entries in U. It returns the entries permuted by the
2769    row and column permutation used during the symbolic factorization.
2770 
2771    Level: intermediate
2772 
2773    Concepts: matrices^accessing diagonals
2774 
2775 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
2776 @*/
2777 int MatGetDiagonal(Mat mat,Vec v)
2778 {
2779   int ierr;
2780 
2781   PetscFunctionBegin;
2782   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2783   PetscValidType(mat);
2784   MatPreallocated(mat);
2785   PetscValidHeaderSpecific(v,VEC_COOKIE);
2786   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2787   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2788   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2789 
2790   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
2791   ierr = PetscObjectIncreaseState((PetscObject)v); CHKERRQ(ierr);
2792   PetscFunctionReturn(0);
2793 }
2794 
2795 #undef __FUNCT__
2796 #define __FUNCT__ "MatGetRowMax"
2797 /*@
2798    MatGetRowMax - Gets the maximum value (in absolute value) of each
2799         row of the matrix
2800 
2801    Collective on Mat and Vec
2802 
2803    Input Parameters:
2804 .  mat - the matrix
2805 
2806    Output Parameter:
2807 .  v - the vector for storing the maximums
2808 
2809    Level: intermediate
2810 
2811    Concepts: matrices^getting row maximums
2812 
2813 .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
2814 @*/
2815 int MatGetRowMax(Mat mat,Vec v)
2816 {
2817   int ierr;
2818 
2819   PetscFunctionBegin;
2820   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2821   PetscValidType(mat);
2822   MatPreallocated(mat);
2823   PetscValidHeaderSpecific(v,VEC_COOKIE);
2824   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2825   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2826   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2827 
2828   ierr = (*mat->ops->getrowmax)(mat,v);CHKERRQ(ierr);
2829   ierr = PetscObjectIncreaseState((PetscObject)v); CHKERRQ(ierr);
2830   PetscFunctionReturn(0);
2831 }
2832 
2833 #undef __FUNCT__
2834 #define __FUNCT__ "MatTranspose"
2835 /*@C
2836    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
2837 
2838    Collective on Mat
2839 
2840    Input Parameter:
2841 .  mat - the matrix to transpose
2842 
2843    Output Parameters:
2844 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
2845 
2846    Level: intermediate
2847 
2848    Concepts: matrices^transposing
2849 
2850 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
2851 @*/
2852 int MatTranspose(Mat mat,Mat *B)
2853 {
2854   int ierr;
2855 
2856   PetscFunctionBegin;
2857   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2858   PetscValidType(mat);
2859   MatPreallocated(mat);
2860   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2861   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2862   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2863 
2864   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
2865   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
2866   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
2867   if (B) {ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);}
2868   PetscFunctionReturn(0);
2869 }
2870 
2871 #undef __FUNCT__
2872 #define __FUNCT__ "MatIsTranspose"
2873 /*@C
2874    MatIsTranspose - Test whether a matrix is another one's transpose,
2875         or its own, in which case it tests symmetry.
2876 
2877    Collective on Mat
2878 
2879    Input Parameter:
2880 +  A - the matrix to test
2881 -  B - the matrix to test against, this can equal the first parameter
2882 
2883    Output Parameters:
2884 .  flg - the result
2885 
2886    Notes:
2887    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
2888    has a running time of the order of the number of nonzeros; the parallel
2889    test involves parallel copies of the block-offdiagonal parts of the matrix.
2890 
2891    Level: intermediate
2892 
2893    Concepts: matrices^transposing, matrix^symmetry
2894 
2895 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
2896 @*/
2897 int MatIsTranspose(Mat A,Mat B,PetscTruth *flg)
2898 {
2899   int ierr,(*f)(Mat,Mat,PetscTruth*),(*g)(Mat,Mat,PetscTruth*);
2900 
2901   PetscFunctionBegin;
2902   PetscValidHeaderSpecific(A,MAT_COOKIE);
2903   PetscValidHeaderSpecific(B,MAT_COOKIE);
2904   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
2905   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
2906   if (f && g) {
2907     if (f==g) {
2908       ierr = (*f)(A,B,flg);CHKERRQ(ierr);
2909     } else {
2910       SETERRQ(1,"Matrices do not have the same comparator for symmetry test");
2911     }
2912   }
2913   PetscFunctionReturn(0);
2914 }
2915 
2916 #undef __FUNCT__
2917 #define __FUNCT__ "MatPermute"
2918 /*@C
2919    MatPermute - Creates a new matrix with rows and columns permuted from the
2920    original.
2921 
2922    Collective on Mat
2923 
2924    Input Parameters:
2925 +  mat - the matrix to permute
2926 .  row - row permutation, each processor supplies only the permutation for its rows
2927 -  col - column permutation, each processor needs the entire column permutation, that is
2928          this is the same size as the total number of columns in the matrix
2929 
2930    Output Parameters:
2931 .  B - the permuted matrix
2932 
2933    Level: advanced
2934 
2935    Concepts: matrices^permuting
2936 
2937 .seealso: MatGetOrdering()
2938 @*/
2939 int MatPermute(Mat mat,IS row,IS col,Mat *B)
2940 {
2941   int ierr;
2942 
2943   PetscFunctionBegin;
2944   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2945   PetscValidType(mat);
2946   MatPreallocated(mat);
2947   PetscValidHeaderSpecific(row,IS_COOKIE);
2948   PetscValidHeaderSpecific(col,IS_COOKIE);
2949   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2950   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2951   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2952   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
2953   ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);
2954   PetscFunctionReturn(0);
2955 }
2956 
2957 #undef __FUNCT__
2958 #define __FUNCT__ "MatPermuteSparsify"
2959 /*@C
2960   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
2961   original and sparsified to the prescribed tolerance.
2962 
2963   Collective on Mat
2964 
2965   Input Parameters:
2966 + A    - The matrix to permute
2967 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
2968 . frac - The half-bandwidth as a fraction of the total size, or 0.0
2969 . tol  - The drop tolerance
2970 . rowp - The row permutation
2971 - colp - The column permutation
2972 
2973   Output Parameter:
2974 . B    - The permuted, sparsified matrix
2975 
2976   Level: advanced
2977 
2978   Note:
2979   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
2980   restrict the half-bandwidth of the resulting matrix to 5% of the
2981   total matrix size.
2982 
2983 .keywords: matrix, permute, sparsify
2984 
2985 .seealso: MatGetOrdering(), MatPermute()
2986 @*/
2987 int MatPermuteSparsify(Mat A, int band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
2988 {
2989   IS           irowp, icolp;
2990   int         *rows, *cols;
2991   int          M, N, locRowStart, locRowEnd;
2992   int          nz, newNz;
2993   int         *cwork, *cnew;
2994   PetscScalar *vwork, *vnew;
2995   int          bw, size;
2996   int          row, locRow, newRow, col, newCol;
2997   int          ierr;
2998 
2999   PetscFunctionBegin;
3000   PetscValidHeaderSpecific(A,    MAT_COOKIE);
3001   PetscValidHeaderSpecific(rowp, IS_COOKIE);
3002   PetscValidHeaderSpecific(colp, IS_COOKIE);
3003   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
3004   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
3005   if (!A->ops->permutesparsify) {
3006     ierr = MatGetSize(A, &M, &N);                                                                         CHKERRQ(ierr);
3007     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);                                             CHKERRQ(ierr);
3008     ierr = ISGetSize(rowp, &size);                                                                        CHKERRQ(ierr);
3009     if (size != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for row permutation, should be %d", size, M);
3010     ierr = ISGetSize(colp, &size);                                                                        CHKERRQ(ierr);
3011     if (size != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for column permutation, should be %d", size, N);
3012     ierr = ISInvertPermutation(rowp, 0, &irowp);                                                          CHKERRQ(ierr);
3013     ierr = ISGetIndices(irowp, &rows);                                                                    CHKERRQ(ierr);
3014     ierr = ISInvertPermutation(colp, 0, &icolp);                                                          CHKERRQ(ierr);
3015     ierr = ISGetIndices(icolp, &cols);                                                                    CHKERRQ(ierr);
3016     ierr = PetscMalloc(N * sizeof(int),         &cnew);                                                   CHKERRQ(ierr);
3017     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);                                                   CHKERRQ(ierr);
3018 
3019     /* Setup bandwidth to include */
3020     if (band == PETSC_DECIDE) {
3021       if (frac <= 0.0)
3022         bw = (int) (M * 0.05);
3023       else
3024         bw = (int) (M * frac);
3025     } else {
3026       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
3027       bw = band;
3028     }
3029 
3030     /* Put values into new matrix */
3031     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);                                                    CHKERRQ(ierr);
3032     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
3033       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);                                                      CHKERRQ(ierr);
3034       newRow   = rows[locRow]+locRowStart;
3035       for(col = 0, newNz = 0; col < nz; col++) {
3036         newCol = cols[cwork[col]];
3037         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
3038           cnew[newNz] = newCol;
3039           vnew[newNz] = vwork[col];
3040           newNz++;
3041         }
3042       }
3043       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);                              CHKERRQ(ierr);
3044       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);                                                  CHKERRQ(ierr);
3045     }
3046     ierr = PetscFree(cnew);                                                                               CHKERRQ(ierr);
3047     ierr = PetscFree(vnew);                                                                               CHKERRQ(ierr);
3048     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);                                                      CHKERRQ(ierr);
3049     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);                                                        CHKERRQ(ierr);
3050     ierr = ISRestoreIndices(irowp, &rows);                                                                CHKERRQ(ierr);
3051     ierr = ISRestoreIndices(icolp, &cols);                                                                CHKERRQ(ierr);
3052     ierr = ISDestroy(irowp);                                                                              CHKERRQ(ierr);
3053     ierr = ISDestroy(icolp);                                                                              CHKERRQ(ierr);
3054   } else {
3055     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);                                 CHKERRQ(ierr);
3056   }
3057   ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);
3058   PetscFunctionReturn(0);
3059 }
3060 
3061 #undef __FUNCT__
3062 #define __FUNCT__ "MatEqual"
3063 /*@
3064    MatEqual - Compares two matrices.
3065 
3066    Collective on Mat
3067 
3068    Input Parameters:
3069 +  A - the first matrix
3070 -  B - the second matrix
3071 
3072    Output Parameter:
3073 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
3074 
3075    Level: intermediate
3076 
3077    Concepts: matrices^equality between
3078 @*/
3079 int MatEqual(Mat A,Mat B,PetscTruth *flg)
3080 {
3081   int ierr;
3082 
3083   PetscFunctionBegin;
3084   PetscValidHeaderSpecific(A,MAT_COOKIE);
3085   PetscValidHeaderSpecific(B,MAT_COOKIE);
3086   PetscValidType(A);
3087   MatPreallocated(A);
3088   PetscValidType(B);
3089   MatPreallocated(B);
3090   PetscValidIntPointer(flg);
3091   PetscCheckSameComm(A,B);
3092   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3093   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3094   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);
3095   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
3096   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",B->type_name);
3097   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);
3098   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
3099   PetscFunctionReturn(0);
3100 }
3101 
3102 #undef __FUNCT__
3103 #define __FUNCT__ "MatDiagonalScale"
3104 /*@
3105    MatDiagonalScale - Scales a matrix on the left and right by diagonal
3106    matrices that are stored as vectors.  Either of the two scaling
3107    matrices can be PETSC_NULL.
3108 
3109    Collective on Mat
3110 
3111    Input Parameters:
3112 +  mat - the matrix to be scaled
3113 .  l - the left scaling vector (or PETSC_NULL)
3114 -  r - the right scaling vector (or PETSC_NULL)
3115 
3116    Notes:
3117    MatDiagonalScale() computes A = LAR, where
3118    L = a diagonal matrix, R = a diagonal matrix
3119 
3120    Level: intermediate
3121 
3122    Concepts: matrices^diagonal scaling
3123    Concepts: diagonal scaling of matrices
3124 
3125 .seealso: MatScale()
3126 @*/
3127 int MatDiagonalScale(Mat mat,Vec l,Vec r)
3128 {
3129   int ierr;
3130 
3131   PetscFunctionBegin;
3132   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3133   PetscValidType(mat);
3134   MatPreallocated(mat);
3135   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3136   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE);PetscCheckSameComm(mat,l);}
3137   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE);PetscCheckSameComm(mat,r);}
3138   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3139   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3140 
3141   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3142   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
3143   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3144   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3145   PetscFunctionReturn(0);
3146 }
3147 
3148 #undef __FUNCT__
3149 #define __FUNCT__ "MatScale"
3150 /*@
3151     MatScale - Scales all elements of a matrix by a given number.
3152 
3153     Collective on Mat
3154 
3155     Input Parameters:
3156 +   mat - the matrix to be scaled
3157 -   a  - the scaling value
3158 
3159     Output Parameter:
3160 .   mat - the scaled matrix
3161 
3162     Level: intermediate
3163 
3164     Concepts: matrices^scaling all entries
3165 
3166 .seealso: MatDiagonalScale()
3167 @*/
3168 int MatScale(const PetscScalar *a,Mat mat)
3169 {
3170   int ierr;
3171 
3172   PetscFunctionBegin;
3173   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3174   PetscValidType(mat);
3175   MatPreallocated(mat);
3176   PetscValidScalarPointer(a);
3177   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3178   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3179   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3180 
3181   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3182   ierr = (*mat->ops->scale)(a,mat);CHKERRQ(ierr);
3183   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3184   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3185   PetscFunctionReturn(0);
3186 }
3187 
3188 #undef __FUNCT__
3189 #define __FUNCT__ "MatNorm"
3190 /*@
3191    MatNorm - Calculates various norms of a matrix.
3192 
3193    Collective on Mat
3194 
3195    Input Parameters:
3196 +  mat - the matrix
3197 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
3198 
3199    Output Parameters:
3200 .  nrm - the resulting norm
3201 
3202    Level: intermediate
3203 
3204    Concepts: matrices^norm
3205    Concepts: norm^of matrix
3206 @*/
3207 int MatNorm(Mat mat,NormType type,PetscReal *nrm)
3208 {
3209   int ierr;
3210 
3211   PetscFunctionBegin;
3212   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3213   PetscValidType(mat);
3214   MatPreallocated(mat);
3215   PetscValidScalarPointer(nrm);
3216 
3217   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3218   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3219   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3220   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
3221   PetscFunctionReturn(0);
3222 }
3223 
3224 /*
3225      This variable is used to prevent counting of MatAssemblyBegin() that
3226    are called from within a MatAssemblyEnd().
3227 */
3228 static int MatAssemblyEnd_InUse = 0;
3229 #undef __FUNCT__
3230 #define __FUNCT__ "MatAssemblyBegin"
3231 /*@
3232    MatAssemblyBegin - Begins assembling the matrix.  This routine should
3233    be called after completing all calls to MatSetValues().
3234 
3235    Collective on Mat
3236 
3237    Input Parameters:
3238 +  mat - the matrix
3239 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3240 
3241    Notes:
3242    MatSetValues() generally caches the values.  The matrix is ready to
3243    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3244    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3245    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3246    using the matrix.
3247 
3248    Level: beginner
3249 
3250    Concepts: matrices^assembling
3251 
3252 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
3253 @*/
3254 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
3255 {
3256   int ierr;
3257 
3258   PetscFunctionBegin;
3259   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3260   PetscValidType(mat);
3261   MatPreallocated(mat);
3262   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
3263   if (mat->assembled) {
3264     mat->was_assembled = PETSC_TRUE;
3265     mat->assembled     = PETSC_FALSE;
3266   }
3267   if (!MatAssemblyEnd_InUse) {
3268     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3269     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3270     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3271   } else {
3272     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3273   }
3274   PetscFunctionReturn(0);
3275 }
3276 
3277 #undef __FUNCT__
3278 #define __FUNCT__ "MatAssembed"
3279 /*@
3280    MatAssembled - Indicates if a matrix has been assembled and is ready for
3281      use; for example, in matrix-vector product.
3282 
3283    Collective on Mat
3284 
3285    Input Parameter:
3286 .  mat - the matrix
3287 
3288    Output Parameter:
3289 .  assembled - PETSC_TRUE or PETSC_FALSE
3290 
3291    Level: advanced
3292 
3293    Concepts: matrices^assembled?
3294 
3295 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
3296 @*/
3297 int MatAssembled(Mat mat,PetscTruth *assembled)
3298 {
3299   PetscFunctionBegin;
3300   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3301   PetscValidType(mat);
3302   MatPreallocated(mat);
3303   *assembled = mat->assembled;
3304   PetscFunctionReturn(0);
3305 }
3306 
3307 #undef __FUNCT__
3308 #define __FUNCT__ "MatView_Private"
3309 /*
3310     Processes command line options to determine if/how a matrix
3311   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
3312 */
3313 int MatView_Private(Mat mat)
3314 {
3315   int               ierr;
3316   PetscTruth        flg;
3317   static PetscTruth incall = PETSC_FALSE;
3318 
3319   PetscFunctionBegin;
3320   if (incall) PetscFunctionReturn(0);
3321   incall = PETSC_TRUE;
3322   ierr = PetscOptionsBegin(mat->comm,mat->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
3323     ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg);CHKERRQ(ierr);
3324     if (flg) {
3325       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
3326       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3327       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3328     }
3329     ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg);CHKERRQ(ierr);
3330     if (flg) {
3331       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
3332       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3333       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3334     }
3335     ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg);CHKERRQ(ierr);
3336     if (flg) {
3337       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3338     }
3339     ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg);CHKERRQ(ierr);
3340     if (flg) {
3341       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
3342       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3343       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3344     }
3345     ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg);CHKERRQ(ierr);
3346     if (flg) {
3347       ierr = MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3348       ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3349     }
3350     ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg);CHKERRQ(ierr);
3351     if (flg) {
3352       ierr = MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3353       ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3354     }
3355   ierr = PetscOptionsEnd();CHKERRQ(ierr);
3356   /* cannot have inside PetscOptionsBegin() because uses PetscOptionsBegin() */
3357   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);CHKERRQ(ierr);
3358   if (flg) {
3359     ierr = PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);CHKERRQ(ierr);
3360     if (flg) {
3361       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
3362     }
3363     ierr = MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3364     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3365     if (flg) {
3366       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3367     }
3368   }
3369   incall = PETSC_FALSE;
3370   PetscFunctionReturn(0);
3371 }
3372 
3373 #undef __FUNCT__
3374 #define __FUNCT__ "MatAssemblyEnd"
3375 /*@
3376    MatAssemblyEnd - Completes assembling the matrix.  This routine should
3377    be called after MatAssemblyBegin().
3378 
3379    Collective on Mat
3380 
3381    Input Parameters:
3382 +  mat - the matrix
3383 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3384 
3385    Options Database Keys:
3386 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3387 .  -mat_view_info_detailed - Prints more detailed info
3388 .  -mat_view - Prints matrix in ASCII format
3389 .  -mat_view_matlab - Prints matrix in Matlab format
3390 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3391 .  -display <name> - Sets display name (default is host)
3392 .  -draw_pause <sec> - Sets number of seconds to pause after display
3393 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
3394 .  -viewer_socket_machine <machine>
3395 .  -viewer_socket_port <port>
3396 .  -mat_view_binary - save matrix to file in binary format
3397 -  -viewer_binary_filename <name>
3398 
3399    Notes:
3400    MatSetValues() generally caches the values.  The matrix is ready to
3401    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3402    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3403    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3404    using the matrix.
3405 
3406    Level: beginner
3407 
3408 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
3409 @*/
3410 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
3411 {
3412   int        ierr;
3413   static int inassm = 0;
3414   PetscTruth flg;
3415 
3416   PetscFunctionBegin;
3417   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3418   PetscValidType(mat);
3419   MatPreallocated(mat);
3420 
3421   inassm++;
3422   MatAssemblyEnd_InUse++;
3423   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3424     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3425     if (mat->ops->assemblyend) {
3426       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3427     }
3428     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3429   } else {
3430     if (mat->ops->assemblyend) {
3431       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3432     }
3433   }
3434 
3435   /* Flush assembly is not a true assembly */
3436   if (type != MAT_FLUSH_ASSEMBLY) {
3437     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3438   }
3439   mat->insertmode = NOT_SET_VALUES;
3440   MatAssemblyEnd_InUse--;
3441   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3442   if (!mat->symmetric_eternal) {
3443     mat->symmetric_set              = PETSC_FALSE;
3444     mat->hermitian_set              = PETSC_FALSE;
3445     mat->structurally_symmetric_set = PETSC_FALSE;
3446   }
3447   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3448     ierr = MatView_Private(mat);CHKERRQ(ierr);
3449   }
3450   inassm--;
3451   ierr = PetscOptionsHasName(mat->prefix,"-help",&flg);CHKERRQ(ierr);
3452   if (flg) {
3453     ierr = MatPrintHelp(mat);CHKERRQ(ierr);
3454   }
3455   PetscFunctionReturn(0);
3456 }
3457 
3458 
3459 #undef __FUNCT__
3460 #define __FUNCT__ "MatCompress"
3461 /*@
3462    MatCompress - Tries to store the matrix in as little space as
3463    possible.  May fail if memory is already fully used, since it
3464    tries to allocate new space.
3465 
3466    Collective on Mat
3467 
3468    Input Parameters:
3469 .  mat - the matrix
3470 
3471    Level: advanced
3472 
3473 @*/
3474 int MatCompress(Mat mat)
3475 {
3476   int ierr;
3477 
3478   PetscFunctionBegin;
3479   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3480   PetscValidType(mat);
3481   MatPreallocated(mat);
3482   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
3483   PetscFunctionReturn(0);
3484 }
3485 
3486 #undef __FUNCT__
3487 #define __FUNCT__ "MatSetOption"
3488 /*@
3489    MatSetOption - Sets a parameter option for a matrix. Some options
3490    may be specific to certain storage formats.  Some options
3491    determine how values will be inserted (or added). Sorted,
3492    row-oriented input will generally assemble the fastest. The default
3493    is row-oriented, nonsorted input.
3494 
3495    Collective on Mat
3496 
3497    Input Parameters:
3498 +  mat - the matrix
3499 -  option - the option, one of those listed below (and possibly others),
3500              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
3501 
3502    Options Describing Matrix Structure:
3503 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3504 .    MAT_HERMITIAN - transpose is the complex conjugation
3505 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
3506 .    MAT_NOT_SYMMETRIC - not symmetric in value
3507 .    MAT_NOT_HERMITIAN - transpose is not the complex conjugation
3508 .    MAT_NOT_STRUCTURALLY_SYMMETRIC - not symmetric nonzero structure
3509 .    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
3510                             you set to be kept with all future use of the matrix
3511                             including after MatAssemblyBegin/End() which could
3512                             potentially change the symmetry structure, i.e. you
3513                             KNOW the matrix will ALWAYS have the property you set.
3514 -    MAT_NOT_SYMMETRY_ETERNAL - if MatAssemblyBegin/End() is called then the
3515                                 flags you set will be dropped (in case potentially
3516                                 the symmetry etc was lost).
3517 
3518    Options For Use with MatSetValues():
3519    Insert a logically dense subblock, which can be
3520 +    MAT_ROW_ORIENTED - row-oriented (default)
3521 .    MAT_COLUMN_ORIENTED - column-oriented
3522 .    MAT_ROWS_SORTED - sorted by row
3523 .    MAT_ROWS_UNSORTED - not sorted by row (default)
3524 .    MAT_COLUMNS_SORTED - sorted by column
3525 -    MAT_COLUMNS_UNSORTED - not sorted by column (default)
3526 
3527    Not these options reflect the data you pass in with MatSetValues(); it has
3528    nothing to do with how the data is stored internally in the matrix
3529    data structure.
3530 
3531    When (re)assembling a matrix, we can restrict the input for
3532    efficiency/debugging purposes.  These options include
3533 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
3534         allowed if they generate a new nonzero
3535 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
3536 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
3537          they generate a nonzero in a new diagonal (for block diagonal format only)
3538 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
3539 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
3540 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
3541 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
3542 
3543    Notes:
3544    Some options are relevant only for particular matrix types and
3545    are thus ignored by others.  Other options are not supported by
3546    certain matrix types and will generate an error message if set.
3547 
3548    If using a Fortran 77 module to compute a matrix, one may need to
3549    use the column-oriented option (or convert to the row-oriented
3550    format).
3551 
3552    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
3553    that would generate a new entry in the nonzero structure is instead
3554    ignored.  Thus, if memory has not alredy been allocated for this particular
3555    data, then the insertion is ignored. For dense matrices, in which
3556    the entire array is allocated, no entries are ever ignored.
3557    Set after the first MatAssemblyEnd()
3558 
3559    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
3560    that would generate a new entry in the nonzero structure instead produces
3561    an error. (Currently supported for AIJ and BAIJ formats only.)
3562    This is a useful flag when using SAME_NONZERO_PATTERN in calling
3563    KSPSetOperators() to ensure that the nonzero pattern truely does
3564    remain unchanged. Set after the first MatAssemblyEnd()
3565 
3566    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
3567    that would generate a new entry that has not been preallocated will
3568    instead produce an error. (Currently supported for AIJ and BAIJ formats
3569    only.) This is a useful flag when debugging matrix memory preallocation.
3570 
3571    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
3572    other processors should be dropped, rather than stashed.
3573    This is useful if you know that the "owning" processor is also
3574    always generating the correct matrix entries, so that PETSc need
3575    not transfer duplicate entries generated on another processor.
3576 
3577    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
3578    searches during matrix assembly. When this flag is set, the hash table
3579    is created during the first Matrix Assembly. This hash table is
3580    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
3581    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
3582    should be used with MAT_USE_HASH_TABLE flag. This option is currently
3583    supported by MATMPIBAIJ format only.
3584 
3585    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
3586    are kept in the nonzero structure
3587 
3588    MAT_IGNORE_ZERO_ENTRIES - for AIJ matrices this will stop zero values from creating
3589    a zero location in the matrix
3590 
3591    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
3592    ROWBS matrix types
3593 
3594    MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works
3595    with AIJ and ROWBS matrix types
3596 
3597    Level: intermediate
3598 
3599    Concepts: matrices^setting options
3600 
3601 @*/
3602 int MatSetOption(Mat mat,MatOption op)
3603 {
3604   int ierr;
3605 
3606   PetscFunctionBegin;
3607   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3608   PetscValidType(mat);
3609   MatPreallocated(mat);
3610   switch (op) {
3611   case MAT_SYMMETRIC:
3612     mat->symmetric                  = PETSC_TRUE;
3613     mat->structurally_symmetric     = PETSC_TRUE;
3614     mat->symmetric_set              = PETSC_TRUE;
3615     mat->structurally_symmetric_set = PETSC_TRUE;
3616     break;
3617   case MAT_HERMITIAN:
3618     mat->hermitian                  = PETSC_TRUE;
3619     mat->structurally_symmetric     = PETSC_TRUE;
3620     mat->hermitian_set              = PETSC_TRUE;
3621     mat->structurally_symmetric_set = PETSC_TRUE;
3622     break;
3623   case MAT_STRUCTURALLY_SYMMETRIC:
3624     mat->structurally_symmetric     = PETSC_TRUE;
3625     mat->structurally_symmetric_set = PETSC_TRUE;
3626     break;
3627   case MAT_NOT_SYMMETRIC:
3628     mat->symmetric                  = PETSC_FALSE;
3629     mat->symmetric_set              = PETSC_TRUE;
3630     break;
3631   case MAT_NOT_HERMITIAN:
3632     mat->hermitian                  = PETSC_FALSE;
3633     mat->hermitian_set              = PETSC_TRUE;
3634     break;
3635   case MAT_NOT_STRUCTURALLY_SYMMETRIC:
3636     mat->structurally_symmetric     = PETSC_FALSE;
3637     mat->structurally_symmetric_set = PETSC_TRUE;
3638     break;
3639   case MAT_SYMMETRY_ETERNAL:
3640     mat->symmetric_eternal          = PETSC_TRUE;
3641   case MAT_NOT_SYMMETRY_ETERNAL:
3642     mat->symmetric_eternal          = PETSC_FALSE;
3643   default:
3644     break;
3645   }
3646   if (mat->ops->setoption) {
3647     ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);
3648   }
3649   PetscFunctionReturn(0);
3650 }
3651 
3652 #undef __FUNCT__
3653 #define __FUNCT__ "MatZeroEntries"
3654 /*@
3655    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
3656    this routine retains the old nonzero structure.
3657 
3658    Collective on Mat
3659 
3660    Input Parameters:
3661 .  mat - the matrix
3662 
3663    Level: intermediate
3664 
3665    Concepts: matrices^zeroing
3666 
3667 .seealso: MatZeroRows()
3668 @*/
3669 int MatZeroEntries(Mat mat)
3670 {
3671   int ierr;
3672 
3673   PetscFunctionBegin;
3674   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3675   PetscValidType(mat);
3676   MatPreallocated(mat);
3677   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3678   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3679 
3680   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3681   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
3682   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3683   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3684   PetscFunctionReturn(0);
3685 }
3686 
3687 #undef __FUNCT__
3688 #define __FUNCT__ "MatZeroRows"
3689 /*@C
3690    MatZeroRows - Zeros all entries (except possibly the main diagonal)
3691    of a set of rows of a matrix.
3692 
3693    Collective on Mat
3694 
3695    Input Parameters:
3696 +  mat - the matrix
3697 .  is - index set of rows to remove
3698 -  diag - pointer to value put in all diagonals of eliminated rows.
3699           Note that diag is not a pointer to an array, but merely a
3700           pointer to a single value.
3701 
3702    Notes:
3703    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
3704    but does not release memory.  For the dense and block diagonal
3705    formats this does not alter the nonzero structure.
3706 
3707    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3708    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3709    merely zeroed.
3710 
3711    The user can set a value in the diagonal entry (or for the AIJ and
3712    row formats can optionally remove the main diagonal entry from the
3713    nonzero structure as well, by passing a null pointer (PETSC_NULL
3714    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3715 
3716    For the parallel case, all processes that share the matrix (i.e.,
3717    those in the communicator used for matrix creation) MUST call this
3718    routine, regardless of whether any rows being zeroed are owned by
3719    them.
3720 
3721    Level: intermediate
3722 
3723    Concepts: matrices^zeroing rows
3724 
3725 .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
3726 @*/
3727 int MatZeroRows(Mat mat,IS is,const PetscScalar *diag)
3728 {
3729   int ierr;
3730 
3731   PetscFunctionBegin;
3732   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3733   PetscValidType(mat);
3734   MatPreallocated(mat);
3735   PetscValidHeaderSpecific(is,IS_COOKIE);
3736   if (diag) PetscValidScalarPointer(diag);
3737   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3738   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3739   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3740 
3741   ierr = (*mat->ops->zerorows)(mat,is,diag);CHKERRQ(ierr);
3742   ierr = MatView_Private(mat);CHKERRQ(ierr);
3743   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3744   PetscFunctionReturn(0);
3745 }
3746 
3747 #undef __FUNCT__
3748 #define __FUNCT__ "MatZeroRowsLocal"
3749 /*@C
3750    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
3751    of a set of rows of a matrix; using local numbering of rows.
3752 
3753    Collective on Mat
3754 
3755    Input Parameters:
3756 +  mat - the matrix
3757 .  is - index set of rows to remove
3758 -  diag - pointer to value put in all diagonals of eliminated rows.
3759           Note that diag is not a pointer to an array, but merely a
3760           pointer to a single value.
3761 
3762    Notes:
3763    Before calling MatZeroRowsLocal(), the user must first set the
3764    local-to-global mapping by calling MatSetLocalToGlobalMapping().
3765 
3766    For the AIJ matrix formats this removes the old nonzero structure,
3767    but does not release memory.  For the dense and block diagonal
3768    formats this does not alter the nonzero structure.
3769 
3770    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3771    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3772    merely zeroed.
3773 
3774    The user can set a value in the diagonal entry (or for the AIJ and
3775    row formats can optionally remove the main diagonal entry from the
3776    nonzero structure as well, by passing a null pointer (PETSC_NULL
3777    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3778 
3779    Level: intermediate
3780 
3781    Concepts: matrices^zeroing
3782 
3783 .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3784 @*/
3785 int MatZeroRowsLocal(Mat mat,IS is,const PetscScalar *diag)
3786 {
3787   int ierr;
3788   IS  newis;
3789 
3790   PetscFunctionBegin;
3791   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3792   PetscValidType(mat);
3793   MatPreallocated(mat);
3794   PetscValidHeaderSpecific(is,IS_COOKIE);
3795   if (diag) PetscValidScalarPointer(diag);
3796   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3797   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3798 
3799   if (mat->ops->zerorowslocal) {
3800     ierr = (*mat->ops->zerorowslocal)(mat,is,diag);CHKERRQ(ierr);
3801   } else {
3802     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3803     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
3804     ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr);
3805     ierr = ISDestroy(newis);CHKERRQ(ierr);
3806   }
3807   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3808   PetscFunctionReturn(0);
3809 }
3810 
3811 #undef __FUNCT__
3812 #define __FUNCT__ "MatGetSize"
3813 /*@
3814    MatGetSize - Returns the numbers of rows and columns in a matrix.
3815 
3816    Not Collective
3817 
3818    Input Parameter:
3819 .  mat - the matrix
3820 
3821    Output Parameters:
3822 +  m - the number of global rows
3823 -  n - the number of global columns
3824 
3825    Level: beginner
3826 
3827    Concepts: matrices^size
3828 
3829 .seealso: MatGetLocalSize()
3830 @*/
3831 int MatGetSize(Mat mat,int *m,int* n)
3832 {
3833   PetscFunctionBegin;
3834   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3835   if (m) *m = mat->M;
3836   if (n) *n = mat->N;
3837   PetscFunctionReturn(0);
3838 }
3839 
3840 #undef __FUNCT__
3841 #define __FUNCT__ "MatGetLocalSize"
3842 /*@
3843    MatGetLocalSize - Returns the number of rows and columns in a matrix
3844    stored locally.  This information may be implementation dependent, so
3845    use with care.
3846 
3847    Not Collective
3848 
3849    Input Parameters:
3850 .  mat - the matrix
3851 
3852    Output Parameters:
3853 +  m - the number of local rows
3854 -  n - the number of local columns
3855 
3856    Level: beginner
3857 
3858    Concepts: matrices^local size
3859 
3860 .seealso: MatGetSize()
3861 @*/
3862 int MatGetLocalSize(Mat mat,int *m,int* n)
3863 {
3864   PetscFunctionBegin;
3865   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3866   if (m) *m = mat->m;
3867   if (n) *n = mat->n;
3868   PetscFunctionReturn(0);
3869 }
3870 
3871 #undef __FUNCT__
3872 #define __FUNCT__ "MatGetOwnershipRange"
3873 /*@
3874    MatGetOwnershipRange - Returns the range of matrix rows owned by
3875    this processor, assuming that the matrix is laid out with the first
3876    n1 rows on the first processor, the next n2 rows on the second, etc.
3877    For certain parallel layouts this range may not be well defined.
3878 
3879    Not Collective
3880 
3881    Input Parameters:
3882 .  mat - the matrix
3883 
3884    Output Parameters:
3885 +  m - the global index of the first local row
3886 -  n - one more than the global index of the last local row
3887 
3888    Level: beginner
3889 
3890    Concepts: matrices^row ownership
3891 @*/
3892 int MatGetOwnershipRange(Mat mat,int *m,int* n)
3893 {
3894   int ierr;
3895 
3896   PetscFunctionBegin;
3897   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3898   PetscValidType(mat);
3899   MatPreallocated(mat);
3900   if (m) PetscValidIntPointer(m);
3901   if (n) PetscValidIntPointer(n);
3902   ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr);
3903   PetscFunctionReturn(0);
3904 }
3905 
3906 #undef __FUNCT__
3907 #define __FUNCT__ "MatILUFactorSymbolic"
3908 /*@
3909    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3910    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
3911    to complete the factorization.
3912 
3913    Collective on Mat
3914 
3915    Input Parameters:
3916 +  mat - the matrix
3917 .  row - row permutation
3918 .  column - column permutation
3919 -  info - structure containing
3920 $      levels - number of levels of fill.
3921 $      expected fill - as ratio of original fill.
3922 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3923                 missing diagonal entries)
3924 
3925    Output Parameters:
3926 .  fact - new matrix that has been symbolically factored
3927 
3928    Notes:
3929    See the users manual for additional information about
3930    choosing the fill factor for better efficiency.
3931 
3932    Most users should employ the simplified KSP interface for linear solvers
3933    instead of working directly with matrix algebra routines such as this.
3934    See, e.g., KSPCreate().
3935 
3936    Level: developer
3937 
3938   Concepts: matrices^symbolic LU factorization
3939   Concepts: matrices^factorization
3940   Concepts: LU^symbolic factorization
3941 
3942 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3943           MatGetOrdering(), MatFactorInfo
3944 
3945 @*/
3946 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
3947 {
3948   int ierr;
3949 
3950   PetscFunctionBegin;
3951   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3952   PetscValidType(mat);
3953   MatPreallocated(mat);
3954   PetscValidPointer(fact);
3955   PetscValidHeaderSpecific(row,IS_COOKIE);
3956   PetscValidHeaderSpecific(col,IS_COOKIE);
3957   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",(int)info->levels);
3958   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3959   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3960   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3961   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3962 
3963   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3964   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
3965   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3966   PetscFunctionReturn(0);
3967 }
3968 
3969 #undef __FUNCT__
3970 #define __FUNCT__ "MatICCFactorSymbolic"
3971 /*@
3972    MatICCFactorSymbolic - Performs symbolic incomplete
3973    Cholesky factorization for a symmetric matrix.  Use
3974    MatCholeskyFactorNumeric() to complete the factorization.
3975 
3976    Collective on Mat
3977 
3978    Input Parameters:
3979 +  mat - the matrix
3980 .  perm - row and column permutation
3981 -  info - structure containing
3982 $      levels - number of levels of fill.
3983 $      expected fill - as ratio of original fill.
3984 
3985    Output Parameter:
3986 .  fact - the factored matrix
3987 
3988    Notes:
3989    Currently only no-fill factorization is supported.
3990 
3991    Most users should employ the simplified KSP interface for linear solvers
3992    instead of working directly with matrix algebra routines such as this.
3993    See, e.g., KSPCreate().
3994 
3995    Level: developer
3996 
3997   Concepts: matrices^symbolic incomplete Cholesky factorization
3998   Concepts: matrices^factorization
3999   Concepts: Cholsky^symbolic factorization
4000 
4001 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
4002 @*/
4003 int MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
4004 {
4005   int ierr;
4006 
4007   PetscFunctionBegin;
4008   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4009   PetscValidType(mat);
4010   MatPreallocated(mat);
4011   PetscValidPointer(fact);
4012   PetscValidHeaderSpecific(perm,IS_COOKIE);
4013   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4014   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %d",(int) info->levels);
4015   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
4016   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
4017   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4018 
4019   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4020   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
4021   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4022   PetscFunctionReturn(0);
4023 }
4024 
4025 #undef __FUNCT__
4026 #define __FUNCT__ "MatGetArray"
4027 /*@C
4028    MatGetArray - Returns a pointer to the element values in the matrix.
4029    The result of this routine is dependent on the underlying matrix data
4030    structure, and may not even work for certain matrix types.  You MUST
4031    call MatRestoreArray() when you no longer need to access the array.
4032 
4033    Not Collective
4034 
4035    Input Parameter:
4036 .  mat - the matrix
4037 
4038    Output Parameter:
4039 .  v - the location of the values
4040 
4041 
4042    Fortran Note:
4043    This routine is used differently from Fortran, e.g.,
4044 .vb
4045         Mat         mat
4046         PetscScalar mat_array(1)
4047         PetscOffset i_mat
4048         int         ierr
4049         call MatGetArray(mat,mat_array,i_mat,ierr)
4050 
4051   C  Access first local entry in matrix; note that array is
4052   C  treated as one dimensional
4053         value = mat_array(i_mat + 1)
4054 
4055         [... other code ...]
4056         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4057 .ve
4058 
4059    See the Fortran chapter of the users manual and
4060    petsc/src/mat/examples/tests for details.
4061 
4062    Level: advanced
4063 
4064    Concepts: matrices^access array
4065 
4066 .seealso: MatRestoreArray(), MatGetArrayF90()
4067 @*/
4068 int MatGetArray(Mat mat,PetscScalar *v[])
4069 {
4070   int ierr;
4071 
4072   PetscFunctionBegin;
4073   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4074   PetscValidType(mat);
4075   MatPreallocated(mat);
4076   PetscValidPointer(v);
4077   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4078   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
4079   PetscFunctionReturn(0);
4080 }
4081 
4082 #undef __FUNCT__
4083 #define __FUNCT__ "MatRestoreArray"
4084 /*@C
4085    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
4086 
4087    Not Collective
4088 
4089    Input Parameter:
4090 +  mat - the matrix
4091 -  v - the location of the values
4092 
4093    Fortran Note:
4094    This routine is used differently from Fortran, e.g.,
4095 .vb
4096         Mat         mat
4097         PetscScalar mat_array(1)
4098         PetscOffset i_mat
4099         int         ierr
4100         call MatGetArray(mat,mat_array,i_mat,ierr)
4101 
4102   C  Access first local entry in matrix; note that array is
4103   C  treated as one dimensional
4104         value = mat_array(i_mat + 1)
4105 
4106         [... other code ...]
4107         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4108 .ve
4109 
4110    See the Fortran chapter of the users manual and
4111    petsc/src/mat/examples/tests for details
4112 
4113    Level: advanced
4114 
4115 .seealso: MatGetArray(), MatRestoreArrayF90()
4116 @*/
4117 int MatRestoreArray(Mat mat,PetscScalar *v[])
4118 {
4119   int ierr;
4120 
4121   PetscFunctionBegin;
4122   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4123   PetscValidType(mat);
4124   MatPreallocated(mat);
4125   PetscValidPointer(v);
4126 #if defined(PETSC_USE_BOPT_g)
4127   CHKMEMQ;
4128 #endif
4129   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4130   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
4131   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
4132   PetscFunctionReturn(0);
4133 }
4134 
4135 #undef __FUNCT__
4136 #define __FUNCT__ "MatGetSubMatrices"
4137 /*@C
4138    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
4139    points to an array of valid matrices, they may be reused to store the new
4140    submatrices.
4141 
4142    Collective on Mat
4143 
4144    Input Parameters:
4145 +  mat - the matrix
4146 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
4147 .  irow, icol - index sets of rows and columns to extract
4148 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4149 
4150    Output Parameter:
4151 .  submat - the array of submatrices
4152 
4153    Notes:
4154    MatGetSubMatrices() can extract only sequential submatrices
4155    (from both sequential and parallel matrices). Use MatGetSubMatrix()
4156    to extract a parallel submatrix.
4157 
4158    When extracting submatrices from a parallel matrix, each processor can
4159    form a different submatrix by setting the rows and columns of its
4160    individual index sets according to the local submatrix desired.
4161 
4162    When finished using the submatrices, the user should destroy
4163    them with MatDestroyMatrices().
4164 
4165    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
4166    original matrix has not changed from that last call to MatGetSubMatrices().
4167 
4168    This routine creates the matrices in submat; you should NOT create them before
4169    calling it. It also allocates the array of matrix pointers submat.
4170 
4171    Fortran Note:
4172    The Fortran interface is slightly different from that given below; it
4173    requires one to pass in  as submat a Mat (integer) array of size at least m.
4174 
4175    Level: advanced
4176 
4177    Concepts: matrices^accessing submatrices
4178    Concepts: submatrices
4179 
4180 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
4181 @*/
4182 int MatGetSubMatrices(Mat mat,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
4183 {
4184   int        ierr;
4185 
4186   PetscFunctionBegin;
4187   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4188   PetscValidType(mat);
4189   MatPreallocated(mat);
4190   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4191   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4192   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4193 
4194   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4195   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
4196   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4197   PetscFunctionReturn(0);
4198 }
4199 
4200 #undef __FUNCT__
4201 #define __FUNCT__ "MatDestroyMatrices"
4202 /*@C
4203    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
4204 
4205    Collective on Mat
4206 
4207    Input Parameters:
4208 +  n - the number of local matrices
4209 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
4210                        sequence of MatGetSubMatrices())
4211 
4212    Level: advanced
4213 
4214     Notes: Frees not only the matrices, but also the array that contains the matrices
4215 
4216 .seealso: MatGetSubMatrices()
4217 @*/
4218 int MatDestroyMatrices(int n,Mat *mat[])
4219 {
4220   int ierr,i;
4221 
4222   PetscFunctionBegin;
4223   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
4224   PetscValidPointer(mat);
4225   for (i=0; i<n; i++) {
4226     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
4227   }
4228   /* memory is allocated even if n = 0 */
4229   ierr = PetscFree(*mat);CHKERRQ(ierr);
4230   PetscFunctionReturn(0);
4231 }
4232 
4233 #undef __FUNCT__
4234 #define __FUNCT__ "MatIncreaseOverlap"
4235 /*@
4236    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
4237    replaces the index sets by larger ones that represent submatrices with
4238    additional overlap.
4239 
4240    Collective on Mat
4241 
4242    Input Parameters:
4243 +  mat - the matrix
4244 .  n   - the number of index sets
4245 .  is  - the array of index sets (these index sets will changed during the call)
4246 -  ov  - the additional overlap requested
4247 
4248    Level: developer
4249 
4250    Concepts: overlap
4251    Concepts: ASM^computing overlap
4252 
4253 .seealso: MatGetSubMatrices()
4254 @*/
4255 int MatIncreaseOverlap(Mat mat,int n,IS is[],int ov)
4256 {
4257   int ierr;
4258 
4259   PetscFunctionBegin;
4260   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4261   PetscValidType(mat);
4262   MatPreallocated(mat);
4263   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4264   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4265 
4266   if (!ov) PetscFunctionReturn(0);
4267   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4268   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4269   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
4270   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4271   PetscFunctionReturn(0);
4272 }
4273 
4274 #undef __FUNCT__
4275 #define __FUNCT__ "MatPrintHelp"
4276 /*@
4277    MatPrintHelp - Prints all the options for the matrix.
4278 
4279    Collective on Mat
4280 
4281    Input Parameter:
4282 .  mat - the matrix
4283 
4284    Options Database Keys:
4285 +  -help - Prints matrix options
4286 -  -h - Prints matrix options
4287 
4288    Level: developer
4289 
4290 .seealso: MatCreate(), MatCreateXXX()
4291 @*/
4292 int MatPrintHelp(Mat mat)
4293 {
4294   static PetscTruth called = PETSC_FALSE;
4295   int               ierr;
4296 
4297   PetscFunctionBegin;
4298   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4299   PetscValidType(mat);
4300   MatPreallocated(mat);
4301 
4302   if (!called) {
4303     if (mat->ops->printhelp) {
4304       ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
4305     }
4306     called = PETSC_TRUE;
4307   }
4308   PetscFunctionReturn(0);
4309 }
4310 
4311 #undef __FUNCT__
4312 #define __FUNCT__ "MatGetBlockSize"
4313 /*@
4314    MatGetBlockSize - Returns the matrix block size; useful especially for the
4315    block row and block diagonal formats.
4316 
4317    Not Collective
4318 
4319    Input Parameter:
4320 .  mat - the matrix
4321 
4322    Output Parameter:
4323 .  bs - block size
4324 
4325    Notes:
4326    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
4327    Block row formats are MATSEQBAIJ, MATMPIBAIJ
4328 
4329    Level: intermediate
4330 
4331    Concepts: matrices^block size
4332 
4333 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
4334 @*/
4335 int MatGetBlockSize(Mat mat,int *bs)
4336 {
4337   int ierr;
4338 
4339   PetscFunctionBegin;
4340   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4341   PetscValidType(mat);
4342   MatPreallocated(mat);
4343   PetscValidIntPointer(bs);
4344   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4345   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
4346   PetscFunctionReturn(0);
4347 }
4348 
4349 #undef __FUNCT__
4350 #define __FUNCT__ "MatGetRowIJ"
4351 /*@C
4352     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
4353 
4354    Collective on Mat
4355 
4356     Input Parameters:
4357 +   mat - the matrix
4358 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
4359 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4360                 symmetrized
4361 
4362     Output Parameters:
4363 +   n - number of rows in the (possibly compressed) matrix
4364 .   ia - the row pointers
4365 .   ja - the column indices
4366 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4367 
4368     Level: developer
4369 
4370 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4371 @*/
4372 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4373 {
4374   int ierr;
4375 
4376   PetscFunctionBegin;
4377   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4378   PetscValidType(mat);
4379   MatPreallocated(mat);
4380   if (ia) PetscValidIntPointer(ia);
4381   if (ja) PetscValidIntPointer(ja);
4382   PetscValidIntPointer(done);
4383   if (!mat->ops->getrowij) *done = PETSC_FALSE;
4384   else {
4385     *done = PETSC_TRUE;
4386     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4387   }
4388   PetscFunctionReturn(0);
4389 }
4390 
4391 #undef __FUNCT__
4392 #define __FUNCT__ "MatGetColumnIJ"
4393 /*@C
4394     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
4395 
4396     Collective on Mat
4397 
4398     Input Parameters:
4399 +   mat - the matrix
4400 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4401 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4402                 symmetrized
4403 
4404     Output Parameters:
4405 +   n - number of columns in the (possibly compressed) matrix
4406 .   ia - the column pointers
4407 .   ja - the row indices
4408 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4409 
4410     Level: developer
4411 
4412 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4413 @*/
4414 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4415 {
4416   int ierr;
4417 
4418   PetscFunctionBegin;
4419   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4420   PetscValidType(mat);
4421   MatPreallocated(mat);
4422   if (ia) PetscValidIntPointer(ia);
4423   if (ja) PetscValidIntPointer(ja);
4424   PetscValidIntPointer(done);
4425 
4426   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
4427   else {
4428     *done = PETSC_TRUE;
4429     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4430   }
4431   PetscFunctionReturn(0);
4432 }
4433 
4434 #undef __FUNCT__
4435 #define __FUNCT__ "MatRestoreRowIJ"
4436 /*@C
4437     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
4438     MatGetRowIJ().
4439 
4440     Collective on Mat
4441 
4442     Input Parameters:
4443 +   mat - the matrix
4444 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4445 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4446                 symmetrized
4447 
4448     Output Parameters:
4449 +   n - size of (possibly compressed) matrix
4450 .   ia - the row pointers
4451 .   ja - the column indices
4452 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4453 
4454     Level: developer
4455 
4456 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4457 @*/
4458 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4459 {
4460   int ierr;
4461 
4462   PetscFunctionBegin;
4463   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4464   PetscValidType(mat);
4465   MatPreallocated(mat);
4466   if (ia) PetscValidIntPointer(ia);
4467   if (ja) PetscValidIntPointer(ja);
4468   PetscValidIntPointer(done);
4469 
4470   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
4471   else {
4472     *done = PETSC_TRUE;
4473     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4474   }
4475   PetscFunctionReturn(0);
4476 }
4477 
4478 #undef __FUNCT__
4479 #define __FUNCT__ "MatRestoreColumnIJ"
4480 /*@C
4481     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4482     MatGetColumnIJ().
4483 
4484     Collective on Mat
4485 
4486     Input Parameters:
4487 +   mat - the matrix
4488 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4489 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4490                 symmetrized
4491 
4492     Output Parameters:
4493 +   n - size of (possibly compressed) matrix
4494 .   ia - the column pointers
4495 .   ja - the row indices
4496 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4497 
4498     Level: developer
4499 
4500 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4501 @*/
4502 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4503 {
4504   int ierr;
4505 
4506   PetscFunctionBegin;
4507   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4508   PetscValidType(mat);
4509   MatPreallocated(mat);
4510   if (ia) PetscValidIntPointer(ia);
4511   if (ja) PetscValidIntPointer(ja);
4512   PetscValidIntPointer(done);
4513 
4514   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4515   else {
4516     *done = PETSC_TRUE;
4517     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4518   }
4519   PetscFunctionReturn(0);
4520 }
4521 
4522 #undef __FUNCT__
4523 #define __FUNCT__ "MatColoringPatch"
4524 /*@C
4525     MatColoringPatch -Used inside matrix coloring routines that
4526     use MatGetRowIJ() and/or MatGetColumnIJ().
4527 
4528     Collective on Mat
4529 
4530     Input Parameters:
4531 +   mat - the matrix
4532 .   n   - number of colors
4533 -   colorarray - array indicating color for each column
4534 
4535     Output Parameters:
4536 .   iscoloring - coloring generated using colorarray information
4537 
4538     Level: developer
4539 
4540 .seealso: MatGetRowIJ(), MatGetColumnIJ()
4541 
4542 @*/
4543 int MatColoringPatch(Mat mat,int n,int ncolors,const ISColoringValue colorarray[],ISColoring *iscoloring)
4544 {
4545   int ierr;
4546 
4547   PetscFunctionBegin;
4548   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4549   PetscValidType(mat);
4550   MatPreallocated(mat);
4551   PetscValidIntPointer(colorarray);
4552 
4553   if (!mat->ops->coloringpatch){
4554     ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr);
4555   } else {
4556     ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr);
4557   }
4558   PetscFunctionReturn(0);
4559 }
4560 
4561 
4562 #undef __FUNCT__
4563 #define __FUNCT__ "MatSetUnfactored"
4564 /*@
4565    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
4566 
4567    Collective on Mat
4568 
4569    Input Parameter:
4570 .  mat - the factored matrix to be reset
4571 
4572    Notes:
4573    This routine should be used only with factored matrices formed by in-place
4574    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
4575    format).  This option can save memory, for example, when solving nonlinear
4576    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
4577    ILU(0) preconditioner.
4578 
4579    Note that one can specify in-place ILU(0) factorization by calling
4580 .vb
4581      PCType(pc,PCILU);
4582      PCILUSeUseInPlace(pc);
4583 .ve
4584    or by using the options -pc_type ilu -pc_ilu_in_place
4585 
4586    In-place factorization ILU(0) can also be used as a local
4587    solver for the blocks within the block Jacobi or additive Schwarz
4588    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
4589    of these preconditioners in the users manual for details on setting
4590    local solver options.
4591 
4592    Most users should employ the simplified KSP interface for linear solvers
4593    instead of working directly with matrix algebra routines such as this.
4594    See, e.g., KSPCreate().
4595 
4596    Level: developer
4597 
4598 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
4599 
4600    Concepts: matrices^unfactored
4601 
4602 @*/
4603 int MatSetUnfactored(Mat mat)
4604 {
4605   int ierr;
4606 
4607   PetscFunctionBegin;
4608   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4609   PetscValidType(mat);
4610   MatPreallocated(mat);
4611   mat->factor = 0;
4612   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
4613   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
4614   PetscFunctionReturn(0);
4615 }
4616 
4617 /*MC
4618     MatGetArrayF90 - Accesses a matrix array from Fortran90.
4619 
4620     Synopsis:
4621     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4622 
4623     Not collective
4624 
4625     Input Parameter:
4626 .   x - matrix
4627 
4628     Output Parameters:
4629 +   xx_v - the Fortran90 pointer to the array
4630 -   ierr - error code
4631 
4632     Example of Usage:
4633 .vb
4634       PetscScalar, pointer xx_v(:)
4635       ....
4636       call MatGetArrayF90(x,xx_v,ierr)
4637       a = xx_v(3)
4638       call MatRestoreArrayF90(x,xx_v,ierr)
4639 .ve
4640 
4641     Notes:
4642     Not yet supported for all F90 compilers
4643 
4644     Level: advanced
4645 
4646 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
4647 
4648     Concepts: matrices^accessing array
4649 
4650 M*/
4651 
4652 /*MC
4653     MatRestoreArrayF90 - Restores a matrix array that has been
4654     accessed with MatGetArrayF90().
4655 
4656     Synopsis:
4657     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4658 
4659     Not collective
4660 
4661     Input Parameters:
4662 +   x - matrix
4663 -   xx_v - the Fortran90 pointer to the array
4664 
4665     Output Parameter:
4666 .   ierr - error code
4667 
4668     Example of Usage:
4669 .vb
4670        PetscScalar, pointer xx_v(:)
4671        ....
4672        call MatGetArrayF90(x,xx_v,ierr)
4673        a = xx_v(3)
4674        call MatRestoreArrayF90(x,xx_v,ierr)
4675 .ve
4676 
4677     Notes:
4678     Not yet supported for all F90 compilers
4679 
4680     Level: advanced
4681 
4682 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
4683 
4684 M*/
4685 
4686 
4687 #undef __FUNCT__
4688 #define __FUNCT__ "MatGetSubMatrix"
4689 /*@
4690     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4691                       as the original matrix.
4692 
4693     Collective on Mat
4694 
4695     Input Parameters:
4696 +   mat - the original matrix
4697 .   isrow - rows this processor should obtain
4698 .   iscol - columns for all processors you wish to keep
4699 .   csize - number of columns "local" to this processor (does nothing for sequential
4700             matrices). This should match the result from VecGetLocalSize(x,...) if you
4701             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4702 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4703 
4704     Output Parameter:
4705 .   newmat - the new submatrix, of the same type as the old
4706 
4707     Level: advanced
4708 
4709     Notes: the iscol argument MUST be the same on each processor. You might be
4710     able to create the iscol argument with ISAllGather().
4711 
4712       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
4713    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
4714    to this routine with a mat of the same nonzero structure will reuse the matrix
4715    generated the first time.
4716 
4717     Concepts: matrices^submatrices
4718 
4719 .seealso: MatGetSubMatrices(), ISAllGather()
4720 @*/
4721 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4722 {
4723   int     ierr, size;
4724   Mat     *local;
4725 
4726   PetscFunctionBegin;
4727   PetscValidType(mat);
4728   MatPreallocated(mat);
4729   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4730   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
4731 
4732   /* if original matrix is on just one processor then use submatrix generated */
4733   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4734     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
4735     PetscFunctionReturn(0);
4736   } else if (!mat->ops->getsubmatrix && size == 1) {
4737     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
4738     *newmat = *local;
4739     ierr    = PetscFree(local);CHKERRQ(ierr);
4740     PetscFunctionReturn(0);
4741   }
4742 
4743   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4744   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
4745   ierr = PetscObjectIncreaseState((PetscObject)*newmat); CHKERRQ(ierr);
4746   PetscFunctionReturn(0);
4747 }
4748 
4749 #undef __FUNCT__
4750 #define __FUNCT__ "MatGetPetscMaps"
4751 /*@C
4752    MatGetPetscMaps - Returns the maps associated with the matrix.
4753 
4754    Not Collective
4755 
4756    Input Parameter:
4757 .  mat - the matrix
4758 
4759    Output Parameters:
4760 +  rmap - the row (right) map
4761 -  cmap - the column (left) map
4762 
4763    Level: developer
4764 
4765    Concepts: maps^getting from matrix
4766 
4767 @*/
4768 int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4769 {
4770   int ierr;
4771 
4772   PetscFunctionBegin;
4773   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4774   PetscValidType(mat);
4775   MatPreallocated(mat);
4776   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
4777   PetscFunctionReturn(0);
4778 }
4779 
4780 /*
4781       Version that works for all PETSc matrices
4782 */
4783 #undef __FUNCT__
4784 #define __FUNCT__ "MatGetPetscMaps_Petsc"
4785 int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4786 {
4787   PetscFunctionBegin;
4788   if (rmap) *rmap = mat->rmap;
4789   if (cmap) *cmap = mat->cmap;
4790   PetscFunctionReturn(0);
4791 }
4792 
4793 #undef __FUNCT__
4794 #define __FUNCT__ "MatSetStashInitialSize"
4795 /*@
4796    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4797    used during the assembly process to store values that belong to
4798    other processors.
4799 
4800    Not Collective
4801 
4802    Input Parameters:
4803 +  mat   - the matrix
4804 .  size  - the initial size of the stash.
4805 -  bsize - the initial size of the block-stash(if used).
4806 
4807    Options Database Keys:
4808 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4809 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
4810 
4811    Level: intermediate
4812 
4813    Notes:
4814      The block-stash is used for values set with VecSetValuesBlocked() while
4815      the stash is used for values set with VecSetValues()
4816 
4817      Run with the option -log_info and look for output of the form
4818      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4819      to determine the appropriate value, MM, to use for size and
4820      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4821      to determine the value, BMM to use for bsize
4822 
4823    Concepts: stash^setting matrix size
4824    Concepts: matrices^stash
4825 
4826 @*/
4827 int MatSetStashInitialSize(Mat mat,int size, int bsize)
4828 {
4829   int ierr;
4830 
4831   PetscFunctionBegin;
4832   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4833   PetscValidType(mat);
4834   MatPreallocated(mat);
4835   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
4836   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
4837   PetscFunctionReturn(0);
4838 }
4839 
4840 #undef __FUNCT__
4841 #define __FUNCT__ "MatInterpolateAdd"
4842 /*@
4843    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
4844      the matrix
4845 
4846    Collective on Mat
4847 
4848    Input Parameters:
4849 +  mat   - the matrix
4850 .  x,y - the vectors
4851 -  w - where the result is stored
4852 
4853    Level: intermediate
4854 
4855    Notes:
4856     w may be the same vector as y.
4857 
4858     This allows one to use either the restriction or interpolation (its transpose)
4859     matrix to do the interpolation
4860 
4861     Concepts: interpolation
4862 
4863 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4864 
4865 @*/
4866 int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4867 {
4868   int M,N,ierr;
4869 
4870   PetscFunctionBegin;
4871   PetscValidType(A);
4872   MatPreallocated(A);
4873   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4874   if (N > M) {
4875     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
4876   } else {
4877     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
4878   }
4879   PetscFunctionReturn(0);
4880 }
4881 
4882 #undef __FUNCT__
4883 #define __FUNCT__ "MatInterpolate"
4884 /*@
4885    MatInterpolate - y = A*x or A'*x depending on the shape of
4886      the matrix
4887 
4888    Collective on Mat
4889 
4890    Input Parameters:
4891 +  mat   - the matrix
4892 -  x,y - the vectors
4893 
4894    Level: intermediate
4895 
4896    Notes:
4897     This allows one to use either the restriction or interpolation (its transpose)
4898     matrix to do the interpolation
4899 
4900    Concepts: matrices^interpolation
4901 
4902 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4903 
4904 @*/
4905 int MatInterpolate(Mat A,Vec x,Vec y)
4906 {
4907   int M,N,ierr;
4908 
4909   PetscFunctionBegin;
4910   PetscValidType(A);
4911   MatPreallocated(A);
4912   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4913   if (N > M) {
4914     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4915   } else {
4916     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4917   }
4918   PetscFunctionReturn(0);
4919 }
4920 
4921 #undef __FUNCT__
4922 #define __FUNCT__ "MatRestrict"
4923 /*@
4924    MatRestrict - y = A*x or A'*x
4925 
4926    Collective on Mat
4927 
4928    Input Parameters:
4929 +  mat   - the matrix
4930 -  x,y - the vectors
4931 
4932    Level: intermediate
4933 
4934    Notes:
4935     This allows one to use either the restriction or interpolation (its transpose)
4936     matrix to do the restriction
4937 
4938    Concepts: matrices^restriction
4939 
4940 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
4941 
4942 @*/
4943 int MatRestrict(Mat A,Vec x,Vec y)
4944 {
4945   int M,N,ierr;
4946 
4947   PetscFunctionBegin;
4948   PetscValidType(A);
4949   MatPreallocated(A);
4950   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4951   if (N > M) {
4952     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4953   } else {
4954     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4955   }
4956   PetscFunctionReturn(0);
4957 }
4958 
4959 #undef __FUNCT__
4960 #define __FUNCT__ "MatNullSpaceAttach"
4961 /*@C
4962    MatNullSpaceAttach - attaches a null space to a matrix.
4963         This null space will be removed from the resulting vector whenever
4964         MatMult() is called
4965 
4966    Collective on Mat
4967 
4968    Input Parameters:
4969 +  mat - the matrix
4970 -  nullsp - the null space object
4971 
4972    Level: developer
4973 
4974    Notes:
4975       Overwrites any previous null space that may have been attached
4976 
4977    Concepts: null space^attaching to matrix
4978 
4979 .seealso: MatCreate(), MatNullSpaceCreate()
4980 @*/
4981 int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
4982 {
4983   int ierr;
4984 
4985   PetscFunctionBegin;
4986   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4987   PetscValidType(mat);
4988   MatPreallocated(mat);
4989   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE);
4990 
4991   if (mat->nullsp) {
4992     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
4993   }
4994   mat->nullsp = nullsp;
4995   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
4996   PetscFunctionReturn(0);
4997 }
4998 
4999 #undef __FUNCT__
5000 #define __FUNCT__ "MatICCFactor"
5001 /*@
5002    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
5003 
5004    Collective on Mat
5005 
5006    Input Parameters:
5007 +  mat - the matrix
5008 .  row - row/column permutation
5009 .  fill - expected fill factor >= 1.0
5010 -  level - level of fill, for ICC(k)
5011 
5012    Notes:
5013    Probably really in-place only when level of fill is zero, otherwise allocates
5014    new space to store factored matrix and deletes previous memory.
5015 
5016    Most users should employ the simplified KSP interface for linear solvers
5017    instead of working directly with matrix algebra routines such as this.
5018    See, e.g., KSPCreate().
5019 
5020    Level: developer
5021 
5022    Concepts: matrices^incomplete Cholesky factorization
5023    Concepts: Cholesky factorization
5024 
5025 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5026 @*/
5027 int MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
5028 {
5029   int ierr;
5030 
5031   PetscFunctionBegin;
5032   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5033   PetscValidType(mat);
5034   MatPreallocated(mat);
5035   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
5036   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5037   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5038   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5039   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
5040   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5041   PetscFunctionReturn(0);
5042 }
5043 
5044 #undef __FUNCT__
5045 #define __FUNCT__ "MatSetValuesAdic"
5046 /*@
5047    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
5048 
5049    Not Collective
5050 
5051    Input Parameters:
5052 +  mat - the matrix
5053 -  v - the values compute with ADIC
5054 
5055    Level: developer
5056 
5057    Notes:
5058      Must call MatSetColoring() before using this routine. Also this matrix must already
5059      have its nonzero pattern determined.
5060 
5061 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5062           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5063 @*/
5064 int MatSetValuesAdic(Mat mat,void *v)
5065 {
5066   int ierr;
5067 
5068   PetscFunctionBegin;
5069   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5070   PetscValidType(mat);
5071 
5072   if (!mat->assembled) {
5073     SETERRQ(1,"Matrix must be already assembled");
5074   }
5075   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5076   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5077   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
5078   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5079   ierr = MatView_Private(mat);CHKERRQ(ierr);
5080   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5081   PetscFunctionReturn(0);
5082 }
5083 
5084 
5085 #undef __FUNCT__
5086 #define __FUNCT__ "MatSetColoring"
5087 /*@
5088    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
5089 
5090    Not Collective
5091 
5092    Input Parameters:
5093 +  mat - the matrix
5094 -  coloring - the coloring
5095 
5096    Level: developer
5097 
5098 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5099           MatSetValues(), MatSetValuesAdic()
5100 @*/
5101 int MatSetColoring(Mat mat,ISColoring coloring)
5102 {
5103   int ierr;
5104 
5105   PetscFunctionBegin;
5106   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5107   PetscValidType(mat);
5108 
5109   if (!mat->assembled) {
5110     SETERRQ(1,"Matrix must be already assembled");
5111   }
5112   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5113   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
5114   PetscFunctionReturn(0);
5115 }
5116 
5117 #undef __FUNCT__
5118 #define __FUNCT__ "MatSetValuesAdifor"
5119 /*@
5120    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
5121 
5122    Not Collective
5123 
5124    Input Parameters:
5125 +  mat - the matrix
5126 .  nl - leading dimension of v
5127 -  v - the values compute with ADIFOR
5128 
5129    Level: developer
5130 
5131    Notes:
5132      Must call MatSetColoring() before using this routine. Also this matrix must already
5133      have its nonzero pattern determined.
5134 
5135 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5136           MatSetValues(), MatSetColoring()
5137 @*/
5138 int MatSetValuesAdifor(Mat mat,int nl,void *v)
5139 {
5140   int ierr;
5141 
5142   PetscFunctionBegin;
5143   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5144   PetscValidType(mat);
5145 
5146   if (!mat->assembled) {
5147     SETERRQ(1,"Matrix must be already assembled");
5148   }
5149   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5150   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5151   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
5152   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5153   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5154   PetscFunctionReturn(0);
5155 }
5156 
5157 EXTERN int MatMPIAIJDiagonalScaleLocal(Mat,Vec);
5158 EXTERN int MatMPIBAIJDiagonalScaleLocal(Mat,Vec);
5159 
5160 #undef __FUNCT__
5161 #define __FUNCT__ "MatDiagonalScaleLocal"
5162 /*@
5163    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
5164          ghosted ones.
5165 
5166    Not Collective
5167 
5168    Input Parameters:
5169 +  mat - the matrix
5170 -  diag = the diagonal values, including ghost ones
5171 
5172    Level: developer
5173 
5174    Notes: Works only for MPIAIJ and MPIBAIJ matrices
5175 
5176 .seealso: MatDiagonalScale()
5177 @*/
5178 int MatDiagonalScaleLocal(Mat mat,Vec diag)
5179 {
5180   int        ierr,size;
5181 
5182   PetscFunctionBegin;
5183   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5184   PetscValidHeaderSpecific(diag,VEC_COOKIE);
5185   PetscValidType(mat);
5186 
5187   if (!mat->assembled) {
5188     SETERRQ(1,"Matrix must be already assembled");
5189   }
5190   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5191   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5192   if (size == 1) {
5193     int n,m;
5194     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
5195     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
5196     if (m == n) {
5197       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
5198     } else {
5199       SETERRQ(1,"Only supprted for sequential matrices when no ghost points/periodic conditions");
5200     }
5201   } else {
5202     int (*f)(Mat,Vec);
5203     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
5204     if (f) {
5205       ierr = (*f)(mat,diag);CHKERRQ(ierr);
5206     } else {
5207       SETERRQ(1,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
5208     }
5209   }
5210   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5211   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5212   PetscFunctionReturn(0);
5213 }
5214 
5215 #undef __FUNCT__
5216 #define __FUNCT__ "MatGetInertia"
5217 /*@
5218    MatGetInertia - Gets the inertia from a factored matrix
5219 
5220    Collective on Mat
5221 
5222    Input Parameter:
5223 .  mat - the matrix
5224 
5225    Output Parameters:
5226 +   nneg - number of negative eigenvalues
5227 .   nzero - number of zero eigenvalues
5228 -   npos - number of positive eigenvalues
5229 
5230    Level: advanced
5231 
5232    Notes: Matrix must have been factored by MatCholeskyFactor()
5233 
5234 
5235 @*/
5236 int MatGetInertia(Mat mat,int *nneg,int *nzero,int *npos)
5237 {
5238   int        ierr;
5239 
5240   PetscFunctionBegin;
5241   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5242   PetscValidType(mat);
5243   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5244   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
5245   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5246   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
5247   PetscFunctionReturn(0);
5248 }
5249 
5250 /* ----------------------------------------------------------------*/
5251 #undef __FUNCT__
5252 #define __FUNCT__ "MatSolves"
5253 /*@
5254    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
5255 
5256    Collective on Mat and Vecs
5257 
5258    Input Parameters:
5259 +  mat - the factored matrix
5260 -  b - the right-hand-side vectors
5261 
5262    Output Parameter:
5263 .  x - the result vectors
5264 
5265    Notes:
5266    The vectors b and x cannot be the same.  I.e., one cannot
5267    call MatSolves(A,x,x).
5268 
5269    Notes:
5270    Most users should employ the simplified KSP interface for linear solvers
5271    instead of working directly with matrix algebra routines such as this.
5272    See, e.g., KSPCreate().
5273 
5274    Level: developer
5275 
5276    Concepts: matrices^triangular solves
5277 
5278 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
5279 @*/
5280 int MatSolves(Mat mat,Vecs b,Vecs x)
5281 {
5282   int ierr;
5283 
5284   PetscFunctionBegin;
5285   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5286   PetscValidType(mat);
5287   MatPreallocated(mat);
5288   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
5289   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5290   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
5291 
5292   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5293   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5294   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
5295   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5296   PetscFunctionReturn(0);
5297 }
5298 
5299 #undef __FUNCT__
5300 #define __FUNCT__ "MatIsSymmetric"
5301 /*@C
5302    MatIsSymmetric - Test whether a matrix is symmetric
5303 
5304    Collective on Mat
5305 
5306    Input Parameter:
5307 .  A - the matrix to test
5308 
5309    Output Parameters:
5310 .  flg - the result
5311 
5312    Level: intermediate
5313 
5314    Concepts: matrix^symmetry
5315 
5316 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption()
5317 @*/
5318 int MatIsSymmetric(Mat A,PetscTruth *flg)
5319 {
5320   int ierr;
5321 
5322   PetscFunctionBegin;
5323   PetscValidHeaderSpecific(A,MAT_COOKIE);
5324   if (!A->symmetric_set) {
5325     if (!A->ops->issymmetric) {
5326       MatType mattype;
5327       ierr = MatGetType(A,&mattype); CHKERRQ(ierr);
5328       SETERRQ1(1,"Matrix of type <%s> does not support checking for symmetric",
5329 	       mattype);
5330     }
5331     ierr = (*A->ops->issymmetric)(A,&A->symmetric); CHKERRQ(ierr);
5332     A->symmetric_set = PETSC_TRUE;
5333     if (A->symmetric) {
5334       A->structurally_symmetric_set = PETSC_TRUE;
5335       A->structurally_symmetric     = PETSC_TRUE;
5336     }
5337   }
5338   *flg = A->symmetric;
5339   PetscFunctionReturn(0);
5340 }
5341 
5342 #undef __FUNCT__
5343 #define __FUNCT__ "MatIsStructurallySymmetric"
5344 /*@C
5345    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
5346 
5347    Collective on Mat
5348 
5349    Input Parameter:
5350 .  A - the matrix to test
5351 
5352    Output Parameters:
5353 .  flg - the result
5354 
5355    Level: intermediate
5356 
5357    Concepts: matrix^symmetry
5358 
5359 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
5360 @*/
5361 int MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
5362 {
5363   int ierr;
5364 
5365   PetscFunctionBegin;
5366   PetscValidHeaderSpecific(A,MAT_COOKIE);
5367   if (!A->structurally_symmetric_set) {
5368     if (!A->ops->isstructurallysymmetric) SETERRQ(1,"Matrix does not support checking for structural symmetric");
5369     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
5370     A->structurally_symmetric_set = PETSC_TRUE;
5371   }
5372   *flg = A->structurally_symmetric;
5373   PetscFunctionReturn(0);
5374 }
5375 
5376 #undef __FUNCT__
5377 #define __FUNCT__ "MatIsHermitian"
5378 /*@C
5379    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.
5380 
5381    Collective on Mat
5382 
5383    Input Parameter:
5384 .  A - the matrix to test
5385 
5386    Output Parameters:
5387 .  flg - the result
5388 
5389    Level: intermediate
5390 
5391    Concepts: matrix^symmetry
5392 
5393 .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
5394 @*/
5395 int MatIsHermitian(Mat A,PetscTruth *flg)
5396 {
5397   int ierr;
5398 
5399   PetscFunctionBegin;
5400   PetscValidHeaderSpecific(A,MAT_COOKIE);
5401   if (!A->hermitian_set) {
5402     if (!A->ops->ishermitian) SETERRQ(1,"Matrix does not support checking for being Hermitian");
5403     ierr = (*A->ops->ishermitian)(A,&A->hermitian);CHKERRQ(ierr);
5404     A->hermitian_set = PETSC_TRUE;
5405     if (A->hermitian) {
5406       A->structurally_symmetric_set = PETSC_TRUE;
5407       A->structurally_symmetric     = PETSC_TRUE;
5408     }
5409   }
5410   *flg = A->hermitian;
5411   PetscFunctionReturn(0);
5412 }
5413