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