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