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