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