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