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