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