xref: /petsc/src/mat/interface/matrix.c (revision f22f69f01ec1ca0bb29797ff3752b65f1e1c47db)
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 ./configure 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 ./configure 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 ./configure 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   if (!((PetscObject)mat)->type_name) SETERRQ(PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
4862   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4863   switch (op) {
4864   case MAT_SYMMETRIC:
4865     mat->symmetric                  = flg;
4866     if (flg) mat->structurally_symmetric = PETSC_TRUE;
4867     mat->symmetric_set              = PETSC_TRUE;
4868     mat->structurally_symmetric_set = flg;
4869     break;
4870   case MAT_HERMITIAN:
4871     mat->hermitian                  = flg;
4872     if (flg) mat->structurally_symmetric = PETSC_TRUE;
4873     mat->hermitian_set              = PETSC_TRUE;
4874     mat->structurally_symmetric_set = flg;
4875     break;
4876   case MAT_STRUCTURALLY_SYMMETRIC:
4877     mat->structurally_symmetric     = flg;
4878     mat->structurally_symmetric_set = PETSC_TRUE;
4879     break;
4880   case MAT_SYMMETRY_ETERNAL:
4881     mat->symmetric_eternal          = flg;
4882     break;
4883   default:
4884     break;
4885   }
4886   if (mat->ops->setoption) {
4887     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
4888   }
4889   PetscFunctionReturn(0);
4890 }
4891 
4892 #undef __FUNCT__
4893 #define __FUNCT__ "MatZeroEntries"
4894 /*@
4895    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4896    this routine retains the old nonzero structure.
4897 
4898    Collective on Mat
4899 
4900    Input Parameters:
4901 .  mat - the matrix
4902 
4903    Level: intermediate
4904 
4905    Concepts: matrices^zeroing
4906 
4907 .seealso: MatZeroRows()
4908 @*/
4909 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroEntries(Mat mat)
4910 {
4911   PetscErrorCode ierr;
4912 
4913   PetscFunctionBegin;
4914   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4915   PetscValidType(mat,1);
4916   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4917   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4918   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4919   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4920 
4921   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4922   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
4923   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4924   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4925   PetscFunctionReturn(0);
4926 }
4927 
4928 #undef __FUNCT__
4929 #define __FUNCT__ "MatZeroRows"
4930 /*@C
4931    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4932    of a set of rows of a matrix.
4933 
4934    Collective on Mat
4935 
4936    Input Parameters:
4937 +  mat - the matrix
4938 .  numRows - the number of rows to remove
4939 .  rows - the global row indices
4940 -  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
4941 
4942    Notes:
4943    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4944    but does not release memory.  For the dense and block diagonal
4945    formats this does not alter the nonzero structure.
4946 
4947    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
4948    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4949    merely zeroed.
4950 
4951    The user can set a value in the diagonal entry (or for the AIJ and
4952    row formats can optionally remove the main diagonal entry from the
4953    nonzero structure as well, by passing 0.0 as the final argument).
4954 
4955    For the parallel case, all processes that share the matrix (i.e.,
4956    those in the communicator used for matrix creation) MUST call this
4957    routine, regardless of whether any rows being zeroed are owned by
4958    them.
4959 
4960    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
4961    list only rows local to itself).
4962 
4963    Level: intermediate
4964 
4965    Concepts: matrices^zeroing rows
4966 
4967 .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4968 @*/
4969 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4970 {
4971   PetscErrorCode ierr;
4972 
4973   PetscFunctionBegin;
4974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4975   PetscValidType(mat,1);
4976   if (numRows) PetscValidIntPointer(rows,3);
4977   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4978   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4979   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4980   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4981 
4982   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag);CHKERRQ(ierr);
4983   ierr = MatView_Private(mat);CHKERRQ(ierr);
4984   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4985   PetscFunctionReturn(0);
4986 }
4987 
4988 #undef __FUNCT__
4989 #define __FUNCT__ "MatZeroRowsIS"
4990 /*@C
4991    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4992    of a set of rows of a matrix.
4993 
4994    Collective on Mat
4995 
4996    Input Parameters:
4997 +  mat - the matrix
4998 .  is - index set of rows to remove
4999 -  diag - value put in all diagonals of eliminated rows
5000 
5001    Notes:
5002    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5003    but does not release memory.  For the dense and block diagonal
5004    formats this does not alter the nonzero structure.
5005 
5006    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5007    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5008    merely zeroed.
5009 
5010    The user can set a value in the diagonal entry (or for the AIJ and
5011    row formats can optionally remove the main diagonal entry from the
5012    nonzero structure as well, by passing 0.0 as the final argument).
5013 
5014    For the parallel case, all processes that share the matrix (i.e.,
5015    those in the communicator used for matrix creation) MUST call this
5016    routine, regardless of whether any rows being zeroed are owned by
5017    them.
5018 
5019    Each processor should list the rows that IT wants zeroed
5020 
5021    Level: intermediate
5022 
5023    Concepts: matrices^zeroing rows
5024 
5025 .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5026 @*/
5027 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
5028 {
5029   PetscInt       numRows;
5030   const PetscInt *rows;
5031   PetscErrorCode ierr;
5032 
5033   PetscFunctionBegin;
5034   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5035   PetscValidType(mat,1);
5036   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5037   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5038   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5039   ierr = MatZeroRows(mat,numRows,rows,diag);CHKERRQ(ierr);
5040   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5041   PetscFunctionReturn(0);
5042 }
5043 
5044 #undef __FUNCT__
5045 #define __FUNCT__ "MatZeroRowsLocal"
5046 /*@C
5047    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5048    of a set of rows of a matrix; using local numbering of rows.
5049 
5050    Collective on Mat
5051 
5052    Input Parameters:
5053 +  mat - the matrix
5054 .  numRows - the number of rows to remove
5055 .  rows - the global row indices
5056 -  diag - value put in all diagonals of eliminated rows
5057 
5058    Notes:
5059    Before calling MatZeroRowsLocal(), the user must first set the
5060    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5061 
5062    For the AIJ matrix formats this removes the old nonzero structure,
5063    but does not release memory.  For the dense and block diagonal
5064    formats this does not alter the nonzero structure.
5065 
5066    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5067    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5068    merely zeroed.
5069 
5070    The user can set a value in the diagonal entry (or for the AIJ and
5071    row formats can optionally remove the main diagonal entry from the
5072    nonzero structure as well, by passing 0.0 as the final argument).
5073 
5074    Level: intermediate
5075 
5076    Concepts: matrices^zeroing
5077 
5078 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5079 @*/
5080 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
5081 {
5082   PetscErrorCode ierr;
5083 
5084   PetscFunctionBegin;
5085   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5086   PetscValidType(mat,1);
5087   if (numRows) PetscValidIntPointer(rows,3);
5088   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5089   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5090   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5091 
5092   if (mat->ops->zerorowslocal) {
5093     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);CHKERRQ(ierr);
5094   } else {
5095     IS             is, newis;
5096     const PetscInt *newRows;
5097 
5098     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5099     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);CHKERRQ(ierr);
5100     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
5101     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5102     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag);CHKERRQ(ierr);
5103     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5104     ierr = ISDestroy(newis);CHKERRQ(ierr);
5105     ierr = ISDestroy(is);CHKERRQ(ierr);
5106   }
5107   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5108   PetscFunctionReturn(0);
5109 }
5110 
5111 #undef __FUNCT__
5112 #define __FUNCT__ "MatZeroRowsLocalIS"
5113 /*@C
5114    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5115    of a set of rows of a matrix; using local numbering of rows.
5116 
5117    Collective on Mat
5118 
5119    Input Parameters:
5120 +  mat - the matrix
5121 .  is - index set of rows to remove
5122 -  diag - value put in all diagonals of eliminated rows
5123 
5124    Notes:
5125    Before calling MatZeroRowsLocalIS(), the user must first set the
5126    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5127 
5128    For the AIJ matrix formats this removes the old nonzero structure,
5129    but does not release memory.  For the dense and block diagonal
5130    formats this does not alter the nonzero structure.
5131 
5132    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5133    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5134    merely zeroed.
5135 
5136    The user can set a value in the diagonal entry (or for the AIJ and
5137    row formats can optionally remove the main diagonal entry from the
5138    nonzero structure as well, by passing 0.0 as the final argument).
5139 
5140    Level: intermediate
5141 
5142    Concepts: matrices^zeroing
5143 
5144 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5145 @*/
5146 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
5147 {
5148   PetscErrorCode ierr;
5149   PetscInt       numRows;
5150   const PetscInt *rows;
5151 
5152   PetscFunctionBegin;
5153   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5154   PetscValidType(mat,1);
5155   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5156   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5157   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5158   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5159 
5160   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5161   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5162   ierr = MatZeroRowsLocal(mat,numRows,rows,diag);CHKERRQ(ierr);
5163   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5164   PetscFunctionReturn(0);
5165 }
5166 
5167 #undef __FUNCT__
5168 #define __FUNCT__ "MatGetSize"
5169 /*@
5170    MatGetSize - Returns the numbers of rows and columns in a matrix.
5171 
5172    Not Collective
5173 
5174    Input Parameter:
5175 .  mat - the matrix
5176 
5177    Output Parameters:
5178 +  m - the number of global rows
5179 -  n - the number of global columns
5180 
5181    Note: both output parameters can be PETSC_NULL on input.
5182 
5183    Level: beginner
5184 
5185    Concepts: matrices^size
5186 
5187 .seealso: MatGetLocalSize()
5188 @*/
5189 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5190 {
5191   PetscFunctionBegin;
5192   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5193   if (m) *m = mat->rmap->N;
5194   if (n) *n = mat->cmap->N;
5195   PetscFunctionReturn(0);
5196 }
5197 
5198 #undef __FUNCT__
5199 #define __FUNCT__ "MatGetLocalSize"
5200 /*@
5201    MatGetLocalSize - Returns the number of rows and columns in a matrix
5202    stored locally.  This information may be implementation dependent, so
5203    use with care.
5204 
5205    Not Collective
5206 
5207    Input Parameters:
5208 .  mat - the matrix
5209 
5210    Output Parameters:
5211 +  m - the number of local rows
5212 -  n - the number of local columns
5213 
5214    Note: both output parameters can be PETSC_NULL on input.
5215 
5216    Level: beginner
5217 
5218    Concepts: matrices^local size
5219 
5220 .seealso: MatGetSize()
5221 @*/
5222 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5223 {
5224   PetscFunctionBegin;
5225   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5226   if (m) PetscValidIntPointer(m,2);
5227   if (n) PetscValidIntPointer(n,3);
5228   if (m) *m = mat->rmap->n;
5229   if (n) *n = mat->cmap->n;
5230   PetscFunctionReturn(0);
5231 }
5232 
5233 #undef __FUNCT__
5234 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5235 /*@
5236    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5237    this processor.
5238 
5239    Not Collective, unless matrix has not been allocated, then collective on Mat
5240 
5241    Input Parameters:
5242 .  mat - the matrix
5243 
5244    Output Parameters:
5245 +  m - the global index of the first local column
5246 -  n - one more than the global index of the last local column
5247 
5248    Notes: both output parameters can be PETSC_NULL on input.
5249 
5250    Level: developer
5251 
5252    Concepts: matrices^column ownership
5253 
5254 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5255 
5256 @*/
5257 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5258 {
5259   PetscErrorCode ierr;
5260 
5261   PetscFunctionBegin;
5262   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5263   PetscValidType(mat,1);
5264   if (m) PetscValidIntPointer(m,2);
5265   if (n) PetscValidIntPointer(n,3);
5266   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5267   if (m) *m = mat->cmap->rstart;
5268   if (n) *n = mat->cmap->rend;
5269   PetscFunctionReturn(0);
5270 }
5271 
5272 #undef __FUNCT__
5273 #define __FUNCT__ "MatGetOwnershipRange"
5274 /*@
5275    MatGetOwnershipRange - Returns the range of matrix rows owned by
5276    this processor, assuming that the matrix is laid out with the first
5277    n1 rows on the first processor, the next n2 rows on the second, etc.
5278    For certain parallel layouts this range may not be well defined.
5279 
5280    Not Collective, unless matrix has not been allocated, then collective on Mat
5281 
5282    Input Parameters:
5283 .  mat - the matrix
5284 
5285    Output Parameters:
5286 +  m - the global index of the first local row
5287 -  n - one more than the global index of the last local row
5288 
5289    Note: both output parameters can be PETSC_NULL on input.
5290 
5291    Level: beginner
5292 
5293    Concepts: matrices^row ownership
5294 
5295 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5296 
5297 @*/
5298 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5299 {
5300   PetscErrorCode ierr;
5301 
5302   PetscFunctionBegin;
5303   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5304   PetscValidType(mat,1);
5305   if (m) PetscValidIntPointer(m,2);
5306   if (n) PetscValidIntPointer(n,3);
5307   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5308   if (m) *m = mat->rmap->rstart;
5309   if (n) *n = mat->rmap->rend;
5310   PetscFunctionReturn(0);
5311 }
5312 
5313 #undef __FUNCT__
5314 #define __FUNCT__ "MatGetOwnershipRanges"
5315 /*@C
5316    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5317    each process
5318 
5319    Not Collective, unless matrix has not been allocated, then collective on Mat
5320 
5321    Input Parameters:
5322 .  mat - the matrix
5323 
5324    Output Parameters:
5325 .  ranges - start of each processors portion plus one more then the total length at the end
5326 
5327    Level: beginner
5328 
5329    Concepts: matrices^row ownership
5330 
5331 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5332 
5333 @*/
5334 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5335 {
5336   PetscErrorCode ierr;
5337 
5338   PetscFunctionBegin;
5339   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5340   PetscValidType(mat,1);
5341   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5342   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
5343   PetscFunctionReturn(0);
5344 }
5345 
5346 #undef __FUNCT__
5347 #define __FUNCT__ "MatGetOwnershipRangesColumn"
5348 /*@C
5349    MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5350 
5351    Not Collective, unless matrix has not been allocated, then collective on Mat
5352 
5353    Input Parameters:
5354 .  mat - the matrix
5355 
5356    Output Parameters:
5357 .  ranges - start of each processors portion plus one more then the total length at the end
5358 
5359    Level: beginner
5360 
5361    Concepts: matrices^column ownership
5362 
5363 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5364 
5365 @*/
5366 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5367 {
5368   PetscErrorCode ierr;
5369 
5370   PetscFunctionBegin;
5371   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5372   PetscValidType(mat,1);
5373   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5374   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
5375   PetscFunctionReturn(0);
5376 }
5377 
5378 #undef __FUNCT__
5379 #define __FUNCT__ "MatILUFactorSymbolic"
5380 /*@C
5381    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5382    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5383    to complete the factorization.
5384 
5385    Collective on Mat
5386 
5387    Input Parameters:
5388 +  mat - the matrix
5389 .  row - row permutation
5390 .  column - column permutation
5391 -  info - structure containing
5392 $      levels - number of levels of fill.
5393 $      expected fill - as ratio of original fill.
5394 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5395                 missing diagonal entries)
5396 
5397    Output Parameters:
5398 .  fact - new matrix that has been symbolically factored
5399 
5400    Notes:
5401    See the users manual for additional information about
5402    choosing the fill factor for better efficiency.
5403 
5404    Most users should employ the simplified KSP interface for linear solvers
5405    instead of working directly with matrix algebra routines such as this.
5406    See, e.g., KSPCreate().
5407 
5408    Level: developer
5409 
5410   Concepts: matrices^symbolic LU factorization
5411   Concepts: matrices^factorization
5412   Concepts: LU^symbolic factorization
5413 
5414 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5415           MatGetOrdering(), MatFactorInfo
5416 
5417     Developer Note: fortran interface is not autogenerated as the f90
5418     interface defintion cannot be generated correctly [due to MatFactorInfo]
5419 
5420 @*/
5421 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5422 {
5423   PetscErrorCode ierr;
5424 
5425   PetscFunctionBegin;
5426   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5427   PetscValidType(mat,1);
5428   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5429   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5430   PetscValidPointer(info,4);
5431   PetscValidPointer(fact,5);
5432   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5433   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5434   if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
5435   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5436   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5437   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5438 
5439   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5440   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
5441   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5442   PetscFunctionReturn(0);
5443 }
5444 
5445 #undef __FUNCT__
5446 #define __FUNCT__ "MatICCFactorSymbolic"
5447 /*@C
5448    MatICCFactorSymbolic - Performs symbolic incomplete
5449    Cholesky factorization for a symmetric matrix.  Use
5450    MatCholeskyFactorNumeric() to complete the factorization.
5451 
5452    Collective on Mat
5453 
5454    Input Parameters:
5455 +  mat - the matrix
5456 .  perm - row and column permutation
5457 -  info - structure containing
5458 $      levels - number of levels of fill.
5459 $      expected fill - as ratio of original fill.
5460 
5461    Output Parameter:
5462 .  fact - the factored matrix
5463 
5464    Notes:
5465    Most users should employ the KSP interface for linear solvers
5466    instead of working directly with matrix algebra routines such as this.
5467    See, e.g., KSPCreate().
5468 
5469    Level: developer
5470 
5471   Concepts: matrices^symbolic incomplete Cholesky factorization
5472   Concepts: matrices^factorization
5473   Concepts: Cholsky^symbolic factorization
5474 
5475 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5476 
5477     Developer Note: fortran interface is not autogenerated as the f90
5478     interface defintion cannot be generated correctly [due to MatFactorInfo]
5479 
5480 @*/
5481 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5482 {
5483   PetscErrorCode ierr;
5484 
5485   PetscFunctionBegin;
5486   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5487   PetscValidType(mat,1);
5488   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
5489   PetscValidPointer(info,3);
5490   PetscValidPointer(fact,4);
5491   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5492   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5493   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5494   if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
5495   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5496   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5497 
5498   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5499   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
5500   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5501   PetscFunctionReturn(0);
5502 }
5503 
5504 #undef __FUNCT__
5505 #define __FUNCT__ "MatGetArray"
5506 /*@C
5507    MatGetArray - Returns a pointer to the element values in the matrix.
5508    The result of this routine is dependent on the underlying matrix data
5509    structure, and may not even work for certain matrix types.  You MUST
5510    call MatRestoreArray() when you no longer need to access the array.
5511 
5512    Not Collective
5513 
5514    Input Parameter:
5515 .  mat - the matrix
5516 
5517    Output Parameter:
5518 .  v - the location of the values
5519 
5520 
5521    Fortran Note:
5522    This routine is used differently from Fortran, e.g.,
5523 .vb
5524         Mat         mat
5525         PetscScalar mat_array(1)
5526         PetscOffset i_mat
5527         PetscErrorCode ierr
5528         call MatGetArray(mat,mat_array,i_mat,ierr)
5529 
5530   C  Access first local entry in matrix; note that array is
5531   C  treated as one dimensional
5532         value = mat_array(i_mat + 1)
5533 
5534         [... other code ...]
5535         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5536 .ve
5537 
5538    See the Fortran chapter of the users manual and
5539    petsc/src/mat/examples/tests for details.
5540 
5541    Level: advanced
5542 
5543    Concepts: matrices^access array
5544 
5545 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5546 @*/
5547 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
5548 {
5549   PetscErrorCode ierr;
5550 
5551   PetscFunctionBegin;
5552   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5553   PetscValidType(mat,1);
5554   PetscValidPointer(v,2);
5555   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5556   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5557   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
5558   CHKMEMQ;
5559   PetscFunctionReturn(0);
5560 }
5561 
5562 #undef __FUNCT__
5563 #define __FUNCT__ "MatRestoreArray"
5564 /*@C
5565    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5566 
5567    Not Collective
5568 
5569    Input Parameter:
5570 +  mat - the matrix
5571 -  v - the location of the values
5572 
5573    Fortran Note:
5574    This routine is used differently from Fortran, e.g.,
5575 .vb
5576         Mat         mat
5577         PetscScalar mat_array(1)
5578         PetscOffset i_mat
5579         PetscErrorCode ierr
5580         call MatGetArray(mat,mat_array,i_mat,ierr)
5581 
5582   C  Access first local entry in matrix; note that array is
5583   C  treated as one dimensional
5584         value = mat_array(i_mat + 1)
5585 
5586         [... other code ...]
5587         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5588 .ve
5589 
5590    See the Fortran chapter of the users manual and
5591    petsc/src/mat/examples/tests for details
5592 
5593    Level: advanced
5594 
5595 .seealso: MatGetArray(), MatRestoreArrayF90()
5596 @*/
5597 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
5598 {
5599   PetscErrorCode ierr;
5600 
5601   PetscFunctionBegin;
5602   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5603   PetscValidType(mat,1);
5604   PetscValidPointer(v,2);
5605 #if defined(PETSC_USE_DEBUG)
5606   CHKMEMQ;
5607 #endif
5608   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5609   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
5610   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5611   PetscFunctionReturn(0);
5612 }
5613 
5614 #undef __FUNCT__
5615 #define __FUNCT__ "MatGetSubMatrices"
5616 /*@C
5617    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5618    points to an array of valid matrices, they may be reused to store the new
5619    submatrices.
5620 
5621    Collective on Mat
5622 
5623    Input Parameters:
5624 +  mat - the matrix
5625 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5626 .  irow, icol - index sets of rows and columns to extract
5627 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5628 
5629    Output Parameter:
5630 .  submat - the array of submatrices
5631 
5632    Notes:
5633    MatGetSubMatrices() can extract ONLY sequential submatrices
5634    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5635    to extract a parallel submatrix.
5636 
5637    When extracting submatrices from a parallel matrix, each processor can
5638    form a different submatrix by setting the rows and columns of its
5639    individual index sets according to the local submatrix desired.
5640 
5641    When finished using the submatrices, the user should destroy
5642    them with MatDestroyMatrices().
5643 
5644    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5645    original matrix has not changed from that last call to MatGetSubMatrices().
5646 
5647    This routine creates the matrices in submat; you should NOT create them before
5648    calling it. It also allocates the array of matrix pointers submat.
5649 
5650    For BAIJ matrices the index sets must respect the block structure, that is if they
5651    request one row/column in a block, they must request all rows/columns that are in
5652    that block. For example, if the block size is 2 you cannot request just row 0 and
5653    column 0.
5654 
5655    Fortran Note:
5656    The Fortran interface is slightly different from that given below; it
5657    requires one to pass in  as submat a Mat (integer) array of size at least m.
5658 
5659    Level: advanced
5660 
5661    Concepts: matrices^accessing submatrices
5662    Concepts: submatrices
5663 
5664 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5665 @*/
5666 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5667 {
5668   PetscErrorCode ierr;
5669   PetscInt        i;
5670   PetscTruth      eq;
5671 
5672   PetscFunctionBegin;
5673   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5674   PetscValidType(mat,1);
5675   if (n) {
5676     PetscValidPointer(irow,3);
5677     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
5678     PetscValidPointer(icol,4);
5679     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
5680   }
5681   PetscValidPointer(submat,6);
5682   if (n && scall == MAT_REUSE_MATRIX) {
5683     PetscValidPointer(*submat,6);
5684     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
5685   }
5686   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5687   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5688   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5689   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5690 
5691   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5692   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
5693   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5694   for (i=0; i<n; i++) {
5695     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5696       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
5697       if (eq) {
5698 	if (mat->symmetric){
5699 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5700 	} else if (mat->hermitian) {
5701 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
5702 	} else if (mat->structurally_symmetric) {
5703 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5704 	}
5705       }
5706     }
5707   }
5708   PetscFunctionReturn(0);
5709 }
5710 
5711 #undef __FUNCT__
5712 #define __FUNCT__ "MatDestroyMatrices"
5713 /*@C
5714    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5715 
5716    Collective on Mat
5717 
5718    Input Parameters:
5719 +  n - the number of local matrices
5720 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5721                        sequence of MatGetSubMatrices())
5722 
5723    Level: advanced
5724 
5725     Notes: Frees not only the matrices, but also the array that contains the matrices
5726            In Fortran will not free the array.
5727 
5728 .seealso: MatGetSubMatrices()
5729 @*/
5730 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
5731 {
5732   PetscErrorCode ierr;
5733   PetscInt       i;
5734 
5735   PetscFunctionBegin;
5736   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5737   PetscValidPointer(mat,2);
5738   for (i=0; i<n; i++) {
5739     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
5740   }
5741   /* memory is allocated even if n = 0 */
5742   ierr = PetscFree(*mat);CHKERRQ(ierr);
5743   PetscFunctionReturn(0);
5744 }
5745 
5746 #undef __FUNCT__
5747 #define __FUNCT__ "MatGetSeqNonzeroStructure"
5748 /*@C
5749    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5750 
5751    Collective on Mat
5752 
5753    Input Parameters:
5754 .  mat - the matrix
5755 
5756    Output Parameter:
5757 .  matstruct - the sequential matrix with the nonzero structure of mat
5758 
5759   Level: intermediate
5760 
5761 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5762 @*/
5763 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
5764 {
5765   PetscErrorCode ierr;
5766 
5767   PetscFunctionBegin;
5768   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5769   PetscValidPointer(matstruct,2);
5770 
5771   PetscValidType(mat,1);
5772   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5773   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5774 
5775   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
5776   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5777   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
5778   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5779   PetscFunctionReturn(0);
5780 }
5781 
5782 #undef __FUNCT__
5783 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
5784 /*@C
5785    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5786 
5787    Collective on Mat
5788 
5789    Input Parameters:
5790 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5791                        sequence of MatGetSequentialNonzeroStructure())
5792 
5793    Level: advanced
5794 
5795     Notes: Frees not only the matrices, but also the array that contains the matrices
5796 
5797 .seealso: MatGetSeqNonzeroStructure()
5798 @*/
5799 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroySeqNonzeroStructure(Mat *mat)
5800 {
5801   PetscErrorCode ierr;
5802 
5803   PetscFunctionBegin;
5804   PetscValidPointer(mat,1);
5805   ierr = MatDestroy(*mat);CHKERRQ(ierr);
5806   PetscFunctionReturn(0);
5807 }
5808 
5809 #undef __FUNCT__
5810 #define __FUNCT__ "MatIncreaseOverlap"
5811 /*@
5812    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5813    replaces the index sets by larger ones that represent submatrices with
5814    additional overlap.
5815 
5816    Collective on Mat
5817 
5818    Input Parameters:
5819 +  mat - the matrix
5820 .  n   - the number of index sets
5821 .  is  - the array of index sets (these index sets will changed during the call)
5822 -  ov  - the additional overlap requested
5823 
5824    Level: developer
5825 
5826    Concepts: overlap
5827    Concepts: ASM^computing overlap
5828 
5829 .seealso: MatGetSubMatrices()
5830 @*/
5831 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5832 {
5833   PetscErrorCode ierr;
5834 
5835   PetscFunctionBegin;
5836   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5837   PetscValidType(mat,1);
5838   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5839   if (n) {
5840     PetscValidPointer(is,3);
5841     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
5842   }
5843   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5844   if (mat->factortype)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5845   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5846 
5847   if (!ov) PetscFunctionReturn(0);
5848   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5849   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5850   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
5851   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5852   PetscFunctionReturn(0);
5853 }
5854 
5855 #undef __FUNCT__
5856 #define __FUNCT__ "MatGetBlockSize"
5857 /*@
5858    MatGetBlockSize - Returns the matrix block size; useful especially for the
5859    block row and block diagonal formats.
5860 
5861    Not Collective
5862 
5863    Input Parameter:
5864 .  mat - the matrix
5865 
5866    Output Parameter:
5867 .  bs - block size
5868 
5869    Notes:
5870    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5871 
5872    Level: intermediate
5873 
5874    Concepts: matrices^block size
5875 
5876 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5877 @*/
5878 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
5879 {
5880   PetscErrorCode ierr;
5881 
5882   PetscFunctionBegin;
5883   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5884   PetscValidType(mat,1);
5885   PetscValidIntPointer(bs,2);
5886   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5887   *bs = mat->rmap->bs;
5888   PetscFunctionReturn(0);
5889 }
5890 
5891 #undef __FUNCT__
5892 #define __FUNCT__ "MatSetBlockSize"
5893 /*@
5894    MatSetBlockSize - Sets the matrix block size; for many matrix types you
5895      cannot use this and MUST set the blocksize when you preallocate the matrix
5896 
5897    Collective on Mat
5898 
5899    Input Parameters:
5900 +  mat - the matrix
5901 -  bs - block size
5902 
5903    Notes:
5904      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
5905      it is not possible to change BAIJ block sizes after preallocation.
5906 
5907    Level: intermediate
5908 
5909    Concepts: matrices^block size
5910 
5911 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5912 @*/
5913 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
5914 {
5915   PetscErrorCode ierr;
5916 
5917   PetscFunctionBegin;
5918   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5919   PetscValidType(mat,1);
5920   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5921   if (bs < 1) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Block size %d, must be positive",bs);
5922   if (mat->ops->setblocksize) {
5923     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
5924   } else {
5925     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5926   }
5927   PetscFunctionReturn(0);
5928 }
5929 
5930 #undef __FUNCT__
5931 #define __FUNCT__ "MatGetRowIJ"
5932 /*@C
5933     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5934 
5935    Collective on Mat
5936 
5937     Input Parameters:
5938 +   mat - the matrix
5939 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5940 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5941                 symmetrized
5942 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5943                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
5944                  always used.
5945 
5946     Output Parameters:
5947 +   n - number of rows in the (possibly compressed) matrix
5948 .   ia - the row pointers [of length n+1]
5949 .   ja - the column indices
5950 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5951            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5952 
5953     Level: developer
5954 
5955     Notes: You CANNOT change any of the ia[] or ja[] values.
5956 
5957            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5958 
5959     Fortran Node
5960 
5961            In Fortran use
5962 $           PetscInt ia(1), ja(1)
5963 $           PetscOffset iia, jja
5964 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
5965 $
5966 $          or
5967 $
5968 $           PetscScalar, pointer :: xx_v(:)
5969 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
5970 
5971 
5972        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5973 
5974 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5975 @*/
5976 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5977 {
5978   PetscErrorCode ierr;
5979 
5980   PetscFunctionBegin;
5981   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5982   PetscValidType(mat,1);
5983   PetscValidIntPointer(n,4);
5984   if (ia) PetscValidIntPointer(ia,5);
5985   if (ja) PetscValidIntPointer(ja,6);
5986   PetscValidIntPointer(done,7);
5987   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5988   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5989   else {
5990     *done = PETSC_TRUE;
5991     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5992     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
5993     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5994   }
5995   PetscFunctionReturn(0);
5996 }
5997 
5998 #undef __FUNCT__
5999 #define __FUNCT__ "MatGetColumnIJ"
6000 /*@C
6001     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6002 
6003     Collective on Mat
6004 
6005     Input Parameters:
6006 +   mat - the matrix
6007 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6008 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6009                 symmetrized
6010 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6011                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6012                  always used.
6013 
6014     Output Parameters:
6015 +   n - number of columns in the (possibly compressed) matrix
6016 .   ia - the column pointers
6017 .   ja - the row indices
6018 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6019 
6020     Level: developer
6021 
6022 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6023 @*/
6024 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6025 {
6026   PetscErrorCode ierr;
6027 
6028   PetscFunctionBegin;
6029   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6030   PetscValidType(mat,1);
6031   PetscValidIntPointer(n,4);
6032   if (ia) PetscValidIntPointer(ia,5);
6033   if (ja) PetscValidIntPointer(ja,6);
6034   PetscValidIntPointer(done,7);
6035   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6036   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6037   else {
6038     *done = PETSC_TRUE;
6039     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6040   }
6041   PetscFunctionReturn(0);
6042 }
6043 
6044 #undef __FUNCT__
6045 #define __FUNCT__ "MatRestoreRowIJ"
6046 /*@C
6047     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6048     MatGetRowIJ().
6049 
6050     Collective on Mat
6051 
6052     Input Parameters:
6053 +   mat - the matrix
6054 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6055 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6056                 symmetrized
6057 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6058                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6059                  always used.
6060 
6061     Output Parameters:
6062 +   n - size of (possibly compressed) matrix
6063 .   ia - the row pointers
6064 .   ja - the column indices
6065 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6066 
6067     Level: developer
6068 
6069 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6070 @*/
6071 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6072 {
6073   PetscErrorCode ierr;
6074 
6075   PetscFunctionBegin;
6076   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6077   PetscValidType(mat,1);
6078   if (ia) PetscValidIntPointer(ia,5);
6079   if (ja) PetscValidIntPointer(ja,6);
6080   PetscValidIntPointer(done,7);
6081   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6082 
6083   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6084   else {
6085     *done = PETSC_TRUE;
6086     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6087   }
6088   PetscFunctionReturn(0);
6089 }
6090 
6091 #undef __FUNCT__
6092 #define __FUNCT__ "MatRestoreColumnIJ"
6093 /*@C
6094     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6095     MatGetColumnIJ().
6096 
6097     Collective on Mat
6098 
6099     Input Parameters:
6100 +   mat - the matrix
6101 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6102 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6103                 symmetrized
6104 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6105                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6106                  always used.
6107 
6108     Output Parameters:
6109 +   n - size of (possibly compressed) matrix
6110 .   ia - the column pointers
6111 .   ja - the row indices
6112 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6113 
6114     Level: developer
6115 
6116 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6117 @*/
6118 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6119 {
6120   PetscErrorCode ierr;
6121 
6122   PetscFunctionBegin;
6123   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6124   PetscValidType(mat,1);
6125   if (ia) PetscValidIntPointer(ia,5);
6126   if (ja) PetscValidIntPointer(ja,6);
6127   PetscValidIntPointer(done,7);
6128   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6129 
6130   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6131   else {
6132     *done = PETSC_TRUE;
6133     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6134   }
6135   PetscFunctionReturn(0);
6136 }
6137 
6138 #undef __FUNCT__
6139 #define __FUNCT__ "MatColoringPatch"
6140 /*@C
6141     MatColoringPatch -Used inside matrix coloring routines that
6142     use MatGetRowIJ() and/or MatGetColumnIJ().
6143 
6144     Collective on Mat
6145 
6146     Input Parameters:
6147 +   mat - the matrix
6148 .   ncolors - max color value
6149 .   n   - number of entries in colorarray
6150 -   colorarray - array indicating color for each column
6151 
6152     Output Parameters:
6153 .   iscoloring - coloring generated using colorarray information
6154 
6155     Level: developer
6156 
6157 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6158 
6159 @*/
6160 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6161 {
6162   PetscErrorCode ierr;
6163 
6164   PetscFunctionBegin;
6165   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6166   PetscValidType(mat,1);
6167   PetscValidIntPointer(colorarray,4);
6168   PetscValidPointer(iscoloring,5);
6169   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6170 
6171   if (!mat->ops->coloringpatch){
6172     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6173   } else {
6174     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6175   }
6176   PetscFunctionReturn(0);
6177 }
6178 
6179 
6180 #undef __FUNCT__
6181 #define __FUNCT__ "MatSetUnfactored"
6182 /*@
6183    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6184 
6185    Collective on Mat
6186 
6187    Input Parameter:
6188 .  mat - the factored matrix to be reset
6189 
6190    Notes:
6191    This routine should be used only with factored matrices formed by in-place
6192    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6193    format).  This option can save memory, for example, when solving nonlinear
6194    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6195    ILU(0) preconditioner.
6196 
6197    Note that one can specify in-place ILU(0) factorization by calling
6198 .vb
6199      PCType(pc,PCILU);
6200      PCFactorSeUseInPlace(pc);
6201 .ve
6202    or by using the options -pc_type ilu -pc_factor_in_place
6203 
6204    In-place factorization ILU(0) can also be used as a local
6205    solver for the blocks within the block Jacobi or additive Schwarz
6206    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6207    of these preconditioners in the users manual for details on setting
6208    local solver options.
6209 
6210    Most users should employ the simplified KSP interface for linear solvers
6211    instead of working directly with matrix algebra routines such as this.
6212    See, e.g., KSPCreate().
6213 
6214    Level: developer
6215 
6216 .seealso: PCFactorSetUseInPlace()
6217 
6218    Concepts: matrices^unfactored
6219 
6220 @*/
6221 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
6222 {
6223   PetscErrorCode ierr;
6224 
6225   PetscFunctionBegin;
6226   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6227   PetscValidType(mat,1);
6228   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6229   mat->factortype = MAT_FACTOR_NONE;
6230   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6231   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6232   PetscFunctionReturn(0);
6233 }
6234 
6235 /*MC
6236     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6237 
6238     Synopsis:
6239     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6240 
6241     Not collective
6242 
6243     Input Parameter:
6244 .   x - matrix
6245 
6246     Output Parameters:
6247 +   xx_v - the Fortran90 pointer to the array
6248 -   ierr - error code
6249 
6250     Example of Usage:
6251 .vb
6252       PetscScalar, pointer xx_v(:)
6253       ....
6254       call MatGetArrayF90(x,xx_v,ierr)
6255       a = xx_v(3)
6256       call MatRestoreArrayF90(x,xx_v,ierr)
6257 .ve
6258 
6259     Notes:
6260     Not yet supported for all F90 compilers
6261 
6262     Level: advanced
6263 
6264 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6265 
6266     Concepts: matrices^accessing array
6267 
6268 M*/
6269 
6270 /*MC
6271     MatRestoreArrayF90 - Restores a matrix array that has been
6272     accessed with MatGetArrayF90().
6273 
6274     Synopsis:
6275     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6276 
6277     Not collective
6278 
6279     Input Parameters:
6280 +   x - matrix
6281 -   xx_v - the Fortran90 pointer to the array
6282 
6283     Output Parameter:
6284 .   ierr - error code
6285 
6286     Example of Usage:
6287 .vb
6288        PetscScalar, pointer xx_v(:)
6289        ....
6290        call MatGetArrayF90(x,xx_v,ierr)
6291        a = xx_v(3)
6292        call MatRestoreArrayF90(x,xx_v,ierr)
6293 .ve
6294 
6295     Notes:
6296     Not yet supported for all F90 compilers
6297 
6298     Level: advanced
6299 
6300 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6301 
6302 M*/
6303 
6304 
6305 #undef __FUNCT__
6306 #define __FUNCT__ "MatGetSubMatrix"
6307 /*@
6308     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6309                       as the original matrix.
6310 
6311     Collective on Mat
6312 
6313     Input Parameters:
6314 +   mat - the original matrix
6315 .   isrow - parallel IS containing the rows this processor should obtain
6316 .   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.
6317 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6318 
6319     Output Parameter:
6320 .   newmat - the new submatrix, of the same type as the old
6321 
6322     Level: advanced
6323 
6324     Notes:
6325     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
6326 
6327     The rows in isrow will be sorted into the same order as the original matrix on each process.
6328 
6329       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6330    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6331    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6332    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
6333    you are finished using it.
6334 
6335     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6336     the input matrix.
6337 
6338     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
6339 
6340    Example usage:
6341    Consider the following 8x8 matrix with 34 non-zero values, that is
6342    assembled across 3 processors. Lets assume that proc0 owns 3 rows,
6343    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
6344    as follows:
6345 
6346 .vb
6347             1  2  0  |  0  3  0  |  0  4
6348     Proc0   0  5  6  |  7  0  0  |  8  0
6349             9  0 10  | 11  0  0  | 12  0
6350     -------------------------------------
6351            13  0 14  | 15 16 17  |  0  0
6352     Proc1   0 18  0  | 19 20 21  |  0  0
6353             0  0  0  | 22 23  0  | 24  0
6354     -------------------------------------
6355     Proc2  25 26 27  |  0  0 28  | 29  0
6356            30  0  0  | 31 32 33  |  0 34
6357 .ve
6358 
6359     Suppose isrow = [0 1 | 4 | 5 6] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
6360 
6361 .vb
6362             2  0  |  0  3  0  |  0
6363     Proc0   5  6  |  7  0  0  |  8
6364     -------------------------------
6365     Proc1  18  0  | 19 20 21  |  0
6366     -------------------------------
6367     Proc2  26 27  |  0  0 28  | 29
6368             0  0  | 31 32 33  |  0
6369 .ve
6370 
6371 
6372     Concepts: matrices^submatrices
6373 
6374 .seealso: MatGetSubMatrices()
6375 @*/
6376 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
6377 {
6378   PetscErrorCode ierr;
6379   PetscMPIInt    size;
6380   Mat            *local;
6381   IS             iscoltmp;
6382 
6383   PetscFunctionBegin;
6384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6385   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
6386   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
6387   PetscValidPointer(newmat,5);
6388   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
6389   PetscValidType(mat,1);
6390   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6391   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6392   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6393 
6394   if (!iscol) {
6395     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
6396   } else {
6397     iscoltmp = iscol;
6398   }
6399 
6400   /* if original matrix is on just one processor then use submatrix generated */
6401   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6402     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
6403     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6404     PetscFunctionReturn(0);
6405   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
6406     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
6407     *newmat = *local;
6408     ierr    = PetscFree(local);CHKERRQ(ierr);
6409     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6410     PetscFunctionReturn(0);
6411   } else if (!mat->ops->getsubmatrix) {
6412     /* Create a new matrix type that implements the operation using the full matrix */
6413     switch (cll) {
6414       case MAT_INITIAL_MATRIX:
6415         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
6416         break;
6417       case MAT_REUSE_MATRIX:
6418         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
6419         break;
6420       default: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
6421     }
6422     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6423     PetscFunctionReturn(0);
6424   }
6425 
6426   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6427   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
6428   if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6429   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
6430   PetscFunctionReturn(0);
6431 }
6432 
6433 #undef __FUNCT__
6434 #define __FUNCT__ "MatStashSetInitialSize"
6435 /*@
6436    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6437    used during the assembly process to store values that belong to
6438    other processors.
6439 
6440    Not Collective
6441 
6442    Input Parameters:
6443 +  mat   - the matrix
6444 .  size  - the initial size of the stash.
6445 -  bsize - the initial size of the block-stash(if used).
6446 
6447    Options Database Keys:
6448 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6449 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
6450 
6451    Level: intermediate
6452 
6453    Notes:
6454      The block-stash is used for values set with MatSetValuesBlocked() while
6455      the stash is used for values set with MatSetValues()
6456 
6457      Run with the option -info and look for output of the form
6458      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6459      to determine the appropriate value, MM, to use for size and
6460      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6461      to determine the value, BMM to use for bsize
6462 
6463    Concepts: stash^setting matrix size
6464    Concepts: matrices^stash
6465 
6466 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
6467 
6468 @*/
6469 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6470 {
6471   PetscErrorCode ierr;
6472 
6473   PetscFunctionBegin;
6474   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6475   PetscValidType(mat,1);
6476   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
6477   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
6478   PetscFunctionReturn(0);
6479 }
6480 
6481 #undef __FUNCT__
6482 #define __FUNCT__ "MatInterpolateAdd"
6483 /*@
6484    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6485      the matrix
6486 
6487    Collective on Mat
6488 
6489    Input Parameters:
6490 +  mat   - the matrix
6491 .  x,y - the vectors
6492 -  w - where the result is stored
6493 
6494    Level: intermediate
6495 
6496    Notes:
6497     w may be the same vector as y.
6498 
6499     This allows one to use either the restriction or interpolation (its transpose)
6500     matrix to do the interpolation
6501 
6502     Concepts: interpolation
6503 
6504 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6505 
6506 @*/
6507 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6508 {
6509   PetscErrorCode ierr;
6510   PetscInt       M,N;
6511 
6512   PetscFunctionBegin;
6513   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
6514   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
6515   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
6516   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
6517   PetscValidType(A,1);
6518   ierr = MatPreallocated(A);CHKERRQ(ierr);
6519   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6520   if (N > M) {
6521     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
6522   } else {
6523     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
6524   }
6525   PetscFunctionReturn(0);
6526 }
6527 
6528 #undef __FUNCT__
6529 #define __FUNCT__ "MatInterpolate"
6530 /*@
6531    MatInterpolate - y = A*x or A'*x depending on the shape of
6532      the matrix
6533 
6534    Collective on Mat
6535 
6536    Input Parameters:
6537 +  mat   - the matrix
6538 -  x,y - the vectors
6539 
6540    Level: intermediate
6541 
6542    Notes:
6543     This allows one to use either the restriction or interpolation (its transpose)
6544     matrix to do the interpolation
6545 
6546    Concepts: matrices^interpolation
6547 
6548 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6549 
6550 @*/
6551 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
6552 {
6553   PetscErrorCode ierr;
6554   PetscInt       M,N;
6555 
6556   PetscFunctionBegin;
6557   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
6558   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
6559   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
6560   PetscValidType(A,1);
6561   ierr = MatPreallocated(A);CHKERRQ(ierr);
6562   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6563   if (N > M) {
6564     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6565   } else {
6566     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6567   }
6568   PetscFunctionReturn(0);
6569 }
6570 
6571 #undef __FUNCT__
6572 #define __FUNCT__ "MatRestrict"
6573 /*@
6574    MatRestrict - y = A*x or A'*x
6575 
6576    Collective on Mat
6577 
6578    Input Parameters:
6579 +  mat   - the matrix
6580 -  x,y - the vectors
6581 
6582    Level: intermediate
6583 
6584    Notes:
6585     This allows one to use either the restriction or interpolation (its transpose)
6586     matrix to do the restriction
6587 
6588    Concepts: matrices^restriction
6589 
6590 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6591 
6592 @*/
6593 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
6594 {
6595   PetscErrorCode ierr;
6596   PetscInt       M,N;
6597 
6598   PetscFunctionBegin;
6599   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
6600   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
6601   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
6602   PetscValidType(A,1);
6603   ierr = MatPreallocated(A);CHKERRQ(ierr);
6604 
6605   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6606   if (N > M) {
6607     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6608   } else {
6609     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6610   }
6611   PetscFunctionReturn(0);
6612 }
6613 
6614 #undef __FUNCT__
6615 #define __FUNCT__ "MatNullSpaceAttach"
6616 /*@
6617    MatNullSpaceAttach - attaches a null space to a matrix.
6618         This null space will be removed from the resulting vector whenever
6619         MatMult() is called
6620 
6621    Collective on Mat
6622 
6623    Input Parameters:
6624 +  mat - the matrix
6625 -  nullsp - the null space object
6626 
6627    Level: developer
6628 
6629    Notes:
6630       Overwrites any previous null space that may have been attached
6631 
6632    Concepts: null space^attaching to matrix
6633 
6634 .seealso: MatCreate(), MatNullSpaceCreate()
6635 @*/
6636 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6637 {
6638   PetscErrorCode ierr;
6639 
6640   PetscFunctionBegin;
6641   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6642   PetscValidType(mat,1);
6643   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
6644   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6645   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
6646   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
6647   mat->nullsp = nullsp;
6648   PetscFunctionReturn(0);
6649 }
6650 
6651 #undef __FUNCT__
6652 #define __FUNCT__ "MatICCFactor"
6653 /*@C
6654    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6655 
6656    Collective on Mat
6657 
6658    Input Parameters:
6659 +  mat - the matrix
6660 .  row - row/column permutation
6661 .  fill - expected fill factor >= 1.0
6662 -  level - level of fill, for ICC(k)
6663 
6664    Notes:
6665    Probably really in-place only when level of fill is zero, otherwise allocates
6666    new space to store factored matrix and deletes previous memory.
6667 
6668    Most users should employ the simplified KSP interface for linear solvers
6669    instead of working directly with matrix algebra routines such as this.
6670    See, e.g., KSPCreate().
6671 
6672    Level: developer
6673 
6674    Concepts: matrices^incomplete Cholesky factorization
6675    Concepts: Cholesky factorization
6676 
6677 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6678 
6679     Developer Note: fortran interface is not autogenerated as the f90
6680     interface defintion cannot be generated correctly [due to MatFactorInfo]
6681 
6682 @*/
6683 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6684 {
6685   PetscErrorCode ierr;
6686 
6687   PetscFunctionBegin;
6688   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6689   PetscValidType(mat,1);
6690   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
6691   PetscValidPointer(info,3);
6692   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6693   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6694   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6695   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6696   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6697   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
6698   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6699   PetscFunctionReturn(0);
6700 }
6701 
6702 #undef __FUNCT__
6703 #define __FUNCT__ "MatSetValuesAdic"
6704 /*@
6705    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6706 
6707    Not Collective
6708 
6709    Input Parameters:
6710 +  mat - the matrix
6711 -  v - the values compute with ADIC
6712 
6713    Level: developer
6714 
6715    Notes:
6716      Must call MatSetColoring() before using this routine. Also this matrix must already
6717      have its nonzero pattern determined.
6718 
6719 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6720           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6721 @*/
6722 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
6723 {
6724   PetscErrorCode ierr;
6725 
6726   PetscFunctionBegin;
6727   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6728   PetscValidType(mat,1);
6729   PetscValidPointer(mat,2);
6730 
6731   if (!mat->assembled) {
6732     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6733   }
6734   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6735   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6736   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
6737   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6738   ierr = MatView_Private(mat);CHKERRQ(ierr);
6739   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6740   PetscFunctionReturn(0);
6741 }
6742 
6743 
6744 #undef __FUNCT__
6745 #define __FUNCT__ "MatSetColoring"
6746 /*@
6747    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6748 
6749    Not Collective
6750 
6751    Input Parameters:
6752 +  mat - the matrix
6753 -  coloring - the coloring
6754 
6755    Level: developer
6756 
6757 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6758           MatSetValues(), MatSetValuesAdic()
6759 @*/
6760 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
6761 {
6762   PetscErrorCode ierr;
6763 
6764   PetscFunctionBegin;
6765   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6766   PetscValidType(mat,1);
6767   PetscValidPointer(coloring,2);
6768 
6769   if (!mat->assembled) {
6770     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6771   }
6772   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6773   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
6774   PetscFunctionReturn(0);
6775 }
6776 
6777 #undef __FUNCT__
6778 #define __FUNCT__ "MatSetValuesAdifor"
6779 /*@
6780    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6781 
6782    Not Collective
6783 
6784    Input Parameters:
6785 +  mat - the matrix
6786 .  nl - leading dimension of v
6787 -  v - the values compute with ADIFOR
6788 
6789    Level: developer
6790 
6791    Notes:
6792      Must call MatSetColoring() before using this routine. Also this matrix must already
6793      have its nonzero pattern determined.
6794 
6795 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6796           MatSetValues(), MatSetColoring()
6797 @*/
6798 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6799 {
6800   PetscErrorCode ierr;
6801 
6802   PetscFunctionBegin;
6803   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6804   PetscValidType(mat,1);
6805   PetscValidPointer(v,3);
6806 
6807   if (!mat->assembled) {
6808     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6809   }
6810   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6811   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6812   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
6813   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6814   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6815   PetscFunctionReturn(0);
6816 }
6817 
6818 #undef __FUNCT__
6819 #define __FUNCT__ "MatDiagonalScaleLocal"
6820 /*@
6821    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6822          ghosted ones.
6823 
6824    Not Collective
6825 
6826    Input Parameters:
6827 +  mat - the matrix
6828 -  diag = the diagonal values, including ghost ones
6829 
6830    Level: developer
6831 
6832    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6833 
6834 .seealso: MatDiagonalScale()
6835 @*/
6836 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
6837 {
6838   PetscErrorCode ierr;
6839   PetscMPIInt    size;
6840 
6841   PetscFunctionBegin;
6842   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6843   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
6844   PetscValidType(mat,1);
6845 
6846   if (!mat->assembled) {
6847     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6848   }
6849   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6850   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6851   if (size == 1) {
6852     PetscInt n,m;
6853     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
6854     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
6855     if (m == n) {
6856       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
6857     } else {
6858       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6859     }
6860   } else {
6861     PetscErrorCode (*f)(Mat,Vec);
6862     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
6863     if (f) {
6864       ierr = (*f)(mat,diag);CHKERRQ(ierr);
6865     } else {
6866       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6867     }
6868   }
6869   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6870   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6871   PetscFunctionReturn(0);
6872 }
6873 
6874 #undef __FUNCT__
6875 #define __FUNCT__ "MatGetInertia"
6876 /*@
6877    MatGetInertia - Gets the inertia from a factored matrix
6878 
6879    Collective on Mat
6880 
6881    Input Parameter:
6882 .  mat - the matrix
6883 
6884    Output Parameters:
6885 +   nneg - number of negative eigenvalues
6886 .   nzero - number of zero eigenvalues
6887 -   npos - number of positive eigenvalues
6888 
6889    Level: advanced
6890 
6891    Notes: Matrix must have been factored by MatCholeskyFactor()
6892 
6893 
6894 @*/
6895 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6896 {
6897   PetscErrorCode ierr;
6898 
6899   PetscFunctionBegin;
6900   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6901   PetscValidType(mat,1);
6902   if (!mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6903   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6904   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6905   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
6906   PetscFunctionReturn(0);
6907 }
6908 
6909 /* ----------------------------------------------------------------*/
6910 #undef __FUNCT__
6911 #define __FUNCT__ "MatSolves"
6912 /*@C
6913    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6914 
6915    Collective on Mat and Vecs
6916 
6917    Input Parameters:
6918 +  mat - the factored matrix
6919 -  b - the right-hand-side vectors
6920 
6921    Output Parameter:
6922 .  x - the result vectors
6923 
6924    Notes:
6925    The vectors b and x cannot be the same.  I.e., one cannot
6926    call MatSolves(A,x,x).
6927 
6928    Notes:
6929    Most users should employ the simplified KSP interface for linear solvers
6930    instead of working directly with matrix algebra routines such as this.
6931    See, e.g., KSPCreate().
6932 
6933    Level: developer
6934 
6935    Concepts: matrices^triangular solves
6936 
6937 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6938 @*/
6939 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6940 {
6941   PetscErrorCode ierr;
6942 
6943   PetscFunctionBegin;
6944   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6945   PetscValidType(mat,1);
6946   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6947   if (!mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6948   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
6949 
6950   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6951   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6952   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6953   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6954   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6955   PetscFunctionReturn(0);
6956 }
6957 
6958 #undef __FUNCT__
6959 #define __FUNCT__ "MatIsSymmetric"
6960 /*@
6961    MatIsSymmetric - Test whether a matrix is symmetric
6962 
6963    Collective on Mat
6964 
6965    Input Parameter:
6966 +  A - the matrix to test
6967 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6968 
6969    Output Parameters:
6970 .  flg - the result
6971 
6972    Level: intermediate
6973 
6974    Concepts: matrix^symmetry
6975 
6976 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6977 @*/
6978 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6979 {
6980   PetscErrorCode ierr;
6981 
6982   PetscFunctionBegin;
6983   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
6984   PetscValidPointer(flg,2);
6985 
6986   if (!A->symmetric_set) {
6987     if (!A->ops->issymmetric) {
6988       const MatType mattype;
6989       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6990       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6991     }
6992     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
6993     if (!tol) {
6994       A->symmetric_set = PETSC_TRUE;
6995       A->symmetric = *flg;
6996       if (A->symmetric) {
6997 	A->structurally_symmetric_set = PETSC_TRUE;
6998 	A->structurally_symmetric     = PETSC_TRUE;
6999       }
7000     }
7001   } else if (A->symmetric) {
7002     *flg = PETSC_TRUE;
7003   } else if (!tol) {
7004     *flg = PETSC_FALSE;
7005   } else {
7006     if (!A->ops->issymmetric) {
7007       const MatType mattype;
7008       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7009       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7010     }
7011     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7012   }
7013   PetscFunctionReturn(0);
7014 }
7015 
7016 #undef __FUNCT__
7017 #define __FUNCT__ "MatIsHermitian"
7018 /*@
7019    MatIsHermitian - Test whether a matrix is Hermitian
7020 
7021    Collective on Mat
7022 
7023    Input Parameter:
7024 +  A - the matrix to test
7025 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7026 
7027    Output Parameters:
7028 .  flg - the result
7029 
7030    Level: intermediate
7031 
7032    Concepts: matrix^symmetry
7033 
7034 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7035 @*/
7036 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
7037 {
7038   PetscErrorCode ierr;
7039 
7040   PetscFunctionBegin;
7041   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7042   PetscValidPointer(flg,2);
7043 
7044   if (!A->hermitian_set) {
7045     if (!A->ops->ishermitian) {
7046       const MatType mattype;
7047       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7048       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7049     }
7050     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7051     if (!tol) {
7052       A->hermitian_set = PETSC_TRUE;
7053       A->hermitian = *flg;
7054       if (A->hermitian) {
7055 	A->structurally_symmetric_set = PETSC_TRUE;
7056 	A->structurally_symmetric     = PETSC_TRUE;
7057       }
7058     }
7059   } else if (A->hermitian) {
7060     *flg = PETSC_TRUE;
7061   } else if (!tol) {
7062     *flg = PETSC_FALSE;
7063   } else {
7064     if (!A->ops->ishermitian) {
7065       const MatType mattype;
7066       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7067       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7068     }
7069     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7070   }
7071   PetscFunctionReturn(0);
7072 }
7073 
7074 #undef __FUNCT__
7075 #define __FUNCT__ "MatIsSymmetricKnown"
7076 /*@
7077    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7078 
7079    Collective on Mat
7080 
7081    Input Parameter:
7082 .  A - the matrix to check
7083 
7084    Output Parameters:
7085 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7086 -  flg - the result
7087 
7088    Level: advanced
7089 
7090    Concepts: matrix^symmetry
7091 
7092    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7093          if you want it explicitly checked
7094 
7095 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7096 @*/
7097 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7098 {
7099   PetscFunctionBegin;
7100   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7101   PetscValidPointer(set,2);
7102   PetscValidPointer(flg,3);
7103   if (A->symmetric_set) {
7104     *set = PETSC_TRUE;
7105     *flg = A->symmetric;
7106   } else {
7107     *set = PETSC_FALSE;
7108   }
7109   PetscFunctionReturn(0);
7110 }
7111 
7112 #undef __FUNCT__
7113 #define __FUNCT__ "MatIsHermitianKnown"
7114 /*@
7115    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7116 
7117    Collective on Mat
7118 
7119    Input Parameter:
7120 .  A - the matrix to check
7121 
7122    Output Parameters:
7123 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7124 -  flg - the result
7125 
7126    Level: advanced
7127 
7128    Concepts: matrix^symmetry
7129 
7130    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7131          if you want it explicitly checked
7132 
7133 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7134 @*/
7135 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7136 {
7137   PetscFunctionBegin;
7138   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7139   PetscValidPointer(set,2);
7140   PetscValidPointer(flg,3);
7141   if (A->hermitian_set) {
7142     *set = PETSC_TRUE;
7143     *flg = A->hermitian;
7144   } else {
7145     *set = PETSC_FALSE;
7146   }
7147   PetscFunctionReturn(0);
7148 }
7149 
7150 #undef __FUNCT__
7151 #define __FUNCT__ "MatIsStructurallySymmetric"
7152 /*@
7153    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7154 
7155    Collective on Mat
7156 
7157    Input Parameter:
7158 .  A - the matrix to test
7159 
7160    Output Parameters:
7161 .  flg - the result
7162 
7163    Level: intermediate
7164 
7165    Concepts: matrix^symmetry
7166 
7167 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7168 @*/
7169 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
7170 {
7171   PetscErrorCode ierr;
7172 
7173   PetscFunctionBegin;
7174   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7175   PetscValidPointer(flg,2);
7176   if (!A->structurally_symmetric_set) {
7177     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7178     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7179     A->structurally_symmetric_set = PETSC_TRUE;
7180   }
7181   *flg = A->structurally_symmetric;
7182   PetscFunctionReturn(0);
7183 }
7184 
7185 #undef __FUNCT__
7186 #define __FUNCT__ "MatStashGetInfo"
7187 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7188 /*@
7189    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7190        to be communicated to other processors during the MatAssemblyBegin/End() process
7191 
7192     Not collective
7193 
7194    Input Parameter:
7195 .   vec - the vector
7196 
7197    Output Parameters:
7198 +   nstash   - the size of the stash
7199 .   reallocs - the number of additional mallocs incurred.
7200 .   bnstash   - the size of the block stash
7201 -   breallocs - the number of additional mallocs incurred.in the block stash
7202 
7203    Level: advanced
7204 
7205 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7206 
7207 @*/
7208 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7209 {
7210   PetscErrorCode ierr;
7211   PetscFunctionBegin;
7212   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7213   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7214   PetscFunctionReturn(0);
7215 }
7216 
7217 #undef __FUNCT__
7218 #define __FUNCT__ "MatGetVecs"
7219 /*@C
7220    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7221      parallel layout
7222 
7223    Collective on Mat
7224 
7225    Input Parameter:
7226 .  mat - the matrix
7227 
7228    Output Parameter:
7229 +   right - (optional) vector that the matrix can be multiplied against
7230 -   left - (optional) vector that the matrix vector product can be stored in
7231 
7232   Level: advanced
7233 
7234 .seealso: MatCreate()
7235 @*/
7236 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
7237 {
7238   PetscErrorCode ierr;
7239 
7240   PetscFunctionBegin;
7241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7242   PetscValidType(mat,1);
7243   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7244   if (mat->ops->getvecs) {
7245     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7246   } else {
7247     PetscMPIInt size;
7248     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7249     if (right) {
7250       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7251       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7252       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7253       if (size > 1) {
7254         /* New vectors uses Mat cmap and does not create a new one */
7255 	ierr = PetscLayoutDestroy((*right)->map);CHKERRQ(ierr);
7256 	(*right)->map = mat->cmap;
7257 	mat->cmap->refcnt++;
7258 
7259         ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);
7260       } else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
7261     }
7262     if (left) {
7263       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7264       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7265       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7266       if (size > 1) {
7267         /* New vectors uses Mat rmap and does not create a new one */
7268 	ierr = PetscLayoutDestroy((*left)->map);CHKERRQ(ierr);
7269 	(*left)->map = mat->rmap;
7270 	mat->rmap->refcnt++;
7271 
7272         ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);
7273       } else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
7274     }
7275   }
7276   if (mat->mapping) {
7277     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->mapping);CHKERRQ(ierr);}
7278     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->mapping);CHKERRQ(ierr);}
7279   }
7280   if (mat->bmapping) {
7281     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);CHKERRQ(ierr);}
7282     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);CHKERRQ(ierr);}
7283   }
7284   PetscFunctionReturn(0);
7285 }
7286 
7287 #undef __FUNCT__
7288 #define __FUNCT__ "MatFactorInfoInitialize"
7289 /*@C
7290    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7291      with default values.
7292 
7293    Not Collective
7294 
7295    Input Parameters:
7296 .    info - the MatFactorInfo data structure
7297 
7298 
7299    Notes: The solvers are generally used through the KSP and PC objects, for example
7300           PCLU, PCILU, PCCHOLESKY, PCICC
7301 
7302    Level: developer
7303 
7304 .seealso: MatFactorInfo
7305 
7306     Developer Note: fortran interface is not autogenerated as the f90
7307     interface defintion cannot be generated correctly [due to MatFactorInfo]
7308 
7309 @*/
7310 
7311 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
7312 {
7313   PetscErrorCode ierr;
7314 
7315   PetscFunctionBegin;
7316   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
7317   PetscFunctionReturn(0);
7318 }
7319 
7320 #undef __FUNCT__
7321 #define __FUNCT__ "MatPtAP"
7322 /*@
7323    MatPtAP - Creates the matrix projection C = P^T * A * P
7324 
7325    Collective on Mat
7326 
7327    Input Parameters:
7328 +  A - the matrix
7329 .  P - the projection matrix
7330 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7331 -  fill - expected fill as ratio of nnz(C)/nnz(A)
7332 
7333    Output Parameters:
7334 .  C - the product matrix
7335 
7336    Notes:
7337    C will be created and must be destroyed by the user with MatDestroy().
7338 
7339    This routine is currently only implemented for pairs of AIJ matrices and classes
7340    which inherit from AIJ.
7341 
7342    Level: intermediate
7343 
7344 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7345 @*/
7346 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7347 {
7348   PetscErrorCode ierr;
7349 
7350   PetscFunctionBegin;
7351   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7352   PetscValidType(A,1);
7353   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7354   if (A->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7355   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
7356   PetscValidType(P,2);
7357   ierr = MatPreallocated(P);CHKERRQ(ierr);
7358   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7359   if (P->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7360   PetscValidPointer(C,3);
7361   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7362   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7363   ierr = MatPreallocated(A);CHKERRQ(ierr);
7364 
7365   if (!A->ops->ptap) {
7366     const MatType mattype;
7367     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7368     SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
7369   }
7370   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7371   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
7372   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7373 
7374   PetscFunctionReturn(0);
7375 }
7376 
7377 #undef __FUNCT__
7378 #define __FUNCT__ "MatPtAPNumeric"
7379 /*@
7380    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
7381 
7382    Collective on Mat
7383 
7384    Input Parameters:
7385 +  A - the matrix
7386 -  P - the projection matrix
7387 
7388    Output Parameters:
7389 .  C - the product matrix
7390 
7391    Notes:
7392    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7393    the user using MatDeatroy().
7394 
7395    This routine is currently only implemented for pairs of AIJ matrices and classes
7396    which inherit from AIJ.  C will be of type MATAIJ.
7397 
7398    Level: intermediate
7399 
7400 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7401 @*/
7402 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
7403 {
7404   PetscErrorCode ierr;
7405 
7406   PetscFunctionBegin;
7407   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7408   PetscValidType(A,1);
7409   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7410   if (A->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7411   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
7412   PetscValidType(P,2);
7413   ierr = MatPreallocated(P);CHKERRQ(ierr);
7414   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7415   if (P->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7416   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
7417   PetscValidType(C,3);
7418   ierr = MatPreallocated(C);CHKERRQ(ierr);
7419   if (C->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7420   if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7421   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7422   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);
7423   if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7424   ierr = MatPreallocated(A);CHKERRQ(ierr);
7425 
7426   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7427   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
7428   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7429   PetscFunctionReturn(0);
7430 }
7431 
7432 #undef __FUNCT__
7433 #define __FUNCT__ "MatPtAPSymbolic"
7434 /*@
7435    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
7436 
7437    Collective on Mat
7438 
7439    Input Parameters:
7440 +  A - the matrix
7441 -  P - the projection matrix
7442 
7443    Output Parameters:
7444 .  C - the (i,j) structure of the product matrix
7445 
7446    Notes:
7447    C will be created and must be destroyed by the user with MatDestroy().
7448 
7449    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7450    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
7451    this (i,j) structure by calling MatPtAPNumeric().
7452 
7453    Level: intermediate
7454 
7455 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7456 @*/
7457 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7458 {
7459   PetscErrorCode ierr;
7460 
7461   PetscFunctionBegin;
7462   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7463   PetscValidType(A,1);
7464   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7465   if (A->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7466   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7467   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
7468   PetscValidType(P,2);
7469   ierr = MatPreallocated(P);CHKERRQ(ierr);
7470   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7471   if (P->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7472   PetscValidPointer(C,3);
7473 
7474   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7475   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);
7476   ierr = MatPreallocated(A);CHKERRQ(ierr);
7477   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7478   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
7479   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7480 
7481   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
7482 
7483   PetscFunctionReturn(0);
7484 }
7485 
7486 #undef __FUNCT__
7487 #define __FUNCT__ "MatMatMult"
7488 /*@
7489    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7490 
7491    Collective on Mat
7492 
7493    Input Parameters:
7494 +  A - the left matrix
7495 .  B - the right matrix
7496 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7497 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7498           if the result is a dense matrix this is irrelevent
7499 
7500    Output Parameters:
7501 .  C - the product matrix
7502 
7503    Notes:
7504    Unless scall is MAT_REUSE_MATRIX C will be created.
7505 
7506    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7507 
7508    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7509    actually needed.
7510 
7511    If you have many matrices with the same non-zero structure to multiply, you
7512    should either
7513 $   1) use MAT_REUSE_MATRIX in all calls but the first or
7514 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7515 
7516    Level: intermediate
7517 
7518 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7519 @*/
7520 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7521 {
7522   PetscErrorCode ierr;
7523   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7524   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7525   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7526 
7527   PetscFunctionBegin;
7528   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7529   PetscValidType(A,1);
7530   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7531   if (A->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7532   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
7533   PetscValidType(B,2);
7534   ierr = MatPreallocated(B);CHKERRQ(ierr);
7535   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7536   if (B->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7537   PetscValidPointer(C,3);
7538   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7539   if (scall == MAT_REUSE_MATRIX){
7540     PetscValidPointer(*C,5);
7541     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
7542   }
7543   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7544   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7545   ierr = MatPreallocated(A);CHKERRQ(ierr);
7546 
7547   fA = A->ops->matmult;
7548   fB = B->ops->matmult;
7549   if (fB == fA) {
7550     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7551     mult = fB;
7552   } else {
7553     /* dispatch based on the type of A and B */
7554     char  multname[256];
7555     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
7556     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7557     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
7558     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7559     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7560     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
7561     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);
7562   }
7563   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7564   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
7565   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7566   PetscFunctionReturn(0);
7567 }
7568 
7569 #undef __FUNCT__
7570 #define __FUNCT__ "MatMatMultSymbolic"
7571 /*@
7572    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7573    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
7574 
7575    Collective on Mat
7576 
7577    Input Parameters:
7578 +  A - the left matrix
7579 .  B - the right matrix
7580 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7581       if C is a dense matrix this is irrelevent
7582 
7583    Output Parameters:
7584 .  C - the product matrix
7585 
7586    Notes:
7587    Unless scall is MAT_REUSE_MATRIX C will be created.
7588 
7589    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7590    actually needed.
7591 
7592    This routine is currently implemented for
7593     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7594     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7595     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7596 
7597    Level: intermediate
7598 
7599 .seealso: MatMatMult(), MatMatMultNumeric()
7600 @*/
7601 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7602 {
7603   PetscErrorCode ierr;
7604   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7605   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7606   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7607 
7608   PetscFunctionBegin;
7609   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7610   PetscValidType(A,1);
7611   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7612   if (A->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7613 
7614   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
7615   PetscValidType(B,2);
7616   ierr = MatPreallocated(B);CHKERRQ(ierr);
7617   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7618   if (B->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7619   PetscValidPointer(C,3);
7620 
7621   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7622   if (fill == PETSC_DEFAULT) fill = 2.0;
7623   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7624   ierr = MatPreallocated(A);CHKERRQ(ierr);
7625 
7626   Asymbolic = A->ops->matmultsymbolic;
7627   Bsymbolic = B->ops->matmultsymbolic;
7628   if (Asymbolic == Bsymbolic){
7629     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7630     symbolic = Bsymbolic;
7631   } else { /* dispatch based on the type of A and B */
7632     char  symbolicname[256];
7633     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
7634     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7635     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
7636     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7637     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
7638     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
7639     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);
7640   }
7641   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7642   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
7643   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7644   PetscFunctionReturn(0);
7645 }
7646 
7647 #undef __FUNCT__
7648 #define __FUNCT__ "MatMatMultNumeric"
7649 /*@
7650    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7651    Call this routine after first calling MatMatMultSymbolic().
7652 
7653    Collective on Mat
7654 
7655    Input Parameters:
7656 +  A - the left matrix
7657 -  B - the right matrix
7658 
7659    Output Parameters:
7660 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7661 
7662    Notes:
7663    C must have been created with MatMatMultSymbolic().
7664 
7665    This routine is currently implemented for
7666     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7667     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7668     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7669 
7670    Level: intermediate
7671 
7672 .seealso: MatMatMult(), MatMatMultSymbolic()
7673 @*/
7674 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
7675 {
7676   PetscErrorCode ierr;
7677   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7678   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7679   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7680 
7681   PetscFunctionBegin;
7682   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7683   PetscValidType(A,1);
7684   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7685   if (A->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7686 
7687   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
7688   PetscValidType(B,2);
7689   ierr = MatPreallocated(B);CHKERRQ(ierr);
7690   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7691   if (B->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7692 
7693   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
7694   PetscValidType(C,3);
7695   ierr = MatPreallocated(C);CHKERRQ(ierr);
7696   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7697   if (C->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7698 
7699   if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7700   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7701   if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7702   ierr = MatPreallocated(A);CHKERRQ(ierr);
7703 
7704   Anumeric = A->ops->matmultnumeric;
7705   Bnumeric = B->ops->matmultnumeric;
7706   if (Anumeric == Bnumeric){
7707     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7708     numeric = Bnumeric;
7709   } else {
7710     char  numericname[256];
7711     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
7712     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7713     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
7714     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7715     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
7716     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
7717     if (!numeric)
7718       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7719   }
7720   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7721   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
7722   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7723   PetscFunctionReturn(0);
7724 }
7725 
7726 #undef __FUNCT__
7727 #define __FUNCT__ "MatMatMultTranspose"
7728 /*@
7729    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7730 
7731    Collective on Mat
7732 
7733    Input Parameters:
7734 +  A - the left matrix
7735 .  B - the right matrix
7736 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7737 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7738 
7739    Output Parameters:
7740 .  C - the product matrix
7741 
7742    Notes:
7743    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7744 
7745    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7746 
7747   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7748    actually needed.
7749 
7750    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7751    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
7752 
7753    Level: intermediate
7754 
7755 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7756 @*/
7757 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7758 {
7759   PetscErrorCode ierr;
7760   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7761   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7762 
7763   PetscFunctionBegin;
7764   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7765   PetscValidType(A,1);
7766   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7767   if (A->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7768   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
7769   PetscValidType(B,2);
7770   ierr = MatPreallocated(B);CHKERRQ(ierr);
7771   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7772   if (B->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7773   PetscValidPointer(C,3);
7774   if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7775   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7776   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7777   ierr = MatPreallocated(A);CHKERRQ(ierr);
7778 
7779   fA = A->ops->matmulttranspose;
7780   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7781   fB = B->ops->matmulttranspose;
7782   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7783   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);
7784 
7785   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7786   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
7787   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7788 
7789   PetscFunctionReturn(0);
7790 }
7791 
7792 #undef __FUNCT__
7793 #define __FUNCT__ "MatGetRedundantMatrix"
7794 /*@C
7795    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7796 
7797    Collective on Mat
7798 
7799    Input Parameters:
7800 +  mat - the matrix
7801 .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7802 .  subcomm - MPI communicator split from the communicator where mat resides in
7803 .  mlocal_red - number of local rows of the redundant matrix
7804 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7805 
7806    Output Parameter:
7807 .  matredundant - redundant matrix
7808 
7809    Notes:
7810    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7811    original matrix has not changed from that last call to MatGetRedundantMatrix().
7812 
7813    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7814    calling it.
7815 
7816    Only MPIAIJ matrix is supported.
7817 
7818    Level: advanced
7819 
7820    Concepts: subcommunicator
7821    Concepts: duplicate matrix
7822 
7823 .seealso: MatDestroy()
7824 @*/
7825 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7826 {
7827   PetscErrorCode ierr;
7828 
7829   PetscFunctionBegin;
7830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7831   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7832     PetscValidPointer(*matredundant,6);
7833     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
7834   }
7835   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7836   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7837   if (mat->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7838   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7839 
7840   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7841   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
7842   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7843   PetscFunctionReturn(0);
7844 }
7845