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