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