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