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