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