xref: /petsc/src/mat/interface/matrix.c (revision a5cbb4622ed52e72c8d7541d198395561ac0a2bf)
1 #define PETSCMAT_DLL
2 
3 /*
4    This is where the abstract matrix operations are defined
5 */
6 
7 #include "private/matimpl.h"        /*I "petscmat.h" I*/
8 #include "private/vecimpl.h"
9 
10 /* Logging support */
11 PetscCookie PETSCMAT_DLLEXPORT MAT_COOKIE;
12 PetscCookie PETSCMAT_DLLEXPORT MAT_FDCOLORING_COOKIE;
13 
14 PetscLogEvent  MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
15 PetscLogEvent  MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
16 PetscLogEvent  MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
17 PetscLogEvent  MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
18 PetscLogEvent  MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
19 PetscLogEvent  MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
20 PetscLogEvent  MAT_IncreaseOverlap, MAT_Partitioning, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
21 PetscLogEvent  MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
22 PetscLogEvent  MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
23 PetscLogEvent  MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric;
24 PetscLogEvent  MAT_MatMultTranspose, MAT_MatMultTransposeSymbolic, MAT_MatMultTransposeNumeric;
25 PetscLogEvent  MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
26 PetscLogEvent  MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
27 PetscLogEvent  MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
28 PetscLogEvent  MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
29 
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_COOKIE,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->factor) 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_COOKIE,1);
132   PetscValidType(mat,1);
133   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
134   if (mat->factor) 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_COOKIE,1);
166   PetscValidType(mat,1);
167   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
168   if (mat->factor) 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_COOKIE,1);
200   PetscValidType(mat,1);
201   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
202   if (mat->factor) 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_COOKIE,1);
234   PetscValidType(mat,1);
235   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
236   if (mat->factor) 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_COOKIE,1);
312   PetscValidType(mat,1);
313   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
314   if (mat->factor) 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_COOKIE,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_COOKIE,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_COOKIE,1);
424   PetscValidType(mat,1);
425   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
426   if (mat->factor) 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_COOKIE,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_COOKIE,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_COOKIE,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_COOKIE,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_COOKIE,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_COOKIE,1);
682   PetscValidType(mat,1);
683   if (!viewer) {
684     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
685   }
686   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,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->factor) {
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_COOKIE,1);
767   PetscValidType(mat,1);
768   ierr = MatPreallocated(mat);CHKERRQ(ierr);
769   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,3);PetscCheckSameComm(mat,1,x,3);}
770   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,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_COOKIE,1);
809   PetscValidType(mat,1);
810   ierr = MatPreallocated(mat);CHKERRQ(ierr);
811   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,3);PetscCheckSameComm(mat,1,x,3);}
812   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,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_COOKIE,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_COOKIE,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)->cookie != MAT_COOKIE) *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_COOKIE,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->factor) 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_COOKIE,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_COOKIE,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->factor) 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_COOKIE,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_COOKIE,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_COOKIE,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_COOKIE,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->factor) 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_COOKIE,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->factor) 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_COOKIE,1);
1571   PetscValidType(x,1);
1572   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,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_COOKIE,1);
1615   PetscValidType(x,1);
1616   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,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_COOKIE,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->factor) 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_COOKIE,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->factor) 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_COOKIE,1);
1835   PetscValidType(mat,1);
1836   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1837   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1838 
1839   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1840   if (mat->factor) 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_COOKIE,1);
1881   PetscValidType(mat,1);
1882   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1883   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1884 
1885   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1886   if (mat->factor) 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_COOKIE,1);
1941   PetscValidType(mat,1);
1942   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1943   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1944 
1945   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1946   if (mat->factor) 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_COOKIE,1);
1992   PetscValidType(mat,1);
1993   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1994   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1995 
1996   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1997   if (mat->factor) 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_COOKIE,1);
2043   PetscValidType(mat,1);
2044   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
2045   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
2046   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
2047 
2048   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2049   if (mat->factor) 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_COOKIE,1);
2095   PetscValidType(mat,1);
2096   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
2097   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
2098   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
2099 
2100   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2101   if (mat->factor) 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_COOKIE,1);
2146   PetscValidType(mat,1);
2147   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
2148   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
2149   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
2150 
2151   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2152   if (mat->factor) 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_COOKIE,1);
2197   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
2198   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
2199   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2200   if (mat->factor) 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_COOKIE,1);
2244   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
2245   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
2246   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2247   if (mat->factor) 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_COOKIE,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_COOKIE,1);
2381   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2382   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,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->factor) 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_COOKIE,1);
2438   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2439   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,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->factor) 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_COOKIE,1);
2497   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
2498   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,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->factor) 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_COOKIE,1);
2551   PetscValidType(mat,1);
2552   PetscValidPointer(fact,2);
2553   PetscValidHeaderSpecific(fact,MAT_COOKIE,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_COOKIE,1);
2607   PetscValidType(mat,1);
2608   PetscValidHeaderSpecific(perm,IS_COOKIE,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->factor) 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_COOKIE,1);
2665   PetscValidType(mat,1);
2666   if (perm) PetscValidHeaderSpecific(perm,IS_COOKIE,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->factor) 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_COOKIE,1);
2719   PetscValidType(mat,1);
2720   PetscValidPointer(fact,2);
2721   PetscValidHeaderSpecific(fact,MAT_COOKIE,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_COOKIE,1);
2774   PetscValidType(mat,1);
2775   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2776   PetscValidHeaderSpecific(x,VEC_COOKIE,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->factor) 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_COOKIE,1);
2860   PetscValidType(A,1);
2861   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
2862   PetscValidHeaderSpecific(X,MAT_COOKIE,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->factor) 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_COOKIE,1);
2930   PetscValidType(mat,1);
2931   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2932   PetscValidHeaderSpecific(x,VEC_COOKIE,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->factor) 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_COOKIE,1);
2993   PetscValidType(mat,1);
2994   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
2995   PetscValidHeaderSpecific(x,VEC_COOKIE,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->factor) 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_COOKIE,1);
3050   PetscValidType(mat,1);
3051   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
3052   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
3053   PetscValidHeaderSpecific(x,VEC_COOKIE,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->factor) 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_COOKIE,1);
3122   PetscValidType(mat,1);
3123   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
3124   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
3125   PetscCheckSameComm(mat,1,b,2);
3126   PetscCheckSameComm(mat,1,x,3);
3127   if (!mat->factor) 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_COOKIE,1);
3178   PetscValidType(mat,1);
3179   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
3180   PetscValidHeaderSpecific(b,VEC_COOKIE,3);
3181   PetscValidHeaderSpecific(x,VEC_COOKIE,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->factor) 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_COOKIE,1);
3280   PetscValidType(mat,1);
3281   PetscValidHeaderSpecific(b,VEC_COOKIE,2);
3282   PetscValidHeaderSpecific(x,VEC_COOKIE,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->factor) 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_COOKIE,1);
3366   PetscValidHeaderSpecific(B,MAT_COOKIE,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->factor) 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_COOKIE,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->factor) 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_COOKIE,1);
3561   PetscValidType(mat,1);
3562   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3563   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);CHKERRQ(ierr);
3564   if (!conv) {
3565     *type = MAT_SOLVER_PETSC;
3566   } else {
3567     ierr = (*conv)(mat,type);CHKERRQ(ierr);
3568   }
3569   PetscFunctionReturn(0);
3570 }
3571 
3572 #undef __FUNCT__
3573 #define __FUNCT__ "MatGetFactor"
3574 /*@C
3575    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3576 
3577    Collective on Mat
3578 
3579    Input Parameters:
3580 +  mat - the matrix
3581 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3582 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3583 
3584    Output Parameters:
3585 .  f - the factor matrix used with MatXXFactorSymbolic() calls
3586 
3587    Notes:
3588       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3589      such as pastix, superlu, mumps, spooles etc.
3590 
3591       PETSc must have been config/configure.py to use the external solver, using the option --download-package
3592 
3593    Level: intermediate
3594 
3595 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3596 @*/
3597 PetscErrorCode PETSCMAT_DLLEXPORT MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3598 {
3599   PetscErrorCode         ierr;
3600   char                   convname[256];
3601   PetscErrorCode         (*conv)(Mat,MatFactorType,Mat*);
3602 
3603   PetscFunctionBegin;
3604   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3605   PetscValidType(mat,1);
3606 
3607   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3608   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3609 
3610   ierr = PetscStrcpy(convname,"MatGetFactor_");CHKERRQ(ierr);
3611   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3612   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3613   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3614   if (!conv) {
3615     PetscTruth flag;
3616     ierr = PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);CHKERRQ(ierr);
3617     if (flag) {
3618       SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3619     } else {
3620       SETERRQ3(PETSC_ERR_SUP,"Matrix format %s does not have a solver %s. Perhaps you must config/configure.py with --download-%s",((PetscObject)mat)->type_name,type,type);
3621     }
3622   }
3623   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
3624   PetscFunctionReturn(0);
3625 }
3626 
3627 #undef __FUNCT__
3628 #define __FUNCT__ "MatGetFactorAvailable"
3629 /*@C
3630    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3631 
3632    Collective on Mat
3633 
3634    Input Parameters:
3635 +  mat - the matrix
3636 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3637 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3638 
3639    Output Parameter:
3640 .    flg - PETSC_TRUE if the factorization is available
3641 
3642    Notes:
3643       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3644      such as pastix, superlu, mumps, spooles etc.
3645 
3646       PETSc must have been config/configure.py to use the external solver, using the option --download-package
3647 
3648    Level: intermediate
3649 
3650 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3651 @*/
3652 PetscErrorCode PETSCMAT_DLLEXPORT MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3653 {
3654   PetscErrorCode         ierr;
3655   char                   convname[256];
3656   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscTruth*);
3657 
3658   PetscFunctionBegin;
3659   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
3660   PetscValidType(mat,1);
3661 
3662   if (mat->factor) 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_COOKIE,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->factor) 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_COOKIE,1);
3769   PetscValidType(mat,1);
3770   PetscValidHeaderSpecific(v,VEC_COOKIE,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_COOKIE,1);
3813   PetscValidType(mat,1);
3814   PetscValidHeaderSpecific(v,VEC_COOKIE,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_COOKIE,1);
3856   PetscValidType(mat,1);
3857   PetscValidHeaderSpecific(v,VEC_COOKIE,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_COOKIE,1);
3900   PetscValidType(mat,1);
3901   PetscValidHeaderSpecific(v,VEC_COOKIE,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_COOKIE,1);
3943   PetscValidType(mat,1);
3944   PetscValidHeaderSpecific(v,VEC_COOKIE,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_COOKIE,1);
3984   PetscValidType(mat,1);
3985   PetscValidHeaderSpecific(v,VEC_COOKIE,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_COOKIE,1);
4036   PetscValidType(mat,1);
4037   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4038   if (mat->factor) 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_COOKIE,1);
4081   PetscValidHeaderSpecific(B,MAT_COOKIE,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_COOKIE,1);
4161   PetscValidHeaderSpecific(B,MAT_COOKIE,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_COOKIE,1);
4206   PetscValidType(mat,1);
4207   PetscValidHeaderSpecific(row,IS_COOKIE,2);
4208   PetscValidHeaderSpecific(col,IS_COOKIE,3);
4209   PetscValidPointer(B,4);
4210   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4211   if (mat->factor) 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_COOKIE,1);
4266   PetscValidHeaderSpecific(rowp, IS_COOKIE,5);
4267   PetscValidHeaderSpecific(colp, IS_COOKIE,6);
4268   PetscValidPointer(B,7);
4269   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4270   if (A->factor)     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_COOKIE,1);
4351   PetscValidHeaderSpecific(B,MAT_COOKIE,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 
4387    Level: intermediate
4388 
4389    Concepts: matrices^diagonal scaling
4390    Concepts: diagonal scaling of matrices
4391 
4392 .seealso: MatScale()
4393 @*/
4394 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScale(Mat mat,Vec l,Vec r)
4395 {
4396   PetscErrorCode ierr;
4397 
4398   PetscFunctionBegin;
4399   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4400   PetscValidType(mat,1);
4401   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4402   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE,2);PetscCheckSameComm(mat,1,l,2);}
4403   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE,3);PetscCheckSameComm(mat,1,r,3);}
4404   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4405   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4406   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4407 
4408   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4409   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4410   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4411   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4412   PetscFunctionReturn(0);
4413 }
4414 
4415 #undef __FUNCT__
4416 #define __FUNCT__ "MatScale"
4417 /*@
4418     MatScale - Scales all elements of a matrix by a given number.
4419 
4420     Collective on Mat
4421 
4422     Input Parameters:
4423 +   mat - the matrix to be scaled
4424 -   a  - the scaling value
4425 
4426     Output Parameter:
4427 .   mat - the scaled matrix
4428 
4429     Level: intermediate
4430 
4431     Concepts: matrices^scaling all entries
4432 
4433 .seealso: MatDiagonalScale()
4434 @*/
4435 PetscErrorCode PETSCMAT_DLLEXPORT MatScale(Mat mat,PetscScalar a)
4436 {
4437   PetscErrorCode ierr;
4438 
4439   PetscFunctionBegin;
4440   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4441   PetscValidType(mat,1);
4442   if (a != 1.0 && !mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4443   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4444   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4445   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4446 
4447   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4448   if (a != 1.0) {
4449     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4450     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4451   }
4452   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4453   PetscFunctionReturn(0);
4454 }
4455 
4456 #undef __FUNCT__
4457 #define __FUNCT__ "MatNorm"
4458 /*@
4459    MatNorm - Calculates various norms of a matrix.
4460 
4461    Collective on Mat
4462 
4463    Input Parameters:
4464 +  mat - the matrix
4465 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4466 
4467    Output Parameters:
4468 .  nrm - the resulting norm
4469 
4470    Level: intermediate
4471 
4472    Concepts: matrices^norm
4473    Concepts: norm^of matrix
4474 @*/
4475 PetscErrorCode PETSCMAT_DLLEXPORT MatNorm(Mat mat,NormType type,PetscReal *nrm)
4476 {
4477   PetscErrorCode ierr;
4478 
4479   PetscFunctionBegin;
4480   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4481   PetscValidType(mat,1);
4482   PetscValidScalarPointer(nrm,3);
4483 
4484   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4485   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4486   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4487   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4488 
4489   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4490   PetscFunctionReturn(0);
4491 }
4492 
4493 /*
4494      This variable is used to prevent counting of MatAssemblyBegin() that
4495    are called from within a MatAssemblyEnd().
4496 */
4497 static PetscInt MatAssemblyEnd_InUse = 0;
4498 #undef __FUNCT__
4499 #define __FUNCT__ "MatAssemblyBegin"
4500 /*@
4501    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4502    be called after completing all calls to MatSetValues().
4503 
4504    Collective on Mat
4505 
4506    Input Parameters:
4507 +  mat - the matrix
4508 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4509 
4510    Notes:
4511    MatSetValues() generally caches the values.  The matrix is ready to
4512    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4513    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4514    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4515    using the matrix.
4516 
4517    Level: beginner
4518 
4519    Concepts: matrices^assembling
4520 
4521 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4522 @*/
4523 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyBegin(Mat mat,MatAssemblyType type)
4524 {
4525   PetscErrorCode ierr;
4526 
4527   PetscFunctionBegin;
4528   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4529   PetscValidType(mat,1);
4530   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4531   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4532   if (mat->assembled) {
4533     mat->was_assembled = PETSC_TRUE;
4534     mat->assembled     = PETSC_FALSE;
4535   }
4536   if (!MatAssemblyEnd_InUse) {
4537     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4538     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4539     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4540   } else {
4541     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4542   }
4543   PetscFunctionReturn(0);
4544 }
4545 
4546 #undef __FUNCT__
4547 #define __FUNCT__ "MatAssembled"
4548 /*@
4549    MatAssembled - Indicates if a matrix has been assembled and is ready for
4550      use; for example, in matrix-vector product.
4551 
4552    Collective on Mat
4553 
4554    Input Parameter:
4555 .  mat - the matrix
4556 
4557    Output Parameter:
4558 .  assembled - PETSC_TRUE or PETSC_FALSE
4559 
4560    Level: advanced
4561 
4562    Concepts: matrices^assembled?
4563 
4564 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4565 @*/
4566 PetscErrorCode PETSCMAT_DLLEXPORT MatAssembled(Mat mat,PetscTruth *assembled)
4567 {
4568   PetscFunctionBegin;
4569   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4570   PetscValidType(mat,1);
4571   PetscValidPointer(assembled,2);
4572   *assembled = mat->assembled;
4573   PetscFunctionReturn(0);
4574 }
4575 
4576 #undef __FUNCT__
4577 #define __FUNCT__ "MatView_Private"
4578 /*
4579     Processes command line options to determine if/how a matrix
4580   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4581 */
4582 PetscErrorCode MatView_Private(Mat mat)
4583 {
4584   PetscErrorCode    ierr;
4585   PetscTruth        flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4586   static PetscTruth incall = PETSC_FALSE;
4587 #if defined(PETSC_USE_SOCKET_VIEWER)
4588   PetscTruth        flg5 = PETSC_FALSE;
4589 #endif
4590 
4591   PetscFunctionBegin;
4592   if (incall) PetscFunctionReturn(0);
4593   incall = PETSC_TRUE;
4594   ierr = PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
4595     ierr = PetscOptionsTruth("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);CHKERRQ(ierr);
4596     ierr = PetscOptionsTruth("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);CHKERRQ(ierr);
4597     ierr = PetscOptionsTruth("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);CHKERRQ(ierr);
4598     ierr = PetscOptionsTruth("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);CHKERRQ(ierr);
4599 #if defined(PETSC_USE_SOCKET_VIEWER)
4600     ierr = PetscOptionsTruth("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);CHKERRQ(ierr);
4601 #endif
4602     ierr = PetscOptionsTruth("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);CHKERRQ(ierr);
4603     ierr = PetscOptionsTruth("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);CHKERRQ(ierr);
4604   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4605 
4606   if (flg1) {
4607     PetscViewer viewer;
4608 
4609     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4610     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4611     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4612     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4613   }
4614   if (flg2) {
4615     PetscViewer viewer;
4616 
4617     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4618     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4619     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4620     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4621   }
4622   if (flg3) {
4623     PetscViewer viewer;
4624 
4625     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4626     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4627   }
4628   if (flg4) {
4629     PetscViewer viewer;
4630 
4631     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4632     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4633     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4634     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4635   }
4636 #if defined(PETSC_USE_SOCKET_VIEWER)
4637   if (flg5) {
4638     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4639     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4640   }
4641 #endif
4642   if (flg6) {
4643     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4644     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4645   }
4646   if (flg7) {
4647     ierr = PetscOptionsGetTruth(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);CHKERRQ(ierr);
4648     if (flg8) {
4649       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4650     }
4651     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4652     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4653     if (flg8) {
4654       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4655     }
4656   }
4657   incall = PETSC_FALSE;
4658   PetscFunctionReturn(0);
4659 }
4660 
4661 #undef __FUNCT__
4662 #define __FUNCT__ "MatAssemblyEnd"
4663 /*@
4664    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4665    be called after MatAssemblyBegin().
4666 
4667    Collective on Mat
4668 
4669    Input Parameters:
4670 +  mat - the matrix
4671 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4672 
4673    Options Database Keys:
4674 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4675 .  -mat_view_info_detailed - Prints more detailed info
4676 .  -mat_view - Prints matrix in ASCII format
4677 .  -mat_view_matlab - Prints matrix in Matlab format
4678 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4679 .  -display <name> - Sets display name (default is host)
4680 .  -draw_pause <sec> - Sets number of seconds to pause after display
4681 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4682 .  -viewer_socket_machine <machine>
4683 .  -viewer_socket_port <port>
4684 .  -mat_view_binary - save matrix to file in binary format
4685 -  -viewer_binary_filename <name>
4686 
4687    Notes:
4688    MatSetValues() generally caches the values.  The matrix is ready to
4689    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4690    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4691    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4692    using the matrix.
4693 
4694    Level: beginner
4695 
4696 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4697 @*/
4698 PetscErrorCode PETSCMAT_DLLEXPORT MatAssemblyEnd(Mat mat,MatAssemblyType type)
4699 {
4700   PetscErrorCode  ierr;
4701   static PetscInt inassm = 0;
4702   PetscTruth      flg = PETSC_FALSE;
4703 
4704   PetscFunctionBegin;
4705   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4706   PetscValidType(mat,1);
4707 
4708   inassm++;
4709   MatAssemblyEnd_InUse++;
4710   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4711     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4712     if (mat->ops->assemblyend) {
4713       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4714     }
4715     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4716   } else {
4717     if (mat->ops->assemblyend) {
4718       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4719     }
4720   }
4721 
4722   /* Flush assembly is not a true assembly */
4723   if (type != MAT_FLUSH_ASSEMBLY) {
4724     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4725   }
4726   mat->insertmode = NOT_SET_VALUES;
4727   MatAssemblyEnd_InUse--;
4728   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4729   if (!mat->symmetric_eternal) {
4730     mat->symmetric_set              = PETSC_FALSE;
4731     mat->hermitian_set              = PETSC_FALSE;
4732     mat->structurally_symmetric_set = PETSC_FALSE;
4733   }
4734   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4735     ierr = MatView_Private(mat);CHKERRQ(ierr);
4736     ierr = PetscOptionsGetTruth(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);CHKERRQ(ierr);
4737     if (flg) {
4738       PetscReal tol = 0.0;
4739       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
4740       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
4741       if (flg) {
4742         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4743       } else {
4744         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4745       }
4746     }
4747   }
4748   inassm--;
4749   PetscFunctionReturn(0);
4750 }
4751 
4752 #undef __FUNCT__
4753 #define __FUNCT__ "MatSetOption"
4754 /*@
4755    MatSetOption - Sets a parameter option for a matrix. Some options
4756    may be specific to certain storage formats.  Some options
4757    determine how values will be inserted (or added). Sorted,
4758    row-oriented input will generally assemble the fastest. The default
4759    is row-oriented, nonsorted input.
4760 
4761    Collective on Mat
4762 
4763    Input Parameters:
4764 +  mat - the matrix
4765 .  option - the option, one of those listed below (and possibly others),
4766 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4767 
4768   Options Describing Matrix Structure:
4769 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
4770 .    MAT_HERMITIAN - transpose is the complex conjugation
4771 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4772 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4773                             you set to be kept with all future use of the matrix
4774                             including after MatAssemblyBegin/End() which could
4775                             potentially change the symmetry structure, i.e. you
4776                             KNOW the matrix will ALWAYS have the property you set.
4777 
4778 
4779    Options For Use with MatSetValues():
4780    Insert a logically dense subblock, which can be
4781 .    MAT_ROW_ORIENTED - row-oriented (default)
4782 
4783    Note these options reflect the data you pass in with MatSetValues(); it has
4784    nothing to do with how the data is stored internally in the matrix
4785    data structure.
4786 
4787    When (re)assembling a matrix, we can restrict the input for
4788    efficiency/debugging purposes.  These options include
4789 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4790         allowed if they generate a new nonzero
4791 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4792 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4793 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4794 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4795 
4796    Notes:
4797    Some options are relevant only for particular matrix types and
4798    are thus ignored by others.  Other options are not supported by
4799    certain matrix types and will generate an error message if set.
4800 
4801    If using a Fortran 77 module to compute a matrix, one may need to
4802    use the column-oriented option (or convert to the row-oriented
4803    format).
4804 
4805    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4806    that would generate a new entry in the nonzero structure is instead
4807    ignored.  Thus, if memory has not alredy been allocated for this particular
4808    data, then the insertion is ignored. For dense matrices, in which
4809    the entire array is allocated, no entries are ever ignored.
4810    Set after the first MatAssemblyEnd()
4811 
4812    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4813    that would generate a new entry in the nonzero structure instead produces
4814    an error. (Currently supported for AIJ and BAIJ formats only.)
4815    This is a useful flag when using SAME_NONZERO_PATTERN in calling
4816    KSPSetOperators() to ensure that the nonzero pattern truely does
4817    remain unchanged. Set after the first MatAssemblyEnd()
4818 
4819    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
4820    that would generate a new entry that has not been preallocated will
4821    instead produce an error. (Currently supported for AIJ and BAIJ formats
4822    only.) This is a useful flag when debugging matrix memory preallocation.
4823 
4824    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
4825    other processors should be dropped, rather than stashed.
4826    This is useful if you know that the "owning" processor is also
4827    always generating the correct matrix entries, so that PETSc need
4828    not transfer duplicate entries generated on another processor.
4829 
4830    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4831    searches during matrix assembly. When this flag is set, the hash table
4832    is created during the first Matrix Assembly. This hash table is
4833    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4834    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
4835    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4836    supported by MATMPIBAIJ format only.
4837 
4838    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
4839    are kept in the nonzero structure
4840 
4841    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
4842    a zero location in the matrix
4843 
4844    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
4845    ROWBS matrix types
4846 
4847    Level: intermediate
4848 
4849    Concepts: matrices^setting options
4850 
4851 @*/
4852 PetscErrorCode PETSCMAT_DLLEXPORT MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4853 {
4854   PetscErrorCode ierr;
4855 
4856   PetscFunctionBegin;
4857   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4858   PetscValidType(mat,1);
4859   if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4860   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4861   switch (op) {
4862   case MAT_SYMMETRIC:
4863     mat->symmetric                  = flg;
4864     if (flg) mat->structurally_symmetric = PETSC_TRUE;
4865     mat->symmetric_set              = PETSC_TRUE;
4866     mat->structurally_symmetric_set = flg;
4867     break;
4868   case MAT_HERMITIAN:
4869     mat->hermitian                  = flg;
4870     if (flg) mat->structurally_symmetric = PETSC_TRUE;
4871     mat->hermitian_set              = PETSC_TRUE;
4872     mat->structurally_symmetric_set = flg;
4873     break;
4874   case MAT_STRUCTURALLY_SYMMETRIC:
4875     mat->structurally_symmetric     = flg;
4876     mat->structurally_symmetric_set = PETSC_TRUE;
4877     break;
4878   case MAT_SYMMETRY_ETERNAL:
4879     mat->symmetric_eternal          = flg;
4880     break;
4881   default:
4882     break;
4883   }
4884   if (mat->ops->setoption) {
4885     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
4886   }
4887   PetscFunctionReturn(0);
4888 }
4889 
4890 #undef __FUNCT__
4891 #define __FUNCT__ "MatZeroEntries"
4892 /*@
4893    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4894    this routine retains the old nonzero structure.
4895 
4896    Collective on Mat
4897 
4898    Input Parameters:
4899 .  mat - the matrix
4900 
4901    Level: intermediate
4902 
4903    Concepts: matrices^zeroing
4904 
4905 .seealso: MatZeroRows()
4906 @*/
4907 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroEntries(Mat mat)
4908 {
4909   PetscErrorCode ierr;
4910 
4911   PetscFunctionBegin;
4912   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4913   PetscValidType(mat,1);
4914   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4915   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4916   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4917   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4918 
4919   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4920   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
4921   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
4922   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4923   PetscFunctionReturn(0);
4924 }
4925 
4926 #undef __FUNCT__
4927 #define __FUNCT__ "MatZeroRows"
4928 /*@C
4929    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4930    of a set of rows of a matrix.
4931 
4932    Collective on Mat
4933 
4934    Input Parameters:
4935 +  mat - the matrix
4936 .  numRows - the number of rows to remove
4937 .  rows - the global row indices
4938 -  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
4939 
4940    Notes:
4941    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4942    but does not release memory.  For the dense and block diagonal
4943    formats this does not alter the nonzero structure.
4944 
4945    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
4946    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4947    merely zeroed.
4948 
4949    The user can set a value in the diagonal entry (or for the AIJ and
4950    row formats can optionally remove the main diagonal entry from the
4951    nonzero structure as well, by passing 0.0 as the final argument).
4952 
4953    For the parallel case, all processes that share the matrix (i.e.,
4954    those in the communicator used for matrix creation) MUST call this
4955    routine, regardless of whether any rows being zeroed are owned by
4956    them.
4957 
4958    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
4959    list only rows local to itself).
4960 
4961    Level: intermediate
4962 
4963    Concepts: matrices^zeroing rows
4964 
4965 .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4966 @*/
4967 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4968 {
4969   PetscErrorCode ierr;
4970 
4971   PetscFunctionBegin;
4972   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
4973   PetscValidType(mat,1);
4974   if (numRows) PetscValidIntPointer(rows,3);
4975   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4976   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4977   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4978   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4979 
4980   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag);CHKERRQ(ierr);
4981   ierr = MatView_Private(mat);CHKERRQ(ierr);
4982   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4983   PetscFunctionReturn(0);
4984 }
4985 
4986 #undef __FUNCT__
4987 #define __FUNCT__ "MatZeroRowsIS"
4988 /*@C
4989    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4990    of a set of rows of a matrix.
4991 
4992    Collective on Mat
4993 
4994    Input Parameters:
4995 +  mat - the matrix
4996 .  is - index set of rows to remove
4997 -  diag - value put in all diagonals of eliminated rows
4998 
4999    Notes:
5000    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5001    but does not release memory.  For the dense and block diagonal
5002    formats this does not alter the nonzero structure.
5003 
5004    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5005    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5006    merely zeroed.
5007 
5008    The user can set a value in the diagonal entry (or for the AIJ and
5009    row formats can optionally remove the main diagonal entry from the
5010    nonzero structure as well, by passing 0.0 as the final argument).
5011 
5012    For the parallel case, all processes that share the matrix (i.e.,
5013    those in the communicator used for matrix creation) MUST call this
5014    routine, regardless of whether any rows being zeroed are owned by
5015    them.
5016 
5017    Each processor should list the rows that IT wants zeroed
5018 
5019    Level: intermediate
5020 
5021    Concepts: matrices^zeroing rows
5022 
5023 .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5024 @*/
5025 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
5026 {
5027   PetscInt       numRows;
5028   const PetscInt *rows;
5029   PetscErrorCode ierr;
5030 
5031   PetscFunctionBegin;
5032   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5033   PetscValidType(mat,1);
5034   PetscValidHeaderSpecific(is,IS_COOKIE,2);
5035   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5036   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5037   ierr = MatZeroRows(mat,numRows,rows,diag);CHKERRQ(ierr);
5038   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5039   PetscFunctionReturn(0);
5040 }
5041 
5042 #undef __FUNCT__
5043 #define __FUNCT__ "MatZeroRowsLocal"
5044 /*@C
5045    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5046    of a set of rows of a matrix; using local numbering of rows.
5047 
5048    Collective on Mat
5049 
5050    Input Parameters:
5051 +  mat - the matrix
5052 .  numRows - the number of rows to remove
5053 .  rows - the global row indices
5054 -  diag - value put in all diagonals of eliminated rows
5055 
5056    Notes:
5057    Before calling MatZeroRowsLocal(), the user must first set the
5058    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5059 
5060    For the AIJ matrix formats this removes the old nonzero structure,
5061    but does not release memory.  For the dense and block diagonal
5062    formats this does not alter the nonzero structure.
5063 
5064    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5065    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5066    merely zeroed.
5067 
5068    The user can set a value in the diagonal entry (or for the AIJ and
5069    row formats can optionally remove the main diagonal entry from the
5070    nonzero structure as well, by passing 0.0 as the final argument).
5071 
5072    Level: intermediate
5073 
5074    Concepts: matrices^zeroing
5075 
5076 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5077 @*/
5078 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
5079 {
5080   PetscErrorCode ierr;
5081 
5082   PetscFunctionBegin;
5083   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5084   PetscValidType(mat,1);
5085   if (numRows) PetscValidIntPointer(rows,3);
5086   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5087   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5088   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5089 
5090   if (mat->ops->zerorowslocal) {
5091     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);CHKERRQ(ierr);
5092   } else {
5093     IS             is, newis;
5094     const PetscInt *newRows;
5095 
5096     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5097     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);CHKERRQ(ierr);
5098     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
5099     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5100     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag);CHKERRQ(ierr);
5101     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5102     ierr = ISDestroy(newis);CHKERRQ(ierr);
5103     ierr = ISDestroy(is);CHKERRQ(ierr);
5104   }
5105   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5106   PetscFunctionReturn(0);
5107 }
5108 
5109 #undef __FUNCT__
5110 #define __FUNCT__ "MatZeroRowsLocalIS"
5111 /*@C
5112    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5113    of a set of rows of a matrix; using local numbering of rows.
5114 
5115    Collective on Mat
5116 
5117    Input Parameters:
5118 +  mat - the matrix
5119 .  is - index set of rows to remove
5120 -  diag - value put in all diagonals of eliminated rows
5121 
5122    Notes:
5123    Before calling MatZeroRowsLocalIS(), the user must first set the
5124    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5125 
5126    For the AIJ matrix formats this removes the old nonzero structure,
5127    but does not release memory.  For the dense and block diagonal
5128    formats this does not alter the nonzero structure.
5129 
5130    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5131    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5132    merely zeroed.
5133 
5134    The user can set a value in the diagonal entry (or for the AIJ and
5135    row formats can optionally remove the main diagonal entry from the
5136    nonzero structure as well, by passing 0.0 as the final argument).
5137 
5138    Level: intermediate
5139 
5140    Concepts: matrices^zeroing
5141 
5142 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5143 @*/
5144 PetscErrorCode PETSCMAT_DLLEXPORT MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
5145 {
5146   PetscErrorCode ierr;
5147   PetscInt       numRows;
5148   const PetscInt *rows;
5149 
5150   PetscFunctionBegin;
5151   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5152   PetscValidType(mat,1);
5153   PetscValidHeaderSpecific(is,IS_COOKIE,2);
5154   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5155   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5156   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5157 
5158   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5159   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5160   ierr = MatZeroRowsLocal(mat,numRows,rows,diag);CHKERRQ(ierr);
5161   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5162   PetscFunctionReturn(0);
5163 }
5164 
5165 #undef __FUNCT__
5166 #define __FUNCT__ "MatGetSize"
5167 /*@
5168    MatGetSize - Returns the numbers of rows and columns in a matrix.
5169 
5170    Not Collective
5171 
5172    Input Parameter:
5173 .  mat - the matrix
5174 
5175    Output Parameters:
5176 +  m - the number of global rows
5177 -  n - the number of global columns
5178 
5179    Note: both output parameters can be PETSC_NULL on input.
5180 
5181    Level: beginner
5182 
5183    Concepts: matrices^size
5184 
5185 .seealso: MatGetLocalSize()
5186 @*/
5187 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5188 {
5189   PetscFunctionBegin;
5190   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5191   if (m) *m = mat->rmap->N;
5192   if (n) *n = mat->cmap->N;
5193   PetscFunctionReturn(0);
5194 }
5195 
5196 #undef __FUNCT__
5197 #define __FUNCT__ "MatGetLocalSize"
5198 /*@
5199    MatGetLocalSize - Returns the number of rows and columns in a matrix
5200    stored locally.  This information may be implementation dependent, so
5201    use with care.
5202 
5203    Not Collective
5204 
5205    Input Parameters:
5206 .  mat - the matrix
5207 
5208    Output Parameters:
5209 +  m - the number of local rows
5210 -  n - the number of local columns
5211 
5212    Note: both output parameters can be PETSC_NULL on input.
5213 
5214    Level: beginner
5215 
5216    Concepts: matrices^local size
5217 
5218 .seealso: MatGetSize()
5219 @*/
5220 PetscErrorCode PETSCMAT_DLLEXPORT MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5221 {
5222   PetscFunctionBegin;
5223   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5224   if (m) PetscValidIntPointer(m,2);
5225   if (n) PetscValidIntPointer(n,3);
5226   if (m) *m = mat->rmap->n;
5227   if (n) *n = mat->cmap->n;
5228   PetscFunctionReturn(0);
5229 }
5230 
5231 #undef __FUNCT__
5232 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5233 /*@
5234    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5235    this processor.
5236 
5237    Not Collective, unless matrix has not been allocated, then collective on Mat
5238 
5239    Input Parameters:
5240 .  mat - the matrix
5241 
5242    Output Parameters:
5243 +  m - the global index of the first local column
5244 -  n - one more than the global index of the last local column
5245 
5246    Notes: both output parameters can be PETSC_NULL on input.
5247 
5248    Level: developer
5249 
5250    Concepts: matrices^column ownership
5251 
5252 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5253 
5254 @*/
5255 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5256 {
5257   PetscErrorCode ierr;
5258 
5259   PetscFunctionBegin;
5260   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5261   PetscValidType(mat,1);
5262   if (m) PetscValidIntPointer(m,2);
5263   if (n) PetscValidIntPointer(n,3);
5264   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5265   if (m) *m = mat->cmap->rstart;
5266   if (n) *n = mat->cmap->rend;
5267   PetscFunctionReturn(0);
5268 }
5269 
5270 #undef __FUNCT__
5271 #define __FUNCT__ "MatGetOwnershipRange"
5272 /*@
5273    MatGetOwnershipRange - Returns the range of matrix rows owned by
5274    this processor, assuming that the matrix is laid out with the first
5275    n1 rows on the first processor, the next n2 rows on the second, etc.
5276    For certain parallel layouts this range may not be well defined.
5277 
5278    Not Collective, unless matrix has not been allocated, then collective on Mat
5279 
5280    Input Parameters:
5281 .  mat - the matrix
5282 
5283    Output Parameters:
5284 +  m - the global index of the first local row
5285 -  n - one more than the global index of the last local row
5286 
5287    Note: both output parameters can be PETSC_NULL on input.
5288 
5289    Level: beginner
5290 
5291    Concepts: matrices^row ownership
5292 
5293 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5294 
5295 @*/
5296 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5297 {
5298   PetscErrorCode ierr;
5299 
5300   PetscFunctionBegin;
5301   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5302   PetscValidType(mat,1);
5303   if (m) PetscValidIntPointer(m,2);
5304   if (n) PetscValidIntPointer(n,3);
5305   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5306   if (m) *m = mat->rmap->rstart;
5307   if (n) *n = mat->rmap->rend;
5308   PetscFunctionReturn(0);
5309 }
5310 
5311 #undef __FUNCT__
5312 #define __FUNCT__ "MatGetOwnershipRanges"
5313 /*@C
5314    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5315    each process
5316 
5317    Not Collective, unless matrix has not been allocated, then collective on Mat
5318 
5319    Input Parameters:
5320 .  mat - the matrix
5321 
5322    Output Parameters:
5323 .  ranges - start of each processors portion plus one more then the total length at the end
5324 
5325    Level: beginner
5326 
5327    Concepts: matrices^row ownership
5328 
5329 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5330 
5331 @*/
5332 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5333 {
5334   PetscErrorCode ierr;
5335 
5336   PetscFunctionBegin;
5337   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5338   PetscValidType(mat,1);
5339   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5340   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
5341   PetscFunctionReturn(0);
5342 }
5343 
5344 #undef __FUNCT__
5345 #define __FUNCT__ "MatGetOwnershipRangesColumn"
5346 /*@C
5347    MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5348 
5349    Not Collective, unless matrix has not been allocated, then collective on Mat
5350 
5351    Input Parameters:
5352 .  mat - the matrix
5353 
5354    Output Parameters:
5355 .  ranges - start of each processors portion plus one more then the total length at the end
5356 
5357    Level: beginner
5358 
5359    Concepts: matrices^column ownership
5360 
5361 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5362 
5363 @*/
5364 PetscErrorCode PETSCMAT_DLLEXPORT MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5365 {
5366   PetscErrorCode ierr;
5367 
5368   PetscFunctionBegin;
5369   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5370   PetscValidType(mat,1);
5371   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5372   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
5373   PetscFunctionReturn(0);
5374 }
5375 
5376 #undef __FUNCT__
5377 #define __FUNCT__ "MatILUFactorSymbolic"
5378 /*@C
5379    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5380    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5381    to complete the factorization.
5382 
5383    Collective on Mat
5384 
5385    Input Parameters:
5386 +  mat - the matrix
5387 .  row - row permutation
5388 .  column - column permutation
5389 -  info - structure containing
5390 $      levels - number of levels of fill.
5391 $      expected fill - as ratio of original fill.
5392 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5393                 missing diagonal entries)
5394 
5395    Output Parameters:
5396 .  fact - new matrix that has been symbolically factored
5397 
5398    Notes:
5399    See the users manual for additional information about
5400    choosing the fill factor for better efficiency.
5401 
5402    Most users should employ the simplified KSP interface for linear solvers
5403    instead of working directly with matrix algebra routines such as this.
5404    See, e.g., KSPCreate().
5405 
5406    Level: developer
5407 
5408   Concepts: matrices^symbolic LU factorization
5409   Concepts: matrices^factorization
5410   Concepts: LU^symbolic factorization
5411 
5412 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5413           MatGetOrdering(), MatFactorInfo
5414 
5415     Developer Note: fortran interface is not autogenerated as the f90
5416     interface defintion cannot be generated correctly [due to MatFactorInfo]
5417 
5418 @*/
5419 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5420 {
5421   PetscErrorCode ierr;
5422 
5423   PetscFunctionBegin;
5424   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5425   PetscValidType(mat,1);
5426   PetscValidHeaderSpecific(row,IS_COOKIE,2);
5427   PetscValidHeaderSpecific(col,IS_COOKIE,3);
5428   PetscValidPointer(info,4);
5429   PetscValidPointer(fact,5);
5430   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5431   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5432   if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
5433   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5434   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5435   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5436 
5437   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5438   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
5439   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
5440   PetscFunctionReturn(0);
5441 }
5442 
5443 #undef __FUNCT__
5444 #define __FUNCT__ "MatICCFactorSymbolic"
5445 /*@C
5446    MatICCFactorSymbolic - Performs symbolic incomplete
5447    Cholesky factorization for a symmetric matrix.  Use
5448    MatCholeskyFactorNumeric() to complete the factorization.
5449 
5450    Collective on Mat
5451 
5452    Input Parameters:
5453 +  mat - the matrix
5454 .  perm - row and column permutation
5455 -  info - structure containing
5456 $      levels - number of levels of fill.
5457 $      expected fill - as ratio of original fill.
5458 
5459    Output Parameter:
5460 .  fact - the factored matrix
5461 
5462    Notes:
5463    Most users should employ the KSP interface for linear solvers
5464    instead of working directly with matrix algebra routines such as this.
5465    See, e.g., KSPCreate().
5466 
5467    Level: developer
5468 
5469   Concepts: matrices^symbolic incomplete Cholesky factorization
5470   Concepts: matrices^factorization
5471   Concepts: Cholsky^symbolic factorization
5472 
5473 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
5474 
5475     Developer Note: fortran interface is not autogenerated as the f90
5476     interface defintion cannot be generated correctly [due to MatFactorInfo]
5477 
5478 @*/
5479 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5480 {
5481   PetscErrorCode ierr;
5482 
5483   PetscFunctionBegin;
5484   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5485   PetscValidType(mat,1);
5486   PetscValidHeaderSpecific(perm,IS_COOKIE,2);
5487   PetscValidPointer(info,3);
5488   PetscValidPointer(fact,4);
5489   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5490   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5491   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5492   if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
5493   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5494   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5495 
5496   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5497   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
5498   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
5499   PetscFunctionReturn(0);
5500 }
5501 
5502 #undef __FUNCT__
5503 #define __FUNCT__ "MatGetArray"
5504 /*@C
5505    MatGetArray - Returns a pointer to the element values in the matrix.
5506    The result of this routine is dependent on the underlying matrix data
5507    structure, and may not even work for certain matrix types.  You MUST
5508    call MatRestoreArray() when you no longer need to access the array.
5509 
5510    Not Collective
5511 
5512    Input Parameter:
5513 .  mat - the matrix
5514 
5515    Output Parameter:
5516 .  v - the location of the values
5517 
5518 
5519    Fortran Note:
5520    This routine is used differently from Fortran, e.g.,
5521 .vb
5522         Mat         mat
5523         PetscScalar mat_array(1)
5524         PetscOffset i_mat
5525         PetscErrorCode ierr
5526         call MatGetArray(mat,mat_array,i_mat,ierr)
5527 
5528   C  Access first local entry in matrix; note that array is
5529   C  treated as one dimensional
5530         value = mat_array(i_mat + 1)
5531 
5532         [... other code ...]
5533         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5534 .ve
5535 
5536    See the Fortran chapter of the users manual and
5537    petsc/src/mat/examples/tests for details.
5538 
5539    Level: advanced
5540 
5541    Concepts: matrices^access array
5542 
5543 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5544 @*/
5545 PetscErrorCode PETSCMAT_DLLEXPORT MatGetArray(Mat mat,PetscScalar *v[])
5546 {
5547   PetscErrorCode ierr;
5548 
5549   PetscFunctionBegin;
5550   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5551   PetscValidType(mat,1);
5552   PetscValidPointer(v,2);
5553   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5554   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5555   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
5556   CHKMEMQ;
5557   PetscFunctionReturn(0);
5558 }
5559 
5560 #undef __FUNCT__
5561 #define __FUNCT__ "MatRestoreArray"
5562 /*@C
5563    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
5564 
5565    Not Collective
5566 
5567    Input Parameter:
5568 +  mat - the matrix
5569 -  v - the location of the values
5570 
5571    Fortran Note:
5572    This routine is used differently from Fortran, e.g.,
5573 .vb
5574         Mat         mat
5575         PetscScalar mat_array(1)
5576         PetscOffset i_mat
5577         PetscErrorCode ierr
5578         call MatGetArray(mat,mat_array,i_mat,ierr)
5579 
5580   C  Access first local entry in matrix; note that array is
5581   C  treated as one dimensional
5582         value = mat_array(i_mat + 1)
5583 
5584         [... other code ...]
5585         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5586 .ve
5587 
5588    See the Fortran chapter of the users manual and
5589    petsc/src/mat/examples/tests for details
5590 
5591    Level: advanced
5592 
5593 .seealso: MatGetArray(), MatRestoreArrayF90()
5594 @*/
5595 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreArray(Mat mat,PetscScalar *v[])
5596 {
5597   PetscErrorCode ierr;
5598 
5599   PetscFunctionBegin;
5600   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5601   PetscValidType(mat,1);
5602   PetscValidPointer(v,2);
5603 #if defined(PETSC_USE_DEBUG)
5604   CHKMEMQ;
5605 #endif
5606   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5607   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
5608   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5609   PetscFunctionReturn(0);
5610 }
5611 
5612 #undef __FUNCT__
5613 #define __FUNCT__ "MatGetSubMatrices"
5614 /*@C
5615    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5616    points to an array of valid matrices, they may be reused to store the new
5617    submatrices.
5618 
5619    Collective on Mat
5620 
5621    Input Parameters:
5622 +  mat - the matrix
5623 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5624 .  irow, icol - index sets of rows and columns to extract
5625 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
5626 
5627    Output Parameter:
5628 .  submat - the array of submatrices
5629 
5630    Notes:
5631    MatGetSubMatrices() can extract ONLY sequential submatrices
5632    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5633    to extract a parallel submatrix.
5634 
5635    When extracting submatrices from a parallel matrix, each processor can
5636    form a different submatrix by setting the rows and columns of its
5637    individual index sets according to the local submatrix desired.
5638 
5639    When finished using the submatrices, the user should destroy
5640    them with MatDestroyMatrices().
5641 
5642    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
5643    original matrix has not changed from that last call to MatGetSubMatrices().
5644 
5645    This routine creates the matrices in submat; you should NOT create them before
5646    calling it. It also allocates the array of matrix pointers submat.
5647 
5648    For BAIJ matrices the index sets must respect the block structure, that is if they
5649    request one row/column in a block, they must request all rows/columns that are in
5650    that block. For example, if the block size is 2 you cannot request just row 0 and
5651    column 0.
5652 
5653    Fortran Note:
5654    The Fortran interface is slightly different from that given below; it
5655    requires one to pass in  as submat a Mat (integer) array of size at least m.
5656 
5657    Level: advanced
5658 
5659    Concepts: matrices^accessing submatrices
5660    Concepts: submatrices
5661 
5662 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5663 @*/
5664 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5665 {
5666   PetscErrorCode ierr;
5667   PetscInt        i;
5668   PetscTruth      eq;
5669 
5670   PetscFunctionBegin;
5671   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5672   PetscValidType(mat,1);
5673   if (n) {
5674     PetscValidPointer(irow,3);
5675     PetscValidHeaderSpecific(*irow,IS_COOKIE,3);
5676     PetscValidPointer(icol,4);
5677     PetscValidHeaderSpecific(*icol,IS_COOKIE,4);
5678   }
5679   PetscValidPointer(submat,6);
5680   if (n && scall == MAT_REUSE_MATRIX) {
5681     PetscValidPointer(*submat,6);
5682     PetscValidHeaderSpecific(**submat,MAT_COOKIE,6);
5683   }
5684   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5685   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5686   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5687   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5688 
5689   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5690   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
5691   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
5692   for (i=0; i<n; i++) {
5693     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5694       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
5695       if (eq) {
5696 	if (mat->symmetric){
5697 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5698 	} else if (mat->hermitian) {
5699 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
5700 	} else if (mat->structurally_symmetric) {
5701 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
5702 	}
5703       }
5704     }
5705   }
5706   PetscFunctionReturn(0);
5707 }
5708 
5709 #undef __FUNCT__
5710 #define __FUNCT__ "MatDestroyMatrices"
5711 /*@C
5712    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
5713 
5714    Collective on Mat
5715 
5716    Input Parameters:
5717 +  n - the number of local matrices
5718 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5719                        sequence of MatGetSubMatrices())
5720 
5721    Level: advanced
5722 
5723     Notes: Frees not only the matrices, but also the array that contains the matrices
5724            In Fortran will not free the array.
5725 
5726 .seealso: MatGetSubMatrices()
5727 @*/
5728 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroyMatrices(PetscInt n,Mat *mat[])
5729 {
5730   PetscErrorCode ierr;
5731   PetscInt       i;
5732 
5733   PetscFunctionBegin;
5734   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5735   PetscValidPointer(mat,2);
5736   for (i=0; i<n; i++) {
5737     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
5738   }
5739   /* memory is allocated even if n = 0 */
5740   ierr = PetscFree(*mat);CHKERRQ(ierr);
5741   PetscFunctionReturn(0);
5742 }
5743 
5744 #undef __FUNCT__
5745 #define __FUNCT__ "MatGetSeqNonzeroStructure"
5746 /*@C
5747    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
5748 
5749    Collective on Mat
5750 
5751    Input Parameters:
5752 .  mat - the matrix
5753 
5754    Output Parameter:
5755 .  matstruct - the sequential matrix with the nonzero structure of mat
5756 
5757   Level: intermediate
5758 
5759 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5760 @*/
5761 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
5762 {
5763   PetscErrorCode ierr;
5764 
5765   PetscFunctionBegin;
5766   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5767   PetscValidPointer(matstruct,2);
5768 
5769   PetscValidType(mat,1);
5770   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5771   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5772 
5773   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
5774   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5775   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
5776   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
5777   PetscFunctionReturn(0);
5778 }
5779 
5780 #undef __FUNCT__
5781 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
5782 /*@C
5783    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
5784 
5785    Collective on Mat
5786 
5787    Input Parameters:
5788 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
5789                        sequence of MatGetSequentialNonzeroStructure())
5790 
5791    Level: advanced
5792 
5793     Notes: Frees not only the matrices, but also the array that contains the matrices
5794 
5795 .seealso: MatGetSeqNonzeroStructure()
5796 @*/
5797 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroySeqNonzeroStructure(Mat *mat)
5798 {
5799   PetscErrorCode ierr;
5800 
5801   PetscFunctionBegin;
5802   PetscValidPointer(mat,1);
5803   ierr = MatDestroy(*mat);CHKERRQ(ierr);
5804   PetscFunctionReturn(0);
5805 }
5806 
5807 #undef __FUNCT__
5808 #define __FUNCT__ "MatIncreaseOverlap"
5809 /*@
5810    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5811    replaces the index sets by larger ones that represent submatrices with
5812    additional overlap.
5813 
5814    Collective on Mat
5815 
5816    Input Parameters:
5817 +  mat - the matrix
5818 .  n   - the number of index sets
5819 .  is  - the array of index sets (these index sets will changed during the call)
5820 -  ov  - the additional overlap requested
5821 
5822    Level: developer
5823 
5824    Concepts: overlap
5825    Concepts: ASM^computing overlap
5826 
5827 .seealso: MatGetSubMatrices()
5828 @*/
5829 PetscErrorCode PETSCMAT_DLLEXPORT MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5830 {
5831   PetscErrorCode ierr;
5832 
5833   PetscFunctionBegin;
5834   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5835   PetscValidType(mat,1);
5836   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5837   if (n) {
5838     PetscValidPointer(is,3);
5839     PetscValidHeaderSpecific(*is,IS_COOKIE,3);
5840   }
5841   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5842   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5843   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5844 
5845   if (!ov) PetscFunctionReturn(0);
5846   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5847   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5848   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
5849   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
5850   PetscFunctionReturn(0);
5851 }
5852 
5853 #undef __FUNCT__
5854 #define __FUNCT__ "MatGetBlockSize"
5855 /*@
5856    MatGetBlockSize - Returns the matrix block size; useful especially for the
5857    block row and block diagonal formats.
5858 
5859    Not Collective
5860 
5861    Input Parameter:
5862 .  mat - the matrix
5863 
5864    Output Parameter:
5865 .  bs - block size
5866 
5867    Notes:
5868    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
5869 
5870    Level: intermediate
5871 
5872    Concepts: matrices^block size
5873 
5874 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5875 @*/
5876 PetscErrorCode PETSCMAT_DLLEXPORT MatGetBlockSize(Mat mat,PetscInt *bs)
5877 {
5878   PetscErrorCode ierr;
5879 
5880   PetscFunctionBegin;
5881   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5882   PetscValidType(mat,1);
5883   PetscValidIntPointer(bs,2);
5884   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5885   *bs = mat->rmap->bs;
5886   PetscFunctionReturn(0);
5887 }
5888 
5889 #undef __FUNCT__
5890 #define __FUNCT__ "MatSetBlockSize"
5891 /*@
5892    MatSetBlockSize - Sets the matrix block size; for many matrix types you
5893      cannot use this and MUST set the blocksize when you preallocate the matrix
5894 
5895    Collective on Mat
5896 
5897    Input Parameters:
5898 +  mat - the matrix
5899 -  bs - block size
5900 
5901    Notes:
5902      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
5903      it is not possible to change BAIJ block sizes after preallocation.
5904 
5905    Level: intermediate
5906 
5907    Concepts: matrices^block size
5908 
5909 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5910 @*/
5911 PetscErrorCode PETSCMAT_DLLEXPORT MatSetBlockSize(Mat mat,PetscInt bs)
5912 {
5913   PetscErrorCode ierr;
5914 
5915   PetscFunctionBegin;
5916   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5917   PetscValidType(mat,1);
5918   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5919   if (bs < 1) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Block size %d, must be positive",bs);
5920   if (mat->ops->setblocksize) {
5921     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
5922   } else {
5923     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5924   }
5925   PetscFunctionReturn(0);
5926 }
5927 
5928 #undef __FUNCT__
5929 #define __FUNCT__ "MatGetRowIJ"
5930 /*@C
5931     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
5932 
5933    Collective on Mat
5934 
5935     Input Parameters:
5936 +   mat - the matrix
5937 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5938 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5939                 symmetrized
5940 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5941                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
5942                  always used.
5943 
5944     Output Parameters:
5945 +   n - number of rows in the (possibly compressed) matrix
5946 .   ia - the row pointers [of length n+1]
5947 .   ja - the column indices
5948 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
5949            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
5950 
5951     Level: developer
5952 
5953     Notes: You CANNOT change any of the ia[] or ja[] values.
5954 
5955            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
5956 
5957     Fortran Node
5958 
5959            In Fortran use
5960 $           PetscInt ia(1), ja(1)
5961 $           PetscOffset iia, jja
5962 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
5963 $
5964 $          or
5965 $
5966 $           PetscScalar, pointer :: xx_v(:)
5967 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
5968 
5969 
5970        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
5971 
5972 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5973 @*/
5974 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5975 {
5976   PetscErrorCode ierr;
5977 
5978   PetscFunctionBegin;
5979   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5980   PetscValidType(mat,1);
5981   PetscValidIntPointer(n,4);
5982   if (ia) PetscValidIntPointer(ia,5);
5983   if (ja) PetscValidIntPointer(ja,6);
5984   PetscValidIntPointer(done,7);
5985   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5986   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5987   else {
5988     *done = PETSC_TRUE;
5989     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5990     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
5991     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
5992   }
5993   PetscFunctionReturn(0);
5994 }
5995 
5996 #undef __FUNCT__
5997 #define __FUNCT__ "MatGetColumnIJ"
5998 /*@C
5999     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6000 
6001     Collective on Mat
6002 
6003     Input Parameters:
6004 +   mat - the matrix
6005 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6006 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6007                 symmetrized
6008 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6009                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6010                  always used.
6011 
6012     Output Parameters:
6013 +   n - number of columns in the (possibly compressed) matrix
6014 .   ia - the column pointers
6015 .   ja - the row indices
6016 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6017 
6018     Level: developer
6019 
6020 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6021 @*/
6022 PetscErrorCode PETSCMAT_DLLEXPORT MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6023 {
6024   PetscErrorCode ierr;
6025 
6026   PetscFunctionBegin;
6027   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6028   PetscValidType(mat,1);
6029   PetscValidIntPointer(n,4);
6030   if (ia) PetscValidIntPointer(ia,5);
6031   if (ja) PetscValidIntPointer(ja,6);
6032   PetscValidIntPointer(done,7);
6033   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6034   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6035   else {
6036     *done = PETSC_TRUE;
6037     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6038   }
6039   PetscFunctionReturn(0);
6040 }
6041 
6042 #undef __FUNCT__
6043 #define __FUNCT__ "MatRestoreRowIJ"
6044 /*@C
6045     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6046     MatGetRowIJ().
6047 
6048     Collective on Mat
6049 
6050     Input Parameters:
6051 +   mat - the matrix
6052 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6053 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6054                 symmetrized
6055 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6056                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6057                  always used.
6058 
6059     Output Parameters:
6060 +   n - size of (possibly compressed) matrix
6061 .   ia - the row pointers
6062 .   ja - the column indices
6063 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6064 
6065     Level: developer
6066 
6067 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6068 @*/
6069 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6070 {
6071   PetscErrorCode ierr;
6072 
6073   PetscFunctionBegin;
6074   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6075   PetscValidType(mat,1);
6076   if (ia) PetscValidIntPointer(ia,5);
6077   if (ja) PetscValidIntPointer(ja,6);
6078   PetscValidIntPointer(done,7);
6079   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6080 
6081   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6082   else {
6083     *done = PETSC_TRUE;
6084     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6085   }
6086   PetscFunctionReturn(0);
6087 }
6088 
6089 #undef __FUNCT__
6090 #define __FUNCT__ "MatRestoreColumnIJ"
6091 /*@C
6092     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6093     MatGetColumnIJ().
6094 
6095     Collective on Mat
6096 
6097     Input Parameters:
6098 +   mat - the matrix
6099 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6100 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6101                 symmetrized
6102 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6103                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6104                  always used.
6105 
6106     Output Parameters:
6107 +   n - size of (possibly compressed) matrix
6108 .   ia - the column pointers
6109 .   ja - the row indices
6110 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6111 
6112     Level: developer
6113 
6114 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6115 @*/
6116 PetscErrorCode PETSCMAT_DLLEXPORT MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6117 {
6118   PetscErrorCode ierr;
6119 
6120   PetscFunctionBegin;
6121   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6122   PetscValidType(mat,1);
6123   if (ia) PetscValidIntPointer(ia,5);
6124   if (ja) PetscValidIntPointer(ja,6);
6125   PetscValidIntPointer(done,7);
6126   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6127 
6128   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6129   else {
6130     *done = PETSC_TRUE;
6131     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6132   }
6133   PetscFunctionReturn(0);
6134 }
6135 
6136 #undef __FUNCT__
6137 #define __FUNCT__ "MatColoringPatch"
6138 /*@C
6139     MatColoringPatch -Used inside matrix coloring routines that
6140     use MatGetRowIJ() and/or MatGetColumnIJ().
6141 
6142     Collective on Mat
6143 
6144     Input Parameters:
6145 +   mat - the matrix
6146 .   ncolors - max color value
6147 .   n   - number of entries in colorarray
6148 -   colorarray - array indicating color for each column
6149 
6150     Output Parameters:
6151 .   iscoloring - coloring generated using colorarray information
6152 
6153     Level: developer
6154 
6155 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6156 
6157 @*/
6158 PetscErrorCode PETSCMAT_DLLEXPORT MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6159 {
6160   PetscErrorCode ierr;
6161 
6162   PetscFunctionBegin;
6163   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6164   PetscValidType(mat,1);
6165   PetscValidIntPointer(colorarray,4);
6166   PetscValidPointer(iscoloring,5);
6167   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6168 
6169   if (!mat->ops->coloringpatch){
6170     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6171   } else {
6172     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6173   }
6174   PetscFunctionReturn(0);
6175 }
6176 
6177 
6178 #undef __FUNCT__
6179 #define __FUNCT__ "MatSetUnfactored"
6180 /*@
6181    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6182 
6183    Collective on Mat
6184 
6185    Input Parameter:
6186 .  mat - the factored matrix to be reset
6187 
6188    Notes:
6189    This routine should be used only with factored matrices formed by in-place
6190    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6191    format).  This option can save memory, for example, when solving nonlinear
6192    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6193    ILU(0) preconditioner.
6194 
6195    Note that one can specify in-place ILU(0) factorization by calling
6196 .vb
6197      PCType(pc,PCILU);
6198      PCFactorSeUseInPlace(pc);
6199 .ve
6200    or by using the options -pc_type ilu -pc_factor_in_place
6201 
6202    In-place factorization ILU(0) can also be used as a local
6203    solver for the blocks within the block Jacobi or additive Schwarz
6204    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6205    of these preconditioners in the users manual for details on setting
6206    local solver options.
6207 
6208    Most users should employ the simplified KSP interface for linear solvers
6209    instead of working directly with matrix algebra routines such as this.
6210    See, e.g., KSPCreate().
6211 
6212    Level: developer
6213 
6214 .seealso: PCFactorSetUseInPlace()
6215 
6216    Concepts: matrices^unfactored
6217 
6218 @*/
6219 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUnfactored(Mat mat)
6220 {
6221   PetscErrorCode ierr;
6222 
6223   PetscFunctionBegin;
6224   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6225   PetscValidType(mat,1);
6226   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6227   mat->factor = MAT_FACTOR_NONE;
6228   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6229   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6230   PetscFunctionReturn(0);
6231 }
6232 
6233 /*MC
6234     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6235 
6236     Synopsis:
6237     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6238 
6239     Not collective
6240 
6241     Input Parameter:
6242 .   x - matrix
6243 
6244     Output Parameters:
6245 +   xx_v - the Fortran90 pointer to the array
6246 -   ierr - error code
6247 
6248     Example of Usage:
6249 .vb
6250       PetscScalar, pointer xx_v(:)
6251       ....
6252       call MatGetArrayF90(x,xx_v,ierr)
6253       a = xx_v(3)
6254       call MatRestoreArrayF90(x,xx_v,ierr)
6255 .ve
6256 
6257     Notes:
6258     Not yet supported for all F90 compilers
6259 
6260     Level: advanced
6261 
6262 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6263 
6264     Concepts: matrices^accessing array
6265 
6266 M*/
6267 
6268 /*MC
6269     MatRestoreArrayF90 - Restores a matrix array that has been
6270     accessed with MatGetArrayF90().
6271 
6272     Synopsis:
6273     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6274 
6275     Not collective
6276 
6277     Input Parameters:
6278 +   x - matrix
6279 -   xx_v - the Fortran90 pointer to the array
6280 
6281     Output Parameter:
6282 .   ierr - error code
6283 
6284     Example of Usage:
6285 .vb
6286        PetscScalar, pointer xx_v(:)
6287        ....
6288        call MatGetArrayF90(x,xx_v,ierr)
6289        a = xx_v(3)
6290        call MatRestoreArrayF90(x,xx_v,ierr)
6291 .ve
6292 
6293     Notes:
6294     Not yet supported for all F90 compilers
6295 
6296     Level: advanced
6297 
6298 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6299 
6300 M*/
6301 
6302 
6303 #undef __FUNCT__
6304 #define __FUNCT__ "MatGetSubMatrix"
6305 /*@
6306     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6307                       as the original matrix.
6308 
6309     Collective on Mat
6310 
6311     Input Parameters:
6312 +   mat - the original matrix
6313 .   isrow - parallel IS containing the rows this processor should obtain
6314 .   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.
6315 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6316 
6317     Output Parameter:
6318 .   newmat - the new submatrix, of the same type as the old
6319 
6320     Level: advanced
6321 
6322     Notes:
6323     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
6324 
6325     The rows in isrow will be sorted into the same order as the original matrix on each process.
6326 
6327       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6328    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6329    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6330    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
6331    you are finished using it.
6332 
6333     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6334     the input matrix.
6335 
6336     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
6337 
6338    Example usage:
6339    Consider the following 8x8 matrix with 34 non-zero values, that is
6340    assembled across 3 processors. Lets assume that proc0 owns 3 rows,
6341    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
6342    as follows:
6343 
6344 .vb
6345             1  2  0  |  0  3  0  |  0  4
6346     Proc0   0  5  6  |  7  0  0  |  8  0
6347             9  0 10  | 11  0  0  | 12  0
6348     -------------------------------------
6349            13  0 14  | 15 16 17  |  0  0
6350     Proc1   0 18  0  | 19 20 21  |  0  0
6351             0  0  0  | 22 23  0  | 24  0
6352     -------------------------------------
6353     Proc2  25 26 27  |  0  0 28  | 29  0
6354            30  0  0  | 31 32 33  |  0 34
6355 .ve
6356 
6357     Suppose isrow = [0 1 | 4 | 5 6] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
6358 
6359 .vb
6360             2  0  |  0  3  0  |  0
6361     Proc0   5  6  |  7  0  0  |  8
6362     -------------------------------
6363     Proc1  18  0  | 19 20 21  |  0
6364     -------------------------------
6365     Proc2  26 27  |  0  0 28  | 29
6366             0  0  | 31 32 33  |  0
6367 .ve
6368 
6369 
6370     Concepts: matrices^submatrices
6371 
6372 .seealso: MatGetSubMatrices()
6373 @*/
6374 PetscErrorCode PETSCMAT_DLLEXPORT MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
6375 {
6376   PetscErrorCode ierr;
6377   PetscMPIInt    size;
6378   Mat            *local;
6379   IS             iscoltmp;
6380 
6381   PetscFunctionBegin;
6382   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6383   PetscValidHeaderSpecific(isrow,IS_COOKIE,2);
6384   if (iscol) PetscValidHeaderSpecific(iscol,IS_COOKIE,3);
6385   PetscValidPointer(newmat,5);
6386   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_COOKIE,5);
6387   PetscValidType(mat,1);
6388   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6389   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6390   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6391 
6392   if (!iscol) {
6393     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
6394   } else {
6395     iscoltmp = iscol;
6396   }
6397 
6398   /* if original matrix is on just one processor then use submatrix generated */
6399   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6400     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
6401     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6402     PetscFunctionReturn(0);
6403   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
6404     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
6405     *newmat = *local;
6406     ierr    = PetscFree(local);CHKERRQ(ierr);
6407     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6408     PetscFunctionReturn(0);
6409   } else if (!mat->ops->getsubmatrix) {
6410     /* Create a new matrix type that implements the operation using the full matrix */
6411     switch (cll) {
6412       case MAT_INITIAL_MATRIX:
6413         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
6414         break;
6415       case MAT_REUSE_MATRIX:
6416         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
6417         break;
6418       default: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
6419     }
6420     if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6421     PetscFunctionReturn(0);
6422   }
6423 
6424   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6425   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
6426   if (!iscol) {ierr = ISDestroy(iscoltmp);CHKERRQ(ierr);}
6427   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
6428   PetscFunctionReturn(0);
6429 }
6430 
6431 #undef __FUNCT__
6432 #define __FUNCT__ "MatStashSetInitialSize"
6433 /*@
6434    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6435    used during the assembly process to store values that belong to
6436    other processors.
6437 
6438    Not Collective
6439 
6440    Input Parameters:
6441 +  mat   - the matrix
6442 .  size  - the initial size of the stash.
6443 -  bsize - the initial size of the block-stash(if used).
6444 
6445    Options Database Keys:
6446 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6447 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
6448 
6449    Level: intermediate
6450 
6451    Notes:
6452      The block-stash is used for values set with MatSetValuesBlocked() while
6453      the stash is used for values set with MatSetValues()
6454 
6455      Run with the option -info and look for output of the form
6456      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6457      to determine the appropriate value, MM, to use for size and
6458      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6459      to determine the value, BMM to use for bsize
6460 
6461    Concepts: stash^setting matrix size
6462    Concepts: matrices^stash
6463 
6464 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
6465 
6466 @*/
6467 PetscErrorCode PETSCMAT_DLLEXPORT MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6468 {
6469   PetscErrorCode ierr;
6470 
6471   PetscFunctionBegin;
6472   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6473   PetscValidType(mat,1);
6474   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
6475   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
6476   PetscFunctionReturn(0);
6477 }
6478 
6479 #undef __FUNCT__
6480 #define __FUNCT__ "MatInterpolateAdd"
6481 /*@
6482    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
6483      the matrix
6484 
6485    Collective on Mat
6486 
6487    Input Parameters:
6488 +  mat   - the matrix
6489 .  x,y - the vectors
6490 -  w - where the result is stored
6491 
6492    Level: intermediate
6493 
6494    Notes:
6495     w may be the same vector as y.
6496 
6497     This allows one to use either the restriction or interpolation (its transpose)
6498     matrix to do the interpolation
6499 
6500     Concepts: interpolation
6501 
6502 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6503 
6504 @*/
6505 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6506 {
6507   PetscErrorCode ierr;
6508   PetscInt       M,N;
6509 
6510   PetscFunctionBegin;
6511   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6512   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6513   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6514   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
6515   PetscValidType(A,1);
6516   ierr = MatPreallocated(A);CHKERRQ(ierr);
6517   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6518   if (N > M) {
6519     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
6520   } else {
6521     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
6522   }
6523   PetscFunctionReturn(0);
6524 }
6525 
6526 #undef __FUNCT__
6527 #define __FUNCT__ "MatInterpolate"
6528 /*@
6529    MatInterpolate - y = A*x or A'*x depending on the shape of
6530      the matrix
6531 
6532    Collective on Mat
6533 
6534    Input Parameters:
6535 +  mat   - the matrix
6536 -  x,y - the vectors
6537 
6538    Level: intermediate
6539 
6540    Notes:
6541     This allows one to use either the restriction or interpolation (its transpose)
6542     matrix to do the interpolation
6543 
6544    Concepts: matrices^interpolation
6545 
6546 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
6547 
6548 @*/
6549 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
6550 {
6551   PetscErrorCode ierr;
6552   PetscInt       M,N;
6553 
6554   PetscFunctionBegin;
6555   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6556   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6557   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6558   PetscValidType(A,1);
6559   ierr = MatPreallocated(A);CHKERRQ(ierr);
6560   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6561   if (N > M) {
6562     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6563   } else {
6564     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6565   }
6566   PetscFunctionReturn(0);
6567 }
6568 
6569 #undef __FUNCT__
6570 #define __FUNCT__ "MatRestrict"
6571 /*@
6572    MatRestrict - y = A*x or A'*x
6573 
6574    Collective on Mat
6575 
6576    Input Parameters:
6577 +  mat   - the matrix
6578 -  x,y - the vectors
6579 
6580    Level: intermediate
6581 
6582    Notes:
6583     This allows one to use either the restriction or interpolation (its transpose)
6584     matrix to do the restriction
6585 
6586    Concepts: matrices^restriction
6587 
6588 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
6589 
6590 @*/
6591 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
6592 {
6593   PetscErrorCode ierr;
6594   PetscInt       M,N;
6595 
6596   PetscFunctionBegin;
6597   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6598   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
6599   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
6600   PetscValidType(A,1);
6601   ierr = MatPreallocated(A);CHKERRQ(ierr);
6602 
6603   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
6604   if (N > M) {
6605     ierr = MatMult(A,x,y);CHKERRQ(ierr);
6606   } else {
6607     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
6608   }
6609   PetscFunctionReturn(0);
6610 }
6611 
6612 #undef __FUNCT__
6613 #define __FUNCT__ "MatNullSpaceAttach"
6614 /*@
6615    MatNullSpaceAttach - attaches a null space to a matrix.
6616         This null space will be removed from the resulting vector whenever
6617         MatMult() is called
6618 
6619    Collective on Mat
6620 
6621    Input Parameters:
6622 +  mat - the matrix
6623 -  nullsp - the null space object
6624 
6625    Level: developer
6626 
6627    Notes:
6628       Overwrites any previous null space that may have been attached
6629 
6630    Concepts: null space^attaching to matrix
6631 
6632 .seealso: MatCreate(), MatNullSpaceCreate()
6633 @*/
6634 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6635 {
6636   PetscErrorCode ierr;
6637 
6638   PetscFunctionBegin;
6639   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6640   PetscValidType(mat,1);
6641   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
6642   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6643   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
6644   if (mat->nullsp) { ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); }
6645   mat->nullsp = nullsp;
6646   PetscFunctionReturn(0);
6647 }
6648 
6649 #undef __FUNCT__
6650 #define __FUNCT__ "MatICCFactor"
6651 /*@C
6652    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
6653 
6654    Collective on Mat
6655 
6656    Input Parameters:
6657 +  mat - the matrix
6658 .  row - row/column permutation
6659 .  fill - expected fill factor >= 1.0
6660 -  level - level of fill, for ICC(k)
6661 
6662    Notes:
6663    Probably really in-place only when level of fill is zero, otherwise allocates
6664    new space to store factored matrix and deletes previous memory.
6665 
6666    Most users should employ the simplified KSP interface for linear solvers
6667    instead of working directly with matrix algebra routines such as this.
6668    See, e.g., KSPCreate().
6669 
6670    Level: developer
6671 
6672    Concepts: matrices^incomplete Cholesky factorization
6673    Concepts: Cholesky factorization
6674 
6675 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6676 
6677     Developer Note: fortran interface is not autogenerated as the f90
6678     interface defintion cannot be generated correctly [due to MatFactorInfo]
6679 
6680 @*/
6681 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6682 {
6683   PetscErrorCode ierr;
6684 
6685   PetscFunctionBegin;
6686   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6687   PetscValidType(mat,1);
6688   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
6689   PetscValidPointer(info,3);
6690   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6691   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6692   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6693   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6694   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6695   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
6696   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6697   PetscFunctionReturn(0);
6698 }
6699 
6700 #undef __FUNCT__
6701 #define __FUNCT__ "MatSetValuesAdic"
6702 /*@
6703    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
6704 
6705    Not Collective
6706 
6707    Input Parameters:
6708 +  mat - the matrix
6709 -  v - the values compute with ADIC
6710 
6711    Level: developer
6712 
6713    Notes:
6714      Must call MatSetColoring() before using this routine. Also this matrix must already
6715      have its nonzero pattern determined.
6716 
6717 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6718           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6719 @*/
6720 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
6721 {
6722   PetscErrorCode ierr;
6723 
6724   PetscFunctionBegin;
6725   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6726   PetscValidType(mat,1);
6727   PetscValidPointer(mat,2);
6728 
6729   if (!mat->assembled) {
6730     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6731   }
6732   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6733   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6734   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
6735   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6736   ierr = MatView_Private(mat);CHKERRQ(ierr);
6737   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6738   PetscFunctionReturn(0);
6739 }
6740 
6741 
6742 #undef __FUNCT__
6743 #define __FUNCT__ "MatSetColoring"
6744 /*@
6745    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
6746 
6747    Not Collective
6748 
6749    Input Parameters:
6750 +  mat - the matrix
6751 -  coloring - the coloring
6752 
6753    Level: developer
6754 
6755 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6756           MatSetValues(), MatSetValuesAdic()
6757 @*/
6758 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
6759 {
6760   PetscErrorCode ierr;
6761 
6762   PetscFunctionBegin;
6763   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6764   PetscValidType(mat,1);
6765   PetscValidPointer(coloring,2);
6766 
6767   if (!mat->assembled) {
6768     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6769   }
6770   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6771   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
6772   PetscFunctionReturn(0);
6773 }
6774 
6775 #undef __FUNCT__
6776 #define __FUNCT__ "MatSetValuesAdifor"
6777 /*@
6778    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
6779 
6780    Not Collective
6781 
6782    Input Parameters:
6783 +  mat - the matrix
6784 .  nl - leading dimension of v
6785 -  v - the values compute with ADIFOR
6786 
6787    Level: developer
6788 
6789    Notes:
6790      Must call MatSetColoring() before using this routine. Also this matrix must already
6791      have its nonzero pattern determined.
6792 
6793 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6794           MatSetValues(), MatSetColoring()
6795 @*/
6796 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6797 {
6798   PetscErrorCode ierr;
6799 
6800   PetscFunctionBegin;
6801   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6802   PetscValidType(mat,1);
6803   PetscValidPointer(v,3);
6804 
6805   if (!mat->assembled) {
6806     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6807   }
6808   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6809   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6810   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
6811   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
6812   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6813   PetscFunctionReturn(0);
6814 }
6815 
6816 #undef __FUNCT__
6817 #define __FUNCT__ "MatDiagonalScaleLocal"
6818 /*@
6819    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
6820          ghosted ones.
6821 
6822    Not Collective
6823 
6824    Input Parameters:
6825 +  mat - the matrix
6826 -  diag = the diagonal values, including ghost ones
6827 
6828    Level: developer
6829 
6830    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6831 
6832 .seealso: MatDiagonalScale()
6833 @*/
6834 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
6835 {
6836   PetscErrorCode ierr;
6837   PetscMPIInt    size;
6838 
6839   PetscFunctionBegin;
6840   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6841   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
6842   PetscValidType(mat,1);
6843 
6844   if (!mat->assembled) {
6845     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6846   }
6847   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6848   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
6849   if (size == 1) {
6850     PetscInt n,m;
6851     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
6852     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
6853     if (m == n) {
6854       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
6855     } else {
6856       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6857     }
6858   } else {
6859     PetscErrorCode (*f)(Mat,Vec);
6860     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
6861     if (f) {
6862       ierr = (*f)(mat,diag);CHKERRQ(ierr);
6863     } else {
6864       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6865     }
6866   }
6867   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
6868   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6869   PetscFunctionReturn(0);
6870 }
6871 
6872 #undef __FUNCT__
6873 #define __FUNCT__ "MatGetInertia"
6874 /*@
6875    MatGetInertia - Gets the inertia from a factored matrix
6876 
6877    Collective on Mat
6878 
6879    Input Parameter:
6880 .  mat - the matrix
6881 
6882    Output Parameters:
6883 +   nneg - number of negative eigenvalues
6884 .   nzero - number of zero eigenvalues
6885 -   npos - number of positive eigenvalues
6886 
6887    Level: advanced
6888 
6889    Notes: Matrix must have been factored by MatCholeskyFactor()
6890 
6891 
6892 @*/
6893 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6894 {
6895   PetscErrorCode ierr;
6896 
6897   PetscFunctionBegin;
6898   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6899   PetscValidType(mat,1);
6900   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6901   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6902   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6903   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
6904   PetscFunctionReturn(0);
6905 }
6906 
6907 /* ----------------------------------------------------------------*/
6908 #undef __FUNCT__
6909 #define __FUNCT__ "MatSolves"
6910 /*@C
6911    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
6912 
6913    Collective on Mat and Vecs
6914 
6915    Input Parameters:
6916 +  mat - the factored matrix
6917 -  b - the right-hand-side vectors
6918 
6919    Output Parameter:
6920 .  x - the result vectors
6921 
6922    Notes:
6923    The vectors b and x cannot be the same.  I.e., one cannot
6924    call MatSolves(A,x,x).
6925 
6926    Notes:
6927    Most users should employ the simplified KSP interface for linear solvers
6928    instead of working directly with matrix algebra routines such as this.
6929    See, e.g., KSPCreate().
6930 
6931    Level: developer
6932 
6933    Concepts: matrices^triangular solves
6934 
6935 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6936 @*/
6937 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
6938 {
6939   PetscErrorCode ierr;
6940 
6941   PetscFunctionBegin;
6942   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
6943   PetscValidType(mat,1);
6944   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6945   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6946   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
6947 
6948   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6949   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6950   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6951   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
6952   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
6953   PetscFunctionReturn(0);
6954 }
6955 
6956 #undef __FUNCT__
6957 #define __FUNCT__ "MatIsSymmetric"
6958 /*@
6959    MatIsSymmetric - Test whether a matrix is symmetric
6960 
6961    Collective on Mat
6962 
6963    Input Parameter:
6964 +  A - the matrix to test
6965 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
6966 
6967    Output Parameters:
6968 .  flg - the result
6969 
6970    Level: intermediate
6971 
6972    Concepts: matrix^symmetry
6973 
6974 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6975 @*/
6976 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6977 {
6978   PetscErrorCode ierr;
6979 
6980   PetscFunctionBegin;
6981   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6982   PetscValidPointer(flg,2);
6983 
6984   if (!A->symmetric_set) {
6985     if (!A->ops->issymmetric) {
6986       const MatType mattype;
6987       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
6988       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6989     }
6990     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
6991     if (!tol) {
6992       A->symmetric_set = PETSC_TRUE;
6993       A->symmetric = *flg;
6994       if (A->symmetric) {
6995 	A->structurally_symmetric_set = PETSC_TRUE;
6996 	A->structurally_symmetric     = PETSC_TRUE;
6997       }
6998     }
6999   } else if (A->symmetric) {
7000     *flg = PETSC_TRUE;
7001   } else if (!tol) {
7002     *flg = PETSC_FALSE;
7003   } else {
7004     if (!A->ops->issymmetric) {
7005       const MatType mattype;
7006       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7007       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7008     }
7009     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7010   }
7011   PetscFunctionReturn(0);
7012 }
7013 
7014 #undef __FUNCT__
7015 #define __FUNCT__ "MatIsHermitian"
7016 /*@
7017    MatIsHermitian - Test whether a matrix is Hermitian
7018 
7019    Collective on Mat
7020 
7021    Input Parameter:
7022 +  A - the matrix to test
7023 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7024 
7025    Output Parameters:
7026 .  flg - the result
7027 
7028    Level: intermediate
7029 
7030    Concepts: matrix^symmetry
7031 
7032 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7033 @*/
7034 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
7035 {
7036   PetscErrorCode ierr;
7037 
7038   PetscFunctionBegin;
7039   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7040   PetscValidPointer(flg,2);
7041 
7042   if (!A->hermitian_set) {
7043     if (!A->ops->ishermitian) {
7044       const MatType mattype;
7045       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7046       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7047     }
7048     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7049     if (!tol) {
7050       A->hermitian_set = PETSC_TRUE;
7051       A->hermitian = *flg;
7052       if (A->hermitian) {
7053 	A->structurally_symmetric_set = PETSC_TRUE;
7054 	A->structurally_symmetric     = PETSC_TRUE;
7055       }
7056     }
7057   } else if (A->hermitian) {
7058     *flg = PETSC_TRUE;
7059   } else if (!tol) {
7060     *flg = PETSC_FALSE;
7061   } else {
7062     if (!A->ops->ishermitian) {
7063       const MatType mattype;
7064       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7065       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7066     }
7067     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7068   }
7069   PetscFunctionReturn(0);
7070 }
7071 
7072 #undef __FUNCT__
7073 #define __FUNCT__ "MatIsSymmetricKnown"
7074 /*@
7075    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7076 
7077    Collective on Mat
7078 
7079    Input Parameter:
7080 .  A - the matrix to check
7081 
7082    Output Parameters:
7083 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7084 -  flg - the result
7085 
7086    Level: advanced
7087 
7088    Concepts: matrix^symmetry
7089 
7090    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7091          if you want it explicitly checked
7092 
7093 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7094 @*/
7095 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7096 {
7097   PetscFunctionBegin;
7098   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7099   PetscValidPointer(set,2);
7100   PetscValidPointer(flg,3);
7101   if (A->symmetric_set) {
7102     *set = PETSC_TRUE;
7103     *flg = A->symmetric;
7104   } else {
7105     *set = PETSC_FALSE;
7106   }
7107   PetscFunctionReturn(0);
7108 }
7109 
7110 #undef __FUNCT__
7111 #define __FUNCT__ "MatIsHermitianKnown"
7112 /*@
7113    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7114 
7115    Collective on Mat
7116 
7117    Input Parameter:
7118 .  A - the matrix to check
7119 
7120    Output Parameters:
7121 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7122 -  flg - the result
7123 
7124    Level: advanced
7125 
7126    Concepts: matrix^symmetry
7127 
7128    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7129          if you want it explicitly checked
7130 
7131 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7132 @*/
7133 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7134 {
7135   PetscFunctionBegin;
7136   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7137   PetscValidPointer(set,2);
7138   PetscValidPointer(flg,3);
7139   if (A->hermitian_set) {
7140     *set = PETSC_TRUE;
7141     *flg = A->hermitian;
7142   } else {
7143     *set = PETSC_FALSE;
7144   }
7145   PetscFunctionReturn(0);
7146 }
7147 
7148 #undef __FUNCT__
7149 #define __FUNCT__ "MatIsStructurallySymmetric"
7150 /*@
7151    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7152 
7153    Collective on Mat
7154 
7155    Input Parameter:
7156 .  A - the matrix to test
7157 
7158    Output Parameters:
7159 .  flg - the result
7160 
7161    Level: intermediate
7162 
7163    Concepts: matrix^symmetry
7164 
7165 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7166 @*/
7167 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
7168 {
7169   PetscErrorCode ierr;
7170 
7171   PetscFunctionBegin;
7172   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7173   PetscValidPointer(flg,2);
7174   if (!A->structurally_symmetric_set) {
7175     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7176     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7177     A->structurally_symmetric_set = PETSC_TRUE;
7178   }
7179   *flg = A->structurally_symmetric;
7180   PetscFunctionReturn(0);
7181 }
7182 
7183 #undef __FUNCT__
7184 #define __FUNCT__ "MatStashGetInfo"
7185 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7186 /*@
7187    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7188        to be communicated to other processors during the MatAssemblyBegin/End() process
7189 
7190     Not collective
7191 
7192    Input Parameter:
7193 .   vec - the vector
7194 
7195    Output Parameters:
7196 +   nstash   - the size of the stash
7197 .   reallocs - the number of additional mallocs incurred.
7198 .   bnstash   - the size of the block stash
7199 -   breallocs - the number of additional mallocs incurred.in the block stash
7200 
7201    Level: advanced
7202 
7203 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7204 
7205 @*/
7206 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7207 {
7208   PetscErrorCode ierr;
7209   PetscFunctionBegin;
7210   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7211   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7212   PetscFunctionReturn(0);
7213 }
7214 
7215 #undef __FUNCT__
7216 #define __FUNCT__ "MatGetVecs"
7217 /*@C
7218    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7219      parallel layout
7220 
7221    Collective on Mat
7222 
7223    Input Parameter:
7224 .  mat - the matrix
7225 
7226    Output Parameter:
7227 +   right - (optional) vector that the matrix can be multiplied against
7228 -   left - (optional) vector that the matrix vector product can be stored in
7229 
7230   Level: advanced
7231 
7232 .seealso: MatCreate()
7233 @*/
7234 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
7235 {
7236   PetscErrorCode ierr;
7237 
7238   PetscFunctionBegin;
7239   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7240   PetscValidType(mat,1);
7241   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7242   if (mat->ops->getvecs) {
7243     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7244   } else {
7245     PetscMPIInt size;
7246     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7247     if (right) {
7248       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7249       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7250       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7251       if (size > 1) {
7252         /* New vectors uses Mat cmap and does not create a new one */
7253 	ierr = PetscLayoutDestroy((*right)->map);CHKERRQ(ierr);
7254 	(*right)->map = mat->cmap;
7255 	mat->cmap->refcnt++;
7256 
7257         ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);
7258       } else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
7259     }
7260     if (left) {
7261       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7262       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7263       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7264       if (size > 1) {
7265         /* New vectors uses Mat rmap and does not create a new one */
7266 	ierr = PetscLayoutDestroy((*left)->map);CHKERRQ(ierr);
7267 	(*left)->map = mat->rmap;
7268 	mat->rmap->refcnt++;
7269 
7270         ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);
7271       } else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
7272     }
7273   }
7274   if (mat->mapping) {
7275     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->mapping);CHKERRQ(ierr);}
7276     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->mapping);CHKERRQ(ierr);}
7277   }
7278   if (mat->bmapping) {
7279     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);CHKERRQ(ierr);}
7280     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);CHKERRQ(ierr);}
7281   }
7282   PetscFunctionReturn(0);
7283 }
7284 
7285 #undef __FUNCT__
7286 #define __FUNCT__ "MatFactorInfoInitialize"
7287 /*@C
7288    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7289      with default values.
7290 
7291    Not Collective
7292 
7293    Input Parameters:
7294 .    info - the MatFactorInfo data structure
7295 
7296 
7297    Notes: The solvers are generally used through the KSP and PC objects, for example
7298           PCLU, PCILU, PCCHOLESKY, PCICC
7299 
7300    Level: developer
7301 
7302 .seealso: MatFactorInfo
7303 
7304     Developer Note: fortran interface is not autogenerated as the f90
7305     interface defintion cannot be generated correctly [due to MatFactorInfo]
7306 
7307 @*/
7308 
7309 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
7310 {
7311   PetscErrorCode ierr;
7312 
7313   PetscFunctionBegin;
7314   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
7315   PetscFunctionReturn(0);
7316 }
7317 
7318 #undef __FUNCT__
7319 #define __FUNCT__ "MatPtAP"
7320 /*@
7321    MatPtAP - Creates the matrix projection C = P^T * A * P
7322 
7323    Collective on Mat
7324 
7325    Input Parameters:
7326 +  A - the matrix
7327 .  P - the projection matrix
7328 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7329 -  fill - expected fill as ratio of nnz(C)/nnz(A)
7330 
7331    Output Parameters:
7332 .  C - the product matrix
7333 
7334    Notes:
7335    C will be created and must be destroyed by the user with MatDestroy().
7336 
7337    This routine is currently only implemented for pairs of AIJ matrices and classes
7338    which inherit from AIJ.
7339 
7340    Level: intermediate
7341 
7342 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7343 @*/
7344 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7345 {
7346   PetscErrorCode ierr;
7347 
7348   PetscFunctionBegin;
7349   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7350   PetscValidType(A,1);
7351   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7352   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7353   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7354   PetscValidType(P,2);
7355   ierr = MatPreallocated(P);CHKERRQ(ierr);
7356   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7357   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7358   PetscValidPointer(C,3);
7359   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7360   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7361   ierr = MatPreallocated(A);CHKERRQ(ierr);
7362 
7363   if (!A->ops->ptap) {
7364     const MatType mattype;
7365     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7366     SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
7367   }
7368   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7369   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
7370   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
7371 
7372   PetscFunctionReturn(0);
7373 }
7374 
7375 #undef __FUNCT__
7376 #define __FUNCT__ "MatPtAPNumeric"
7377 /*@
7378    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
7379 
7380    Collective on Mat
7381 
7382    Input Parameters:
7383 +  A - the matrix
7384 -  P - the projection matrix
7385 
7386    Output Parameters:
7387 .  C - the product matrix
7388 
7389    Notes:
7390    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7391    the user using MatDeatroy().
7392 
7393    This routine is currently only implemented for pairs of AIJ matrices and classes
7394    which inherit from AIJ.  C will be of type MATAIJ.
7395 
7396    Level: intermediate
7397 
7398 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7399 @*/
7400 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
7401 {
7402   PetscErrorCode ierr;
7403 
7404   PetscFunctionBegin;
7405   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7406   PetscValidType(A,1);
7407   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7408   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7409   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7410   PetscValidType(P,2);
7411   ierr = MatPreallocated(P);CHKERRQ(ierr);
7412   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7413   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7414   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
7415   PetscValidType(C,3);
7416   ierr = MatPreallocated(C);CHKERRQ(ierr);
7417   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7418   if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7419   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7420   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);
7421   if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7422   ierr = MatPreallocated(A);CHKERRQ(ierr);
7423 
7424   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7425   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
7426   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
7427   PetscFunctionReturn(0);
7428 }
7429 
7430 #undef __FUNCT__
7431 #define __FUNCT__ "MatPtAPSymbolic"
7432 /*@
7433    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
7434 
7435    Collective on Mat
7436 
7437    Input Parameters:
7438 +  A - the matrix
7439 -  P - the projection matrix
7440 
7441    Output Parameters:
7442 .  C - the (i,j) structure of the product matrix
7443 
7444    Notes:
7445    C will be created and must be destroyed by the user with MatDestroy().
7446 
7447    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
7448    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
7449    this (i,j) structure by calling MatPtAPNumeric().
7450 
7451    Level: intermediate
7452 
7453 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7454 @*/
7455 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7456 {
7457   PetscErrorCode ierr;
7458 
7459   PetscFunctionBegin;
7460   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7461   PetscValidType(A,1);
7462   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7463   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7464   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7465   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
7466   PetscValidType(P,2);
7467   ierr = MatPreallocated(P);CHKERRQ(ierr);
7468   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7469   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7470   PetscValidPointer(C,3);
7471 
7472   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7473   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);
7474   ierr = MatPreallocated(A);CHKERRQ(ierr);
7475   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7476   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
7477   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
7478 
7479   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
7480 
7481   PetscFunctionReturn(0);
7482 }
7483 
7484 #undef __FUNCT__
7485 #define __FUNCT__ "MatMatMult"
7486 /*@
7487    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
7488 
7489    Collective on Mat
7490 
7491    Input Parameters:
7492 +  A - the left matrix
7493 .  B - the right matrix
7494 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7495 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7496           if the result is a dense matrix this is irrelevent
7497 
7498    Output Parameters:
7499 .  C - the product matrix
7500 
7501    Notes:
7502    Unless scall is MAT_REUSE_MATRIX C will be created.
7503 
7504    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7505 
7506    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7507    actually needed.
7508 
7509    If you have many matrices with the same non-zero structure to multiply, you
7510    should either
7511 $   1) use MAT_REUSE_MATRIX in all calls but the first or
7512 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
7513 
7514    Level: intermediate
7515 
7516 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7517 @*/
7518 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7519 {
7520   PetscErrorCode ierr;
7521   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7522   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7523   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
7524 
7525   PetscFunctionBegin;
7526   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7527   PetscValidType(A,1);
7528   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7529   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7530   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7531   PetscValidType(B,2);
7532   ierr = MatPreallocated(B);CHKERRQ(ierr);
7533   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7534   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7535   PetscValidPointer(C,3);
7536   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7537   if (scall == MAT_REUSE_MATRIX){
7538     PetscValidPointer(*C,5);
7539     PetscValidHeaderSpecific(*C,MAT_COOKIE,5);
7540   }
7541   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7542   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7543   ierr = MatPreallocated(A);CHKERRQ(ierr);
7544 
7545   fA = A->ops->matmult;
7546   fB = B->ops->matmult;
7547   if (fB == fA) {
7548     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7549     mult = fB;
7550   } else {
7551     /* dispatch based on the type of A and B */
7552     char  multname[256];
7553     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
7554     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7555     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
7556     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7557     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7558     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
7559     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);
7560   }
7561   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7562   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
7563   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
7564   PetscFunctionReturn(0);
7565 }
7566 
7567 #undef __FUNCT__
7568 #define __FUNCT__ "MatMatMultSymbolic"
7569 /*@
7570    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
7571    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
7572 
7573    Collective on Mat
7574 
7575    Input Parameters:
7576 +  A - the left matrix
7577 .  B - the right matrix
7578 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7579       if C is a dense matrix this is irrelevent
7580 
7581    Output Parameters:
7582 .  C - the product matrix
7583 
7584    Notes:
7585    Unless scall is MAT_REUSE_MATRIX C will be created.
7586 
7587    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7588    actually needed.
7589 
7590    This routine is currently implemented for
7591     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7592     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7593     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7594 
7595    Level: intermediate
7596 
7597 .seealso: MatMatMult(), MatMatMultNumeric()
7598 @*/
7599 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7600 {
7601   PetscErrorCode ierr;
7602   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7603   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7604   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
7605 
7606   PetscFunctionBegin;
7607   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7608   PetscValidType(A,1);
7609   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7610   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7611 
7612   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7613   PetscValidType(B,2);
7614   ierr = MatPreallocated(B);CHKERRQ(ierr);
7615   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7616   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7617   PetscValidPointer(C,3);
7618 
7619   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7620   if (fill == PETSC_DEFAULT) fill = 2.0;
7621   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7622   ierr = MatPreallocated(A);CHKERRQ(ierr);
7623 
7624   Asymbolic = A->ops->matmultsymbolic;
7625   Bsymbolic = B->ops->matmultsymbolic;
7626   if (Asymbolic == Bsymbolic){
7627     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7628     symbolic = Bsymbolic;
7629   } else { /* dispatch based on the type of A and B */
7630     char  symbolicname[256];
7631     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
7632     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7633     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
7634     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7635     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
7636     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
7637     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);
7638   }
7639   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7640   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
7641   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
7642   PetscFunctionReturn(0);
7643 }
7644 
7645 #undef __FUNCT__
7646 #define __FUNCT__ "MatMatMultNumeric"
7647 /*@
7648    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7649    Call this routine after first calling MatMatMultSymbolic().
7650 
7651    Collective on Mat
7652 
7653    Input Parameters:
7654 +  A - the left matrix
7655 -  B - the right matrix
7656 
7657    Output Parameters:
7658 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
7659 
7660    Notes:
7661    C must have been created with MatMatMultSymbolic().
7662 
7663    This routine is currently implemented for
7664     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7665     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7666     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
7667 
7668    Level: intermediate
7669 
7670 .seealso: MatMatMult(), MatMatMultSymbolic()
7671 @*/
7672 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
7673 {
7674   PetscErrorCode ierr;
7675   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7676   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7677   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
7678 
7679   PetscFunctionBegin;
7680   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7681   PetscValidType(A,1);
7682   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7683   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7684 
7685   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7686   PetscValidType(B,2);
7687   ierr = MatPreallocated(B);CHKERRQ(ierr);
7688   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7689   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7690 
7691   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
7692   PetscValidType(C,3);
7693   ierr = MatPreallocated(C);CHKERRQ(ierr);
7694   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7695   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7696 
7697   if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7698   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7699   if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7700   ierr = MatPreallocated(A);CHKERRQ(ierr);
7701 
7702   Anumeric = A->ops->matmultnumeric;
7703   Bnumeric = B->ops->matmultnumeric;
7704   if (Anumeric == Bnumeric){
7705     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7706     numeric = Bnumeric;
7707   } else {
7708     char  numericname[256];
7709     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
7710     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
7711     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
7712     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
7713     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
7714     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
7715     if (!numeric)
7716       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7717   }
7718   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7719   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
7720   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
7721   PetscFunctionReturn(0);
7722 }
7723 
7724 #undef __FUNCT__
7725 #define __FUNCT__ "MatMatMultTranspose"
7726 /*@
7727    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
7728 
7729    Collective on Mat
7730 
7731    Input Parameters:
7732 +  A - the left matrix
7733 .  B - the right matrix
7734 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7735 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
7736 
7737    Output Parameters:
7738 .  C - the product matrix
7739 
7740    Notes:
7741    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
7742 
7743    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
7744 
7745   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
7746    actually needed.
7747 
7748    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
7749    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
7750 
7751    Level: intermediate
7752 
7753 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7754 @*/
7755 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7756 {
7757   PetscErrorCode ierr;
7758   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7759   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7760 
7761   PetscFunctionBegin;
7762   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
7763   PetscValidType(A,1);
7764   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7765   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7766   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
7767   PetscValidType(B,2);
7768   ierr = MatPreallocated(B);CHKERRQ(ierr);
7769   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7770   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7771   PetscValidPointer(C,3);
7772   if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7773   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7774   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7775   ierr = MatPreallocated(A);CHKERRQ(ierr);
7776 
7777   fA = A->ops->matmulttranspose;
7778   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7779   fB = B->ops->matmulttranspose;
7780   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7781   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);
7782 
7783   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7784   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
7785   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
7786 
7787   PetscFunctionReturn(0);
7788 }
7789 
7790 #undef __FUNCT__
7791 #define __FUNCT__ "MatGetRedundantMatrix"
7792 /*@C
7793    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
7794 
7795    Collective on Mat
7796 
7797    Input Parameters:
7798 +  mat - the matrix
7799 .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7800 .  subcomm - MPI communicator split from the communicator where mat resides in
7801 .  mlocal_red - number of local rows of the redundant matrix
7802 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7803 
7804    Output Parameter:
7805 .  matredundant - redundant matrix
7806 
7807    Notes:
7808    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7809    original matrix has not changed from that last call to MatGetRedundantMatrix().
7810 
7811    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
7812    calling it.
7813 
7814    Only MPIAIJ matrix is supported.
7815 
7816    Level: advanced
7817 
7818    Concepts: subcommunicator
7819    Concepts: duplicate matrix
7820 
7821 .seealso: MatDestroy()
7822 @*/
7823 PetscErrorCode PETSCMAT_DLLEXPORT MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7824 {
7825   PetscErrorCode ierr;
7826 
7827   PetscFunctionBegin;
7828   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
7829   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7830     PetscValidPointer(*matredundant,6);
7831     PetscValidHeaderSpecific(*matredundant,MAT_COOKIE,6);
7832   }
7833   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7834   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7835   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7836   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7837 
7838   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7839   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
7840   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
7841   PetscFunctionReturn(0);
7842 }
7843