xref: /petsc/src/mat/interface/matrix.c (revision e7bfaa8ff3c8a59549747091b8748e3e71968c4c)
1 #define PETSCMAT_DLL
2 
3 /*
4    This is where the abstract matrix operations are defined
5 */
6 
7 #include "private/matimpl.h"        /*I "petscmat.h" I*/
8 #include "private/vecimpl.h"
9 
10 /* Logging support */
11 PetscCookie PETSCMAT_DLLEXPORT MAT_COOKIE;
12 PetscCookie PETSCMAT_DLLEXPORT MAT_FDCOLORING_COOKIE;
13 
14 PetscLogEvent  MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
15 PetscLogEvent  MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
16 PetscLogEvent  MAT_SolveTransposeAdd, MAT_Relax, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
17 PetscLogEvent  MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
18 PetscLogEvent  MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
19 PetscLogEvent  MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
20 PetscLogEvent  MAT_IncreaseOverlap, MAT_Partitioning, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
21 PetscLogEvent  MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
22 PetscLogEvent  MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
23 PetscLogEvent  MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric;
24 PetscLogEvent  MAT_MatMultTranspose, MAT_MatMultTransposeSymbolic, MAT_MatMultTransposeNumeric;
25 PetscLogEvent  MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
26 PetscLogEvent  MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
27 PetscLogEvent  MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
28 
29 /* nasty global values for MatSetValue() */
30 PetscInt    PETSCMAT_DLLEXPORT MatSetValue_Row = 0;
31 PetscInt    PETSCMAT_DLLEXPORT MatSetValue_Column = 0;
32 PetscScalar PETSCMAT_DLLEXPORT MatSetValue_Value = 0.0;
33 
34 #undef __FUNCT__
35 #define __FUNCT__ "MatGetDiagonalBlock"
36 /*@
37    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
38 
39    Not Collective
40 
41    Input Parameters:
42 +  mat - the matrix
43 -  reuse - indicates you are passing in the a matrix and want it reused
44 
45    Output Parameters:
46 +   iscopy - indicates a copy of the diagonal matrix was created and you should use MatDestroy() on it
47 -   a - the diagonal part (which is a SEQUENTIAL matrix)
48 
49    Notes: see the manual page for MatCreateMPIAIJ() for more information on the "diagonal part" of the matrix
50 
51    Level: advanced
52 
53 @*/
54 PetscErrorCode PETSCMAT_DLLEXPORT MatGetDiagonalBlock(Mat A,PetscTruth *iscopy,MatReuse reuse,Mat *a)
55 {
56   PetscErrorCode ierr,(*f)(Mat,PetscTruth*,MatReuse,Mat*);
57   PetscMPIInt    size;
58 
59   PetscFunctionBegin;
60   ierr = MPI_Comm_size(((PetscObject)A)->comm,&size);CHKERRQ(ierr);
61   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",(void (**)(void))&f);CHKERRQ(ierr);
62   if (f) {
63     ierr = (*f)(A,iscopy,reuse,a);CHKERRQ(ierr);
64   } else if (size == 1) {
65     *a = A;
66   } else {
67     SETERRQ(PETSC_ERR_SUP,"Cannot get diagonal part for this matrix");
68   }
69   PetscFunctionReturn(0);
70 }
71 
72 #undef __FUNCT__
73 #define __FUNCT__ "MatRealPart"
74 /*@
75    MatRealPart - Zeros out the imaginary part of the matrix
76 
77    Collective on Mat
78 
79    Input Parameters:
80 .  mat - the matrix
81 
82    Level: advanced
83 
84 
85 .seealso: MatImaginaryPart()
86 @*/
87 PetscErrorCode PETSCMAT_DLLEXPORT MatRealPart(Mat mat)
88 {
89   PetscErrorCode ierr;
90 
91   PetscFunctionBegin;
92   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
93   PetscValidType(mat,1);
94   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
95   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
96   if (!mat->ops->realpart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
97   ierr = MatPreallocated(mat);CHKERRQ(ierr);
98   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
99   PetscFunctionReturn(0);
100 }
101 
102 
103 #undef __FUNCT__
104 #define __FUNCT__ "MatImaginaryPart"
105 /*@
106    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
107 
108    Collective on Mat
109 
110    Input Parameters:
111 .  mat - the matrix
112 
113    Level: advanced
114 
115 
116 .seealso: MatRealPart()
117 @*/
118 PetscErrorCode PETSCMAT_DLLEXPORT MatImaginaryPart(Mat mat)
119 {
120   PetscErrorCode ierr;
121 
122   PetscFunctionBegin;
123   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
124   PetscValidType(mat,1);
125   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
126   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
127   if (!mat->ops->imaginarypart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
128   ierr = MatPreallocated(mat);CHKERRQ(ierr);
129   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
130   PetscFunctionReturn(0);
131 }
132 
133 #undef __FUNCT__
134 #define __FUNCT__ "MatMissingDiagonal"
135 /*@
136    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
137 
138    Collective on Mat
139 
140    Input Parameter:
141 .  mat - the matrix
142 
143    Output Parameters:
144 +  missing - is any diagonal missing
145 -  dd - first diagonal entry that is missing (optional)
146 
147    Level: advanced
148 
149 
150 .seealso: MatRealPart()
151 @*/
152 PetscErrorCode PETSCMAT_DLLEXPORT MatMissingDiagonal(Mat mat,PetscTruth *missing,PetscInt *dd)
153 {
154   PetscErrorCode ierr;
155 
156   PetscFunctionBegin;
157   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
158   PetscValidType(mat,1);
159   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
160   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
161   if (!mat->ops->missingdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
162   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
163   PetscFunctionReturn(0);
164 }
165 
166 #undef __FUNCT__
167 #define __FUNCT__ "MatGetRow"
168 /*@C
169    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
170    for each row that you get to ensure that your application does
171    not bleed memory.
172 
173    Not Collective
174 
175    Input Parameters:
176 +  mat - the matrix
177 -  row - the row to get
178 
179    Output Parameters:
180 +  ncols -  if not NULL, the number of nonzeros in the row
181 .  cols - if not NULL, the column numbers
182 -  vals - if not NULL, the values
183 
184    Notes:
185    This routine is provided for people who need to have direct access
186    to the structure of a matrix.  We hope that we provide enough
187    high-level matrix routines that few users will need it.
188 
189    MatGetRow() always returns 0-based column indices, regardless of
190    whether the internal representation is 0-based (default) or 1-based.
191 
192    For better efficiency, set cols and/or vals to PETSC_NULL if you do
193    not wish to extract these quantities.
194 
195    The user can only examine the values extracted with MatGetRow();
196    the values cannot be altered.  To change the matrix entries, one
197    must use MatSetValues().
198 
199    You can only have one call to MatGetRow() outstanding for a particular
200    matrix at a time, per processor. MatGetRow() can only obtain rows
201    associated with the given processor, it cannot get rows from the
202    other processors; for that we suggest using MatGetSubMatrices(), then
203    MatGetRow() on the submatrix. The row indix passed to MatGetRows()
204    is in the global number of rows.
205 
206    Fortran Notes:
207    The calling sequence from Fortran is
208 .vb
209    MatGetRow(matrix,row,ncols,cols,values,ierr)
210          Mat     matrix (input)
211          integer row    (input)
212          integer ncols  (output)
213          integer cols(maxcols) (output)
214          double precision (or double complex) values(maxcols) output
215 .ve
216    where maxcols >= maximum nonzeros in any row of the matrix.
217 
218 
219    Caution:
220    Do not try to change the contents of the output arrays (cols and vals).
221    In some cases, this may corrupt the matrix.
222 
223    Level: advanced
224 
225    Concepts: matrices^row access
226 
227 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
228 @*/
229 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
230 {
231   PetscErrorCode ierr;
232   PetscInt       incols;
233 
234   PetscFunctionBegin;
235   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
236   PetscValidType(mat,1);
237   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
238   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
239   if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
240   ierr = MatPreallocated(mat);CHKERRQ(ierr);
241   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
242   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
243   if (ncols) *ncols = incols;
244   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
245   PetscFunctionReturn(0);
246 }
247 
248 #undef __FUNCT__
249 #define __FUNCT__ "MatConjugate"
250 /*@
251    MatConjugate - replaces the matrix values with their complex conjugates
252 
253    Collective on Mat
254 
255    Input Parameters:
256 .  mat - the matrix
257 
258    Level: advanced
259 
260 .seealso:  VecConjugate()
261 @*/
262 PetscErrorCode PETSCMAT_DLLEXPORT MatConjugate(Mat mat)
263 {
264   PetscErrorCode ierr;
265 
266   PetscFunctionBegin;
267   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
268   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
269   if (!mat->ops->conjugate) SETERRQ(PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
270   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
271   PetscFunctionReturn(0);
272 }
273 
274 #undef __FUNCT__
275 #define __FUNCT__ "MatRestoreRow"
276 /*@C
277    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
278 
279    Not Collective
280 
281    Input Parameters:
282 +  mat - the matrix
283 .  row - the row to get
284 .  ncols, cols - the number of nonzeros and their columns
285 -  vals - if nonzero the column values
286 
287    Notes:
288    This routine should be called after you have finished examining the entries.
289 
290    Fortran Notes:
291    The calling sequence from Fortran is
292 .vb
293    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
294       Mat     matrix (input)
295       integer row    (input)
296       integer ncols  (output)
297       integer cols(maxcols) (output)
298       double precision (or double complex) values(maxcols) output
299 .ve
300    Where maxcols >= maximum nonzeros in any row of the matrix.
301 
302    In Fortran MatRestoreRow() MUST be called after MatGetRow()
303    before another call to MatGetRow() can be made.
304 
305    Level: advanced
306 
307 .seealso:  MatGetRow()
308 @*/
309 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
310 {
311   PetscErrorCode ierr;
312 
313   PetscFunctionBegin;
314   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
315   PetscValidIntPointer(ncols,3);
316   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
317   if (!mat->ops->restorerow) PetscFunctionReturn(0);
318   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
319   PetscFunctionReturn(0);
320 }
321 
322 #undef __FUNCT__
323 #define __FUNCT__ "MatGetRowUpperTriangular"
324 /*@
325    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
326    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
327 
328    Not Collective
329 
330    Input Parameters:
331 +  mat - the matrix
332 
333    Notes:
334    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
335 
336    Level: advanced
337 
338    Concepts: matrices^row access
339 
340 .seealso: MatRestoreRowRowUpperTriangular()
341 @*/
342 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowUpperTriangular(Mat mat)
343 {
344   PetscErrorCode ierr;
345 
346   PetscFunctionBegin;
347   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
348   PetscValidType(mat,1);
349   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
350   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
351   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
352   ierr = MatPreallocated(mat);CHKERRQ(ierr);
353   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
354   PetscFunctionReturn(0);
355 }
356 
357 #undef __FUNCT__
358 #define __FUNCT__ "MatRestoreRowUpperTriangular"
359 /*@
360    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
361 
362    Not Collective
363 
364    Input Parameters:
365 +  mat - the matrix
366 
367    Notes:
368    This routine should be called after you have finished MatGetRow/MatRestoreRow().
369 
370 
371    Level: advanced
372 
373 .seealso:  MatGetRowUpperTriangular()
374 @*/
375 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowUpperTriangular(Mat mat)
376 {
377   PetscErrorCode ierr;
378 
379   PetscFunctionBegin;
380   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
381   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
382   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
383   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
384   PetscFunctionReturn(0);
385 }
386 
387 #undef __FUNCT__
388 #define __FUNCT__ "MatSetOptionsPrefix"
389 /*@C
390    MatSetOptionsPrefix - Sets the prefix used for searching for all
391    Mat options in the database.
392 
393    Collective on Mat
394 
395    Input Parameter:
396 +  A - the Mat context
397 -  prefix - the prefix to prepend to all option names
398 
399    Notes:
400    A hyphen (-) must NOT be given at the beginning of the prefix name.
401    The first character of all runtime options is AUTOMATICALLY the hyphen.
402 
403    Level: advanced
404 
405 .keywords: Mat, set, options, prefix, database
406 
407 .seealso: MatSetFromOptions()
408 @*/
409 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOptionsPrefix(Mat A,const char prefix[])
410 {
411   PetscErrorCode ierr;
412 
413   PetscFunctionBegin;
414   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
415   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
416   PetscFunctionReturn(0);
417 }
418 
419 #undef __FUNCT__
420 #define __FUNCT__ "MatAppendOptionsPrefix"
421 /*@C
422    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
423    Mat options in the database.
424 
425    Collective on Mat
426 
427    Input Parameters:
428 +  A - the Mat context
429 -  prefix - the prefix to prepend to all option names
430 
431    Notes:
432    A hyphen (-) must NOT be given at the beginning of the prefix name.
433    The first character of all runtime options is AUTOMATICALLY the hyphen.
434 
435    Level: advanced
436 
437 .keywords: Mat, append, options, prefix, database
438 
439 .seealso: MatGetOptionsPrefix()
440 @*/
441 PetscErrorCode PETSCMAT_DLLEXPORT MatAppendOptionsPrefix(Mat A,const char prefix[])
442 {
443   PetscErrorCode ierr;
444 
445   PetscFunctionBegin;
446   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
447   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
448   PetscFunctionReturn(0);
449 }
450 
451 #undef __FUNCT__
452 #define __FUNCT__ "MatGetOptionsPrefix"
453 /*@C
454    MatGetOptionsPrefix - Sets the prefix used for searching for all
455    Mat options in the database.
456 
457    Not Collective
458 
459    Input Parameter:
460 .  A - the Mat context
461 
462    Output Parameter:
463 .  prefix - pointer to the prefix string used
464 
465    Notes: On the fortran side, the user should pass in a string 'prefix' of
466    sufficient length to hold the prefix.
467 
468    Level: advanced
469 
470 .keywords: Mat, get, options, prefix, database
471 
472 .seealso: MatAppendOptionsPrefix()
473 @*/
474 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOptionsPrefix(Mat A,const char *prefix[])
475 {
476   PetscErrorCode ierr;
477 
478   PetscFunctionBegin;
479   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
480   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
481   PetscFunctionReturn(0);
482 }
483 
484 #undef __FUNCT__
485 #define __FUNCT__ "MatSetUp"
486 /*@
487    MatSetUp - Sets up the internal matrix data structures for the later use.
488 
489    Collective on Mat
490 
491    Input Parameters:
492 .  A - the Mat context
493 
494    Notes:
495    For basic use of the Mat classes the user need not explicitly call
496    MatSetUp(), since these actions will happen automatically.
497 
498    Level: advanced
499 
500 .keywords: Mat, setup
501 
502 .seealso: MatCreate(), MatDestroy()
503 @*/
504 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUp(Mat A)
505 {
506   PetscMPIInt    size;
507   PetscErrorCode ierr;
508 
509   PetscFunctionBegin;
510   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
511   if (!((PetscObject)A)->type_name) {
512     ierr = MPI_Comm_size(((PetscObject)A)->comm, &size);CHKERRQ(ierr);
513     if (size == 1) {
514       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
515     } else {
516       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
517     }
518   }
519   ierr = MatSetUpPreallocation(A);CHKERRQ(ierr);
520   PetscFunctionReturn(0);
521 }
522 
523 #undef __FUNCT__
524 #define __FUNCT__ "MatView"
525 /*@C
526    MatView - Visualizes a matrix object.
527 
528    Collective on Mat
529 
530    Input Parameters:
531 +  mat - the matrix
532 -  viewer - visualization context
533 
534   Notes:
535   The available visualization contexts include
536 +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
537 .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
538         output where only the first processor opens
539         the file.  All other processors send their
540         data to the first processor to print.
541 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
542 
543    The user can open alternative visualization contexts with
544 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
545 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
546          specified file; corresponding input uses MatLoad()
547 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
548          an X window display
549 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
550          Currently only the sequential dense and AIJ
551          matrix types support the Socket viewer.
552 
553    The user can call PetscViewerSetFormat() to specify the output
554    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
555    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
556 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
557 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
558 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
559 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
560          format common among all matrix types
561 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
562          format (which is in many cases the same as the default)
563 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
564          size and structure (not the matrix entries)
565 .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
566          the matrix structure
567 
568    Options Database Keys:
569 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
570 .  -mat_view_info_detailed - Prints more detailed info
571 .  -mat_view - Prints matrix in ASCII format
572 .  -mat_view_matlab - Prints matrix in Matlab format
573 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
574 .  -display <name> - Sets display name (default is host)
575 .  -draw_pause <sec> - Sets number of seconds to pause after display
576 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
577 .  -viewer_socket_machine <machine>
578 .  -viewer_socket_port <port>
579 .  -mat_view_binary - save matrix to file in binary format
580 -  -viewer_binary_filename <name>
581    Level: beginner
582 
583    Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
584       viewer is used.
585 
586       See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
587       viewer is used.
588 
589    Concepts: matrices^viewing
590    Concepts: matrices^plotting
591    Concepts: matrices^printing
592 
593 .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
594           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
595 @*/
596 PetscErrorCode PETSCMAT_DLLEXPORT MatView(Mat mat,PetscViewer viewer)
597 {
598   PetscErrorCode    ierr;
599   PetscInt          rows,cols;
600   PetscTruth        iascii;
601   const MatType     cstr;
602   PetscViewerFormat format;
603 
604   PetscFunctionBegin;
605   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
606   PetscValidType(mat,1);
607   if (!viewer) {
608     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
609   }
610   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2);
611   PetscCheckSameComm(mat,1,viewer,2);
612   if (!mat->assembled) SETERRQ(PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
613   ierr = MatPreallocated(mat);CHKERRQ(ierr);
614 
615   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
616   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
617   if (iascii) {
618     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
619     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
620       if (((PetscObject)mat)->prefix) {
621         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",((PetscObject)mat)->prefix);CHKERRQ(ierr);
622       } else {
623         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");CHKERRQ(ierr);
624       }
625       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
626       ierr = MatGetType(mat,&cstr);CHKERRQ(ierr);
627       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
628       ierr = PetscViewerASCIIPrintf(viewer,"type=%s, rows=%D, cols=%D\n",cstr,rows,cols);CHKERRQ(ierr);
629       if (mat->factor) {
630         const MatSolverPackage solver;
631         ierr = MatFactorGetSolverPackage(mat,&solver);CHKERRQ(ierr);
632         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
633       }
634       if (mat->ops->getinfo) {
635         MatInfo info;
636         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
637         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);CHKERRQ(ierr);
638       }
639     }
640   }
641   if (mat->ops->view) {
642     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
643     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
644     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
645   } else if (!iascii) {
646     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
647   }
648   if (iascii) {
649     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
650     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
651       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
652     }
653   }
654   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
655   PetscFunctionReturn(0);
656 }
657 
658 #undef __FUNCT__
659 #define __FUNCT__ "MatScaleSystem"
660 /*@
661    MatScaleSystem - Scale a vector solution and right hand side to
662    match the scaling of a scaled matrix.
663 
664    Collective on Mat
665 
666    Input Parameter:
667 +  mat - the matrix
668 .  b - right hand side vector (or PETSC_NULL)
669 -  x - solution vector (or PETSC_NULL)
670 
671 
672    Notes:
673    For AIJ, and BAIJ matrix formats, the matrices are not
674    internally scaled, so this does nothing. For MPIROWBS it
675    permutes and diagonally scales.
676 
677    The KSP methods automatically call this routine when required
678    (via PCPreSolve()) so it is rarely used directly.
679 
680    Level: Developer
681 
682    Concepts: matrices^scaling
683 
684 .seealso: MatUseScaledForm(), MatUnScaleSystem()
685 @*/
686 PetscErrorCode PETSCMAT_DLLEXPORT MatScaleSystem(Mat mat,Vec b,Vec x)
687 {
688   PetscErrorCode ierr;
689 
690   PetscFunctionBegin;
691   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
692   PetscValidType(mat,1);
693   ierr = MatPreallocated(mat);CHKERRQ(ierr);
694   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,2);PetscCheckSameComm(mat,1,x,2);}
695   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,3);PetscCheckSameComm(mat,1,b,3);}
696 
697   if (mat->ops->scalesystem) {
698     ierr = (*mat->ops->scalesystem)(mat,b,x);CHKERRQ(ierr);
699   }
700   PetscFunctionReturn(0);
701 }
702 
703 #undef __FUNCT__
704 #define __FUNCT__ "MatUnScaleSystem"
705 /*@
706    MatUnScaleSystem - Unscales a vector solution and right hand side to
707    match the original scaling of a scaled matrix.
708 
709    Collective on Mat
710 
711    Input Parameter:
712 +  mat - the matrix
713 .  b - right hand side vector (or PETSC_NULL)
714 -  x - solution vector (or PETSC_NULL)
715 
716 
717    Notes:
718    For AIJ and BAIJ matrix formats, the matrices are not
719    internally scaled, so this does nothing. For MPIROWBS it
720    permutes and diagonally scales.
721 
722    The KSP methods automatically call this routine when required
723    (via PCPreSolve()) so it is rarely used directly.
724 
725    Level: Developer
726 
727 .seealso: MatUseScaledForm(), MatScaleSystem()
728 @*/
729 PetscErrorCode PETSCMAT_DLLEXPORT MatUnScaleSystem(Mat mat,Vec b,Vec x)
730 {
731   PetscErrorCode ierr;
732 
733   PetscFunctionBegin;
734   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
735   PetscValidType(mat,1);
736   ierr = MatPreallocated(mat);CHKERRQ(ierr);
737   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,2);PetscCheckSameComm(mat,1,x,2);}
738   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,3);PetscCheckSameComm(mat,1,b,3);}
739   if (mat->ops->unscalesystem) {
740     ierr = (*mat->ops->unscalesystem)(mat,b,x);CHKERRQ(ierr);
741   }
742   PetscFunctionReturn(0);
743 }
744 
745 #undef __FUNCT__
746 #define __FUNCT__ "MatUseScaledForm"
747 /*@
748    MatUseScaledForm - For matrix storage formats that scale the
749    matrix (for example MPIRowBS matrices are diagonally scaled on
750    assembly) indicates matrix operations (MatMult() etc) are
751    applied using the scaled matrix.
752 
753    Collective on Mat
754 
755    Input Parameter:
756 +  mat - the matrix
757 -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
758             applying the original matrix
759 
760    Notes:
761    For scaled matrix formats, applying the original, unscaled matrix
762    will be slightly more expensive
763 
764    Level: Developer
765 
766 .seealso: MatScaleSystem(), MatUnScaleSystem()
767 @*/
768 PetscErrorCode PETSCMAT_DLLEXPORT MatUseScaledForm(Mat mat,PetscTruth scaled)
769 {
770   PetscErrorCode ierr;
771 
772   PetscFunctionBegin;
773   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
774   PetscValidType(mat,1);
775   ierr = MatPreallocated(mat);CHKERRQ(ierr);
776   if (mat->ops->usescaledform) {
777     ierr = (*mat->ops->usescaledform)(mat,scaled);CHKERRQ(ierr);
778   }
779   PetscFunctionReturn(0);
780 }
781 
782 #undef __FUNCT__
783 #define __FUNCT__ "MatDestroy"
784 /*@
785    MatDestroy - Frees space taken by a matrix.
786 
787    Collective on Mat
788 
789    Input Parameter:
790 .  A - the matrix
791 
792    Level: beginner
793 
794 @*/
795 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroy(Mat A)
796 {
797   PetscErrorCode ierr;
798   PetscFunctionBegin;
799   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
800   if (--((PetscObject)A)->refct > 0) PetscFunctionReturn(0);
801   ierr = MatPreallocated(A);CHKERRQ(ierr);
802   /* if memory was published with AMS then destroy it */
803   ierr = PetscObjectDepublish(A);CHKERRQ(ierr);
804   if (A->ops->destroy) {
805     ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
806   }
807   if (A->mapping) {
808     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
809   }
810   if (A->bmapping) {
811     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
812   }
813 
814   if (A->spptr){ierr = PetscFree(A->spptr);CHKERRQ(ierr);}
815   ierr = PetscMapDestroy(A->rmap);CHKERRQ(ierr);
816   ierr = PetscMapDestroy(A->cmap);CHKERRQ(ierr);
817   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
818   PetscFunctionReturn(0);
819 }
820 
821 #undef __FUNCT__
822 #define __FUNCT__ "MatValid"
823 /*@
824    MatValid - Checks whether a matrix object is valid.
825 
826    Collective on Mat
827 
828    Input Parameter:
829 .  m - the matrix to check
830 
831    Output Parameter:
832    flg - flag indicating matrix status, either
833    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
834 
835    Level: developer
836 
837    Concepts: matrices^validity
838 @*/
839 PetscErrorCode PETSCMAT_DLLEXPORT MatValid(Mat m,PetscTruth *flg)
840 {
841   PetscFunctionBegin;
842   PetscValidIntPointer(flg,1);
843   if (!m)                                          *flg = PETSC_FALSE;
844   else if (((PetscObject)m)->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
845   else                                             *flg = PETSC_TRUE;
846   PetscFunctionReturn(0);
847 }
848 
849 #undef __FUNCT__
850 #define __FUNCT__ "MatSetValues"
851 /*@
852    MatSetValues - Inserts or adds a block of values into a matrix.
853    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
854    MUST be called after all calls to MatSetValues() have been completed.
855 
856    Not Collective
857 
858    Input Parameters:
859 +  mat - the matrix
860 .  v - a logically two-dimensional array of values
861 .  m, idxm - the number of rows and their global indices
862 .  n, idxn - the number of columns and their global indices
863 -  addv - either ADD_VALUES or INSERT_VALUES, where
864    ADD_VALUES adds values to any existing entries, and
865    INSERT_VALUES replaces existing entries with new values
866 
867    Notes:
868    By default the values, v, are row-oriented and unsorted.
869    See MatSetOption() for other options.
870 
871    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
872    options cannot be mixed without intervening calls to the assembly
873    routines.
874 
875    MatSetValues() uses 0-based row and column numbers in Fortran
876    as well as in C.
877 
878    Negative indices may be passed in idxm and idxn, these rows and columns are
879    simply ignored. This allows easily inserting element stiffness matrices
880    with homogeneous Dirchlet boundary conditions that you don't want represented
881    in the matrix.
882 
883    Efficiency Alert:
884    The routine MatSetValuesBlocked() may offer much better efficiency
885    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
886 
887    Level: beginner
888 
889    Concepts: matrices^putting entries in
890 
891 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
892           InsertMode, INSERT_VALUES, ADD_VALUES
893 @*/
894 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
895 {
896   PetscErrorCode ierr;
897 
898   PetscFunctionBegin;
899   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
900   PetscValidType(mat,1);
901   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
902   PetscValidIntPointer(idxm,3);
903   PetscValidIntPointer(idxn,5);
904   ierr = MatPreallocated(mat);CHKERRQ(ierr);
905   if (mat->insertmode == NOT_SET_VALUES) {
906     mat->insertmode = addv;
907   }
908 #if defined(PETSC_USE_DEBUG)
909   else if (mat->insertmode != addv) {
910     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
911   }
912   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
913 #endif
914 
915   if (mat->assembled) {
916     mat->was_assembled = PETSC_TRUE;
917     mat->assembled     = PETSC_FALSE;
918   }
919   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
920   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
921   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
922   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
923   PetscFunctionReturn(0);
924 }
925 
926 
927 #undef __FUNCT__
928 #define __FUNCT__ "MatSetValuesRowLocal"
929 /*@
930    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
931         values into a matrix
932 
933    Not Collective
934 
935    Input Parameters:
936 +  mat - the matrix
937 .  row - the (block) row to set
938 -  v - a logically two-dimensional array of values
939 
940    Notes:
941    By the values, v, are column-oriented (for the block version) and sorted
942 
943    All the nonzeros in the row must be provided
944 
945    The matrix must have previously had its column indices set
946 
947    The row must belong to this process
948 
949    Level: intermediate
950 
951    Concepts: matrices^putting entries in
952 
953 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
954           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
955 @*/
956 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
957 {
958   PetscErrorCode ierr;
959 
960   PetscFunctionBegin;
961   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
962   PetscValidType(mat,1);
963   PetscValidScalarPointer(v,2);
964   ierr = MatSetValuesRow(mat, mat->mapping->indices[row],v);CHKERRQ(ierr);
965   PetscFunctionReturn(0);
966 }
967 
968 #undef __FUNCT__
969 #define __FUNCT__ "MatSetValuesRow"
970 /*@
971    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
972         values into a matrix
973 
974    Not Collective
975 
976    Input Parameters:
977 +  mat - the matrix
978 .  row - the (block) row to set
979 -  v - a logically two-dimensional array of values
980 
981    Notes:
982    By the values, v, are column-oriented (for the block version) and sorted
983 
984    All the nonzeros in the row must be provided
985 
986    The matrix must have previously had its column indices set
987 
988    The row must belong to this process
989 
990    Level: intermediate
991 
992    Concepts: matrices^putting entries in
993 
994 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
995           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
996 @*/
997 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
998 {
999   PetscErrorCode ierr;
1000 
1001   PetscFunctionBegin;
1002   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1003   PetscValidType(mat,1);
1004   PetscValidScalarPointer(v,2);
1005 #if defined(PETSC_USE_DEBUG)
1006   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1007   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1008 #endif
1009   mat->insertmode = INSERT_VALUES;
1010 
1011   if (mat->assembled) {
1012     mat->was_assembled = PETSC_TRUE;
1013     mat->assembled     = PETSC_FALSE;
1014   }
1015   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1016   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1017   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1018   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1019   PetscFunctionReturn(0);
1020 }
1021 
1022 #undef __FUNCT__
1023 #define __FUNCT__ "MatSetValuesStencil"
1024 /*@
1025    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1026      Using structured grid indexing
1027 
1028    Not Collective
1029 
1030    Input Parameters:
1031 +  mat - the matrix
1032 .  v - a logically two-dimensional array of values
1033 .  m - number of rows being entered
1034 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1035 .  n - number of columns being entered
1036 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1037 -  addv - either ADD_VALUES or INSERT_VALUES, where
1038    ADD_VALUES adds values to any existing entries, and
1039    INSERT_VALUES replaces existing entries with new values
1040 
1041    Notes:
1042    By default the values, v, are row-oriented and unsorted.
1043    See MatSetOption() for other options.
1044 
1045    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1046    options cannot be mixed without intervening calls to the assembly
1047    routines.
1048 
1049    The grid coordinates are across the entire grid, not just the local portion
1050 
1051    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1052    as well as in C.
1053 
1054    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1055 
1056    In order to use this routine you must either obtain the matrix with DAGetMatrix()
1057    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1058 
1059    The columns and rows in the stencil passed in MUST be contained within the
1060    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1061    if you create a DA with an overlap of one grid level and on a particular process its first
1062    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1063    first i index you can use in your column and row indices in MatSetStencil() is 5.
1064 
1065    In Fortran idxm and idxn should be declared as
1066 $     MatStencil idxm(4,m),idxn(4,n)
1067    and the values inserted using
1068 $    idxm(MatStencil_i,1) = i
1069 $    idxm(MatStencil_j,1) = j
1070 $    idxm(MatStencil_k,1) = k
1071 $    idxm(MatStencil_c,1) = c
1072    etc
1073 
1074    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1075    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1076    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for the DA_NONPERIODIC
1077    wrap.
1078 
1079    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1080    a single value per point) you can skip filling those indices.
1081 
1082    Inspired by the structured grid interface to the HYPRE package
1083    (http://www.llnl.gov/CASC/hypre)
1084 
1085    Efficiency Alert:
1086    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1087    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1088 
1089    Level: beginner
1090 
1091    Concepts: matrices^putting entries in
1092 
1093 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1094           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1095 @*/
1096 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1097 {
1098   PetscErrorCode ierr;
1099   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1100   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1101 
1102   PetscFunctionBegin;
1103   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1104   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1105   PetscValidType(mat,1);
1106   PetscValidIntPointer(idxm,3);
1107   PetscValidIntPointer(idxn,5);
1108   PetscValidScalarPointer(v,6);
1109 
1110   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1111   if (n > 256) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1112 
1113   for (i=0; i<m; i++) {
1114     for (j=0; j<3-sdim; j++) dxm++;
1115     tmp = *dxm++ - starts[0];
1116     for (j=0; j<dim-1; j++) {
1117       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1118       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1119     }
1120     if (mat->stencil.noc) dxm++;
1121     jdxm[i] = tmp;
1122   }
1123   for (i=0; i<n; i++) {
1124     for (j=0; j<3-sdim; j++) dxn++;
1125     tmp = *dxn++ - starts[0];
1126     for (j=0; j<dim-1; j++) {
1127       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1128       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1129     }
1130     if (mat->stencil.noc) dxn++;
1131     jdxn[i] = tmp;
1132   }
1133   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1134   PetscFunctionReturn(0);
1135 }
1136 
1137 #undef __FUNCT__
1138 #define __FUNCT__ "MatSetValuesBlockedStencil"
1139 /*@C
1140    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1141      Using structured grid indexing
1142 
1143    Not Collective
1144 
1145    Input Parameters:
1146 +  mat - the matrix
1147 .  v - a logically two-dimensional array of values
1148 .  m - number of rows being entered
1149 .  idxm - grid coordinates for matrix rows being entered
1150 .  n - number of columns being entered
1151 .  idxn - grid coordinates for matrix columns being entered
1152 -  addv - either ADD_VALUES or INSERT_VALUES, where
1153    ADD_VALUES adds values to any existing entries, and
1154    INSERT_VALUES replaces existing entries with new values
1155 
1156    Notes:
1157    By default the values, v, are row-oriented and unsorted.
1158    See MatSetOption() for other options.
1159 
1160    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1161    options cannot be mixed without intervening calls to the assembly
1162    routines.
1163 
1164    The grid coordinates are across the entire grid, not just the local portion
1165 
1166    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1167    as well as in C.
1168 
1169    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
1170 
1171    In order to use this routine you must either obtain the matrix with DAGetMatrix()
1172    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1173 
1174    The columns and rows in the stencil passed in MUST be contained within the
1175    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
1176    if you create a DA with an overlap of one grid level and on a particular process its first
1177    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1178    first i index you can use in your column and row indices in MatSetStencil() is 5.
1179 
1180    In Fortran idxm and idxn should be declared as
1181 $     MatStencil idxm(4,m),idxn(4,n)
1182    and the values inserted using
1183 $    idxm(MatStencil_i,1) = i
1184 $    idxm(MatStencil_j,1) = j
1185 $    idxm(MatStencil_k,1) = k
1186    etc
1187 
1188    Negative indices may be passed in idxm and idxn, these rows and columns are
1189    simply ignored. This allows easily inserting element stiffness matrices
1190    with homogeneous Dirchlet boundary conditions that you don't want represented
1191    in the matrix.
1192 
1193    Inspired by the structured grid interface to the HYPRE package
1194    (http://www.llnl.gov/CASC/hypre)
1195 
1196    Level: beginner
1197 
1198    Concepts: matrices^putting entries in
1199 
1200 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1201           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1202 @*/
1203 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1204 {
1205   PetscErrorCode ierr;
1206   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1207   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1208 
1209   PetscFunctionBegin;
1210   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1211   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1212   PetscValidType(mat,1);
1213   PetscValidIntPointer(idxm,3);
1214   PetscValidIntPointer(idxn,5);
1215   PetscValidScalarPointer(v,6);
1216 
1217   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1218   if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
1219 
1220   for (i=0; i<m; i++) {
1221     for (j=0; j<3-sdim; j++) dxm++;
1222     tmp = *dxm++ - starts[0];
1223     for (j=0; j<sdim-1; j++) {
1224       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1225       else                                      tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1226     }
1227     dxm++;
1228     jdxm[i] = tmp;
1229   }
1230   for (i=0; i<n; i++) {
1231     for (j=0; j<3-sdim; j++) dxn++;
1232     tmp = *dxn++ - starts[0];
1233     for (j=0; j<sdim-1; j++) {
1234       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1235       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1236     }
1237     dxn++;
1238     jdxn[i] = tmp;
1239   }
1240   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1241   PetscFunctionReturn(0);
1242 }
1243 
1244 #undef __FUNCT__
1245 #define __FUNCT__ "MatSetStencil"
1246 /*@
1247    MatSetStencil - Sets the grid information for setting values into a matrix via
1248         MatSetValuesStencil()
1249 
1250    Not Collective
1251 
1252    Input Parameters:
1253 +  mat - the matrix
1254 .  dim - dimension of the grid 1, 2, or 3
1255 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1256 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1257 -  dof - number of degrees of freedom per node
1258 
1259 
1260    Inspired by the structured grid interface to the HYPRE package
1261    (www.llnl.gov/CASC/hyper)
1262 
1263    For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
1264    user.
1265 
1266    Level: beginner
1267 
1268    Concepts: matrices^putting entries in
1269 
1270 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1271           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1272 @*/
1273 PetscErrorCode PETSCMAT_DLLEXPORT MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1274 {
1275   PetscInt i;
1276 
1277   PetscFunctionBegin;
1278   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1279   PetscValidIntPointer(dims,3);
1280   PetscValidIntPointer(starts,4);
1281 
1282   mat->stencil.dim = dim + (dof > 1);
1283   for (i=0; i<dim; i++) {
1284     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1285     mat->stencil.starts[i] = starts[dim-i-1];
1286   }
1287   mat->stencil.dims[dim]   = dof;
1288   mat->stencil.starts[dim] = 0;
1289   mat->stencil.noc         = (PetscTruth)(dof == 1);
1290   PetscFunctionReturn(0);
1291 }
1292 
1293 #undef __FUNCT__
1294 #define __FUNCT__ "MatSetValuesBlocked"
1295 /*@
1296    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1297 
1298    Not Collective
1299 
1300    Input Parameters:
1301 +  mat - the matrix
1302 .  v - a logically two-dimensional array of values
1303 .  m, idxm - the number of block rows and their global block indices
1304 .  n, idxn - the number of block columns and their global block indices
1305 -  addv - either ADD_VALUES or INSERT_VALUES, where
1306    ADD_VALUES adds values to any existing entries, and
1307    INSERT_VALUES replaces existing entries with new values
1308 
1309    Notes:
1310    The m and n count the NUMBER of blocks in the row direction and column direction,
1311    NOT the total number of rows/columns; for example, if the block size is 2 and
1312    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1313    The values in idxm would be 1 2; that is the first index for each block divided by
1314    the block size.
1315 
1316    By default the values, v, are row-oriented and unsorted. So the layout of
1317    v is the same as for MatSetValues(). See MatSetOption() for other options.
1318 
1319    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1320    options cannot be mixed without intervening calls to the assembly
1321    routines.
1322 
1323    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1324    as well as in C.
1325 
1326    Negative indices may be passed in idxm and idxn, these rows and columns are
1327    simply ignored. This allows easily inserting element stiffness matrices
1328    with homogeneous Dirchlet boundary conditions that you don't want represented
1329    in the matrix.
1330 
1331    Each time an entry is set within a sparse matrix via MatSetValues(),
1332    internal searching must be done to determine where to place the the
1333    data in the matrix storage space.  By instead inserting blocks of
1334    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1335    reduced.
1336 
1337    Example:
1338 $   Suppose m=n=2 and block size(bs) = 2 The array is
1339 $
1340 $   1  2  | 3  4
1341 $   5  6  | 7  8
1342 $   - - - | - - -
1343 $   9  10 | 11 12
1344 $   13 14 | 15 16
1345 $
1346 $   v[] should be passed in like
1347 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1348 $
1349 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1350 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1351 
1352    Level: intermediate
1353 
1354    Concepts: matrices^putting entries in blocked
1355 
1356 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1357 @*/
1358 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1359 {
1360   PetscErrorCode ierr;
1361 
1362   PetscFunctionBegin;
1363   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1364   PetscValidType(mat,1);
1365   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1366   PetscValidIntPointer(idxm,3);
1367   PetscValidIntPointer(idxn,5);
1368   PetscValidScalarPointer(v,6);
1369   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1370   if (mat->insertmode == NOT_SET_VALUES) {
1371     mat->insertmode = addv;
1372   }
1373 #if defined(PETSC_USE_DEBUG)
1374   else if (mat->insertmode != addv) {
1375     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1376   }
1377   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1378 #endif
1379 
1380   if (mat->assembled) {
1381     mat->was_assembled = PETSC_TRUE;
1382     mat->assembled     = PETSC_FALSE;
1383   }
1384   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1385   if (mat->ops->setvaluesblocked) {
1386     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1387   } else {
1388     PetscInt buf[4096],*ibufm=0,*ibufn=0;
1389     PetscInt i,j,*iidxm,*iidxn,bs=mat->rmap->bs;
1390     if ((m+n)*bs <= 4096) {
1391       iidxm = buf; iidxn = buf + m*bs;
1392     } else {
1393       ierr = PetscMalloc2(m*bs,PetscInt,&ibufm,n*bs,PetscInt,&ibufn);CHKERRQ(ierr);
1394       iidxm = ibufm; iidxn = ibufn;
1395     }
1396     for (i=0; i<m; i++) {
1397       for (j=0; j<bs; j++) {
1398 	iidxm[i*bs+j] = bs*idxm[i] + j;
1399       }
1400     }
1401     for (i=0; i<n; i++) {
1402       for (j=0; j<bs; j++) {
1403 	iidxn[i*bs+j] = bs*idxn[i] + j;
1404       }
1405     }
1406     ierr = MatSetValues(mat,bs*m,iidxm,bs*n,iidxn,v,addv);CHKERRQ(ierr);
1407     ierr = PetscFree2(ibufm,ibufn);CHKERRQ(ierr);
1408   }
1409   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1410   PetscFunctionReturn(0);
1411 }
1412 
1413 #undef __FUNCT__
1414 #define __FUNCT__ "MatGetValues"
1415 /*@
1416    MatGetValues - Gets a block of values from a matrix.
1417 
1418    Not Collective; currently only returns a local block
1419 
1420    Input Parameters:
1421 +  mat - the matrix
1422 .  v - a logically two-dimensional array for storing the values
1423 .  m, idxm - the number of rows and their global indices
1424 -  n, idxn - the number of columns and their global indices
1425 
1426    Notes:
1427    The user must allocate space (m*n PetscScalars) for the values, v.
1428    The values, v, are then returned in a row-oriented format,
1429    analogous to that used by default in MatSetValues().
1430 
1431    MatGetValues() uses 0-based row and column numbers in
1432    Fortran as well as in C.
1433 
1434    MatGetValues() requires that the matrix has been assembled
1435    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1436    MatSetValues() and MatGetValues() CANNOT be made in succession
1437    without intermediate matrix assembly.
1438 
1439    Negative row or column indices will be ignored and those locations in v[] will be
1440    left unchanged.
1441 
1442    Level: advanced
1443 
1444    Concepts: matrices^accessing values
1445 
1446 .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1447 @*/
1448 PetscErrorCode PETSCMAT_DLLEXPORT MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1449 {
1450   PetscErrorCode ierr;
1451 
1452   PetscFunctionBegin;
1453   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1454   PetscValidType(mat,1);
1455   PetscValidIntPointer(idxm,3);
1456   PetscValidIntPointer(idxn,5);
1457   PetscValidScalarPointer(v,6);
1458   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1459   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1460   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1461   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1462 
1463   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1464   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1465   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1466   PetscFunctionReturn(0);
1467 }
1468 
1469 #undef __FUNCT__
1470 #define __FUNCT__ "MatSetLocalToGlobalMapping"
1471 /*@
1472    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1473    the routine MatSetValuesLocal() to allow users to insert matrix entries
1474    using a local (per-processor) numbering.
1475 
1476    Not Collective
1477 
1478    Input Parameters:
1479 +  x - the matrix
1480 -  mapping - mapping created with ISLocalToGlobalMappingCreate()
1481              or ISLocalToGlobalMappingCreateIS()
1482 
1483    Level: intermediate
1484 
1485    Concepts: matrices^local to global mapping
1486    Concepts: local to global mapping^for matrices
1487 
1488 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1489 @*/
1490 PetscErrorCode PETSCMAT_DLLEXPORT MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1491 {
1492   PetscErrorCode ierr;
1493   PetscFunctionBegin;
1494   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
1495   PetscValidType(x,1);
1496   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
1497   if (x->mapping) {
1498     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1499   }
1500   ierr = MatPreallocated(x);CHKERRQ(ierr);
1501 
1502   if (x->ops->setlocaltoglobalmapping) {
1503     ierr = (*x->ops->setlocaltoglobalmapping)(x,mapping);CHKERRQ(ierr);
1504   } else {
1505     ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1506     if (x->mapping) { ierr = ISLocalToGlobalMappingDestroy(x->mapping);CHKERRQ(ierr); }
1507     x->mapping = mapping;
1508   }
1509   PetscFunctionReturn(0);
1510 }
1511 
1512 #undef __FUNCT__
1513 #define __FUNCT__ "MatSetLocalToGlobalMappingBlock"
1514 /*@
1515    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1516    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1517    entries using a local (per-processor) numbering.
1518 
1519    Not Collective
1520 
1521    Input Parameters:
1522 +  x - the matrix
1523 -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
1524              ISLocalToGlobalMappingCreateIS()
1525 
1526    Level: intermediate
1527 
1528    Concepts: matrices^local to global mapping blocked
1529    Concepts: local to global mapping^for matrices, blocked
1530 
1531 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1532            MatSetValuesBlocked(), MatSetValuesLocal()
1533 @*/
1534 PetscErrorCode PETSCMAT_DLLEXPORT MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1535 {
1536   PetscErrorCode ierr;
1537   PetscFunctionBegin;
1538   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
1539   PetscValidType(x,1);
1540   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
1541   if (x->bmapping) {
1542     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1543   }
1544   ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1545   if (x->bmapping) { ierr = ISLocalToGlobalMappingDestroy(x->mapping);CHKERRQ(ierr); }
1546   x->bmapping = mapping;
1547   PetscFunctionReturn(0);
1548 }
1549 
1550 #undef __FUNCT__
1551 #define __FUNCT__ "MatSetValuesLocal"
1552 /*@
1553    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1554    using a local ordering of the nodes.
1555 
1556    Not Collective
1557 
1558    Input Parameters:
1559 +  x - the matrix
1560 .  nrow, irow - number of rows and their local indices
1561 .  ncol, icol - number of columns and their local indices
1562 .  y -  a logically two-dimensional array of values
1563 -  addv - either INSERT_VALUES or ADD_VALUES, where
1564    ADD_VALUES adds values to any existing entries, and
1565    INSERT_VALUES replaces existing entries with new values
1566 
1567    Notes:
1568    Before calling MatSetValuesLocal(), the user must first set the
1569    local-to-global mapping by calling MatSetLocalToGlobalMapping().
1570 
1571    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1572    options cannot be mixed without intervening calls to the assembly
1573    routines.
1574 
1575    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1576    MUST be called after all calls to MatSetValuesLocal() have been completed.
1577 
1578    Level: intermediate
1579 
1580    Concepts: matrices^putting entries in with local numbering
1581 
1582 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1583            MatSetValueLocal()
1584 @*/
1585 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1586 {
1587   PetscErrorCode ierr;
1588   PetscInt       irowm[2048],icolm[2048];
1589 
1590   PetscFunctionBegin;
1591   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1592   PetscValidType(mat,1);
1593   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
1594   PetscValidIntPointer(irow,3);
1595   PetscValidIntPointer(icol,5);
1596   PetscValidScalarPointer(y,6);
1597   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1598   if (mat->insertmode == NOT_SET_VALUES) {
1599     mat->insertmode = addv;
1600   }
1601 #if defined(PETSC_USE_DEBUG)
1602   else if (mat->insertmode != addv) {
1603     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1604   }
1605   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1606     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1607   }
1608   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1609 #endif
1610 
1611   if (mat->assembled) {
1612     mat->was_assembled = PETSC_TRUE;
1613     mat->assembled     = PETSC_FALSE;
1614   }
1615   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1616   if (!mat->ops->setvalueslocal) {
1617     ierr = ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);CHKERRQ(ierr);
1618     ierr = ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);CHKERRQ(ierr);
1619     ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1620   } else {
1621     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
1622   }
1623   mat->same_nonzero = PETSC_FALSE;
1624   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1625   PetscFunctionReturn(0);
1626 }
1627 
1628 #undef __FUNCT__
1629 #define __FUNCT__ "MatSetValuesBlockedLocal"
1630 /*@
1631    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1632    using a local ordering of the nodes a block at a time.
1633 
1634    Not Collective
1635 
1636    Input Parameters:
1637 +  x - the matrix
1638 .  nrow, irow - number of rows and their local indices
1639 .  ncol, icol - number of columns and their local indices
1640 .  y -  a logically two-dimensional array of values
1641 -  addv - either INSERT_VALUES or ADD_VALUES, where
1642    ADD_VALUES adds values to any existing entries, and
1643    INSERT_VALUES replaces existing entries with new values
1644 
1645    Notes:
1646    Before calling MatSetValuesBlockedLocal(), the user must first set the
1647    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1648    where the mapping MUST be set for matrix blocks, not for matrix elements.
1649 
1650    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1651    options cannot be mixed without intervening calls to the assembly
1652    routines.
1653 
1654    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1655    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1656 
1657    Level: intermediate
1658 
1659    Concepts: matrices^putting blocked values in with local numbering
1660 
1661 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1662 @*/
1663 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1664 {
1665   PetscErrorCode ierr;
1666   PetscInt       irowm[2048],icolm[2048];
1667 
1668   PetscFunctionBegin;
1669   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1670   PetscValidType(mat,1);
1671   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
1672   PetscValidIntPointer(irow,3);
1673   PetscValidIntPointer(icol,5);
1674   PetscValidScalarPointer(y,6);
1675   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1676   if (mat->insertmode == NOT_SET_VALUES) {
1677     mat->insertmode = addv;
1678   }
1679 #if defined(PETSC_USE_DEBUG)
1680   else if (mat->insertmode != addv) {
1681     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1682   }
1683   if (!mat->bmapping) {
1684     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1685   }
1686   if (nrow > 2048 || ncol > 2048) {
1687     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1688   }
1689   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1690 #endif
1691 
1692   if (mat->assembled) {
1693     mat->was_assembled = PETSC_TRUE;
1694     mat->assembled     = PETSC_FALSE;
1695   }
1696   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1697   ierr = ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);CHKERRQ(ierr);
1698   ierr = ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);CHKERRQ(ierr);
1699   if (mat->ops->setvaluesblocked) {
1700   ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1701   } else {
1702     PetscInt buf[4096],*ibufm=0,*ibufn=0;
1703     PetscInt i,j,*iirowm,*iicolm,bs=mat->rmap->bs;
1704     if ((nrow+ncol)*bs <= 4096) {
1705       iirowm = buf; iicolm = buf + nrow*bs;
1706     } else {
1707       ierr = PetscMalloc2(nrow*bs,PetscInt,&ibufm,ncol*bs,PetscInt,&ibufn);CHKERRQ(ierr);
1708       iirowm = ibufm; iicolm = ibufn;
1709     }
1710     for (i=0; i<nrow; i++) {
1711       for (j=0; j<bs; j++) {
1712 	iirowm[i*bs+j] = bs*irowm[i] + j;
1713       }
1714     }
1715     for (i=0; i<ncol; i++) {
1716       for (j=0; j<bs; j++) {
1717 	iicolm[i*bs+j] = bs*icolm[i] + j;
1718       }
1719     }
1720     ierr = MatSetValues(mat,bs*nrow,iirowm,bs*ncol,iicolm,y,addv);CHKERRQ(ierr);
1721     ierr = PetscFree2(ibufm,ibufn);CHKERRQ(ierr);
1722   }
1723   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1724   PetscFunctionReturn(0);
1725 }
1726 
1727 /* --------------------------------------------------------*/
1728 #undef __FUNCT__
1729 #define __FUNCT__ "MatMult"
1730 /*@
1731    MatMult - Computes the matrix-vector product, y = Ax.
1732 
1733    Collective on Mat and Vec
1734 
1735    Input Parameters:
1736 +  mat - the matrix
1737 -  x   - the vector to be multiplied
1738 
1739    Output Parameters:
1740 .  y - the result
1741 
1742    Notes:
1743    The vectors x and y cannot be the same.  I.e., one cannot
1744    call MatMult(A,y,y).
1745 
1746    Level: beginner
1747 
1748    Concepts: matrix-vector product
1749 
1750 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1751 @*/
1752 PetscErrorCode PETSCMAT_DLLEXPORT MatMult(Mat mat,Vec x,Vec y)
1753 {
1754   PetscErrorCode ierr;
1755 
1756   PetscFunctionBegin;
1757   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1758   PetscValidType(mat,1);
1759   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1760   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1761 
1762   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1763   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1764   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1765 #ifndef PETSC_HAVE_CONSTRAINTS
1766   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
1767   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
1768   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
1769 #endif
1770   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1771 
1772   if (mat->nullsp) {
1773     ierr = MatNullSpaceRemove(mat->nullsp,x,&x);CHKERRQ(ierr);
1774   }
1775 
1776   if (!mat->ops->mult) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1777   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1778   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
1779   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1780 
1781   if (mat->nullsp) {
1782     ierr = MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);CHKERRQ(ierr);
1783   }
1784   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1785   PetscFunctionReturn(0);
1786 }
1787 
1788 #undef __FUNCT__
1789 #define __FUNCT__ "MatMultTranspose"
1790 /*@
1791    MatMultTranspose - Computes matrix transpose times a vector.
1792 
1793    Collective on Mat and Vec
1794 
1795    Input Parameters:
1796 +  mat - the matrix
1797 -  x   - the vector to be multilplied
1798 
1799    Output Parameters:
1800 .  y - the result
1801 
1802    Notes:
1803    The vectors x and y cannot be the same.  I.e., one cannot
1804    call MatMultTranspose(A,y,y).
1805 
1806    Level: beginner
1807 
1808    Concepts: matrix vector product^transpose
1809 
1810 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1811 @*/
1812 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTranspose(Mat mat,Vec x,Vec y)
1813 {
1814   PetscErrorCode ierr;
1815 
1816   PetscFunctionBegin;
1817   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1818   PetscValidType(mat,1);
1819   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1820   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1821 
1822   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1823   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1824   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1825 #ifndef PETSC_HAVE_CONSTRAINTS
1826   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
1827   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
1828 #endif
1829   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1830 
1831   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1832   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1833   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
1834   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1835   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1836   PetscFunctionReturn(0);
1837 }
1838 
1839 #undef __FUNCT__
1840 #define __FUNCT__ "MatMultAdd"
1841 /*@
1842     MatMultAdd -  Computes v3 = v2 + A * v1.
1843 
1844     Collective on Mat and Vec
1845 
1846     Input Parameters:
1847 +   mat - the matrix
1848 -   v1, v2 - the vectors
1849 
1850     Output Parameters:
1851 .   v3 - the result
1852 
1853     Notes:
1854     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1855     call MatMultAdd(A,v1,v2,v1).
1856 
1857     Level: beginner
1858 
1859     Concepts: matrix vector product^addition
1860 
1861 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1862 @*/
1863 PetscErrorCode PETSCMAT_DLLEXPORT MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1864 {
1865   PetscErrorCode ierr;
1866 
1867   PetscFunctionBegin;
1868   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1869   PetscValidType(mat,1);
1870   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1871   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1872   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1873 
1874   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1875   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1876   if (mat->cmap->N != v1->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
1877   if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
1878   if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N);
1879   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
1880   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
1881   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1882   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1883 
1884   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1885   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1886   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1887   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
1888   PetscFunctionReturn(0);
1889 }
1890 
1891 #undef __FUNCT__
1892 #define __FUNCT__ "MatMultTransposeAdd"
1893 /*@
1894    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1895 
1896    Collective on Mat and Vec
1897 
1898    Input Parameters:
1899 +  mat - the matrix
1900 -  v1, v2 - the vectors
1901 
1902    Output Parameters:
1903 .  v3 - the result
1904 
1905    Notes:
1906    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1907    call MatMultTransposeAdd(A,v1,v2,v1).
1908 
1909    Level: beginner
1910 
1911    Concepts: matrix vector product^transpose and addition
1912 
1913 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1914 @*/
1915 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1916 {
1917   PetscErrorCode ierr;
1918 
1919   PetscFunctionBegin;
1920   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1921   PetscValidType(mat,1);
1922   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1923   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1924   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1925 
1926   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1927   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1928   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1929   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1930   if (mat->rmap->N != v1->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
1931   if (mat->cmap->N != v2->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
1932   if (mat->cmap->N != v3->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
1933   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1934 
1935   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1936   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1937   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1938   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
1939   PetscFunctionReturn(0);
1940 }
1941 
1942 #undef __FUNCT__
1943 #define __FUNCT__ "MatMultConstrained"
1944 /*@
1945    MatMultConstrained - The inner multiplication routine for a
1946    constrained matrix P^T A P.
1947 
1948    Collective on Mat and Vec
1949 
1950    Input Parameters:
1951 +  mat - the matrix
1952 -  x   - the vector to be multilplied
1953 
1954    Output Parameters:
1955 .  y - the result
1956 
1957    Notes:
1958    The vectors x and y cannot be the same.  I.e., one cannot
1959    call MatMult(A,y,y).
1960 
1961    Level: beginner
1962 
1963 .keywords: matrix, multiply, matrix-vector product, constraint
1964 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1965 @*/
1966 PetscErrorCode PETSCMAT_DLLEXPORT MatMultConstrained(Mat mat,Vec x,Vec y)
1967 {
1968   PetscErrorCode ierr;
1969 
1970   PetscFunctionBegin;
1971   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1972   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1973   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1974   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1975   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1976   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1977   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
1978   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
1979   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
1980 
1981   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1982   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
1983   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1984   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1985 
1986   PetscFunctionReturn(0);
1987 }
1988 
1989 #undef __FUNCT__
1990 #define __FUNCT__ "MatMultTransposeConstrained"
1991 /*@
1992    MatMultTransposeConstrained - The inner multiplication routine for a
1993    constrained matrix P^T A^T P.
1994 
1995    Collective on Mat and Vec
1996 
1997    Input Parameters:
1998 +  mat - the matrix
1999 -  x   - the vector to be multilplied
2000 
2001    Output Parameters:
2002 .  y - the result
2003 
2004    Notes:
2005    The vectors x and y cannot be the same.  I.e., one cannot
2006    call MatMult(A,y,y).
2007 
2008    Level: beginner
2009 
2010 .keywords: matrix, multiply, matrix-vector product, constraint
2011 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
2012 @*/
2013 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2014 {
2015   PetscErrorCode ierr;
2016 
2017   PetscFunctionBegin;
2018   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2019   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
2020   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
2021   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2022   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2023   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2024   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2025   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2026 
2027   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2028   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2029   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2030   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2031 
2032   PetscFunctionReturn(0);
2033 }
2034 /* ------------------------------------------------------------*/
2035 #undef __FUNCT__
2036 #define __FUNCT__ "MatGetInfo"
2037 /*@
2038    MatGetInfo - Returns information about matrix storage (number of
2039    nonzeros, memory, etc.).
2040 
2041    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
2042    as the flag
2043 
2044    Input Parameters:
2045 .  mat - the matrix
2046 
2047    Output Parameters:
2048 +  flag - flag indicating the type of parameters to be returned
2049    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2050    MAT_GLOBAL_SUM - sum over all processors)
2051 -  info - matrix information context
2052 
2053    Notes:
2054    The MatInfo context contains a variety of matrix data, including
2055    number of nonzeros allocated and used, number of mallocs during
2056    matrix assembly, etc.  Additional information for factored matrices
2057    is provided (such as the fill ratio, number of mallocs during
2058    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2059    when using the runtime options
2060 $       -info -mat_view_info
2061 
2062    Example for C/C++ Users:
2063    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2064    data within the MatInfo context.  For example,
2065 .vb
2066       MatInfo info;
2067       Mat     A;
2068       double  mal, nz_a, nz_u;
2069 
2070       MatGetInfo(A,MAT_LOCAL,&info);
2071       mal  = info.mallocs;
2072       nz_a = info.nz_allocated;
2073 .ve
2074 
2075    Example for Fortran Users:
2076    Fortran users should declare info as a double precision
2077    array of dimension MAT_INFO_SIZE, and then extract the parameters
2078    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2079    a complete list of parameter names.
2080 .vb
2081       double  precision info(MAT_INFO_SIZE)
2082       double  precision mal, nz_a
2083       Mat     A
2084       integer ierr
2085 
2086       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2087       mal = info(MAT_INFO_MALLOCS)
2088       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2089 .ve
2090 
2091     Level: intermediate
2092 
2093     Concepts: matrices^getting information on
2094 
2095 @*/
2096 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2097 {
2098   PetscErrorCode ierr;
2099 
2100   PetscFunctionBegin;
2101   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2102   PetscValidType(mat,1);
2103   PetscValidPointer(info,3);
2104   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2105   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2106   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2107   PetscFunctionReturn(0);
2108 }
2109 
2110 /* ----------------------------------------------------------*/
2111 #undef __FUNCT__
2112 #define __FUNCT__ "MatILUDTFactor"
2113 /*@C
2114    MatILUDTFactor - Performs a drop tolerance ILU factorization.
2115 
2116    Collective on Mat
2117 
2118    Input Parameters:
2119 +  mat - the matrix
2120 .  row - row permutation
2121 .  col - column permutation
2122 -  info - information about the factorization to be done
2123 
2124    Output Parameters:
2125 .  fact - the factored matrix
2126 
2127    Level: developer
2128 
2129    Notes:
2130    Most users should employ the simplified KSP interface for linear solvers
2131    instead of working directly with matrix algebra routines such as this.
2132    See, e.g., KSPCreate().
2133 
2134    This is currently only supported for the SeqAIJ matrix format using code
2135    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
2136    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
2137    and thus can be distributed with PETSc.
2138 
2139     Concepts: matrices^ILUDT factorization
2140 
2141 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2142 @*/
2143 PetscErrorCode PETSCMAT_DLLEXPORT MatILUDTFactor(Mat mat,IS row,IS col,const MatFactorInfo *info,Mat *fact)
2144 {
2145   PetscErrorCode ierr;
2146 
2147   PetscFunctionBegin;
2148   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2149   PetscValidType(mat,1);
2150   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2151   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2152   PetscValidPointer(info,4);
2153   PetscValidPointer(fact,5);
2154   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2155   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2156   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2157   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2158   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2159   ierr = (*mat->ops->iludtfactor)(mat,row,col,info,fact);CHKERRQ(ierr);
2160   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2161   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
2162 
2163   PetscFunctionReturn(0);
2164 }
2165 
2166 #undef __FUNCT__
2167 #define __FUNCT__ "MatLUFactor"
2168 /*@
2169    MatLUFactor - Performs in-place LU factorization of matrix.
2170 
2171    Collective on Mat
2172 
2173    Input Parameters:
2174 +  mat - the matrix
2175 .  row - row permutation
2176 .  col - column permutation
2177 -  info - options for factorization, includes
2178 $          fill - expected fill as ratio of original fill.
2179 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2180 $                   Run with the option -info to determine an optimal value to use
2181 
2182    Notes:
2183    Most users should employ the simplified KSP interface for linear solvers
2184    instead of working directly with matrix algebra routines such as this.
2185    See, e.g., KSPCreate().
2186 
2187    This changes the state of the matrix to a factored matrix; it cannot be used
2188    for example with MatSetValues() unless one first calls MatSetUnfactored().
2189 
2190    Level: developer
2191 
2192    Concepts: matrices^LU factorization
2193 
2194 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2195           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
2196 
2197 @*/
2198 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2199 {
2200   PetscErrorCode ierr;
2201 
2202   PetscFunctionBegin;
2203   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2204   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2205   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2206   PetscValidPointer(info,4);
2207   PetscValidType(mat,1);
2208   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2209   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2210   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2211   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2212 
2213   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2214   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2215   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2216   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2217   PetscFunctionReturn(0);
2218 }
2219 
2220 #undef __FUNCT__
2221 #define __FUNCT__ "MatILUFactor"
2222 /*@
2223    MatILUFactor - Performs in-place ILU factorization of matrix.
2224 
2225    Collective on Mat
2226 
2227    Input Parameters:
2228 +  mat - the matrix
2229 .  row - row permutation
2230 .  col - column permutation
2231 -  info - structure containing
2232 $      levels - number of levels of fill.
2233 $      expected fill - as ratio of original fill.
2234 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2235                 missing diagonal entries)
2236 
2237    Notes:
2238    Probably really in-place only when level of fill is zero, otherwise allocates
2239    new space to store factored matrix and deletes previous memory.
2240 
2241    Most users should employ the simplified KSP interface for linear solvers
2242    instead of working directly with matrix algebra routines such as this.
2243    See, e.g., KSPCreate().
2244 
2245    Level: developer
2246 
2247    Concepts: matrices^ILU factorization
2248 
2249 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2250 @*/
2251 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2252 {
2253   PetscErrorCode ierr;
2254 
2255   PetscFunctionBegin;
2256   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2257   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2258   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2259   PetscValidPointer(info,4);
2260   PetscValidType(mat,1);
2261   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2262   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2263   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2264   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2265   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2266 
2267   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2268   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
2269   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
2270   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2271   PetscFunctionReturn(0);
2272 }
2273 
2274 #undef __FUNCT__
2275 #define __FUNCT__ "MatLUFactorSymbolic"
2276 /*@
2277    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2278    Call this routine before calling MatLUFactorNumeric().
2279 
2280    Collective on Mat
2281 
2282    Input Parameters:
2283 +  fact - the factor matrix obtained with MatGetFactor()
2284 .  mat - the matrix
2285 .  row, col - row and column permutations
2286 -  info - options for factorization, includes
2287 $          fill - expected fill as ratio of original fill.
2288 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2289 $                   Run with the option -info to determine an optimal value to use
2290 
2291 
2292    Notes:
2293    See the users manual for additional information about
2294    choosing the fill factor for better efficiency.
2295 
2296    Most users should employ the simplified KSP interface for linear solvers
2297    instead of working directly with matrix algebra routines such as this.
2298    See, e.g., KSPCreate().
2299 
2300    Level: developer
2301 
2302    Concepts: matrices^LU symbolic factorization
2303 
2304 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2305 @*/
2306 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2307 {
2308   PetscErrorCode ierr;
2309 
2310   PetscFunctionBegin;
2311   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2312   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2313   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
2314   PetscValidPointer(info,4);
2315   PetscValidType(mat,1);
2316   PetscValidPointer(fact,5);
2317   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2318   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2319   if (!(fact)->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",((PetscObject)mat)->type_name);
2320   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2321 
2322   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2323   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
2324   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
2325   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2326   PetscFunctionReturn(0);
2327 }
2328 
2329 #undef __FUNCT__
2330 #define __FUNCT__ "MatLUFactorNumeric"
2331 /*@
2332    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2333    Call this routine after first calling MatLUFactorSymbolic().
2334 
2335    Collective on Mat
2336 
2337    Input Parameters:
2338 +  fact - the factor matrix obtained with MatGetFactor()
2339 .  mat - the matrix
2340 -  info - options for factorization
2341 
2342    Notes:
2343    See MatLUFactor() for in-place factorization.  See
2344    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2345 
2346    Most users should employ the simplified KSP interface for linear solvers
2347    instead of working directly with matrix algebra routines such as this.
2348    See, e.g., KSPCreate().
2349 
2350    Level: developer
2351 
2352    Concepts: matrices^LU numeric factorization
2353 
2354 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2355 @*/
2356 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2357 {
2358   PetscErrorCode ierr;
2359 
2360   PetscFunctionBegin;
2361   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2362   PetscValidType(mat,1);
2363   PetscValidPointer(fact,2);
2364   PetscValidHeaderSpecific(fact,MAT_COOKIE,2);
2365   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2366   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2367     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2368   }
2369   if (!(fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2370   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2371   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2372   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
2373   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2374 
2375   ierr = MatView_Private(fact);CHKERRQ(ierr);
2376   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2377   PetscFunctionReturn(0);
2378 }
2379 
2380 #undef __FUNCT__
2381 #define __FUNCT__ "MatCholeskyFactor"
2382 /*@
2383    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2384    symmetric matrix.
2385 
2386    Collective on Mat
2387 
2388    Input Parameters:
2389 +  mat - the matrix
2390 .  perm - row and column permutations
2391 -  f - expected fill as ratio of original fill
2392 
2393    Notes:
2394    See MatLUFactor() for the nonsymmetric case.  See also
2395    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
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    Level: developer
2402 
2403    Concepts: matrices^Cholesky factorization
2404 
2405 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2406           MatGetOrdering()
2407 
2408 @*/
2409 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2410 {
2411   PetscErrorCode ierr;
2412 
2413   PetscFunctionBegin;
2414   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2415   PetscValidType(mat,1);
2416   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
2417   PetscValidPointer(info,3);
2418   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2419   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2420   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2421   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2422   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2423 
2424   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2425   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
2426   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
2427   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2428   PetscFunctionReturn(0);
2429 }
2430 
2431 #undef __FUNCT__
2432 #define __FUNCT__ "MatCholeskyFactorSymbolic"
2433 /*@
2434    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2435    of a symmetric matrix.
2436 
2437    Collective on Mat
2438 
2439    Input Parameters:
2440 +  fact - the factor matrix obtained with MatGetFactor()
2441 .  mat - the matrix
2442 .  perm - row and column permutations
2443 -  info - options for factorization, includes
2444 $          fill - expected fill as ratio of original fill.
2445 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2446 $                   Run with the option -info to determine an optimal value to use
2447 
2448    Notes:
2449    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2450    MatCholeskyFactor() and MatCholeskyFactorNumeric().
2451 
2452    Most users should employ the simplified KSP interface for linear solvers
2453    instead of working directly with matrix algebra routines such as this.
2454    See, e.g., KSPCreate().
2455 
2456    Level: developer
2457 
2458    Concepts: matrices^Cholesky symbolic factorization
2459 
2460 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2461           MatGetOrdering()
2462 
2463 @*/
2464 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2465 {
2466   PetscErrorCode ierr;
2467 
2468   PetscFunctionBegin;
2469   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2470   PetscValidType(mat,1);
2471   if (perm) PetscValidHeaderSpecific(perm,IS_COOKIE,2);
2472   PetscValidPointer(info,3);
2473   PetscValidPointer(fact,4);
2474   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2475   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2476   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2477   if (!(fact)->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2478   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2479 
2480   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2481   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
2482   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
2483   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2484   PetscFunctionReturn(0);
2485 }
2486 
2487 #undef __FUNCT__
2488 #define __FUNCT__ "MatCholeskyFactorNumeric"
2489 /*@
2490    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2491    of a symmetric matrix. Call this routine after first calling
2492    MatCholeskyFactorSymbolic().
2493 
2494    Collective on Mat
2495 
2496    Input Parameters:
2497 +  fact - the factor matrix obtained with MatGetFactor()
2498 .  mat - the initial matrix
2499 .  info - options for factorization
2500 -  fact - the symbolic factor of mat
2501 
2502 
2503    Notes:
2504    Most users should employ the simplified KSP interface for linear solvers
2505    instead of working directly with matrix algebra routines such as this.
2506    See, e.g., KSPCreate().
2507 
2508    Level: developer
2509 
2510    Concepts: matrices^Cholesky numeric factorization
2511 
2512 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
2513 @*/
2514 PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2515 {
2516   PetscErrorCode ierr;
2517 
2518   PetscFunctionBegin;
2519   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2520   PetscValidType(mat,1);
2521   PetscValidPointer(fact,2);
2522   PetscValidHeaderSpecific(fact,MAT_COOKIE,2);
2523   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2524   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2525   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2526     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2527   }
2528   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2529 
2530   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2531   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
2532   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
2533 
2534   ierr = MatView_Private(fact);CHKERRQ(ierr);
2535   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
2536   PetscFunctionReturn(0);
2537 }
2538 
2539 /* ----------------------------------------------------------------*/
2540 #undef __FUNCT__
2541 #define __FUNCT__ "MatSolve"
2542 /*@
2543    MatSolve - Solves A x = b, given a factored matrix.
2544 
2545    Collective on Mat and Vec
2546 
2547    Input Parameters:
2548 +  mat - the factored matrix
2549 -  b - the right-hand-side vector
2550 
2551    Output Parameter:
2552 .  x - the result vector
2553 
2554    Notes:
2555    The vectors b and x cannot be the same.  I.e., one cannot
2556    call MatSolve(A,x,x).
2557 
2558    Notes:
2559    Most users should employ the simplified KSP interface for linear solvers
2560    instead of working directly with matrix algebra routines such as this.
2561    See, e.g., KSPCreate().
2562 
2563    Level: developer
2564 
2565    Concepts: matrices^triangular solves
2566 
2567 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2568 @*/
2569 PetscErrorCode PETSCMAT_DLLEXPORT MatSolve(Mat mat,Vec b,Vec x)
2570 {
2571   PetscErrorCode ierr;
2572 
2573   PetscFunctionBegin;
2574   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2575   PetscValidType(mat,1);
2576   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2577   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2578   PetscCheckSameComm(mat,1,b,2);
2579   PetscCheckSameComm(mat,1,x,3);
2580   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2581   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2582   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2583   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2584   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2585   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
2586   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2587   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2588 
2589   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2590   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
2591   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2592   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2593   PetscFunctionReturn(0);
2594 }
2595 
2596 #undef __FUNCT__
2597 #define __FUNCT__ "MatMatSolve_Basic"
2598 PetscErrorCode PETSCMAT_DLLEXPORT MatMatSolve_Basic(Mat A,Mat B,Mat X)
2599 {
2600   PetscErrorCode ierr;
2601   Vec            b,x;
2602   PetscInt       m,N,i;
2603   PetscScalar    *bb,*xx;
2604 
2605   PetscFunctionBegin;
2606   ierr = MatGetArray(B,&bb);CHKERRQ(ierr);
2607   ierr = MatGetArray(X,&xx);CHKERRQ(ierr);
2608   ierr = MatGetLocalSize(B,&m,PETSC_NULL);CHKERRQ(ierr);  /* number local rows */
2609   ierr = MatGetSize(B,PETSC_NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
2610   ierr = VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&b);CHKERRQ(ierr);
2611   ierr = VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&x);CHKERRQ(ierr);
2612   for (i=0; i<N; i++) {
2613     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
2614     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
2615     ierr = MatSolve(A,b,x);CHKERRQ(ierr);
2616     ierr = VecResetArray(x);CHKERRQ(ierr);
2617     ierr = VecResetArray(b);CHKERRQ(ierr);
2618   }
2619   ierr = VecDestroy(b);CHKERRQ(ierr);
2620   ierr = VecDestroy(x);CHKERRQ(ierr);
2621   ierr = MatRestoreArray(B,&bb);CHKERRQ(ierr);
2622   ierr = MatRestoreArray(X,&xx);CHKERRQ(ierr);
2623   PetscFunctionReturn(0);
2624 }
2625 
2626 #undef __FUNCT__
2627 #define __FUNCT__ "MatMatSolve"
2628 /*@
2629    MatMatSolve - Solves A X = B, given a factored matrix.
2630 
2631    Collective on Mat
2632 
2633    Input Parameters:
2634 +  mat - the factored matrix
2635 -  B - the right-hand-side matrix  (dense matrix)
2636 
2637    Output Parameter:
2638 .  X - the result matrix (dense matrix)
2639 
2640    Notes:
2641    The matrices b and x cannot be the same.  I.e., one cannot
2642    call MatMatSolve(A,x,x).
2643 
2644    Notes:
2645    Most users should usually employ the simplified KSP interface for linear solvers
2646    instead of working directly with matrix algebra routines such as this.
2647    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
2648    at a time.
2649 
2650    Level: developer
2651 
2652    Concepts: matrices^triangular solves
2653 
2654 .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2655 @*/
2656 PetscErrorCode PETSCMAT_DLLEXPORT MatMatSolve(Mat A,Mat B,Mat X)
2657 {
2658   PetscErrorCode ierr;
2659 
2660   PetscFunctionBegin;
2661   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
2662   PetscValidType(A,1);
2663   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
2664   PetscValidHeaderSpecific(X,MAT_COOKIE,3);
2665   PetscCheckSameComm(A,1,B,2);
2666   PetscCheckSameComm(A,1,X,3);
2667   if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2668   if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2669   if (A->cmap->N != X->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
2670   if (A->rmap->N != B->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
2671   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
2672   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
2673   ierr = MatPreallocated(A);CHKERRQ(ierr);
2674 
2675   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
2676   if (!A->ops->matsolve) {
2677     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);CHKERRQ(ierr);
2678     ierr = MatMatSolve_Basic(A,B,X);CHKERRQ(ierr);
2679   } else {
2680     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
2681   }
2682   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
2683   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
2684   PetscFunctionReturn(0);
2685 }
2686 
2687 
2688 #undef __FUNCT__
2689 #define __FUNCT__ "MatForwardSolve"
2690 /* @
2691    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
2692                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
2693 
2694    Collective on Mat and Vec
2695 
2696    Input Parameters:
2697 +  mat - the factored matrix
2698 -  b - the right-hand-side vector
2699 
2700    Output Parameter:
2701 .  x - the result vector
2702 
2703    Notes:
2704    MatSolve() should be used for most applications, as it performs
2705    a forward solve followed by a backward solve.
2706 
2707    The vectors b and x cannot be the same,  i.e., one cannot
2708    call MatForwardSolve(A,x,x).
2709 
2710    For matrix in seqsbaij format with block size larger than 1,
2711    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2712    MatForwardSolve() solves U^T*D y = b, and
2713    MatBackwardSolve() solves U x = y.
2714    Thus they do not provide a symmetric preconditioner.
2715 
2716    Most users should employ the simplified KSP interface for linear solvers
2717    instead of working directly with matrix algebra routines such as this.
2718    See, e.g., KSPCreate().
2719 
2720    Level: developer
2721 
2722    Concepts: matrices^forward solves
2723 
2724 .seealso: MatSolve(), MatBackwardSolve()
2725 @ */
2726 PetscErrorCode PETSCMAT_DLLEXPORT MatForwardSolve(Mat mat,Vec b,Vec x)
2727 {
2728   PetscErrorCode ierr;
2729 
2730   PetscFunctionBegin;
2731   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2732   PetscValidType(mat,1);
2733   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2734   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2735   PetscCheckSameComm(mat,1,b,2);
2736   PetscCheckSameComm(mat,1,x,3);
2737   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2738   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2739   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2740   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2741   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2742   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2743   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2744   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2745   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
2746   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2747   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2748   PetscFunctionReturn(0);
2749 }
2750 
2751 #undef __FUNCT__
2752 #define __FUNCT__ "MatBackwardSolve"
2753 /* @
2754    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2755                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
2756 
2757    Collective on Mat and Vec
2758 
2759    Input Parameters:
2760 +  mat - the factored matrix
2761 -  b - the right-hand-side vector
2762 
2763    Output Parameter:
2764 .  x - the result vector
2765 
2766    Notes:
2767    MatSolve() should be used for most applications, as it performs
2768    a forward solve followed by a backward solve.
2769 
2770    The vectors b and x cannot be the same.  I.e., one cannot
2771    call MatBackwardSolve(A,x,x).
2772 
2773    For matrix in seqsbaij format with block size larger than 1,
2774    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
2775    MatForwardSolve() solves U^T*D y = b, and
2776    MatBackwardSolve() solves U x = y.
2777    Thus they do not provide a symmetric preconditioner.
2778 
2779    Most users should employ the simplified KSP interface for linear solvers
2780    instead of working directly with matrix algebra routines such as this.
2781    See, e.g., KSPCreate().
2782 
2783    Level: developer
2784 
2785    Concepts: matrices^backward solves
2786 
2787 .seealso: MatSolve(), MatForwardSolve()
2788 @ */
2789 PetscErrorCode PETSCMAT_DLLEXPORT MatBackwardSolve(Mat mat,Vec b,Vec x)
2790 {
2791   PetscErrorCode ierr;
2792 
2793   PetscFunctionBegin;
2794   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2795   PetscValidType(mat,1);
2796   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2797   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2798   PetscCheckSameComm(mat,1,b,2);
2799   PetscCheckSameComm(mat,1,x,3);
2800   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2801   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2802   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2803   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2804   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2805   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2806   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2807 
2808   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2809   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
2810   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2811   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2812   PetscFunctionReturn(0);
2813 }
2814 
2815 #undef __FUNCT__
2816 #define __FUNCT__ "MatSolveAdd"
2817 /*@
2818    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2819 
2820    Collective on Mat and Vec
2821 
2822    Input Parameters:
2823 +  mat - the factored matrix
2824 .  b - the right-hand-side vector
2825 -  y - the vector to be added to
2826 
2827    Output Parameter:
2828 .  x - the result vector
2829 
2830    Notes:
2831    The vectors b and x cannot be the same.  I.e., one cannot
2832    call MatSolveAdd(A,x,y,x).
2833 
2834    Most users should employ the simplified KSP interface for linear solvers
2835    instead of working directly with matrix algebra routines such as this.
2836    See, e.g., KSPCreate().
2837 
2838    Level: developer
2839 
2840    Concepts: matrices^triangular solves
2841 
2842 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2843 @*/
2844 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2845 {
2846   PetscScalar    one = 1.0;
2847   Vec            tmp;
2848   PetscErrorCode ierr;
2849 
2850   PetscFunctionBegin;
2851   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2852   PetscValidType(mat,1);
2853   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2854   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2855   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2856   PetscCheckSameComm(mat,1,b,2);
2857   PetscCheckSameComm(mat,1,y,2);
2858   PetscCheckSameComm(mat,1,x,3);
2859   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2860   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2861   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2862   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2863   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2864   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2865   if (x->map->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
2866   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2867 
2868   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2869   if (mat->ops->solveadd)  {
2870     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2871   } else {
2872     /* do the solve then the add manually */
2873     if (x != y) {
2874       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2875       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
2876     } else {
2877       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2878       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
2879       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2880       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2881       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
2882       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2883     }
2884   }
2885   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2886   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2887   PetscFunctionReturn(0);
2888 }
2889 
2890 #undef __FUNCT__
2891 #define __FUNCT__ "MatSolveTranspose"
2892 /*@
2893    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2894 
2895    Collective on Mat and Vec
2896 
2897    Input Parameters:
2898 +  mat - the factored matrix
2899 -  b - the right-hand-side vector
2900 
2901    Output Parameter:
2902 .  x - the result vector
2903 
2904    Notes:
2905    The vectors b and x cannot be the same.  I.e., one cannot
2906    call MatSolveTranspose(A,x,x).
2907 
2908    Most users should employ the simplified KSP interface for linear solvers
2909    instead of working directly with matrix algebra routines such as this.
2910    See, e.g., KSPCreate().
2911 
2912    Level: developer
2913 
2914    Concepts: matrices^triangular solves
2915 
2916 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2917 @*/
2918 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTranspose(Mat mat,Vec b,Vec x)
2919 {
2920   PetscErrorCode ierr;
2921 
2922   PetscFunctionBegin;
2923   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2924   PetscValidType(mat,1);
2925   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2926   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2927   PetscCheckSameComm(mat,1,b,2);
2928   PetscCheckSameComm(mat,1,x,3);
2929   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2930   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2931   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
2932   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2933   if (mat->cmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
2934   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2935   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2936   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2937   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2938   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2939   PetscFunctionReturn(0);
2940 }
2941 
2942 #undef __FUNCT__
2943 #define __FUNCT__ "MatSolveTransposeAdd"
2944 /*@
2945    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2946                       factored matrix.
2947 
2948    Collective on Mat and Vec
2949 
2950    Input Parameters:
2951 +  mat - the factored matrix
2952 .  b - the right-hand-side vector
2953 -  y - the vector to be added to
2954 
2955    Output Parameter:
2956 .  x - the result vector
2957 
2958    Notes:
2959    The vectors b and x cannot be the same.  I.e., one cannot
2960    call MatSolveTransposeAdd(A,x,y,x).
2961 
2962    Most users should employ the simplified KSP interface for linear solvers
2963    instead of working directly with matrix algebra routines such as this.
2964    See, e.g., KSPCreate().
2965 
2966    Level: developer
2967 
2968    Concepts: matrices^triangular solves
2969 
2970 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2971 @*/
2972 PetscErrorCode PETSCMAT_DLLEXPORT MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2973 {
2974   PetscScalar    one = 1.0;
2975   PetscErrorCode ierr;
2976   Vec            tmp;
2977 
2978   PetscFunctionBegin;
2979   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
2980   PetscValidType(mat,1);
2981   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2982   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
2983   PetscValidHeaderSpecific(x,VEC_COOKIE,4);
2984   PetscCheckSameComm(mat,1,b,2);
2985   PetscCheckSameComm(mat,1,y,3);
2986   PetscCheckSameComm(mat,1,x,4);
2987   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2988   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2989   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2990   if (mat->cmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
2991   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2992   if (x->map->n != y->map->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
2993   ierr = MatPreallocated(mat);CHKERRQ(ierr);
2994 
2995   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2996   if (mat->ops->solvetransposeadd) {
2997     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
2998   } else {
2999     /* do the solve then the add manually */
3000     if (x != y) {
3001       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3002       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3003     } else {
3004       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3005       ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr);
3006       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3007       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3008       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3009       ierr = VecDestroy(tmp);CHKERRQ(ierr);
3010     }
3011   }
3012   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3013   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3014   PetscFunctionReturn(0);
3015 }
3016 /* ----------------------------------------------------------------*/
3017 
3018 #undef __FUNCT__
3019 #define __FUNCT__ "MatRelax"
3020 /*@
3021    MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3022 
3023    Collective on Mat and Vec
3024 
3025    Input Parameters:
3026 +  mat - the matrix
3027 .  b - the right hand side
3028 .  omega - the relaxation factor
3029 .  flag - flag indicating the type of SOR (see below)
3030 .  shift -  diagonal shift
3031 .  its - the number of iterations
3032 -  lits - the number of local iterations
3033 
3034    Output Parameters:
3035 .  x - the solution (can contain an initial guess)
3036 
3037    SOR Flags:
3038 .     SOR_FORWARD_SWEEP - forward SOR
3039 .     SOR_BACKWARD_SWEEP - backward SOR
3040 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3041 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3042 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3043 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3044 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3045          upper/lower triangular part of matrix to
3046          vector (with omega)
3047 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3048 
3049    Notes:
3050    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3051    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3052    on each processor.
3053 
3054    Application programmers will not generally use MatRelax() directly,
3055    but instead will employ the KSP/PC interface.
3056 
3057    Notes for Advanced Users:
3058    The flags are implemented as bitwise inclusive or operations.
3059    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3060    to specify a zero initial guess for SSOR.
3061 
3062    Most users should employ the simplified KSP interface for linear solvers
3063    instead of working directly with matrix algebra routines such as this.
3064    See, e.g., KSPCreate().
3065 
3066    See also, MatPBRelax(). This routine will automatically call the point block
3067    version if the point version is not available.
3068 
3069    Level: developer
3070 
3071    Concepts: matrices^relaxation
3072    Concepts: matrices^SOR
3073    Concepts: matrices^Gauss-Seidel
3074 
3075 @*/
3076 PetscErrorCode PETSCMAT_DLLEXPORT MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3077 {
3078   PetscErrorCode ierr;
3079 
3080   PetscFunctionBegin;
3081   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3082   PetscValidType(mat,1);
3083   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
3084   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
3085   PetscCheckSameComm(mat,1,b,2);
3086   PetscCheckSameComm(mat,1,x,8);
3087   if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3088   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3089   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3090   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3091   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3092   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3093   if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3094   if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3095 
3096   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3097   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3098   if (mat->ops->relax) {
3099     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3100   } else {
3101     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3102   }
3103   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3104   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3105   PetscFunctionReturn(0);
3106 }
3107 
3108 #undef __FUNCT__
3109 #define __FUNCT__ "MatPBRelax"
3110 /*@
3111    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3112 
3113    Collective on Mat and Vec
3114 
3115    See MatRelax() for usage
3116 
3117    For multi-component PDEs where the Jacobian is stored in a point block format
3118    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
3119    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
3120    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
3121 
3122    Level: developer
3123 
3124 @*/
3125 PetscErrorCode PETSCMAT_DLLEXPORT MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3126 {
3127   PetscErrorCode ierr;
3128 
3129   PetscFunctionBegin;
3130   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3131   PetscValidType(mat,1);
3132   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
3133   PetscValidHeaderSpecific(x,VEC_COOKIE,8);
3134   PetscCheckSameComm(mat,1,b,2);
3135   PetscCheckSameComm(mat,1,x,8);
3136   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3137   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3138   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3139   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3140   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3141   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3142   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3143 
3144   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3145   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
3146   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
3147   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3148   PetscFunctionReturn(0);
3149 }
3150 
3151 #undef __FUNCT__
3152 #define __FUNCT__ "MatCopy_Basic"
3153 /*
3154       Default matrix copy routine.
3155 */
3156 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3157 {
3158   PetscErrorCode    ierr;
3159   PetscInt          i,rstart,rend,nz;
3160   const PetscInt    *cwork;
3161   const PetscScalar *vwork;
3162 
3163   PetscFunctionBegin;
3164   if (B->assembled) {
3165     ierr = MatZeroEntries(B);CHKERRQ(ierr);
3166   }
3167   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
3168   for (i=rstart; i<rend; i++) {
3169     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3170     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
3171     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
3172   }
3173   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3174   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3175   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3176   PetscFunctionReturn(0);
3177 }
3178 
3179 #undef __FUNCT__
3180 #define __FUNCT__ "MatCopy"
3181 /*@
3182    MatCopy - Copys a matrix to another matrix.
3183 
3184    Collective on Mat
3185 
3186    Input Parameters:
3187 +  A - the matrix
3188 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3189 
3190    Output Parameter:
3191 .  B - where the copy is put
3192 
3193    Notes:
3194    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3195    same nonzero pattern or the routine will crash.
3196 
3197    MatCopy() copies the matrix entries of a matrix to another existing
3198    matrix (after first zeroing the second matrix).  A related routine is
3199    MatConvert(), which first creates a new matrix and then copies the data.
3200 
3201    Level: intermediate
3202 
3203    Concepts: matrices^copying
3204 
3205 .seealso: MatConvert(), MatDuplicate()
3206 
3207 @*/
3208 PetscErrorCode PETSCMAT_DLLEXPORT MatCopy(Mat A,Mat B,MatStructure str)
3209 {
3210   PetscErrorCode ierr;
3211   PetscInt       i;
3212 
3213   PetscFunctionBegin;
3214   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3215   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3216   PetscValidType(A,1);
3217   PetscValidType(B,2);
3218   PetscCheckSameComm(A,1,B,2);
3219   ierr = MatPreallocated(B);CHKERRQ(ierr);
3220   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3221   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3222   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3223   ierr = MatPreallocated(A);CHKERRQ(ierr);
3224 
3225   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3226   if (A->ops->copy) {
3227     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
3228   } else { /* generic conversion */
3229     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3230   }
3231   if (A->mapping) {
3232     if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);B->mapping = 0;}
3233     ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr);
3234   }
3235   if (A->bmapping) {
3236     if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);B->bmapping = 0;}
3237     ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr);
3238   }
3239 
3240   B->stencil.dim = A->stencil.dim;
3241   B->stencil.noc = A->stencil.noc;
3242   for (i=0; i<=A->stencil.dim; i++) {
3243     B->stencil.dims[i]   = A->stencil.dims[i];
3244     B->stencil.starts[i] = A->stencil.starts[i];
3245   }
3246 
3247   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
3248   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3249   PetscFunctionReturn(0);
3250 }
3251 
3252 #undef __FUNCT__
3253 #define __FUNCT__ "MatConvert"
3254 /*@C
3255    MatConvert - Converts a matrix to another matrix, either of the same
3256    or different type.
3257 
3258    Collective on Mat
3259 
3260    Input Parameters:
3261 +  mat - the matrix
3262 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3263    same type as the original matrix.
3264 -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3265    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3266    MAT_INITIAL_MATRIX.
3267 
3268    Output Parameter:
3269 .  M - pointer to place new matrix
3270 
3271    Notes:
3272    MatConvert() first creates a new matrix and then copies the data from
3273    the first matrix.  A related routine is MatCopy(), which copies the matrix
3274    entries of one matrix to another already existing matrix context.
3275 
3276    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3277    the MPI communicator of the generated matrix is always the same as the communicator
3278    of the input matrix.
3279 
3280    Level: intermediate
3281 
3282    Concepts: matrices^converting between storage formats
3283 
3284 .seealso: MatCopy(), MatDuplicate()
3285 @*/
3286 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3287 {
3288   PetscErrorCode         ierr;
3289   PetscTruth             sametype,issame,flg;
3290   char                   convname[256],mtype[256];
3291   Mat                    B;
3292 
3293   PetscFunctionBegin;
3294   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3295   PetscValidType(mat,1);
3296   PetscValidPointer(M,3);
3297   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3298   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3299   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3300 
3301   ierr = PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
3302   if (flg) {
3303     newtype = mtype;
3304   }
3305   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
3306   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
3307   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3308     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3309   }
3310 
3311   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
3312 
3313   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3314     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3315   } else {
3316     PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3317     const char     *prefix[3] = {"seq","mpi",""};
3318     PetscInt       i;
3319     /*
3320        Order of precedence:
3321        1) See if a specialized converter is known to the current matrix.
3322        2) See if a specialized converter is known to the desired matrix class.
3323        3) See if a good general converter is registered for the desired class
3324           (as of 6/27/03 only MATMPIADJ falls into this category).
3325        4) See if a good general converter is known for the current matrix.
3326        5) Use a really basic converter.
3327     */
3328 
3329     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3330     for (i=0; i<3; i++) {
3331       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3332       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3333       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3334       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3335       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3336       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3337       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3338       if (conv) goto foundconv;
3339     }
3340 
3341     /* 2)  See if a specialized converter is known to the desired matrix class. */
3342     ierr = MatCreate(((PetscObject)mat)->comm,&B);CHKERRQ(ierr);
3343     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
3344     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
3345     for (i=0; i<3; i++) {
3346       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3347       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3348       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3349       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3350       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3351       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3352       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3353       if (conv) {
3354         ierr = MatDestroy(B);CHKERRQ(ierr);
3355         goto foundconv;
3356       }
3357     }
3358 
3359     /* 3) See if a good general converter is registered for the desired class */
3360     conv = B->ops->convertfrom;
3361     ierr = MatDestroy(B);CHKERRQ(ierr);
3362     if (conv) goto foundconv;
3363 
3364     /* 4) See if a good general converter is known for the current matrix */
3365     if (mat->ops->convert) {
3366       conv = mat->ops->convert;
3367     }
3368     if (conv) goto foundconv;
3369 
3370     /* 5) Use a really basic converter. */
3371     conv = MatConvert_Basic;
3372 
3373     foundconv:
3374     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3375     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
3376     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3377   }
3378   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
3379   PetscFunctionReturn(0);
3380 }
3381 
3382 #undef __FUNCT__
3383 #define __FUNCT__ "MatFactorGetSolverPackage"
3384 /*@C
3385    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3386 
3387    Not Collective
3388 
3389    Input Parameter:
3390 .  mat - the matrix, must be a factored matrix
3391 
3392    Output Parameter:
3393 .   type - the string name of the package (do not free this string)
3394 
3395    Notes:
3396       In Fortran you pass in a empty string and the package name will be copied into it.
3397     (Make sure the string is long enough)
3398 
3399    Level: intermediate
3400 
3401 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3402 @*/
3403 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3404 {
3405   PetscErrorCode         ierr;
3406   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);
3407 
3408   PetscFunctionBegin;
3409   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3410   PetscValidType(mat,1);
3411   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3412   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);CHKERRQ(ierr);
3413   if (!conv) {
3414     *type = MAT_SOLVER_PETSC;
3415   } else {
3416     ierr = (*conv)(mat,type);CHKERRQ(ierr);
3417   }
3418   PetscFunctionReturn(0);
3419 }
3420 
3421 #undef __FUNCT__
3422 #define __FUNCT__ "MatGetFactor"
3423 /*@C
3424    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3425 
3426    Collective on Mat
3427 
3428    Input Parameters:
3429 +  mat - the matrix
3430 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3431 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3432 
3433    Output Parameters:
3434 .  f - the factor matrix used with MatXXFactorSymbolic() calls
3435 
3436    Notes:
3437       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3438      such as pastix, superlu, mumps, spooles etc.
3439 
3440       PETSc must have been config/configure.py to use the external solver, using the option --download-package
3441 
3442    Level: intermediate
3443 
3444 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3445 @*/
3446 PetscErrorCode PETSCMAT_DLLEXPORT MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3447 {
3448   PetscErrorCode         ierr;
3449   char                   convname[256];
3450   PetscErrorCode         (*conv)(Mat,MatFactorType,Mat*);
3451 
3452   PetscFunctionBegin;
3453   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3454   PetscValidType(mat,1);
3455 
3456   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3457   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3458 
3459   ierr = PetscStrcpy(convname,"MatGetFactor_");CHKERRQ(ierr);
3460   ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3461   ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3462   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3463   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3464   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3465   if (!conv) {
3466     PetscTruth flag;
3467     ierr = PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);CHKERRQ(ierr);
3468     if (flag) {
3469       SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3470     } else {
3471       SETERRQ3(PETSC_ERR_SUP,"Matrix format %s does not have a solver %s. Perhaps you must config/configure.py with --download-%s",((PetscObject)mat)->type_name,type,type);
3472     }
3473   }
3474   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
3475   PetscFunctionReturn(0);
3476 }
3477 
3478 #undef __FUNCT__
3479 #define __FUNCT__ "MatGetFactorAvailable"
3480 /*@C
3481    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3482 
3483    Collective on Mat
3484 
3485    Input Parameters:
3486 +  mat - the matrix
3487 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3488 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3489 
3490    Output Parameter:
3491 .    flg - PETSC_TRUE if the factorization is available
3492 
3493    Notes:
3494       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3495      such as pastix, superlu, mumps, spooles etc.
3496 
3497       PETSc must have been config/configure.py to use the external solver, using the option --download-package
3498 
3499    Level: intermediate
3500 
3501 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3502 @*/
3503 PetscErrorCode PETSCMAT_DLLEXPORT MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3504 {
3505   PetscErrorCode         ierr;
3506   char                   convname[256];
3507   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscTruth*);
3508 
3509   PetscFunctionBegin;
3510   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3511   PetscValidType(mat,1);
3512 
3513   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3514   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3515 
3516   ierr = PetscStrcpy(convname,"MatGetFactorAvailable_");CHKERRQ(ierr);
3517   ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3518   ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3519   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3520   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3521   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3522   if (!conv) {
3523     *flg = PETSC_FALSE;
3524   } else {
3525     ierr = (*conv)(mat,ftype,flg);CHKERRQ(ierr);
3526   }
3527   PetscFunctionReturn(0);
3528 }
3529 
3530 
3531 #undef __FUNCT__
3532 #define __FUNCT__ "MatDuplicate"
3533 /*@
3534    MatDuplicate - Duplicates a matrix including the non-zero structure.
3535 
3536    Collective on Mat
3537 
3538    Input Parameters:
3539 +  mat - the matrix
3540 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3541         values as well or not
3542 
3543    Output Parameter:
3544 .  M - pointer to place new matrix
3545 
3546    Level: intermediate
3547 
3548    Concepts: matrices^duplicating
3549 
3550 .seealso: MatCopy(), MatConvert()
3551 @*/
3552 PetscErrorCode PETSCMAT_DLLEXPORT MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3553 {
3554   PetscErrorCode ierr;
3555   Mat            B;
3556   PetscInt       i;
3557 
3558   PetscFunctionBegin;
3559   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3560   PetscValidType(mat,1);
3561   PetscValidPointer(M,3);
3562   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3563   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3564   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3565 
3566   *M  = 0;
3567   if (!mat->ops->duplicate) {
3568     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3569   }
3570   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3571   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
3572   B = *M;
3573   if (mat->mapping) {
3574     ierr = MatSetLocalToGlobalMapping(B,mat->mapping);CHKERRQ(ierr);
3575   }
3576   if (mat->bmapping) {
3577     ierr = MatSetLocalToGlobalMappingBlock(B,mat->bmapping);CHKERRQ(ierr);
3578   }
3579   ierr = PetscMapCopy(((PetscObject)mat)->comm,mat->rmap,B->rmap);CHKERRQ(ierr);
3580   ierr = PetscMapCopy(((PetscObject)mat)->comm,mat->cmap,B->cmap);CHKERRQ(ierr);
3581 
3582   B->stencil.dim = mat->stencil.dim;
3583   B->stencil.noc = mat->stencil.noc;
3584   for (i=0; i<=mat->stencil.dim; i++) {
3585     B->stencil.dims[i]   = mat->stencil.dims[i];
3586     B->stencil.starts[i] = mat->stencil.starts[i];
3587   }
3588 
3589   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3590   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
3591   PetscFunctionReturn(0);
3592 }
3593 
3594 #undef __FUNCT__
3595 #define __FUNCT__ "MatGetDiagonal"
3596 /*@
3597    MatGetDiagonal - Gets the diagonal of a matrix.
3598 
3599    Collective on Mat and Vec
3600 
3601    Input Parameters:
3602 +  mat - the matrix
3603 -  v - the vector for storing the diagonal
3604 
3605    Output Parameter:
3606 .  v - the diagonal of the matrix
3607 
3608    Level: intermediate
3609 
3610    Concepts: matrices^accessing diagonals
3611 
3612 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3613 @*/
3614 PetscErrorCode PETSCMAT_DLLEXPORT MatGetDiagonal(Mat mat,Vec v)
3615 {
3616   PetscErrorCode ierr;
3617 
3618   PetscFunctionBegin;
3619   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3620   PetscValidType(mat,1);
3621   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3622   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3623   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3624   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3625 
3626   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
3627   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3628   PetscFunctionReturn(0);
3629 }
3630 
3631 #undef __FUNCT__
3632 #define __FUNCT__ "MatGetRowMin"
3633 /*@
3634    MatGetRowMin - Gets the minimum value (of the real part) of each
3635         row of the matrix
3636 
3637    Collective on Mat and Vec
3638 
3639    Input Parameters:
3640 .  mat - the matrix
3641 
3642    Output Parameter:
3643 +  v - the vector for storing the maximums
3644 -  idx - the indices of the column found for each row (optional)
3645 
3646    Level: intermediate
3647 
3648    Notes: The result of this call are the same as if one converted the matrix to dense format
3649       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3650 
3651     This code is only implemented for a couple of matrix formats.
3652 
3653    Concepts: matrices^getting row maximums
3654 
3655 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3656           MatGetRowMax()
3657 @*/
3658 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3659 {
3660   PetscErrorCode ierr;
3661 
3662   PetscFunctionBegin;
3663   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3664   PetscValidType(mat,1);
3665   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3666   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3667   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3668   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3669 
3670   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
3671   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3672   PetscFunctionReturn(0);
3673 }
3674 
3675 #undef __FUNCT__
3676 #define __FUNCT__ "MatGetRowMinAbs"
3677 /*@
3678    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
3679         row of the matrix
3680 
3681    Collective on Mat and Vec
3682 
3683    Input Parameters:
3684 .  mat - the matrix
3685 
3686    Output Parameter:
3687 +  v - the vector for storing the minimums
3688 -  idx - the indices of the column found for each row (optional)
3689 
3690    Level: intermediate
3691 
3692    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3693     row is 0 (the first column).
3694 
3695     This code is only implemented for a couple of matrix formats.
3696 
3697    Concepts: matrices^getting row maximums
3698 
3699 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
3700 @*/
3701 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
3702 {
3703   PetscErrorCode ierr;
3704 
3705   PetscFunctionBegin;
3706   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3707   PetscValidType(mat,1);
3708   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3709   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3710   if (!mat->ops->getrowminabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3711   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3712   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
3713 
3714   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
3715   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3716   PetscFunctionReturn(0);
3717 }
3718 
3719 #undef __FUNCT__
3720 #define __FUNCT__ "MatGetRowMax"
3721 /*@
3722    MatGetRowMax - Gets the maximum value (of the real part) of each
3723         row of the matrix
3724 
3725    Collective on Mat and Vec
3726 
3727    Input Parameters:
3728 .  mat - the matrix
3729 
3730    Output Parameter:
3731 +  v - the vector for storing the maximums
3732 -  idx - the indices of the column found for each row (optional)
3733 
3734    Level: intermediate
3735 
3736    Notes: The result of this call are the same as if one converted the matrix to dense format
3737       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
3738 
3739     This code is only implemented for a couple of matrix formats.
3740 
3741    Concepts: matrices^getting row maximums
3742 
3743 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3744 @*/
3745 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3746 {
3747   PetscErrorCode ierr;
3748 
3749   PetscFunctionBegin;
3750   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3751   PetscValidType(mat,1);
3752   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3753   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3754   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3755   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3756 
3757   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
3758   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3759   PetscFunctionReturn(0);
3760 }
3761 
3762 #undef __FUNCT__
3763 #define __FUNCT__ "MatGetRowMaxAbs"
3764 /*@
3765    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3766         row of the matrix
3767 
3768    Collective on Mat and Vec
3769 
3770    Input Parameters:
3771 .  mat - the matrix
3772 
3773    Output Parameter:
3774 +  v - the vector for storing the maximums
3775 -  idx - the indices of the column found for each row (optional)
3776 
3777    Level: intermediate
3778 
3779    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
3780     row is 0 (the first column).
3781 
3782     This code is only implemented for a couple of matrix formats.
3783 
3784    Concepts: matrices^getting row maximums
3785 
3786 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3787 @*/
3788 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3789 {
3790   PetscErrorCode ierr;
3791 
3792   PetscFunctionBegin;
3793   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3794   PetscValidType(mat,1);
3795   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3796   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3797   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3798   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3799   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
3800 
3801   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
3802   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
3803   PetscFunctionReturn(0);
3804 }
3805 
3806 #undef __FUNCT__
3807 #define __FUNCT__ "MatGetRowSum"
3808 /*@
3809    MatGetRowSum - Gets the sum of each row of the matrix
3810 
3811    Collective on Mat and Vec
3812 
3813    Input Parameters:
3814 .  mat - the matrix
3815 
3816    Output Parameter:
3817 .  v - the vector for storing the maximums
3818 
3819    Level: intermediate
3820 
3821    Notes: This code is slow since it is not currently specialized for different formats
3822 
3823    Concepts: matrices^getting row sums
3824 
3825 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3826 @*/
3827 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowSum(Mat mat, Vec v)
3828 {
3829   PetscInt       start, end, row;
3830   PetscScalar   *array;
3831   PetscErrorCode ierr;
3832 
3833   PetscFunctionBegin;
3834   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3835   PetscValidType(mat,1);
3836   PetscValidHeaderSpecific(v,VEC_COOKIE,2);
3837   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3838   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3839   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
3840   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
3841   for(row = start; row < end; ++row) {
3842     PetscInt           ncols, col;
3843     const PetscInt    *cols;
3844     const PetscScalar *vals;
3845 
3846     array[row - start] = 0.0;
3847     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
3848     for(col = 0; col < ncols; col++) {
3849       array[row - start] += vals[col];
3850     }
3851     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
3852   }
3853   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
3854   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
3855   PetscFunctionReturn(0);
3856 }
3857 
3858 #undef __FUNCT__
3859 #define __FUNCT__ "MatTranspose"
3860 /*@
3861    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
3862 
3863    Collective on Mat
3864 
3865    Input Parameter:
3866 +  mat - the matrix to transpose
3867 -  reuse - store the transpose matrix in the provided B
3868 
3869    Output Parameters:
3870 .  B - the transpose
3871 
3872    Notes:
3873      If you  pass in &mat for B the transpose will be done in place
3874 
3875    Level: intermediate
3876 
3877    Concepts: matrices^transposing
3878 
3879 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3880 @*/
3881 PetscErrorCode PETSCMAT_DLLEXPORT MatTranspose(Mat mat,MatReuse reuse,Mat *B)
3882 {
3883   PetscErrorCode ierr;
3884 
3885   PetscFunctionBegin;
3886   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3887   PetscValidType(mat,1);
3888   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3889   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3890   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3891   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3892 
3893   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3894   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
3895   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
3896   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
3897   PetscFunctionReturn(0);
3898 }
3899 
3900 #undef __FUNCT__
3901 #define __FUNCT__ "MatIsTranspose"
3902 /*@
3903    MatIsTranspose - Test whether a matrix is another one's transpose,
3904         or its own, in which case it tests symmetry.
3905 
3906    Collective on Mat
3907 
3908    Input Parameter:
3909 +  A - the matrix to test
3910 -  B - the matrix to test against, this can equal the first parameter
3911 
3912    Output Parameters:
3913 .  flg - the result
3914 
3915    Notes:
3916    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3917    has a running time of the order of the number of nonzeros; the parallel
3918    test involves parallel copies of the block-offdiagonal parts of the matrix.
3919 
3920    Level: intermediate
3921 
3922    Concepts: matrices^transposing, matrix^symmetry
3923 
3924 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3925 @*/
3926 PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3927 {
3928   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3929 
3930   PetscFunctionBegin;
3931   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3932   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3933   PetscValidPointer(flg,3);
3934   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
3935   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
3936   if (f && g) {
3937     if (f==g) {
3938       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
3939     } else {
3940       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3941     }
3942   }
3943   PetscFunctionReturn(0);
3944 }
3945 
3946 #undef __FUNCT__
3947 #define __FUNCT__ "MatIsHermitianTranspose"
3948 /*@
3949    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
3950 
3951    Collective on Mat
3952 
3953    Input Parameter:
3954 +  A - the matrix to test
3955 -  B - the matrix to test against, this can equal the first parameter
3956 
3957    Output Parameters:
3958 .  flg - the result
3959 
3960    Notes:
3961    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
3962    has a running time of the order of the number of nonzeros; the parallel
3963    test involves parallel copies of the block-offdiagonal parts of the matrix.
3964 
3965    Level: intermediate
3966 
3967    Concepts: matrices^transposing, matrix^symmetry
3968 
3969 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
3970 @*/
3971 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3972 {
3973   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);
3974 
3975   PetscFunctionBegin;
3976   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
3977   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
3978   PetscValidPointer(flg,3);
3979   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
3980   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
3981   if (f && g) {
3982     if (f==g) {
3983       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
3984     } else {
3985       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
3986     }
3987   }
3988   PetscFunctionReturn(0);
3989 }
3990 
3991 #undef __FUNCT__
3992 #define __FUNCT__ "MatPermute"
3993 /*@
3994    MatPermute - Creates a new matrix with rows and columns permuted from the
3995    original.
3996 
3997    Collective on Mat
3998 
3999    Input Parameters:
4000 +  mat - the matrix to permute
4001 .  row - row permutation, each processor supplies only the permutation for its rows
4002 -  col - column permutation, each processor needs the entire column permutation, that is
4003          this is the same size as the total number of columns in the matrix
4004 
4005    Output Parameters:
4006 .  B - the permuted matrix
4007 
4008    Level: advanced
4009 
4010    Concepts: matrices^permuting
4011 
4012 .seealso: MatGetOrdering()
4013 @*/
4014 PetscErrorCode PETSCMAT_DLLEXPORT MatPermute(Mat mat,IS row,IS col,Mat *B)
4015 {
4016   PetscErrorCode ierr;
4017 
4018   PetscFunctionBegin;
4019   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4020   PetscValidType(mat,1);
4021   PetscValidHeaderSpecific(row,IS_COOKIE,2);
4022   PetscValidHeaderSpecific(col,IS_COOKIE,3);
4023   PetscValidPointer(B,4);
4024   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4025   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4026   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4027   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4028 
4029   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4030   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4031   PetscFunctionReturn(0);
4032 }
4033 
4034 #undef __FUNCT__
4035 #define __FUNCT__ "MatPermuteSparsify"
4036 /*@
4037   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
4038   original and sparsified to the prescribed tolerance.
4039 
4040   Collective on Mat
4041 
4042   Input Parameters:
4043 + A    - The matrix to permute
4044 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
4045 . frac - The half-bandwidth as a fraction of the total size, or 0.0
4046 . tol  - The drop tolerance
4047 . rowp - The row permutation
4048 - colp - The column permutation
4049 
4050   Output Parameter:
4051 . B    - The permuted, sparsified matrix
4052 
4053   Level: advanced
4054 
4055   Note:
4056   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4057   restrict the half-bandwidth of the resulting matrix to 5% of the
4058   total matrix size.
4059 
4060 .keywords: matrix, permute, sparsify
4061 
4062 .seealso: MatGetOrdering(), MatPermute()
4063 @*/
4064 PetscErrorCode PETSCMAT_DLLEXPORT MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
4065 {
4066   IS                irowp, icolp;
4067   const PetscInt    *rows, *cols;
4068   PetscInt          M, N, locRowStart, locRowEnd;
4069   PetscInt          nz, newNz;
4070   const PetscInt    *cwork;
4071   PetscInt          *cnew;
4072   const PetscScalar *vwork;
4073   PetscScalar       *vnew;
4074   PetscInt          bw, issize;
4075   PetscInt          row, locRow, newRow, col, newCol;
4076   PetscErrorCode    ierr;
4077 
4078   PetscFunctionBegin;
4079   PetscValidHeaderSpecific(A,    MAT_COOKIE,1);
4080   PetscValidHeaderSpecific(rowp, IS_COOKIE,5);
4081   PetscValidHeaderSpecific(colp, IS_COOKIE,6);
4082   PetscValidPointer(B,7);
4083   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4084   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
4085   if (!A->ops->permutesparsify) {
4086     ierr = MatGetSize(A, &M, &N);CHKERRQ(ierr);
4087     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);CHKERRQ(ierr);
4088     ierr = ISGetSize(rowp, &issize);CHKERRQ(ierr);
4089     if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
4090     ierr = ISGetSize(colp, &issize);CHKERRQ(ierr);
4091     if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
4092     ierr = ISInvertPermutation(rowp, 0, &irowp);CHKERRQ(ierr);
4093     ierr = ISGetIndices(irowp, &rows);CHKERRQ(ierr);
4094     ierr = ISInvertPermutation(colp, 0, &icolp);CHKERRQ(ierr);
4095     ierr = ISGetIndices(icolp, &cols);CHKERRQ(ierr);
4096     ierr = PetscMalloc(N * sizeof(PetscInt),         &cnew);CHKERRQ(ierr);
4097     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);CHKERRQ(ierr);
4098 
4099     /* Setup bandwidth to include */
4100     if (band == PETSC_DECIDE) {
4101       if (frac <= 0.0)
4102         bw = (PetscInt) (M * 0.05);
4103       else
4104         bw = (PetscInt) (M * frac);
4105     } else {
4106       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4107       bw = band;
4108     }
4109 
4110     /* Put values into new matrix */
4111     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);CHKERRQ(ierr);
4112     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
4113       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
4114       newRow   = rows[locRow]+locRowStart;
4115       for(col = 0, newNz = 0; col < nz; col++) {
4116         newCol = cols[cwork[col]];
4117         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
4118           cnew[newNz] = newCol;
4119           vnew[newNz] = vwork[col];
4120           newNz++;
4121         }
4122       }
4123       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);CHKERRQ(ierr);
4124       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);CHKERRQ(ierr);
4125     }
4126     ierr = PetscFree(cnew);CHKERRQ(ierr);
4127     ierr = PetscFree(vnew);CHKERRQ(ierr);
4128     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4129     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4130     ierr = ISRestoreIndices(irowp, &rows);CHKERRQ(ierr);
4131     ierr = ISRestoreIndices(icolp, &cols);CHKERRQ(ierr);
4132     ierr = ISDestroy(irowp);CHKERRQ(ierr);
4133     ierr = ISDestroy(icolp);CHKERRQ(ierr);
4134   } else {
4135     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);CHKERRQ(ierr);
4136   }
4137   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4138   PetscFunctionReturn(0);
4139 }
4140 
4141 #undef __FUNCT__
4142 #define __FUNCT__ "MatEqual"
4143 /*@
4144    MatEqual - Compares two matrices.
4145 
4146    Collective on Mat
4147 
4148    Input Parameters:
4149 +  A - the first matrix
4150 -  B - the second matrix
4151 
4152    Output Parameter:
4153 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4154 
4155    Level: intermediate
4156 
4157    Concepts: matrices^equality between
4158 @*/
4159 PetscErrorCode PETSCMAT_DLLEXPORT MatEqual(Mat A,Mat B,PetscTruth *flg)
4160 {
4161   PetscErrorCode ierr;
4162 
4163   PetscFunctionBegin;
4164   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
4165   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
4166   PetscValidType(A,1);
4167   PetscValidType(B,2);
4168   PetscValidIntPointer(flg,3);
4169   PetscCheckSameComm(A,1,B,2);
4170   ierr = MatPreallocated(B);CHKERRQ(ierr);
4171   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4172   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4173   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4174   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4175   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4176   if (A->ops->equal != B->ops->equal) SETERRQ2(PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4177   ierr = MatPreallocated(A);CHKERRQ(ierr);
4178 
4179   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4180   PetscFunctionReturn(0);
4181 }
4182 
4183 #undef __FUNCT__
4184 #define __FUNCT__ "MatDiagonalScale"
4185 /*@
4186    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4187    matrices that are stored as vectors.  Either of the two scaling
4188    matrices can be PETSC_NULL.
4189 
4190    Collective on Mat
4191 
4192    Input Parameters:
4193 +  mat - the matrix to be scaled
4194 .  l - the left scaling vector (or PETSC_NULL)
4195 -  r - the right scaling vector (or PETSC_NULL)
4196 
4197    Notes:
4198    MatDiagonalScale() computes A = LAR, where
4199    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4200 
4201    Level: intermediate
4202 
4203    Concepts: matrices^diagonal scaling
4204    Concepts: diagonal scaling of matrices
4205 
4206 .seealso: MatScale()
4207 @*/
4208 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScale(Mat mat,Vec l,Vec r)
4209 {
4210   PetscErrorCode ierr;
4211 
4212   PetscFunctionBegin;
4213   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4214   PetscValidType(mat,1);
4215   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4216   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE,2);PetscCheckSameComm(mat,1,l,2);}
4217   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE,3);PetscCheckSameComm(mat,1,r,3);}
4218   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4219   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4220   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4221 
4222   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4223   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4224   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4225   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4226   PetscFunctionReturn(0);
4227 }
4228 
4229 #undef __FUNCT__
4230 #define __FUNCT__ "MatScale"
4231 /*@
4232     MatScale - Scales all elements of a matrix by a given number.
4233 
4234     Collective on Mat
4235 
4236     Input Parameters:
4237 +   mat - the matrix to be scaled
4238 -   a  - the scaling value
4239 
4240     Output Parameter:
4241 .   mat - the scaled matrix
4242 
4243     Level: intermediate
4244 
4245     Concepts: matrices^scaling all entries
4246 
4247 .seealso: MatDiagonalScale()
4248 @*/
4249 PetscErrorCode PETSCMAT_DLLEXPORT MatScale(Mat mat,PetscScalar a)
4250 {
4251   PetscErrorCode ierr;
4252 
4253   PetscFunctionBegin;
4254   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4255   PetscValidType(mat,1);
4256   if (a != 1.0 && !mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4257   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4258   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4259   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4260 
4261   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4262   if (a != 1.0) {
4263     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4264     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4265   }
4266   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4267   PetscFunctionReturn(0);
4268 }
4269 
4270 #undef __FUNCT__
4271 #define __FUNCT__ "MatNorm"
4272 /*@
4273    MatNorm - Calculates various norms of a matrix.
4274 
4275    Collective on Mat
4276 
4277    Input Parameters:
4278 +  mat - the matrix
4279 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4280 
4281    Output Parameters:
4282 .  nrm - the resulting norm
4283 
4284    Level: intermediate
4285 
4286    Concepts: matrices^norm
4287    Concepts: norm^of matrix
4288 @*/
4289 PetscErrorCode PETSCMAT_DLLEXPORT MatNorm(Mat mat,NormType type,PetscReal *nrm)
4290 {
4291   PetscErrorCode ierr;
4292 
4293   PetscFunctionBegin;
4294   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4295   PetscValidType(mat,1);
4296   PetscValidScalarPointer(nrm,3);
4297 
4298   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4299   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4300   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4301   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4302 
4303   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4304   PetscFunctionReturn(0);
4305 }
4306 
4307 /*
4308      This variable is used to prevent counting of MatAssemblyBegin() that
4309    are called from within a MatAssemblyEnd().
4310 */
4311 static PetscInt MatAssemblyEnd_InUse = 0;
4312 #undef __FUNCT__
4313 #define __FUNCT__ "MatAssemblyBegin"
4314 /*@
4315    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4316    be called after completing all calls to MatSetValues().
4317 
4318    Collective on Mat
4319 
4320    Input Parameters:
4321 +  mat - the matrix
4322 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4323 
4324    Notes:
4325    MatSetValues() generally caches the values.  The matrix is ready to
4326    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4327    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4328    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4329    using the matrix.
4330 
4331    Level: beginner
4332 
4333    Concepts: matrices^assembling
4334 
4335 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4336 @*/
4337 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyBegin(Mat mat,MatAssemblyType type)
4338 {
4339   PetscErrorCode ierr;
4340 
4341   PetscFunctionBegin;
4342   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4343   PetscValidType(mat,1);
4344   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4345   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4346   if (mat->assembled) {
4347     mat->was_assembled = PETSC_TRUE;
4348     mat->assembled     = PETSC_FALSE;
4349   }
4350   if (!MatAssemblyEnd_InUse) {
4351     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4352     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4353     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4354   } else {
4355     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4356   }
4357   PetscFunctionReturn(0);
4358 }
4359 
4360 #undef __FUNCT__
4361 #define __FUNCT__ "MatAssembed"
4362 /*@
4363    MatAssembled - Indicates if a matrix has been assembled and is ready for
4364      use; for example, in matrix-vector product.
4365 
4366    Collective on Mat
4367 
4368    Input Parameter:
4369 .  mat - the matrix
4370 
4371    Output Parameter:
4372 .  assembled - PETSC_TRUE or PETSC_FALSE
4373 
4374    Level: advanced
4375 
4376    Concepts: matrices^assembled?
4377 
4378 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4379 @*/
4380 PetscErrorCode PETSCMAT_DLLEXPORT MatAssembled(Mat mat,PetscTruth *assembled)
4381 {
4382   PetscFunctionBegin;
4383   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4384   PetscValidType(mat,1);
4385   PetscValidPointer(assembled,2);
4386   *assembled = mat->assembled;
4387   PetscFunctionReturn(0);
4388 }
4389 
4390 #undef __FUNCT__
4391 #define __FUNCT__ "MatView_Private"
4392 /*
4393     Processes command line options to determine if/how a matrix
4394   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4395 */
4396 PetscErrorCode MatView_Private(Mat mat)
4397 {
4398   PetscErrorCode    ierr;
4399   PetscTruth        flg1,flg2,flg3,flg4,flg6,flg7,flg8;
4400   static PetscTruth incall = PETSC_FALSE;
4401 #if defined(PETSC_USE_SOCKET_VIEWER)
4402   PetscTruth        flg5;
4403 #endif
4404 
4405   PetscFunctionBegin;
4406   if (incall) PetscFunctionReturn(0);
4407   incall = PETSC_TRUE;
4408   ierr = PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
4409     ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg1);CHKERRQ(ierr);
4410     ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg2);CHKERRQ(ierr);
4411     ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg3);CHKERRQ(ierr);
4412     ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg4);CHKERRQ(ierr);
4413 #if defined(PETSC_USE_SOCKET_VIEWER)
4414     ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg5);CHKERRQ(ierr);
4415 #endif
4416     ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg6);CHKERRQ(ierr);
4417     ierr = PetscOptionsName("-mat_view_draw","Draw the matrix nonzero structure","MatView",&flg7);CHKERRQ(ierr);
4418   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4419 
4420   if (flg1) {
4421     PetscViewer viewer;
4422 
4423     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4424     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4425     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4426     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4427   }
4428   if (flg2) {
4429     PetscViewer viewer;
4430 
4431     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4432     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4433     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4434     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4435   }
4436   if (flg3) {
4437     PetscViewer viewer;
4438 
4439     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4440     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4441   }
4442   if (flg4) {
4443     PetscViewer viewer;
4444 
4445     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4446     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4447     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4448     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4449   }
4450 #if defined(PETSC_USE_SOCKET_VIEWER)
4451   if (flg5) {
4452     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4453     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4454   }
4455 #endif
4456   if (flg6) {
4457     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4458     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4459   }
4460   if (flg7) {
4461     ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8);CHKERRQ(ierr);
4462     if (flg8) {
4463       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4464     }
4465     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4466     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4467     if (flg8) {
4468       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4469     }
4470   }
4471   incall = PETSC_FALSE;
4472   PetscFunctionReturn(0);
4473 }
4474 
4475 #undef __FUNCT__
4476 #define __FUNCT__ "MatAssemblyEnd"
4477 /*@
4478    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4479    be called after MatAssemblyBegin().
4480 
4481    Collective on Mat
4482 
4483    Input Parameters:
4484 +  mat - the matrix
4485 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4486 
4487    Options Database Keys:
4488 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4489 .  -mat_view_info_detailed - Prints more detailed info
4490 .  -mat_view - Prints matrix in ASCII format
4491 .  -mat_view_matlab - Prints matrix in Matlab format
4492 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4493 .  -display <name> - Sets display name (default is host)
4494 .  -draw_pause <sec> - Sets number of seconds to pause after display
4495 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4496 .  -viewer_socket_machine <machine>
4497 .  -viewer_socket_port <port>
4498 .  -mat_view_binary - save matrix to file in binary format
4499 -  -viewer_binary_filename <name>
4500 
4501    Notes:
4502    MatSetValues() generally caches the values.  The matrix is ready to
4503    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4504    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4505    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4506    using the matrix.
4507 
4508    Level: beginner
4509 
4510 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4511 @*/
4512 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyEnd(Mat mat,MatAssemblyType type)
4513 {
4514   PetscErrorCode  ierr;
4515   static PetscInt inassm = 0;
4516   PetscTruth      flg;
4517 
4518   PetscFunctionBegin;
4519   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4520   PetscValidType(mat,1);
4521 
4522   inassm++;
4523   MatAssemblyEnd_InUse++;
4524   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4525     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4526     if (mat->ops->assemblyend) {
4527       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4528     }
4529     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4530   } else {
4531     if (mat->ops->assemblyend) {
4532       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4533     }
4534   }
4535 
4536   /* Flush assembly is not a true assembly */
4537   if (type != MAT_FLUSH_ASSEMBLY) {
4538     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4539   }
4540   mat->insertmode = NOT_SET_VALUES;
4541   MatAssemblyEnd_InUse--;
4542   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4543   if (!mat->symmetric_eternal) {
4544     mat->symmetric_set              = PETSC_FALSE;
4545     mat->hermitian_set              = PETSC_FALSE;
4546     mat->structurally_symmetric_set = PETSC_FALSE;
4547   }
4548   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4549     ierr = MatView_Private(mat);CHKERRQ(ierr);
4550     ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);CHKERRQ(ierr);
4551     if (flg) {
4552       PetscReal tol = 0.0;
4553       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
4554       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
4555       if (flg) {
4556         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4557       } else {
4558         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4559       }
4560     }
4561   }
4562   inassm--;
4563   PetscFunctionReturn(0);
4564 }
4565 
4566 
4567 #undef __FUNCT__
4568 #define __FUNCT__ "MatCompress"
4569 /*@
4570    MatCompress - Tries to store the matrix in as little space as
4571    possible.  May fail if memory is already fully used, since it
4572    tries to allocate new space.
4573 
4574    Collective on Mat
4575 
4576    Input Parameters:
4577 .  mat - the matrix
4578 
4579    Level: advanced
4580 
4581 @*/
4582 PetscErrorCode PETSCMAT_DLLEXPORT MatCompress(Mat mat)
4583 {
4584   PetscErrorCode ierr;
4585 
4586   PetscFunctionBegin;
4587   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4588   PetscValidType(mat,1);
4589   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4590   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
4591   PetscFunctionReturn(0);
4592 }
4593 
4594 #undef __FUNCT__
4595 #define __FUNCT__ "MatSetOption"
4596 /*@
4597    MatSetOption - Sets a parameter option for a matrix. Some options
4598    may be specific to certain storage formats.  Some options
4599    determine how values will be inserted (or added). Sorted,
4600    row-oriented input will generally assemble the fastest. The default
4601    is row-oriented, nonsorted input.
4602 
4603    Collective on Mat
4604 
4605    Input Parameters:
4606 +  mat - the matrix
4607 .  option - the option, one of those listed below (and possibly others),
4608 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4609 
4610   Options Describing Matrix Structure:
4611 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
4612 .    MAT_HERMITIAN - transpose is the complex conjugation
4613 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4614 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4615                             you set to be kept with all future use of the matrix
4616                             including after MatAssemblyBegin/End() which could
4617                             potentially change the symmetry structure, i.e. you
4618                             KNOW the matrix will ALWAYS have the property you set.
4619 
4620 
4621    Options For Use with MatSetValues():
4622    Insert a logically dense subblock, which can be
4623 .    MAT_ROW_ORIENTED - row-oriented (default)
4624 
4625    Note these options reflect the data you pass in with MatSetValues(); it has
4626    nothing to do with how the data is stored internally in the matrix
4627    data structure.
4628 
4629    When (re)assembling a matrix, we can restrict the input for
4630    efficiency/debugging purposes.  These options include
4631 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4632         allowed if they generate a new nonzero
4633 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4634 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4635 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4636 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4637 
4638    Notes:
4639    Some options are relevant only for particular matrix types and
4640    are thus ignored by others.  Other options are not supported by
4641    certain matrix types and will generate an error message if set.
4642 
4643    If using a Fortran 77 module to compute a matrix, one may need to
4644    use the column-oriented option (or convert to the row-oriented
4645    format).
4646 
4647    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4648    that would generate a new entry in the nonzero structure is instead
4649    ignored.  Thus, if memory has not alredy been allocated for this particular
4650    data, then the insertion is ignored. For dense matrices, in which
4651    the entire array is allocated, no entries are ever ignored.
4652    Set after the first MatAssemblyEnd()
4653 
4654    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4655    that would generate a new entry in the nonzero structure instead produces
4656    an error. (Currently supported for AIJ and BAIJ formats only.)
4657    This is a useful flag when using SAME_NONZERO_PATTERN in calling
4658    KSPSetOperators() to ensure that the nonzero pattern truely does
4659    remain unchanged. Set after the first MatAssemblyEnd()
4660 
4661    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4662    that would generate a new entry that has not been preallocated will
4663    instead produce an error. (Currently supported for AIJ and BAIJ formats
4664    only.) This is a useful flag when debugging matrix memory preallocation.
4665 
4666    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4667    other processors should be dropped, rather than stashed.
4668    This is useful if you know that the "owning" processor is also
4669    always generating the correct matrix entries, so that PETSc need
4670    not transfer duplicate entries generated on another processor.
4671 
4672    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4673    searches during matrix assembly. When this flag is set, the hash table
4674    is created during the first Matrix Assembly. This hash table is
4675    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4676    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
4677    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4678    supported by MATMPIBAIJ format only.
4679 
4680    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4681    are kept in the nonzero structure
4682 
4683    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4684    a zero location in the matrix
4685 
4686    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4687    ROWBS matrix types
4688 
4689    Level: intermediate
4690 
4691    Concepts: matrices^setting options
4692 
4693 @*/
4694 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4695 {
4696   PetscErrorCode ierr;
4697 
4698   PetscFunctionBegin;
4699   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4700   PetscValidType(mat,1);
4701   if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4702   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4703   switch (op) {
4704   case MAT_SYMMETRIC:
4705     mat->symmetric                  = flg;
4706     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4707     mat->symmetric_set              = PETSC_TRUE;
4708     mat->structurally_symmetric_set = flg;
4709     break;
4710   case MAT_HERMITIAN:
4711     mat->hermitian                  = flg;
4712     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4713     mat->hermitian_set              = PETSC_TRUE;
4714     mat->structurally_symmetric_set = flg;
4715     break;
4716   case MAT_STRUCTURALLY_SYMMETRIC:
4717     mat->structurally_symmetric     = flg;
4718     mat->structurally_symmetric_set = PETSC_TRUE;
4719     break;
4720   case MAT_SYMMETRY_ETERNAL:
4721     mat->symmetric_eternal          = flg;
4722     break;
4723   default:
4724     break;
4725   }
4726   if (mat->ops->setoption) {
4727     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
4728   }
4729   PetscFunctionReturn(0);
4730 }
4731 
4732 #undef __FUNCT__
4733 #define __FUNCT__ "MatZeroEntries"
4734 /*@
4735    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4736    this routine retains the old nonzero structure.
4737 
4738    Collective on Mat
4739 
4740    Input Parameters:
4741 .  mat - the matrix
4742 
4743    Level: intermediate
4744 
4745    Concepts: matrices^zeroing
4746 
4747 .seealso: MatZeroRows()
4748 @*/
4749 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroEntries(Mat mat)
4750 {
4751   PetscErrorCode ierr;
4752 
4753   PetscFunctionBegin;
4754   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4755   PetscValidType(mat,1);
4756   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4757   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4758   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4759   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4760 
4761   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4762   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
4763   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4764   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4765   PetscFunctionReturn(0);
4766 }
4767 
4768 #undef __FUNCT__
4769 #define __FUNCT__ "MatZeroRows"
4770 /*@C
4771    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4772    of a set of rows of a matrix.
4773 
4774    Collective on Mat
4775 
4776    Input Parameters:
4777 +  mat - the matrix
4778 .  numRows - the number of rows to remove
4779 .  rows - the global row indices
4780 -  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
4781 
4782    Notes:
4783    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4784    but does not release memory.  For the dense and block diagonal
4785    formats this does not alter the nonzero structure.
4786 
4787    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4788    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4789    merely zeroed.
4790 
4791    The user can set a value in the diagonal entry (or for the AIJ and
4792    row formats can optionally remove the main diagonal entry from the
4793    nonzero structure as well, by passing 0.0 as the final argument).
4794 
4795    For the parallel case, all processes that share the matrix (i.e.,
4796    those in the communicator used for matrix creation) MUST call this
4797    routine, regardless of whether any rows being zeroed are owned by
4798    them.
4799 
4800    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
4801    list only rows local to itself).
4802 
4803    Level: intermediate
4804 
4805    Concepts: matrices^zeroing rows
4806 
4807 .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4808 @*/
4809 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4810 {
4811   PetscErrorCode ierr;
4812 
4813   PetscFunctionBegin;
4814   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4815   PetscValidType(mat,1);
4816   if (numRows) PetscValidIntPointer(rows,3);
4817   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4818   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4819   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4820   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4821 
4822   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag);CHKERRQ(ierr);
4823   ierr = MatView_Private(mat);CHKERRQ(ierr);
4824   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4825   PetscFunctionReturn(0);
4826 }
4827 
4828 #undef __FUNCT__
4829 #define __FUNCT__ "MatZeroRowsIS"
4830 /*@C
4831    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4832    of a set of rows of a matrix.
4833 
4834    Collective on Mat
4835 
4836    Input Parameters:
4837 +  mat - the matrix
4838 .  is - index set of rows to remove
4839 -  diag - value put in all diagonals of eliminated rows
4840 
4841    Notes:
4842    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4843    but does not release memory.  For the dense and block diagonal
4844    formats this does not alter the nonzero structure.
4845 
4846    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4847    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4848    merely zeroed.
4849 
4850    The user can set a value in the diagonal entry (or for the AIJ and
4851    row formats can optionally remove the main diagonal entry from the
4852    nonzero structure as well, by passing 0.0 as the final argument).
4853 
4854    For the parallel case, all processes that share the matrix (i.e.,
4855    those in the communicator used for matrix creation) MUST call this
4856    routine, regardless of whether any rows being zeroed are owned by
4857    them.
4858 
4859    Each processor should list the rows that IT wants zeroed
4860 
4861    Level: intermediate
4862 
4863    Concepts: matrices^zeroing rows
4864 
4865 .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4866 @*/
4867 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4868 {
4869   PetscInt       numRows;
4870   const PetscInt *rows;
4871   PetscErrorCode ierr;
4872 
4873   PetscFunctionBegin;
4874   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4875   PetscValidType(mat,1);
4876   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4877   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
4878   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
4879   ierr = MatZeroRows(mat,numRows,rows,diag);CHKERRQ(ierr);
4880   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
4881   PetscFunctionReturn(0);
4882 }
4883 
4884 #undef __FUNCT__
4885 #define __FUNCT__ "MatZeroRowsLocal"
4886 /*@C
4887    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
4888    of a set of rows of a matrix; using local numbering of rows.
4889 
4890    Collective on Mat
4891 
4892    Input Parameters:
4893 +  mat - the matrix
4894 .  numRows - the number of rows to remove
4895 .  rows - the global row indices
4896 -  diag - value put in all diagonals of eliminated rows
4897 
4898    Notes:
4899    Before calling MatZeroRowsLocal(), the user must first set the
4900    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4901 
4902    For the AIJ matrix formats this removes the old nonzero structure,
4903    but does not release memory.  For the dense and block diagonal
4904    formats this does not alter the nonzero structure.
4905 
4906    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4907    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4908    merely zeroed.
4909 
4910    The user can set a value in the diagonal entry (or for the AIJ and
4911    row formats can optionally remove the main diagonal entry from the
4912    nonzero structure as well, by passing 0.0 as the final argument).
4913 
4914    Level: intermediate
4915 
4916    Concepts: matrices^zeroing
4917 
4918 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4919 @*/
4920 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4921 {
4922   PetscErrorCode ierr;
4923 
4924   PetscFunctionBegin;
4925   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4926   PetscValidType(mat,1);
4927   if (numRows) PetscValidIntPointer(rows,3);
4928   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4929   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4930   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4931 
4932   if (mat->ops->zerorowslocal) {
4933     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);CHKERRQ(ierr);
4934   } else {
4935     IS             is, newis;
4936     const PetscInt *newRows;
4937 
4938     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4939     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);CHKERRQ(ierr);
4940     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
4941     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
4942     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag);CHKERRQ(ierr);
4943     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
4944     ierr = ISDestroy(newis);CHKERRQ(ierr);
4945     ierr = ISDestroy(is);CHKERRQ(ierr);
4946   }
4947   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4948   PetscFunctionReturn(0);
4949 }
4950 
4951 #undef __FUNCT__
4952 #define __FUNCT__ "MatZeroRowsLocalIS"
4953 /*@C
4954    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
4955    of a set of rows of a matrix; using local numbering of rows.
4956 
4957    Collective on Mat
4958 
4959    Input Parameters:
4960 +  mat - the matrix
4961 .  is - index set of rows to remove
4962 -  diag - value put in all diagonals of eliminated rows
4963 
4964    Notes:
4965    Before calling MatZeroRowsLocalIS(), the user must first set the
4966    local-to-global mapping by calling MatSetLocalToGlobalMapping().
4967 
4968    For the AIJ matrix formats this removes the old nonzero structure,
4969    but does not release memory.  For the dense and block diagonal
4970    formats this does not alter the nonzero structure.
4971 
4972    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4973    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4974    merely zeroed.
4975 
4976    The user can set a value in the diagonal entry (or for the AIJ and
4977    row formats can optionally remove the main diagonal entry from the
4978    nonzero structure as well, by passing 0.0 as the final argument).
4979 
4980    Level: intermediate
4981 
4982    Concepts: matrices^zeroing
4983 
4984 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4985 @*/
4986 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
4987 {
4988   PetscErrorCode ierr;
4989   PetscInt       numRows;
4990   const PetscInt *rows;
4991 
4992   PetscFunctionBegin;
4993   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4994   PetscValidType(mat,1);
4995   PetscValidHeaderSpecific(is,IS_COOKIE,2);
4996   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4997   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4998   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4999 
5000   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5001   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5002   ierr = MatZeroRowsLocal(mat,numRows,rows,diag);CHKERRQ(ierr);
5003   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5004   PetscFunctionReturn(0);
5005 }
5006 
5007 #undef __FUNCT__
5008 #define __FUNCT__ "MatGetSize"
5009 /*@
5010    MatGetSize - Returns the numbers of rows and columns in a matrix.
5011 
5012    Not Collective
5013 
5014    Input Parameter:
5015 .  mat - the matrix
5016 
5017    Output Parameters:
5018 +  m - the number of global rows
5019 -  n - the number of global columns
5020 
5021    Note: both output parameters can be PETSC_NULL on input.
5022 
5023    Level: beginner
5024 
5025    Concepts: matrices^size
5026 
5027 .seealso: MatGetLocalSize()
5028 @*/
5029 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5030 {
5031   PetscFunctionBegin;
5032   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5033   if (m) *m = mat->rmap->N;
5034   if (n) *n = mat->cmap->N;
5035   PetscFunctionReturn(0);
5036 }
5037 
5038 #undef __FUNCT__
5039 #define __FUNCT__ "MatGetLocalSize"
5040 /*@
5041    MatGetLocalSize - Returns the number of rows and columns in a matrix
5042    stored locally.  This information may be implementation dependent, so
5043    use with care.
5044 
5045    Not Collective
5046 
5047    Input Parameters:
5048 .  mat - the matrix
5049 
5050    Output Parameters:
5051 +  m - the number of local rows
5052 -  n - the number of local columns
5053 
5054    Note: both output parameters can be PETSC_NULL on input.
5055 
5056    Level: beginner
5057 
5058    Concepts: matrices^local size
5059 
5060 .seealso: MatGetSize()
5061 @*/
5062 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5063 {
5064   PetscFunctionBegin;
5065   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5066   if (m) PetscValidIntPointer(m,2);
5067   if (n) PetscValidIntPointer(n,3);
5068   if (m) *m = mat->rmap->n;
5069   if (n) *n = mat->cmap->n;
5070   PetscFunctionReturn(0);
5071 }
5072 
5073 #undef __FUNCT__
5074 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5075 /*@
5076    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5077    this processor.
5078 
5079    Not Collective, unless matrix has not been allocated, then collective on Mat
5080 
5081    Input Parameters:
5082 .  mat - the matrix
5083 
5084    Output Parameters:
5085 +  m - the global index of the first local column
5086 -  n - one more than the global index of the last local column
5087 
5088    Notes: both output parameters can be PETSC_NULL on input.
5089 
5090    Level: developer
5091 
5092    Concepts: matrices^column ownership
5093 
5094 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5095 
5096 @*/
5097 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5098 {
5099   PetscErrorCode ierr;
5100 
5101   PetscFunctionBegin;
5102   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5103   PetscValidType(mat,1);
5104   if (m) PetscValidIntPointer(m,2);
5105   if (n) PetscValidIntPointer(n,3);
5106   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5107   if (m) *m = mat->cmap->rstart;
5108   if (n) *n = mat->cmap->rend;
5109   PetscFunctionReturn(0);
5110 }
5111 
5112 #undef __FUNCT__
5113 #define __FUNCT__ "MatGetOwnershipRange"
5114 /*@
5115    MatGetOwnershipRange - Returns the range of matrix rows owned by
5116    this processor, assuming that the matrix is laid out with the first
5117    n1 rows on the first processor, the next n2 rows on the second, etc.
5118    For certain parallel layouts this range may not be well defined.
5119 
5120    Not Collective, unless matrix has not been allocated, then collective on Mat
5121 
5122    Input Parameters:
5123 .  mat - the matrix
5124 
5125    Output Parameters:
5126 +  m - the global index of the first local row
5127 -  n - one more than the global index of the last local row
5128 
5129    Note: both output parameters can be PETSC_NULL on input.
5130 
5131    Level: beginner
5132 
5133    Concepts: matrices^row ownership
5134 
5135 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5136 
5137 @*/
5138 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5139 {
5140   PetscErrorCode ierr;
5141 
5142   PetscFunctionBegin;
5143   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5144   PetscValidType(mat,1);
5145   if (m) PetscValidIntPointer(m,2);
5146   if (n) PetscValidIntPointer(n,3);
5147   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5148   if (m) *m = mat->rmap->rstart;
5149   if (n) *n = mat->rmap->rend;
5150   PetscFunctionReturn(0);
5151 }
5152 
5153 #undef __FUNCT__
5154 #define __FUNCT__ "MatGetOwnershipRanges"
5155 /*@C
5156    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5157    each process
5158 
5159    Not Collective, unless matrix has not been allocated, then collective on Mat
5160 
5161    Input Parameters:
5162 .  mat - the matrix
5163 
5164    Output Parameters:
5165 .  ranges - start of each processors portion plus one more then the total length at the end
5166 
5167    Level: beginner
5168 
5169    Concepts: matrices^row ownership
5170 
5171 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5172 
5173 @*/
5174 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5175 {
5176   PetscErrorCode ierr;
5177 
5178   PetscFunctionBegin;
5179   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5180   PetscValidType(mat,1);
5181   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5182   ierr = PetscMapGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
5183   PetscFunctionReturn(0);
5184 }
5185 
5186 #undef __FUNCT__
5187 #define __FUNCT__ "MatGetOwnershipRangesColumn"
5188 /*@C
5189    MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5190 
5191    Not Collective, unless matrix has not been allocated, then collective on Mat
5192 
5193    Input Parameters:
5194 .  mat - the matrix
5195 
5196    Output Parameters:
5197 .  ranges - start of each processors portion plus one more then the total length at the end
5198 
5199    Level: beginner
5200 
5201    Concepts: matrices^column ownership
5202 
5203 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5204 
5205 @*/
5206 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5207 {
5208   PetscErrorCode ierr;
5209 
5210   PetscFunctionBegin;
5211   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5212   PetscValidType(mat,1);
5213   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5214   ierr = PetscMapGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
5215   PetscFunctionReturn(0);
5216 }
5217 
5218 #undef __FUNCT__
5219 #define __FUNCT__ "MatILUFactorSymbolic"
5220 /*@
5221    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5222    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5223    to complete the factorization.
5224 
5225    Collective on Mat
5226 
5227    Input Parameters:
5228 +  mat - the matrix
5229 .  row - row permutation
5230 .  column - column permutation
5231 -  info - structure containing
5232 $      levels - number of levels of fill.
5233 $      expected fill - as ratio of original fill.
5234 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5235                 missing diagonal entries)
5236 
5237    Output Parameters:
5238 .  fact - new matrix that has been symbolically factored
5239 
5240    Notes:
5241    See the users manual for additional information about
5242    choosing the fill factor for better efficiency.
5243 
5244    Most users should employ the simplified KSP interface for linear solvers
5245    instead of working directly with matrix algebra routines such as this.
5246    See, e.g., KSPCreate().
5247 
5248    Level: developer
5249 
5250   Concepts: matrices^symbolic LU factorization
5251   Concepts: matrices^factorization
5252   Concepts: LU^symbolic factorization
5253 
5254 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5255           MatGetOrdering(), MatFactorInfo
5256 
5257 @*/
5258 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5259 {
5260   PetscErrorCode ierr;
5261 
5262   PetscFunctionBegin;
5263   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5264   PetscValidType(mat,1);
5265   PetscValidHeaderSpecific(row,IS_COOKIE,2);
5266   PetscValidHeaderSpecific(col,IS_COOKIE,3);
5267   PetscValidPointer(info,4);
5268   PetscValidPointer(fact,5);
5269   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5270   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5271   if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
5272   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5273   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5274   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5275 
5276   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5277   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
5278   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5279   PetscFunctionReturn(0);
5280 }
5281 
5282 #undef __FUNCT__
5283 #define __FUNCT__ "MatICCFactorSymbolic"
5284 /*@
5285    MatICCFactorSymbolic - Performs symbolic incomplete
5286    Cholesky factorization for a symmetric matrix.  Use
5287    MatCholeskyFactorNumeric() to complete the factorization.
5288 
5289    Collective on Mat
5290 
5291    Input Parameters:
5292 +  mat - the matrix
5293 .  perm - row and column permutation
5294 -  info - structure containing
5295 $      levels - number of levels of fill.
5296 $      expected fill - as ratio of original fill.
5297 
5298    Output Parameter:
5299 .  fact - the factored matrix
5300 
5301    Notes:
5302    Most users should employ the KSP interface for linear solvers
5303    instead of working directly with matrix algebra routines such as this.
5304    See, e.g., KSPCreate().
5305 
5306    Level: developer
5307 
5308   Concepts: matrices^symbolic incomplete Cholesky factorization
5309   Concepts: matrices^factorization
5310   Concepts: Cholsky^symbolic factorization
5311 
5312 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5313 @*/
5314 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5315 {
5316   PetscErrorCode ierr;
5317 
5318   PetscFunctionBegin;
5319   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5320   PetscValidType(mat,1);
5321   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
5322   PetscValidPointer(info,3);
5323   PetscValidPointer(fact,4);
5324   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5325   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5326   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5327   if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
5328   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5329   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5330 
5331   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5332   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
5333   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5334   PetscFunctionReturn(0);
5335 }
5336 
5337 #undef __FUNCT__
5338 #define __FUNCT__ "MatGetArray"
5339 /*@C
5340    MatGetArray - Returns a pointer to the element values in the matrix.
5341    The result of this routine is dependent on the underlying matrix data
5342    structure, and may not even work for certain matrix types.  You MUST
5343    call MatRestoreArray() when you no longer need to access the array.
5344 
5345    Not Collective
5346 
5347    Input Parameter:
5348 .  mat - the matrix
5349 
5350    Output Parameter:
5351 .  v - the location of the values
5352 
5353 
5354    Fortran Note:
5355    This routine is used differently from Fortran, e.g.,
5356 .vb
5357         Mat         mat
5358         PetscScalar mat_array(1)
5359         PetscOffset i_mat
5360         PetscErrorCode ierr
5361         call MatGetArray(mat,mat_array,i_mat,ierr)
5362 
5363   C  Access first local entry in matrix; note that array is
5364   C  treated as one dimensional
5365         value = mat_array(i_mat + 1)
5366 
5367         [... other code ...]
5368         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5369 .ve
5370 
5371    See the Fortran chapter of the users manual and
5372    petsc/src/mat/examples/tests for details.
5373 
5374    Level: advanced
5375 
5376    Concepts: matrices^access array
5377 
5378 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5379 @*/
5380 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
5381 {
5382   PetscErrorCode ierr;
5383 
5384   PetscFunctionBegin;
5385   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5386   PetscValidType(mat,1);
5387   PetscValidPointer(v,2);
5388   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5389   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5390   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
5391   CHKMEMQ;
5392   PetscFunctionReturn(0);
5393 }
5394 
5395 #undef __FUNCT__
5396 #define __FUNCT__ "MatRestoreArray"
5397 /*@C
5398    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5399 
5400    Not Collective
5401 
5402    Input Parameter:
5403 +  mat - the matrix
5404 -  v - the location of the values
5405 
5406    Fortran Note:
5407    This routine is used differently from Fortran, e.g.,
5408 .vb
5409         Mat         mat
5410         PetscScalar mat_array(1)
5411         PetscOffset i_mat
5412         PetscErrorCode ierr
5413         call MatGetArray(mat,mat_array,i_mat,ierr)
5414 
5415   C  Access first local entry in matrix; note that array is
5416   C  treated as one dimensional
5417         value = mat_array(i_mat + 1)
5418 
5419         [... other code ...]
5420         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5421 .ve
5422 
5423    See the Fortran chapter of the users manual and
5424    petsc/src/mat/examples/tests for details
5425 
5426    Level: advanced
5427 
5428 .seealso: MatGetArray(), MatRestoreArrayF90()
5429 @*/
5430 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
5431 {
5432   PetscErrorCode ierr;
5433 
5434   PetscFunctionBegin;
5435   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5436   PetscValidType(mat,1);
5437   PetscValidPointer(v,2);
5438 #if defined(PETSC_USE_DEBUG)
5439   CHKMEMQ;
5440 #endif
5441   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5442   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
5443   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5444   PetscFunctionReturn(0);
5445 }
5446 
5447 #undef __FUNCT__
5448 #define __FUNCT__ "MatGetSubMatrices"
5449 /*@C
5450    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5451    points to an array of valid matrices, they may be reused to store the new
5452    submatrices.
5453 
5454    Collective on Mat
5455 
5456    Input Parameters:
5457 +  mat - the matrix
5458 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5459 .  irow, icol - index sets of rows and columns to extract
5460 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5461 
5462    Output Parameter:
5463 .  submat - the array of submatrices
5464 
5465    Notes:
5466    MatGetSubMatrices() can extract ONLY sequential submatrices
5467    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5468    to extract a parallel submatrix.
5469 
5470    When extracting submatrices from a parallel matrix, each processor can
5471    form a different submatrix by setting the rows and columns of its
5472    individual index sets according to the local submatrix desired.
5473 
5474    When finished using the submatrices, the user should destroy
5475    them with MatDestroyMatrices().
5476 
5477    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5478    original matrix has not changed from that last call to MatGetSubMatrices().
5479 
5480    This routine creates the matrices in submat; you should NOT create them before
5481    calling it. It also allocates the array of matrix pointers submat.
5482 
5483    For BAIJ matrices the index sets must respect the block structure, that is if they
5484    request one row/column in a block, they must request all rows/columns that are in
5485    that block. For example, if the block size is 2 you cannot request just row 0 and
5486    column 0.
5487 
5488    Fortran Note:
5489    The Fortran interface is slightly different from that given below; it
5490    requires one to pass in  as submat a Mat (integer) array of size at least m.
5491 
5492    Level: advanced
5493 
5494    Concepts: matrices^accessing submatrices
5495    Concepts: submatrices
5496 
5497 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5498 @*/
5499 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5500 {
5501   PetscErrorCode ierr;
5502   PetscInt        i;
5503   PetscTruth      eq;
5504 
5505   PetscFunctionBegin;
5506   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5507   PetscValidType(mat,1);
5508   if (n) {
5509     PetscValidPointer(irow,3);
5510     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
5511     PetscValidPointer(icol,4);
5512     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
5513   }
5514   PetscValidPointer(submat,6);
5515   if (n && scall == MAT_REUSE_MATRIX) {
5516     PetscValidPointer(*submat,6);
5517     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
5518   }
5519   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5520   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5521   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5522   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5523 
5524   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5525   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
5526   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5527   for (i=0; i<n; i++) {
5528     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5529       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
5530       if (eq) {
5531 	if (mat->symmetric){
5532 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5533 	} else if (mat->hermitian) {
5534 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
5535 	} else if (mat->structurally_symmetric) {
5536 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5537 	}
5538       }
5539     }
5540   }
5541   PetscFunctionReturn(0);
5542 }
5543 
5544 #undef __FUNCT__
5545 #define __FUNCT__ "MatDestroyMatrices"
5546 /*@C
5547    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5548 
5549    Collective on Mat
5550 
5551    Input Parameters:
5552 +  n - the number of local matrices
5553 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5554                        sequence of MatGetSubMatrices())
5555 
5556    Level: advanced
5557 
5558     Notes: Frees not only the matrices, but also the array that contains the matrices
5559            In Fortran will not free the array.
5560 
5561 .seealso: MatGetSubMatrices()
5562 @*/
5563 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
5564 {
5565   PetscErrorCode ierr;
5566   PetscInt       i;
5567 
5568   PetscFunctionBegin;
5569   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5570   PetscValidPointer(mat,2);
5571   for (i=0; i<n; i++) {
5572     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
5573   }
5574   /* memory is allocated even if n = 0 */
5575   ierr = PetscFree(*mat);CHKERRQ(ierr);
5576   PetscFunctionReturn(0);
5577 }
5578 
5579 #undef __FUNCT__
5580 #define __FUNCT__ "MatGetSeqNonzeroStructure"
5581 /*@C
5582    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5583 
5584    Collective on Mat
5585 
5586    Input Parameters:
5587 .  mat - the matrix
5588 
5589    Output Parameter:
5590 .  matstruct - the sequential matrix with the nonzero structure of mat
5591 
5592   Level: intermediate
5593 
5594 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5595 @*/
5596 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5597 {
5598   PetscErrorCode ierr;
5599 
5600   PetscFunctionBegin;
5601   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5602   PetscValidPointer(matstruct,2);
5603 
5604   PetscValidType(mat,1);
5605   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5606   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5607 
5608   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5609   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
5610   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5611   PetscFunctionReturn(0);
5612 }
5613 
5614 #undef __FUNCT__
5615 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
5616 /*@C
5617    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5618 
5619    Collective on Mat
5620 
5621    Input Parameters:
5622 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5623                        sequence of MatGetSequentialNonzeroStructure())
5624 
5625    Level: advanced
5626 
5627     Notes: Frees not only the matrices, but also the array that contains the matrices
5628 
5629 .seealso: MatGetSeqNonzeroStructure()
5630 @*/
5631 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroySeqNonzeroStructure(Mat *mat[])
5632 {
5633   PetscErrorCode ierr;
5634 
5635   PetscFunctionBegin;
5636   PetscValidPointer(mat,1);
5637   ierr = MatDestroyMatrices(1,mat);CHKERRQ(ierr);
5638   PetscFunctionReturn(0);
5639 }
5640 
5641 #undef __FUNCT__
5642 #define __FUNCT__ "MatIncreaseOverlap"
5643 /*@
5644    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5645    replaces the index sets by larger ones that represent submatrices with
5646    additional overlap.
5647 
5648    Collective on Mat
5649 
5650    Input Parameters:
5651 +  mat - the matrix
5652 .  n   - the number of index sets
5653 .  is  - the array of index sets (these index sets will changed during the call)
5654 -  ov  - the additional overlap requested
5655 
5656    Level: developer
5657 
5658    Concepts: overlap
5659    Concepts: ASM^computing overlap
5660 
5661 .seealso: MatGetSubMatrices()
5662 @*/
5663 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5664 {
5665   PetscErrorCode ierr;
5666 
5667   PetscFunctionBegin;
5668   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5669   PetscValidType(mat,1);
5670   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5671   if (n) {
5672     PetscValidPointer(is,3);
5673     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
5674   }
5675   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5676   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5677   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5678 
5679   if (!ov) PetscFunctionReturn(0);
5680   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5681   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5682   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
5683   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5684   PetscFunctionReturn(0);
5685 }
5686 
5687 #undef __FUNCT__
5688 #define __FUNCT__ "MatGetBlockSize"
5689 /*@
5690    MatGetBlockSize - Returns the matrix block size; useful especially for the
5691    block row and block diagonal formats.
5692 
5693    Not Collective
5694 
5695    Input Parameter:
5696 .  mat - the matrix
5697 
5698    Output Parameter:
5699 .  bs - block size
5700 
5701    Notes:
5702    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5703 
5704    Level: intermediate
5705 
5706    Concepts: matrices^block size
5707 
5708 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5709 @*/
5710 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
5711 {
5712   PetscErrorCode ierr;
5713 
5714   PetscFunctionBegin;
5715   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5716   PetscValidType(mat,1);
5717   PetscValidIntPointer(bs,2);
5718   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5719   *bs = mat->rmap->bs;
5720   PetscFunctionReturn(0);
5721 }
5722 
5723 #undef __FUNCT__
5724 #define __FUNCT__ "MatSetBlockSize"
5725 /*@
5726    MatSetBlockSize - Sets the matrix block size; for many matrix types you
5727      cannot use this and MUST set the blocksize when you preallocate the matrix
5728 
5729    Collective on Mat
5730 
5731    Input Parameters:
5732 +  mat - the matrix
5733 -  bs - block size
5734 
5735    Notes:
5736      Only works for shell and AIJ matrices
5737 
5738    Level: intermediate
5739 
5740    Concepts: matrices^block size
5741 
5742 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5743 @*/
5744 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
5745 {
5746   PetscErrorCode ierr;
5747 
5748   PetscFunctionBegin;
5749   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5750   PetscValidType(mat,1);
5751   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5752   if (mat->ops->setblocksize) {
5753     /* XXX should check if (bs < 1) ??? */
5754     ierr = PetscMapSetBlockSize(mat->rmap,bs);CHKERRQ(ierr);
5755     ierr = PetscMapSetBlockSize(mat->cmap,bs);CHKERRQ(ierr);
5756     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
5757   } else {
5758     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5759   }
5760   PetscFunctionReturn(0);
5761 }
5762 
5763 #undef __FUNCT__
5764 #define __FUNCT__ "MatGetRowIJ"
5765 /*@C
5766     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5767 
5768    Collective on Mat
5769 
5770     Input Parameters:
5771 +   mat - the matrix
5772 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5773 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5774                 symmetrized
5775 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5776                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5777                  nonzero structure which is different than the full nonzero structure]
5778 
5779     Output Parameters:
5780 +   n - number of rows in the (possibly compressed) matrix
5781 .   ia - the row pointers [of length n+1]
5782 .   ja - the column indices
5783 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5784            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5785 
5786     Level: developer
5787 
5788     Notes: You CANNOT change any of the ia[] or ja[] values.
5789 
5790            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5791 
5792     Fortran Node
5793 
5794            In Fortran use
5795 $           PetscInt ia(1), ja(1)
5796 $           PetscOffset iia, jja
5797 $      call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5798 
5799        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5800 
5801 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5802 @*/
5803 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5804 {
5805   PetscErrorCode ierr;
5806 
5807   PetscFunctionBegin;
5808   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5809   PetscValidType(mat,1);
5810   PetscValidIntPointer(n,4);
5811   if (ia) PetscValidIntPointer(ia,5);
5812   if (ja) PetscValidIntPointer(ja,6);
5813   PetscValidIntPointer(done,7);
5814   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5815   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5816   else {
5817     *done = PETSC_TRUE;
5818     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5819     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5820     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5821   }
5822   PetscFunctionReturn(0);
5823 }
5824 
5825 #undef __FUNCT__
5826 #define __FUNCT__ "MatGetColumnIJ"
5827 /*@C
5828     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
5829 
5830     Collective on Mat
5831 
5832     Input Parameters:
5833 +   mat - the matrix
5834 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5835 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5836                 symmetrized
5837 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5838                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5839                  nonzero structure which is different than the full nonzero structure]
5840 
5841     Output Parameters:
5842 +   n - number of columns in the (possibly compressed) matrix
5843 .   ia - the column pointers
5844 .   ja - the row indices
5845 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
5846 
5847     Level: developer
5848 
5849 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5850 @*/
5851 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5852 {
5853   PetscErrorCode ierr;
5854 
5855   PetscFunctionBegin;
5856   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5857   PetscValidType(mat,1);
5858   PetscValidIntPointer(n,4);
5859   if (ia) PetscValidIntPointer(ia,5);
5860   if (ja) PetscValidIntPointer(ja,6);
5861   PetscValidIntPointer(done,7);
5862   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5863   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5864   else {
5865     *done = PETSC_TRUE;
5866     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5867   }
5868   PetscFunctionReturn(0);
5869 }
5870 
5871 #undef __FUNCT__
5872 #define __FUNCT__ "MatRestoreRowIJ"
5873 /*@C
5874     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5875     MatGetRowIJ().
5876 
5877     Collective on Mat
5878 
5879     Input Parameters:
5880 +   mat - the matrix
5881 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5882 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5883                 symmetrized
5884 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5885                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5886                  nonzero structure which is different than the full nonzero structure]
5887 
5888     Output Parameters:
5889 +   n - size of (possibly compressed) matrix
5890 .   ia - the row pointers
5891 .   ja - the column indices
5892 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5893 
5894     Level: developer
5895 
5896 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5897 @*/
5898 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5899 {
5900   PetscErrorCode ierr;
5901 
5902   PetscFunctionBegin;
5903   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5904   PetscValidType(mat,1);
5905   if (ia) PetscValidIntPointer(ia,5);
5906   if (ja) PetscValidIntPointer(ja,6);
5907   PetscValidIntPointer(done,7);
5908   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5909 
5910   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5911   else {
5912     *done = PETSC_TRUE;
5913     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5914   }
5915   PetscFunctionReturn(0);
5916 }
5917 
5918 #undef __FUNCT__
5919 #define __FUNCT__ "MatRestoreColumnIJ"
5920 /*@C
5921     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5922     MatGetColumnIJ().
5923 
5924     Collective on Mat
5925 
5926     Input Parameters:
5927 +   mat - the matrix
5928 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5929 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5930                 symmetrized
5931 -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5932                  blockcompressed matrix is desired or not [inode, baij have blockcompressed
5933                  nonzero structure which is different than the full nonzero structure]
5934 
5935     Output Parameters:
5936 +   n - size of (possibly compressed) matrix
5937 .   ia - the column pointers
5938 .   ja - the row indices
5939 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
5940 
5941     Level: developer
5942 
5943 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5944 @*/
5945 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5946 {
5947   PetscErrorCode ierr;
5948 
5949   PetscFunctionBegin;
5950   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5951   PetscValidType(mat,1);
5952   if (ia) PetscValidIntPointer(ia,5);
5953   if (ja) PetscValidIntPointer(ja,6);
5954   PetscValidIntPointer(done,7);
5955   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5956 
5957   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5958   else {
5959     *done = PETSC_TRUE;
5960     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);CHKERRQ(ierr);
5961   }
5962   PetscFunctionReturn(0);
5963 }
5964 
5965 #undef __FUNCT__
5966 #define __FUNCT__ "MatColoringPatch"
5967 /*@C
5968     MatColoringPatch -Used inside matrix coloring routines that
5969     use MatGetRowIJ() and/or MatGetColumnIJ().
5970 
5971     Collective on Mat
5972 
5973     Input Parameters:
5974 +   mat - the matrix
5975 .   ncolors - max color value
5976 .   n   - number of entries in colorarray
5977 -   colorarray - array indicating color for each column
5978 
5979     Output Parameters:
5980 .   iscoloring - coloring generated using colorarray information
5981 
5982     Level: developer
5983 
5984 .seealso: MatGetRowIJ(), MatGetColumnIJ()
5985 
5986 @*/
5987 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
5988 {
5989   PetscErrorCode ierr;
5990 
5991   PetscFunctionBegin;
5992   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5993   PetscValidType(mat,1);
5994   PetscValidIntPointer(colorarray,4);
5995   PetscValidPointer(iscoloring,5);
5996   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5997 
5998   if (!mat->ops->coloringpatch){
5999     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6000   } else {
6001     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6002   }
6003   PetscFunctionReturn(0);
6004 }
6005 
6006 
6007 #undef __FUNCT__
6008 #define __FUNCT__ "MatSetUnfactored"
6009 /*@
6010    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6011 
6012    Collective on Mat
6013 
6014    Input Parameter:
6015 .  mat - the factored matrix to be reset
6016 
6017    Notes:
6018    This routine should be used only with factored matrices formed by in-place
6019    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6020    format).  This option can save memory, for example, when solving nonlinear
6021    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6022    ILU(0) preconditioner.
6023 
6024    Note that one can specify in-place ILU(0) factorization by calling
6025 .vb
6026      PCType(pc,PCILU);
6027      PCFactorSeUseInPlace(pc);
6028 .ve
6029    or by using the options -pc_type ilu -pc_factor_in_place
6030 
6031    In-place factorization ILU(0) can also be used as a local
6032    solver for the blocks within the block Jacobi or additive Schwarz
6033    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6034    of these preconditioners in the users manual for details on setting
6035    local solver options.
6036 
6037    Most users should employ the simplified KSP interface for linear solvers
6038    instead of working directly with matrix algebra routines such as this.
6039    See, e.g., KSPCreate().
6040 
6041    Level: developer
6042 
6043 .seealso: PCFactorSetUseInPlace()
6044 
6045    Concepts: matrices^unfactored
6046 
6047 @*/
6048 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
6049 {
6050   PetscErrorCode ierr;
6051 
6052   PetscFunctionBegin;
6053   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6054   PetscValidType(mat,1);
6055   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6056   mat->factor = MAT_FACTOR_NONE;
6057   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6058   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6059   PetscFunctionReturn(0);
6060 }
6061 
6062 /*MC
6063     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6064 
6065     Synopsis:
6066     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6067 
6068     Not collective
6069 
6070     Input Parameter:
6071 .   x - matrix
6072 
6073     Output Parameters:
6074 +   xx_v - the Fortran90 pointer to the array
6075 -   ierr - error code
6076 
6077     Example of Usage:
6078 .vb
6079       PetscScalar, pointer xx_v(:)
6080       ....
6081       call MatGetArrayF90(x,xx_v,ierr)
6082       a = xx_v(3)
6083       call MatRestoreArrayF90(x,xx_v,ierr)
6084 .ve
6085 
6086     Notes:
6087     Not yet supported for all F90 compilers
6088 
6089     Level: advanced
6090 
6091 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6092 
6093     Concepts: matrices^accessing array
6094 
6095 M*/
6096 
6097 /*MC
6098     MatRestoreArrayF90 - Restores a matrix array that has been
6099     accessed with MatGetArrayF90().
6100 
6101     Synopsis:
6102     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6103 
6104     Not collective
6105 
6106     Input Parameters:
6107 +   x - matrix
6108 -   xx_v - the Fortran90 pointer to the array
6109 
6110     Output Parameter:
6111 .   ierr - error code
6112 
6113     Example of Usage:
6114 .vb
6115        PetscScalar, pointer xx_v(:)
6116        ....
6117        call MatGetArrayF90(x,xx_v,ierr)
6118        a = xx_v(3)
6119        call MatRestoreArrayF90(x,xx_v,ierr)
6120 .ve
6121 
6122     Notes:
6123     Not yet supported for all F90 compilers
6124 
6125     Level: advanced
6126 
6127 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6128 
6129 M*/
6130 
6131 
6132 #undef __FUNCT__
6133 #define __FUNCT__ "MatGetSubMatrix"
6134 /*@
6135     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6136                       as the original matrix.
6137 
6138     Collective on Mat
6139 
6140     Input Parameters:
6141 +   mat - the original matrix
6142 .   isrow - rows this processor should obtain
6143 .   iscol - columns for all processors you wish to keep
6144 .   csize - number of columns "local" to this processor (does nothing for sequential
6145             matrices). This should match the result from VecGetLocalSize(x,...) if you
6146             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6147 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6148 
6149     Output Parameter:
6150 .   newmat - the new submatrix, of the same type as the old
6151 
6152     Level: advanced
6153 
6154     Notes: the iscol argument MUST be the same on each processor. You might be
6155     able to create the iscol argument with ISAllGather(). The rows is isrow will be
6156     sorted into the same order as the original matrix.
6157 
6158       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6159    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6160    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6161    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
6162    you are finished using it.
6163 
6164     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6165     the input matrix.
6166 
6167     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran), you should
6168     use csize = PETSC_DECIDE also in this case.
6169 
6170     Concepts: matrices^submatrices
6171 
6172 .seealso: MatGetSubMatrices(), ISAllGather()
6173 @*/
6174 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
6175 {
6176   PetscErrorCode ierr;
6177   PetscMPIInt    size;
6178   Mat            *local;
6179   IS             iscoltmp;
6180 
6181   PetscFunctionBegin;
6182   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6183   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
6184   if (iscol) PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
6185   PetscValidPointer(newmat,6);
6186   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
6187   PetscValidType(mat,1);
6188   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6189   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6190   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6191 
6192   if (!iscol) {
6193     if (csize == PETSC_DECIDE) csize = mat->cmap->n;
6194     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->N,0,1,&iscoltmp);CHKERRQ(ierr);
6195   } else {
6196     iscoltmp = iscol;
6197   }
6198 
6199   /* if original matrix is on just one processor then use submatrix generated */
6200   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6201     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
6202     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6203     PetscFunctionReturn(0);
6204   } else if (!mat->ops->getsubmatrix && size == 1) {
6205     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
6206     *newmat = *local;
6207     ierr    = PetscFree(local);CHKERRQ(ierr);
6208     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6209     PetscFunctionReturn(0);
6210   }
6211 
6212   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6213   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,csize,cll,newmat);CHKERRQ(ierr);
6214   if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6215   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
6216   PetscFunctionReturn(0);
6217 }
6218 
6219 #undef __FUNCT__
6220 #define __FUNCT__ "MatGetSubMatrixRaw"
6221 /*@
6222     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
6223                          as the original matrix.
6224 
6225     Collective on Mat
6226 
6227     Input Parameters:
6228 +   mat - the original matrix
6229 .   nrows - the number of rows this processor should obtain
6230 .   rows - rows this processor should obtain
6231 .   ncols - the number of columns for all processors you wish to keep
6232 .   cols - columns for all processors you wish to keep
6233 .   csize - number of columns "local" to this processor (does nothing for sequential
6234             matrices). This should match the result from VecGetLocalSize(x,...) if you
6235             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6236 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6237 
6238     Output Parameter:
6239 .   newmat - the new submatrix, of the same type as the old
6240 
6241     Level: advanced
6242 
6243     Notes: the iscol argument MUST be the same on each processor. You might be
6244     able to create the iscol argument with ISAllGather().
6245 
6246       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6247    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6248    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX
6249    will reuse the matrix generated the first time.
6250 
6251     Concepts: matrices^submatrices
6252 
6253 .seealso: MatGetSubMatrices(), ISAllGather()
6254 @*/
6255 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6256 {
6257   IS             isrow, iscol;
6258   PetscErrorCode ierr;
6259 
6260   PetscFunctionBegin;
6261   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6262   PetscValidIntPointer(rows,2);
6263   PetscValidIntPointer(cols,3);
6264   PetscValidPointer(newmat,6);
6265   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,6);
6266   PetscValidType(mat,1);
6267   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6268   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6269   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);CHKERRQ(ierr);
6270   ierr = ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);CHKERRQ(ierr);
6271   ierr = MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);CHKERRQ(ierr);
6272   ierr = ISDestroy(isrow);CHKERRQ(ierr);
6273   ierr = ISDestroy(iscol);CHKERRQ(ierr);
6274   PetscFunctionReturn(0);
6275 }
6276 
6277 #undef __FUNCT__
6278 #define __FUNCT__ "MatStashSetInitialSize"
6279 /*@
6280    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6281    used during the assembly process to store values that belong to
6282    other processors.
6283 
6284    Not Collective
6285 
6286    Input Parameters:
6287 +  mat   - the matrix
6288 .  size  - the initial size of the stash.
6289 -  bsize - the initial size of the block-stash(if used).
6290 
6291    Options Database Keys:
6292 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6293 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
6294 
6295    Level: intermediate
6296 
6297    Notes:
6298      The block-stash is used for values set with MatSetValuesBlocked() while
6299      the stash is used for values set with MatSetValues()
6300 
6301      Run with the option -info and look for output of the form
6302      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6303      to determine the appropriate value, MM, to use for size and
6304      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6305      to determine the value, BMM to use for bsize
6306 
6307    Concepts: stash^setting matrix size
6308    Concepts: matrices^stash
6309 
6310 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
6311 
6312 @*/
6313 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6314 {
6315   PetscErrorCode ierr;
6316 
6317   PetscFunctionBegin;
6318   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6319   PetscValidType(mat,1);
6320   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
6321   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
6322   PetscFunctionReturn(0);
6323 }
6324 
6325 #undef __FUNCT__
6326 #define __FUNCT__ "MatInterpolateAdd"
6327 /*@
6328    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6329      the matrix
6330 
6331    Collective on Mat
6332 
6333    Input Parameters:
6334 +  mat   - the matrix
6335 .  x,y - the vectors
6336 -  w - where the result is stored
6337 
6338    Level: intermediate
6339 
6340    Notes:
6341     w may be the same vector as y.
6342 
6343     This allows one to use either the restriction or interpolation (its transpose)
6344     matrix to do the interpolation
6345 
6346     Concepts: interpolation
6347 
6348 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6349 
6350 @*/
6351 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6352 {
6353   PetscErrorCode ierr;
6354   PetscInt       M,N;
6355 
6356   PetscFunctionBegin;
6357   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6358   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6359   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6360   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
6361   PetscValidType(A,1);
6362   ierr = MatPreallocated(A);CHKERRQ(ierr);
6363   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6364   if (N > M) {
6365     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
6366   } else {
6367     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
6368   }
6369   PetscFunctionReturn(0);
6370 }
6371 
6372 #undef __FUNCT__
6373 #define __FUNCT__ "MatInterpolate"
6374 /*@
6375    MatInterpolate - y = A*x or A'*x depending on the shape of
6376      the matrix
6377 
6378    Collective on Mat
6379 
6380    Input Parameters:
6381 +  mat   - the matrix
6382 -  x,y - the vectors
6383 
6384    Level: intermediate
6385 
6386    Notes:
6387     This allows one to use either the restriction or interpolation (its transpose)
6388     matrix to do the interpolation
6389 
6390    Concepts: matrices^interpolation
6391 
6392 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6393 
6394 @*/
6395 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
6396 {
6397   PetscErrorCode ierr;
6398   PetscInt       M,N;
6399 
6400   PetscFunctionBegin;
6401   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6402   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6403   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6404   PetscValidType(A,1);
6405   ierr = MatPreallocated(A);CHKERRQ(ierr);
6406   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6407   if (N > M) {
6408     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6409   } else {
6410     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6411   }
6412   PetscFunctionReturn(0);
6413 }
6414 
6415 #undef __FUNCT__
6416 #define __FUNCT__ "MatRestrict"
6417 /*@
6418    MatRestrict - y = A*x or A'*x
6419 
6420    Collective on Mat
6421 
6422    Input Parameters:
6423 +  mat   - the matrix
6424 -  x,y - the vectors
6425 
6426    Level: intermediate
6427 
6428    Notes:
6429     This allows one to use either the restriction or interpolation (its transpose)
6430     matrix to do the restriction
6431 
6432    Concepts: matrices^restriction
6433 
6434 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6435 
6436 @*/
6437 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
6438 {
6439   PetscErrorCode ierr;
6440   PetscInt       M,N;
6441 
6442   PetscFunctionBegin;
6443   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6444   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6445   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6446   PetscValidType(A,1);
6447   ierr = MatPreallocated(A);CHKERRQ(ierr);
6448 
6449   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6450   if (N > M) {
6451     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6452   } else {
6453     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6454   }
6455   PetscFunctionReturn(0);
6456 }
6457 
6458 #undef __FUNCT__
6459 #define __FUNCT__ "MatNullSpaceAttach"
6460 /*@
6461    MatNullSpaceAttach - attaches a null space to a matrix.
6462         This null space will be removed from the resulting vector whenever
6463         MatMult() is called
6464 
6465    Collective on Mat
6466 
6467    Input Parameters:
6468 +  mat - the matrix
6469 -  nullsp - the null space object
6470 
6471    Level: developer
6472 
6473    Notes:
6474       Overwrites any previous null space that may have been attached
6475 
6476    Concepts: null space^attaching to matrix
6477 
6478 .seealso: MatCreate(), MatNullSpaceCreate()
6479 @*/
6480 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6481 {
6482   PetscErrorCode ierr;
6483 
6484   PetscFunctionBegin;
6485   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6486   PetscValidType(mat,1);
6487   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
6488   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6489   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
6490   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
6491   mat->nullsp = nullsp;
6492   PetscFunctionReturn(0);
6493 }
6494 
6495 #undef __FUNCT__
6496 #define __FUNCT__ "MatICCFactor"
6497 /*@
6498    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6499 
6500    Collective on Mat
6501 
6502    Input Parameters:
6503 +  mat - the matrix
6504 .  row - row/column permutation
6505 .  fill - expected fill factor >= 1.0
6506 -  level - level of fill, for ICC(k)
6507 
6508    Notes:
6509    Probably really in-place only when level of fill is zero, otherwise allocates
6510    new space to store factored matrix and deletes previous memory.
6511 
6512    Most users should employ the simplified KSP interface for linear solvers
6513    instead of working directly with matrix algebra routines such as this.
6514    See, e.g., KSPCreate().
6515 
6516    Level: developer
6517 
6518    Concepts: matrices^incomplete Cholesky factorization
6519    Concepts: Cholesky factorization
6520 
6521 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6522 @*/
6523 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6524 {
6525   PetscErrorCode ierr;
6526 
6527   PetscFunctionBegin;
6528   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6529   PetscValidType(mat,1);
6530   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
6531   PetscValidPointer(info,3);
6532   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6533   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6534   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6535   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6536   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6537   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
6538   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6539   PetscFunctionReturn(0);
6540 }
6541 
6542 #undef __FUNCT__
6543 #define __FUNCT__ "MatSetValuesAdic"
6544 /*@
6545    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6546 
6547    Not Collective
6548 
6549    Input Parameters:
6550 +  mat - the matrix
6551 -  v - the values compute with ADIC
6552 
6553    Level: developer
6554 
6555    Notes:
6556      Must call MatSetColoring() before using this routine. Also this matrix must already
6557      have its nonzero pattern determined.
6558 
6559 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6560           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6561 @*/
6562 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
6563 {
6564   PetscErrorCode ierr;
6565 
6566   PetscFunctionBegin;
6567   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6568   PetscValidType(mat,1);
6569   PetscValidPointer(mat,2);
6570 
6571   if (!mat->assembled) {
6572     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6573   }
6574   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6575   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6576   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
6577   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6578   ierr = MatView_Private(mat);CHKERRQ(ierr);
6579   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6580   PetscFunctionReturn(0);
6581 }
6582 
6583 
6584 #undef __FUNCT__
6585 #define __FUNCT__ "MatSetColoring"
6586 /*@
6587    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6588 
6589    Not Collective
6590 
6591    Input Parameters:
6592 +  mat - the matrix
6593 -  coloring - the coloring
6594 
6595    Level: developer
6596 
6597 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6598           MatSetValues(), MatSetValuesAdic()
6599 @*/
6600 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
6601 {
6602   PetscErrorCode ierr;
6603 
6604   PetscFunctionBegin;
6605   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6606   PetscValidType(mat,1);
6607   PetscValidPointer(coloring,2);
6608 
6609   if (!mat->assembled) {
6610     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6611   }
6612   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6613   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
6614   PetscFunctionReturn(0);
6615 }
6616 
6617 #undef __FUNCT__
6618 #define __FUNCT__ "MatSetValuesAdifor"
6619 /*@
6620    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6621 
6622    Not Collective
6623 
6624    Input Parameters:
6625 +  mat - the matrix
6626 .  nl - leading dimension of v
6627 -  v - the values compute with ADIFOR
6628 
6629    Level: developer
6630 
6631    Notes:
6632      Must call MatSetColoring() before using this routine. Also this matrix must already
6633      have its nonzero pattern determined.
6634 
6635 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6636           MatSetValues(), MatSetColoring()
6637 @*/
6638 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6639 {
6640   PetscErrorCode ierr;
6641 
6642   PetscFunctionBegin;
6643   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6644   PetscValidType(mat,1);
6645   PetscValidPointer(v,3);
6646 
6647   if (!mat->assembled) {
6648     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6649   }
6650   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6651   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6652   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
6653   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6654   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6655   PetscFunctionReturn(0);
6656 }
6657 
6658 #undef __FUNCT__
6659 #define __FUNCT__ "MatDiagonalScaleLocal"
6660 /*@
6661    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6662          ghosted ones.
6663 
6664    Not Collective
6665 
6666    Input Parameters:
6667 +  mat - the matrix
6668 -  diag = the diagonal values, including ghost ones
6669 
6670    Level: developer
6671 
6672    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6673 
6674 .seealso: MatDiagonalScale()
6675 @*/
6676 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
6677 {
6678   PetscErrorCode ierr;
6679   PetscMPIInt    size;
6680 
6681   PetscFunctionBegin;
6682   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6683   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
6684   PetscValidType(mat,1);
6685 
6686   if (!mat->assembled) {
6687     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6688   }
6689   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6690   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6691   if (size == 1) {
6692     PetscInt n,m;
6693     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
6694     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
6695     if (m == n) {
6696       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
6697     } else {
6698       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6699     }
6700   } else {
6701     PetscErrorCode (*f)(Mat,Vec);
6702     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
6703     if (f) {
6704       ierr = (*f)(mat,diag);CHKERRQ(ierr);
6705     } else {
6706       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6707     }
6708   }
6709   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6710   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6711   PetscFunctionReturn(0);
6712 }
6713 
6714 #undef __FUNCT__
6715 #define __FUNCT__ "MatGetInertia"
6716 /*@
6717    MatGetInertia - Gets the inertia from a factored matrix
6718 
6719    Collective on Mat
6720 
6721    Input Parameter:
6722 .  mat - the matrix
6723 
6724    Output Parameters:
6725 +   nneg - number of negative eigenvalues
6726 .   nzero - number of zero eigenvalues
6727 -   npos - number of positive eigenvalues
6728 
6729    Level: advanced
6730 
6731    Notes: Matrix must have been factored by MatCholeskyFactor()
6732 
6733 
6734 @*/
6735 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6736 {
6737   PetscErrorCode ierr;
6738 
6739   PetscFunctionBegin;
6740   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6741   PetscValidType(mat,1);
6742   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6743   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6744   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6745   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
6746   PetscFunctionReturn(0);
6747 }
6748 
6749 /* ----------------------------------------------------------------*/
6750 #undef __FUNCT__
6751 #define __FUNCT__ "MatSolves"
6752 /*@C
6753    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6754 
6755    Collective on Mat and Vecs
6756 
6757    Input Parameters:
6758 +  mat - the factored matrix
6759 -  b - the right-hand-side vectors
6760 
6761    Output Parameter:
6762 .  x - the result vectors
6763 
6764    Notes:
6765    The vectors b and x cannot be the same.  I.e., one cannot
6766    call MatSolves(A,x,x).
6767 
6768    Notes:
6769    Most users should employ the simplified KSP interface for linear solvers
6770    instead of working directly with matrix algebra routines such as this.
6771    See, e.g., KSPCreate().
6772 
6773    Level: developer
6774 
6775    Concepts: matrices^triangular solves
6776 
6777 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6778 @*/
6779 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6780 {
6781   PetscErrorCode ierr;
6782 
6783   PetscFunctionBegin;
6784   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6785   PetscValidType(mat,1);
6786   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6787   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6788   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
6789 
6790   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6791   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6792   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6793   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6794   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6795   PetscFunctionReturn(0);
6796 }
6797 
6798 #undef __FUNCT__
6799 #define __FUNCT__ "MatIsSymmetric"
6800 /*@
6801    MatIsSymmetric - Test whether a matrix is symmetric
6802 
6803    Collective on Mat
6804 
6805    Input Parameter:
6806 +  A - the matrix to test
6807 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6808 
6809    Output Parameters:
6810 .  flg - the result
6811 
6812    Level: intermediate
6813 
6814    Concepts: matrix^symmetry
6815 
6816 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6817 @*/
6818 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6819 {
6820   PetscErrorCode ierr;
6821 
6822   PetscFunctionBegin;
6823   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6824   PetscValidPointer(flg,2);
6825   if (!A->symmetric_set) {
6826     if (!A->ops->issymmetric) {
6827       const MatType mattype;
6828       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6829       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6830     }
6831     ierr = (*A->ops->issymmetric)(A,tol,&A->symmetric);CHKERRQ(ierr);
6832     A->symmetric_set = PETSC_TRUE;
6833     if (A->symmetric) {
6834       A->structurally_symmetric_set = PETSC_TRUE;
6835       A->structurally_symmetric     = PETSC_TRUE;
6836     }
6837   }
6838   *flg = A->symmetric;
6839   PetscFunctionReturn(0);
6840 }
6841 
6842 #undef __FUNCT__
6843 #define __FUNCT__ "MatIsHermitian"
6844 /*@
6845    MatIsHermitian - Test whether a matrix is Hermitian
6846 
6847    Collective on Mat
6848 
6849    Input Parameter:
6850 +  A - the matrix to test
6851 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
6852 
6853    Output Parameters:
6854 .  flg - the result
6855 
6856    Level: intermediate
6857 
6858    Concepts: matrix^symmetry
6859 
6860 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6861 @*/
6862 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6863 {
6864   PetscErrorCode ierr;
6865 
6866   PetscFunctionBegin;
6867   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6868   PetscValidPointer(flg,2);
6869   if (!A->hermitian_set) {
6870     if (!A->ops->ishermitian) {
6871       const MatType mattype;
6872       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6873       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6874     }
6875     ierr = (*A->ops->ishermitian)(A,tol,&A->hermitian);CHKERRQ(ierr);
6876     A->hermitian_set = PETSC_TRUE;
6877     if (A->hermitian) {
6878       A->structurally_symmetric_set = PETSC_TRUE;
6879       A->structurally_symmetric     = PETSC_TRUE;
6880     }
6881   }
6882   *flg = A->hermitian;
6883   PetscFunctionReturn(0);
6884 }
6885 
6886 #undef __FUNCT__
6887 #define __FUNCT__ "MatIsSymmetricKnown"
6888 /*@
6889    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
6890 
6891    Collective on Mat
6892 
6893    Input Parameter:
6894 .  A - the matrix to check
6895 
6896    Output Parameters:
6897 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6898 -  flg - the result
6899 
6900    Level: advanced
6901 
6902    Concepts: matrix^symmetry
6903 
6904    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
6905          if you want it explicitly checked
6906 
6907 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6908 @*/
6909 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6910 {
6911   PetscFunctionBegin;
6912   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6913   PetscValidPointer(set,2);
6914   PetscValidPointer(flg,3);
6915   if (A->symmetric_set) {
6916     *set = PETSC_TRUE;
6917     *flg = A->symmetric;
6918   } else {
6919     *set = PETSC_FALSE;
6920   }
6921   PetscFunctionReturn(0);
6922 }
6923 
6924 #undef __FUNCT__
6925 #define __FUNCT__ "MatIsHermitianKnown"
6926 /*@
6927    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
6928 
6929    Collective on Mat
6930 
6931    Input Parameter:
6932 .  A - the matrix to check
6933 
6934    Output Parameters:
6935 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6936 -  flg - the result
6937 
6938    Level: advanced
6939 
6940    Concepts: matrix^symmetry
6941 
6942    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
6943          if you want it explicitly checked
6944 
6945 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6946 @*/
6947 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6948 {
6949   PetscFunctionBegin;
6950   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6951   PetscValidPointer(set,2);
6952   PetscValidPointer(flg,3);
6953   if (A->hermitian_set) {
6954     *set = PETSC_TRUE;
6955     *flg = A->hermitian;
6956   } else {
6957     *set = PETSC_FALSE;
6958   }
6959   PetscFunctionReturn(0);
6960 }
6961 
6962 #undef __FUNCT__
6963 #define __FUNCT__ "MatIsStructurallySymmetric"
6964 /*@
6965    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
6966 
6967    Collective on Mat
6968 
6969    Input Parameter:
6970 .  A - the matrix to test
6971 
6972    Output Parameters:
6973 .  flg - the result
6974 
6975    Level: intermediate
6976 
6977    Concepts: matrix^symmetry
6978 
6979 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
6980 @*/
6981 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
6982 {
6983   PetscErrorCode ierr;
6984 
6985   PetscFunctionBegin;
6986   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6987   PetscValidPointer(flg,2);
6988   if (!A->structurally_symmetric_set) {
6989     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
6990     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
6991     A->structurally_symmetric_set = PETSC_TRUE;
6992   }
6993   *flg = A->structurally_symmetric;
6994   PetscFunctionReturn(0);
6995 }
6996 
6997 #undef __FUNCT__
6998 #define __FUNCT__ "MatStashGetInfo"
6999 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7000 /*@
7001    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7002        to be communicated to other processors during the MatAssemblyBegin/End() process
7003 
7004     Not collective
7005 
7006    Input Parameter:
7007 .   vec - the vector
7008 
7009    Output Parameters:
7010 +   nstash   - the size of the stash
7011 .   reallocs - the number of additional mallocs incurred.
7012 .   bnstash   - the size of the block stash
7013 -   breallocs - the number of additional mallocs incurred.in the block stash
7014 
7015    Level: advanced
7016 
7017 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7018 
7019 @*/
7020 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7021 {
7022   PetscErrorCode ierr;
7023   PetscFunctionBegin;
7024   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7025   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7026   PetscFunctionReturn(0);
7027 }
7028 
7029 #undef __FUNCT__
7030 #define __FUNCT__ "MatGetVecs"
7031 /*@C
7032    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7033      parallel layout
7034 
7035    Collective on Mat
7036 
7037    Input Parameter:
7038 .  mat - the matrix
7039 
7040    Output Parameter:
7041 +   right - (optional) vector that the matrix can be multiplied against
7042 -   left - (optional) vector that the matrix vector product can be stored in
7043 
7044   Level: advanced
7045 
7046 .seealso: MatCreate()
7047 @*/
7048 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
7049 {
7050   PetscErrorCode ierr;
7051 
7052   PetscFunctionBegin;
7053   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7054   PetscValidType(mat,1);
7055   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7056   if (mat->ops->getvecs) {
7057     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7058   } else {
7059     PetscMPIInt size;
7060     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7061     if (right) {
7062       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7063       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7064       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7065       if (size > 1) {
7066         /* New vectors uses Mat cmap and does not create a new one */
7067 	ierr = PetscMapDestroy((*right)->map);CHKERRQ(ierr);
7068 	(*right)->map = mat->cmap;
7069 	mat->cmap->refcnt++;
7070 
7071         ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);
7072       } else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
7073     }
7074     if (left) {
7075       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7076       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7077       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7078       if (size > 1) {
7079         /* New vectors uses Mat rmap and does not create a new one */
7080 	ierr = PetscMapDestroy((*left)->map);CHKERRQ(ierr);
7081 	(*left)->map = mat->rmap;
7082 	mat->rmap->refcnt++;
7083 
7084         ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);
7085       } else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
7086     }
7087   }
7088   if (mat->mapping) {
7089     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->mapping);CHKERRQ(ierr);}
7090     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->mapping);CHKERRQ(ierr);}
7091   }
7092   if (mat->bmapping) {
7093     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);CHKERRQ(ierr);}
7094     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);CHKERRQ(ierr);}
7095   }
7096   PetscFunctionReturn(0);
7097 }
7098 
7099 #undef __FUNCT__
7100 #define __FUNCT__ "MatFactorInfoInitialize"
7101 /*@
7102    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7103      with default values.
7104 
7105    Not Collective
7106 
7107    Input Parameters:
7108 .    info - the MatFactorInfo data structure
7109 
7110 
7111    Notes: The solvers are generally used through the KSP and PC objects, for example
7112           PCLU, PCILU, PCCHOLESKY, PCICC
7113 
7114    Level: developer
7115 
7116 .seealso: MatFactorInfo
7117 @*/
7118 
7119 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
7120 {
7121   PetscErrorCode ierr;
7122 
7123   PetscFunctionBegin;
7124   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
7125   PetscFunctionReturn(0);
7126 }
7127 
7128 #undef __FUNCT__
7129 #define __FUNCT__ "MatPtAP"
7130 /*@
7131    MatPtAP - Creates the matrix projection C = P^T * A * P
7132 
7133    Collective on Mat
7134 
7135    Input Parameters:
7136 +  A - the matrix
7137 .  P - the projection matrix
7138 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7139 -  fill - expected fill as ratio of nnz(C)/nnz(A)
7140 
7141    Output Parameters:
7142 .  C - the product matrix
7143 
7144    Notes:
7145    C will be created and must be destroyed by the user with MatDestroy().
7146 
7147    This routine is currently only implemented for pairs of AIJ matrices and classes
7148    which inherit from AIJ.
7149 
7150    Level: intermediate
7151 
7152 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7153 @*/
7154 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7155 {
7156   PetscErrorCode ierr;
7157 
7158   PetscFunctionBegin;
7159   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7160   PetscValidType(A,1);
7161   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7162   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7163   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7164   PetscValidType(P,2);
7165   ierr = MatPreallocated(P);CHKERRQ(ierr);
7166   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7167   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7168   PetscValidPointer(C,3);
7169   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7170   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7171   ierr = MatPreallocated(A);CHKERRQ(ierr);
7172 
7173   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7174   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
7175   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7176 
7177   PetscFunctionReturn(0);
7178 }
7179 
7180 #undef __FUNCT__
7181 #define __FUNCT__ "MatPtAPNumeric"
7182 /*@
7183    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
7184 
7185    Collective on Mat
7186 
7187    Input Parameters:
7188 +  A - the matrix
7189 -  P - the projection matrix
7190 
7191    Output Parameters:
7192 .  C - the product matrix
7193 
7194    Notes:
7195    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7196    the user using MatDeatroy().
7197 
7198    This routine is currently only implemented for pairs of AIJ matrices and classes
7199    which inherit from AIJ.  C will be of type MATAIJ.
7200 
7201    Level: intermediate
7202 
7203 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7204 @*/
7205 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
7206 {
7207   PetscErrorCode ierr;
7208 
7209   PetscFunctionBegin;
7210   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7211   PetscValidType(A,1);
7212   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7213   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7214   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7215   PetscValidType(P,2);
7216   ierr = MatPreallocated(P);CHKERRQ(ierr);
7217   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7218   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7219   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
7220   PetscValidType(C,3);
7221   ierr = MatPreallocated(C);CHKERRQ(ierr);
7222   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7223   if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7224   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7225   if (A->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
7226   if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7227   ierr = MatPreallocated(A);CHKERRQ(ierr);
7228 
7229   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7230   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
7231   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7232   PetscFunctionReturn(0);
7233 }
7234 
7235 #undef __FUNCT__
7236 #define __FUNCT__ "MatPtAPSymbolic"
7237 /*@
7238    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
7239 
7240    Collective on Mat
7241 
7242    Input Parameters:
7243 +  A - the matrix
7244 -  P - the projection matrix
7245 
7246    Output Parameters:
7247 .  C - the (i,j) structure of the product matrix
7248 
7249    Notes:
7250    C will be created and must be destroyed by the user with MatDestroy().
7251 
7252    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7253    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
7254    this (i,j) structure by calling MatPtAPNumeric().
7255 
7256    Level: intermediate
7257 
7258 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7259 @*/
7260 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7261 {
7262   PetscErrorCode ierr;
7263 
7264   PetscFunctionBegin;
7265   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7266   PetscValidType(A,1);
7267   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7268   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7269   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7270   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7271   PetscValidType(P,2);
7272   ierr = MatPreallocated(P);CHKERRQ(ierr);
7273   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7274   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7275   PetscValidPointer(C,3);
7276 
7277   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7278   if (A->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
7279   ierr = MatPreallocated(A);CHKERRQ(ierr);
7280   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7281   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
7282   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7283 
7284   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
7285 
7286   PetscFunctionReturn(0);
7287 }
7288 
7289 #undef __FUNCT__
7290 #define __FUNCT__ "MatMatMult"
7291 /*@
7292    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7293 
7294    Collective on Mat
7295 
7296    Input Parameters:
7297 +  A - the left matrix
7298 .  B - the right matrix
7299 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7300 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7301           if the result is a dense matrix this is irrelevent
7302 
7303    Output Parameters:
7304 .  C - the product matrix
7305 
7306    Notes:
7307    Unless scall is MAT_REUSE_MATRIX C will be created.
7308 
7309    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7310 
7311    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7312    actually needed.
7313 
7314    If you have many matrices with the same non-zero structure to multiply, you
7315    should either
7316 $   1) use MAT_REUSE_MATRIX in all calls but the first or
7317 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7318 
7319    Level: intermediate
7320 
7321 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7322 @*/
7323 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7324 {
7325   PetscErrorCode ierr;
7326   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7327   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7328   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7329 
7330   PetscFunctionBegin;
7331   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7332   PetscValidType(A,1);
7333   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7334   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7335   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7336   PetscValidType(B,2);
7337   ierr = MatPreallocated(B);CHKERRQ(ierr);
7338   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7339   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7340   PetscValidPointer(C,3);
7341   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7342   if (scall == MAT_REUSE_MATRIX){
7343     PetscValidPointer(*C,5);
7344     PetscValidHeaderSpecific(*C,MAT_COOKIE,5);
7345   }
7346   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7347   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7348   ierr = MatPreallocated(A);CHKERRQ(ierr);
7349 
7350   fA = A->ops->matmult;
7351   fB = B->ops->matmult;
7352   if (fB == fA) {
7353     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7354     mult = fB;
7355   } else {
7356     /* dispatch based on the type of A and B */
7357     char  multname[256];
7358     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
7359     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7360     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
7361     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7362     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7363     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
7364     if (!mult) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7365   }
7366   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7367   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
7368   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7369   PetscFunctionReturn(0);
7370 }
7371 
7372 #undef __FUNCT__
7373 #define __FUNCT__ "MatMatMultSymbolic"
7374 /*@
7375    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7376    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
7377 
7378    Collective on Mat
7379 
7380    Input Parameters:
7381 +  A - the left matrix
7382 .  B - the right matrix
7383 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7384       if C is a dense matrix this is irrelevent
7385 
7386    Output Parameters:
7387 .  C - the product matrix
7388 
7389    Notes:
7390    Unless scall is MAT_REUSE_MATRIX C will be created.
7391 
7392    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7393    actually needed.
7394 
7395    This routine is currently implemented for
7396     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7397     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7398     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7399 
7400    Level: intermediate
7401 
7402 .seealso: MatMatMult(), MatMatMultNumeric()
7403 @*/
7404 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7405 {
7406   PetscErrorCode ierr;
7407   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7408   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7409   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7410 
7411   PetscFunctionBegin;
7412   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7413   PetscValidType(A,1);
7414   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7415   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7416 
7417   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7418   PetscValidType(B,2);
7419   ierr = MatPreallocated(B);CHKERRQ(ierr);
7420   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7421   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7422   PetscValidPointer(C,3);
7423 
7424   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7425   if (fill == PETSC_DEFAULT) fill = 2.0;
7426   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7427   ierr = MatPreallocated(A);CHKERRQ(ierr);
7428 
7429   Asymbolic = A->ops->matmultsymbolic;
7430   Bsymbolic = B->ops->matmultsymbolic;
7431   if (Asymbolic == Bsymbolic){
7432     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7433     symbolic = Bsymbolic;
7434   } else { /* dispatch based on the type of A and B */
7435     char  symbolicname[256];
7436     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
7437     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7438     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
7439     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7440     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
7441     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
7442     if (!symbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7443   }
7444   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7445   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
7446   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7447   PetscFunctionReturn(0);
7448 }
7449 
7450 #undef __FUNCT__
7451 #define __FUNCT__ "MatMatMultNumeric"
7452 /*@
7453    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7454    Call this routine after first calling MatMatMultSymbolic().
7455 
7456    Collective on Mat
7457 
7458    Input Parameters:
7459 +  A - the left matrix
7460 -  B - the right matrix
7461 
7462    Output Parameters:
7463 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7464 
7465    Notes:
7466    C must have been created with MatMatMultSymbolic().
7467 
7468    This routine is currently implemented for
7469     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7470     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7471     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7472 
7473    Level: intermediate
7474 
7475 .seealso: MatMatMult(), MatMatMultSymbolic()
7476 @*/
7477 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
7478 {
7479   PetscErrorCode ierr;
7480   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7481   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7482   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7483 
7484   PetscFunctionBegin;
7485   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7486   PetscValidType(A,1);
7487   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7488   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7489 
7490   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7491   PetscValidType(B,2);
7492   ierr = MatPreallocated(B);CHKERRQ(ierr);
7493   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7494   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7495 
7496   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
7497   PetscValidType(C,3);
7498   ierr = MatPreallocated(C);CHKERRQ(ierr);
7499   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7500   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7501 
7502   if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7503   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7504   if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7505   ierr = MatPreallocated(A);CHKERRQ(ierr);
7506 
7507   Anumeric = A->ops->matmultnumeric;
7508   Bnumeric = B->ops->matmultnumeric;
7509   if (Anumeric == Bnumeric){
7510     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7511     numeric = Bnumeric;
7512   } else {
7513     char  numericname[256];
7514     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
7515     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7516     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
7517     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7518     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
7519     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
7520     if (!numeric)
7521       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7522   }
7523   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7524   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
7525   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7526   PetscFunctionReturn(0);
7527 }
7528 
7529 #undef __FUNCT__
7530 #define __FUNCT__ "MatMatMultTranspose"
7531 /*@
7532    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7533 
7534    Collective on Mat
7535 
7536    Input Parameters:
7537 +  A - the left matrix
7538 .  B - the right matrix
7539 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7540 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7541 
7542    Output Parameters:
7543 .  C - the product matrix
7544 
7545    Notes:
7546    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7547 
7548    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7549 
7550   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7551    actually needed.
7552 
7553    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7554    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
7555 
7556    Level: intermediate
7557 
7558 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7559 @*/
7560 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7561 {
7562   PetscErrorCode ierr;
7563   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7564   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7565 
7566   PetscFunctionBegin;
7567   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7568   PetscValidType(A,1);
7569   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7570   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7571   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7572   PetscValidType(B,2);
7573   ierr = MatPreallocated(B);CHKERRQ(ierr);
7574   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7575   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7576   PetscValidPointer(C,3);
7577   if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7578   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7579   ierr = MatPreallocated(A);CHKERRQ(ierr);
7580 
7581   fA = A->ops->matmulttranspose;
7582   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7583   fB = B->ops->matmulttranspose;
7584   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7585   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7586 
7587   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7588   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
7589   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7590 
7591   PetscFunctionReturn(0);
7592 }
7593 
7594 #undef __FUNCT__
7595 #define __FUNCT__ "MatGetRedundantMatrix"
7596 /*@C
7597    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7598 
7599    Collective on Mat
7600 
7601    Input Parameters:
7602 +  mat - the matrix
7603 .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7604 .  subcomm - MPI communicator split from the communicator where mat resides in
7605 .  mlocal_red - number of local rows of the redundant matrix
7606 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7607 
7608    Output Parameter:
7609 .  matredundant - redundant matrix
7610 
7611    Notes:
7612    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7613    original matrix has not changed from that last call to MatGetRedundantMatrix().
7614 
7615    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7616    calling it.
7617 
7618    Only MPIAIJ matrix is supported.
7619 
7620    Level: advanced
7621 
7622    Concepts: subcommunicator
7623    Concepts: duplicate matrix
7624 
7625 .seealso: MatDestroy()
7626 @*/
7627 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7628 {
7629   PetscErrorCode ierr;
7630 
7631   PetscFunctionBegin;
7632   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7633   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7634     PetscValidPointer(*matredundant,6);
7635     PetscValidHeaderSpecific(*matredundant,MAT_COOKIE,6);
7636   }
7637   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7638   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7639   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7640   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7641 
7642   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7643   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
7644   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7645   PetscFunctionReturn(0);
7646 }
7647