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