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