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