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